On 6/19/2026 8:31 AM, Ackerley Tng via B4 Relay wrote:

[...]

>  
> +static u64 kvm_gmem_get_attributes(struct inode *inode, pgoff_t index)
> +{
> +     struct maple_tree *mt = &GMEM_I(inode)->attributes;
> +     void *entry = mtree_load(mt, index);
> +
> +     return WARN_ON_ONCE(!entry) ? 0 : xa_to_value(entry);

If the entry is unexpectedly missing, returning 0 means the attribute would be 
treated as shared.
And then in kvm_gmem_fault_user_mapping(), it would allow the userspace to 
fault in the folio.

Should gmem deny such edge case?

> +}
> +
> +static bool kvm_gmem_is_private_mem(struct inode *inode, pgoff_t index)
> +{
> +     return kvm_gmem_get_attributes(inode, index) & 
> KVM_MEMORY_ATTRIBUTE_PRIVATE;
> +}
> +
> +static bool kvm_gmem_is_shared_mem(struct inode *inode, pgoff_t index)
> +{
> +     return !kvm_gmem_is_private_mem(inode, index);
> +}
> +
>  static int __kvm_gmem_prepare_folio(struct kvm *kvm, struct kvm_memory_slot 
> *slot,
>                                   pgoff_t index, struct folio *folio)
>  {
> @@ -397,10 +423,13 @@ static vm_fault_t kvm_gmem_fault_user_mapping(struct 
> vm_fault *vmf)
>       if (((loff_t)vmf->pgoff << PAGE_SHIFT) >= i_size_read(inode))
>               return VM_FAULT_SIGBUS;
>  
> -     if (!(GMEM_I(inode)->flags & GUEST_MEMFD_FLAG_INIT_SHARED))
> -             return VM_FAULT_SIGBUS;
> +     filemap_invalidate_lock_shared(inode->i_mapping);
> +     if (kvm_gmem_is_shared_mem(inode, vmf->pgoff))
> +             folio = kvm_gmem_get_folio(inode, vmf->pgoff);
> +     else
> +             folio = ERR_PTR(-EACCES);
> +     filemap_invalidate_unlock_shared(inode->i_mapping);
>  
> -     folio = kvm_gmem_get_folio(inode, vmf->pgoff);
>       if (IS_ERR(folio)) {
>               if (PTR_ERR(folio) == -EAGAIN)
>                       return VM_FAULT_RETRY;
> @@ -557,6 +586,51 @@ bool __weak kvm_arch_supports_gmem_init_shared(struct 
> kvm *kvm)
>       return true;
>  }
>  

Reply via email to