diff --git a/drivers/virt/gunyah/vm_mgr.c b/drivers/virt/gunyah/vm_mgr.c index e2a5558abd0b..eefef8628bb0 100644 --- a/drivers/virt/gunyah/vm_mgr.c +++ b/drivers/virt/gunyah/vm_mgr.c @@ -658,8 +658,12 @@ static long gh_vm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) struct gh_vm *ghvm = filp->private_data; void __user *argp = (void __user *)arg; long r; + bool lend = false; switch (cmd) { + case GH_VM_ANDROID_LEND_USER_MEM: + lend = true; + fallthrough; case GH_VM_SET_USER_MEM_REGION: { struct gh_userspace_memory_region region; @@ -673,7 +677,7 @@ static long gh_vm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (region.flags & ~(GH_MEM_ALLOW_READ | GH_MEM_ALLOW_WRITE | GH_MEM_ALLOW_EXEC)) return -EINVAL; - r = gh_vm_mem_alloc(ghvm, ®ion); + r = gh_vm_mem_alloc(ghvm, ®ion, lend); break; } case GH_VM_SET_DTB_CONFIG: { diff --git a/drivers/virt/gunyah/vm_mgr.h b/drivers/virt/gunyah/vm_mgr.h index df78756639b6..56601661b995 100644 --- a/drivers/virt/gunyah/vm_mgr.h +++ b/drivers/virt/gunyah/vm_mgr.h @@ -60,7 +60,7 @@ struct gh_vm { struct rw_semaphore mmio_handler_lock; }; -int gh_vm_mem_alloc(struct gh_vm *ghvm, struct gh_userspace_memory_region *region); +int gh_vm_mem_alloc(struct gh_vm *ghvm, struct gh_userspace_memory_region *region, bool lend); void gh_vm_mem_reclaim(struct gh_vm *ghvm, struct gh_vm_mem *mapping); int gh_vm_mem_free(struct gh_vm *ghvm, u32 label); struct gh_vm_mem *gh_vm_mem_find_by_label(struct gh_vm *ghvm, u32 label); diff --git a/drivers/virt/gunyah/vm_mgr_mm.c b/drivers/virt/gunyah/vm_mgr_mm.c index 6e1d2e8bddb7..b8896ca6941b 100644 --- a/drivers/virt/gunyah/vm_mgr_mm.c +++ b/drivers/virt/gunyah/vm_mgr_mm.c @@ -85,7 +85,7 @@ struct gh_vm_mem *gh_vm_mem_find_by_label(struct gh_vm *ghvm, u32 label) return mapping ? : ERR_PTR(-ENODEV); } -int gh_vm_mem_alloc(struct gh_vm *ghvm, struct gh_userspace_memory_region *region) +int gh_vm_mem_alloc(struct gh_vm *ghvm, struct gh_userspace_memory_region *region, bool lend) { struct gh_vm_mem *mapping, *tmp_mapping; struct gh_rm_mem_entry *mem_entries; @@ -157,8 +157,13 @@ int gh_vm_mem_alloc(struct gh_vm *ghvm, struct gh_userspace_memory_region *regio goto reclaim; } - parcel->n_acl_entries = 2; - mapping->share_type = VM_MEM_SHARE; + if (lend) { + parcel->n_acl_entries = 1; + mapping->share_type = VM_MEM_LEND; + } else { + parcel->n_acl_entries = 2; + mapping->share_type = VM_MEM_SHARE; + } parcel->acl_entries = kcalloc(parcel->n_acl_entries, sizeof(*parcel->acl_entries), GFP_KERNEL); if (!parcel->acl_entries) { diff --git a/include/uapi/linux/gunyah.h b/include/uapi/linux/gunyah.h index f8482ff4cc55..586cb727fe12 100644 --- a/include/uapi/linux/gunyah.h +++ b/include/uapi/linux/gunyah.h @@ -254,4 +254,14 @@ struct gh_vcpu_run { #define GH_VCPU_RUN _IO(GH_IOCTL_TYPE, 0x5) #define GH_VCPU_MMAP_SIZE _IO(GH_IOCTL_TYPE, 0x6) +/** + * ANDROID: android14-6.1 unfortunately contains UAPI that won't be carried + * in kernel.org. Expose orthogonal ioctls that will never conflict with + * kernel.org for these UAPIs. See b/268234781. + */ +#define GH_ANDROID_IOCTL_TYPE 'A' + +#define GH_VM_ANDROID_LEND_USER_MEM _IOW(GH_ANDROID_IOCTL_TYPE, 0x11, \ + struct gh_userspace_memory_region) + #endif