Lines Matching +full:memory +full:- +full:region

1 // SPDX-License-Identifier: GPL-2.0
3 * ACRN: Memory mapping management
19 static int modify_region(struct acrn_vm *vm, struct vm_memory_region_op *region) in modify_region() argument
26 return -ENOMEM; in modify_region()
28 regions->vmid = vm->vmid; in modify_region()
29 regions->regions_num = 1; in modify_region()
30 regions->regions_gpa = virt_to_phys(region); in modify_region()
35 "Failed to set memory region for VM[%u]!\n", vm->vmid); in modify_region()
42 * acrn_mm_region_add() - Set up the EPT mapping of a memory region.
46 * @size: Size of the region.
55 struct vm_memory_region_op *region; in acrn_mm_region_add() local
58 region = kzalloc(sizeof(*region), GFP_KERNEL); in acrn_mm_region_add()
59 if (!region) in acrn_mm_region_add()
60 return -ENOMEM; in acrn_mm_region_add()
62 region->type = ACRN_MEM_REGION_ADD; in acrn_mm_region_add()
63 region->user_vm_pa = user_gpa; in acrn_mm_region_add()
64 region->service_vm_pa = service_gpa; in acrn_mm_region_add()
65 region->size = size; in acrn_mm_region_add()
66 region->attr = ((mem_type & ACRN_MEM_TYPE_MASK) | in acrn_mm_region_add()
68 ret = modify_region(vm, region); in acrn_mm_region_add()
71 "%s: user-GPA[%pK] service-GPA[%pK] size[0x%llx].\n", in acrn_mm_region_add()
73 kfree(region); in acrn_mm_region_add()
78 * acrn_mm_region_del() - Del the EPT mapping of a memory region.
81 * @size: Size of the region.
87 struct vm_memory_region_op *region; in acrn_mm_region_del() local
90 region = kzalloc(sizeof(*region), GFP_KERNEL); in acrn_mm_region_del()
91 if (!region) in acrn_mm_region_del()
92 return -ENOMEM; in acrn_mm_region_del()
94 region->type = ACRN_MEM_REGION_DEL; in acrn_mm_region_del()
95 region->user_vm_pa = user_gpa; in acrn_mm_region_del()
96 region->service_vm_pa = 0UL; in acrn_mm_region_del()
97 region->size = size; in acrn_mm_region_del()
98 region->attr = 0U; in acrn_mm_region_del()
100 ret = modify_region(vm, region); in acrn_mm_region_del()
102 dev_dbg(acrn_dev.this_device, "%s: user-GPA[%pK] size[0x%llx].\n", in acrn_mm_region_del()
104 kfree(region); in acrn_mm_region_del()
112 if (memmap->type == ACRN_MEMMAP_RAM) in acrn_vm_memseg_map()
115 if (memmap->type != ACRN_MEMMAP_MMIO) { in acrn_vm_memseg_map()
117 "Invalid memmap type: %u\n", memmap->type); in acrn_vm_memseg_map()
118 return -EINVAL; in acrn_vm_memseg_map()
121 ret = acrn_mm_region_add(vm, memmap->user_vm_pa, in acrn_vm_memseg_map()
122 memmap->service_vm_pa, memmap->len, in acrn_vm_memseg_map()
123 ACRN_MEM_TYPE_UC, memmap->attr); in acrn_vm_memseg_map()
126 "Add memory region failed, VM[%u]!\n", vm->vmid); in acrn_vm_memseg_map()
135 if (memmap->type != ACRN_MEMMAP_MMIO) { in acrn_vm_memseg_unmap()
137 "Invalid memmap type: %u\n", memmap->type); in acrn_vm_memseg_unmap()
138 return -EINVAL; in acrn_vm_memseg_unmap()
141 ret = acrn_mm_region_del(vm, memmap->user_vm_pa, memmap->len); in acrn_vm_memseg_unmap()
144 "Del memory region failed, VM[%u]!\n", vm->vmid); in acrn_vm_memseg_unmap()
150 * acrn_vm_ram_map() - Create a RAM EPT mapping of User VM.
169 return -EINVAL; in acrn_vm_ram_map()
171 /* Get the page number of the map region */ in acrn_vm_ram_map()
172 nr_pages = memmap->len >> PAGE_SHIFT; in acrn_vm_ram_map()
174 return -EINVAL; in acrn_vm_ram_map()
176 mmap_read_lock(current->mm); in acrn_vm_ram_map()
177 vma = vma_lookup(current->mm, memmap->vma_base); in acrn_vm_ram_map()
178 if (vma && ((vma->vm_flags & VM_PFNMAP) != 0)) { in acrn_vm_ram_map()
182 if ((memmap->vma_base + memmap->len) > vma->vm_end) { in acrn_vm_ram_map()
183 mmap_read_unlock(current->mm); in acrn_vm_ram_map()
184 return -EINVAL; in acrn_vm_ram_map()
190 .address = memmap->vma_base + i * PAGE_SIZE, in acrn_vm_ram_map()
205 (memmap->attr & ACRN_MEM_ACCESS_WRITE)) { in acrn_vm_ram_map()
206 ret = -EFAULT; in acrn_vm_ram_map()
213 ret = -EFAULT; in acrn_vm_ram_map()
217 /* Disallow non-contiguous ranges. */ in acrn_vm_ram_map()
219 ret = -EINVAL; in acrn_vm_ram_map()
223 mmap_read_unlock(current->mm); in acrn_vm_ram_map()
227 "Failed to lookup PFN at VMA:%pK.\n", (void *)memmap->vma_base); in acrn_vm_ram_map()
231 return acrn_mm_region_add(vm, memmap->user_vm_pa, in acrn_vm_ram_map()
232 PFN_PHYS(start_pfn), memmap->len, in acrn_vm_ram_map()
233 ACRN_MEM_TYPE_WB, memmap->attr); in acrn_vm_ram_map()
235 mmap_read_unlock(current->mm); in acrn_vm_ram_map()
239 return -ENOMEM; in acrn_vm_ram_map()
241 /* Lock the pages of user memory map region */ in acrn_vm_ram_map()
242 pinned = pin_user_pages_fast(memmap->vma_base, in acrn_vm_ram_map()
249 ret = -EFAULT; in acrn_vm_ram_map()
253 /* Create a kernel map for the map region */ in acrn_vm_ram_map()
256 ret = -ENOMEM; in acrn_vm_ram_map()
260 /* Record Service VM va <-> User VM pa mapping */ in acrn_vm_ram_map()
261 mutex_lock(&vm->regions_mapping_lock); in acrn_vm_ram_map()
262 region_mapping = &vm->regions_mapping[vm->regions_mapping_count]; in acrn_vm_ram_map()
263 if (vm->regions_mapping_count < ACRN_MEM_MAPPING_MAX) { in acrn_vm_ram_map()
264 region_mapping->pages = pages; in acrn_vm_ram_map()
265 region_mapping->npages = nr_pages; in acrn_vm_ram_map()
266 region_mapping->size = memmap->len; in acrn_vm_ram_map()
267 region_mapping->service_vm_va = remap_vaddr; in acrn_vm_ram_map()
268 region_mapping->user_vm_pa = memmap->user_vm_pa; in acrn_vm_ram_map()
269 vm->regions_mapping_count++; in acrn_vm_ram_map()
272 "Run out of memory mapping slots!\n"); in acrn_vm_ram_map()
273 ret = -ENOMEM; in acrn_vm_ram_map()
274 mutex_unlock(&vm->regions_mapping_lock); in acrn_vm_ram_map()
277 mutex_unlock(&vm->regions_mapping_lock); in acrn_vm_ram_map()
291 ret = -ENOMEM; in acrn_vm_ram_map()
294 regions_info->regions_num = nr_regions; in acrn_vm_ram_map()
297 vm_region = regions_info->regions_op; in acrn_vm_ram_map()
298 regions_info->vmid = vm->vmid; in acrn_vm_ram_map()
299 regions_info->regions_gpa = virt_to_phys(vm_region); in acrn_vm_ram_map()
300 user_vm_pa = memmap->user_vm_pa; in acrn_vm_ram_map()
308 vm_region->type = ACRN_MEM_REGION_ADD; in acrn_vm_ram_map()
309 vm_region->user_vm_pa = user_vm_pa; in acrn_vm_ram_map()
310 vm_region->service_vm_pa = page_to_phys(page); in acrn_vm_ram_map()
311 vm_region->size = region_size; in acrn_vm_ram_map()
312 vm_region->attr = (ACRN_MEM_TYPE_WB & ACRN_MEM_TYPE_MASK) | in acrn_vm_ram_map()
313 (memmap->attr & ACRN_MEM_ACCESS_RIGHT_MASK); in acrn_vm_ram_map()
323 "Failed to set regions, VM[%u]!\n", vm->vmid); in acrn_vm_ram_map()
329 "%s: VM[%u] service-GVA[%pK] user-GPA[%pK] size[0x%llx]\n", in acrn_vm_ram_map()
330 __func__, vm->vmid, in acrn_vm_ram_map()
331 remap_vaddr, (void *)memmap->user_vm_pa, memmap->len); in acrn_vm_ram_map()
337 mutex_lock(&vm->regions_mapping_lock); in acrn_vm_ram_map()
338 vm->regions_mapping_count--; in acrn_vm_ram_map()
339 mutex_unlock(&vm->regions_mapping_lock); in acrn_vm_ram_map()
351 * acrn_vm_all_ram_unmap() - Destroy a RAM EPT mapping of User VM.
359 mutex_lock(&vm->regions_mapping_lock); in acrn_vm_all_ram_unmap()
360 for (i = 0; i < vm->regions_mapping_count; i++) { in acrn_vm_all_ram_unmap()
361 region_mapping = &vm->regions_mapping[i]; in acrn_vm_all_ram_unmap()
362 vunmap(region_mapping->service_vm_va); in acrn_vm_all_ram_unmap()
363 for (j = 0; j < region_mapping->npages; j++) in acrn_vm_all_ram_unmap()
364 unpin_user_page(region_mapping->pages[j]); in acrn_vm_all_ram_unmap()
365 vfree(region_mapping->pages); in acrn_vm_all_ram_unmap()
367 mutex_unlock(&vm->regions_mapping_lock); in acrn_vm_all_ram_unmap()