Message ID | 20231121212016.1154303-4-mhklinux@outlook.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | x86/coco: Mark CoCo VM pages not present when changing encrypted state | expand |
On Tue, Nov 21, 2023 at 01:20:11PM -0800, mhkelley58@gmail.com wrote: > From: Michael Kelley <mhklinux@outlook.com> > > The mm subsystem currently provides no mechanism to map memory pages > to a specified virtual address range. A virtual address range can be > allocated using get_vm_area(), but the only function available for > mapping memory pages to a caller-specified address in that range is > ioremap_page_range(), which is inappropriate for system memory. > > Fix this by allowing vmap_pages_range() to be used by callers outside > of vmalloc.c. I really do not want to expose vmap_pages_range. Please try to come up with a good way to encapsulate your map at a certain address primitive and implement it in vmalloc.c.
From: Christoph Hellwig <hch@infradead.org> Sent: Tuesday, November 21, 2023 10:26 PM > > On Tue, Nov 21, 2023 at 01:20:11PM -0800, mhkelley58@gmail.com wrote: > > From: Michael Kelley <mhklinux@outlook.com> > > > > The mm subsystem currently provides no mechanism to map memory pages > > to a specified virtual address range. A virtual address range can be > > allocated using get_vm_area(), but the only function available for > > mapping memory pages to a caller-specified address in that range is > > ioremap_page_range(), which is inappropriate for system memory. > > > > Fix this by allowing vmap_pages_range() to be used by callers outside > > of vmalloc.c. > > I really do not want to expose vmap_pages_range. Please try to come up > with a good way to encapsulate your map at a certain address primitive > and implement it in vmalloc.c. To clarify, is your concern narrowly about vmap_pages_range() specifically? Or is your concern more generally about having two separate steps as applied to system memory: 1) allocate the virtual address space and 2) do the mapping? The two separate steps are already available for MMIO space. Doing the equivalent for system memory should be straightforward. Conversely, combining the two steps into a single new vmap() variant would be a little messy, but can probably be made to work. This combined approach will be less efficient since my use case does a single allocation of virtual address space and repeatedly maps/unmaps the same page in that space. I would need to take some measurements to see if the inefficiency actually matters. Michael
On Thu, Nov 23, 2023 at 12:24:49AM +0000, Michael Kelley wrote: > > I really do not want to expose vmap_pages_range. Please try to come up > > with a good way to encapsulate your map at a certain address primitive > > and implement it in vmalloc.c. > > To clarify, is your concern narrowly about vmap_pages_range() > specifically? The prime concern is that it took a lot of effort to make vmap_pages_range static and remove all the abuses. I absolutely object to undoing that.
From: Christoph Hellwig <hch@infradead.org> Sent: Wednesday, November 22, 2023 11:32 PM > > On Thu, Nov 23, 2023 at 12:24:49AM +0000, Michael Kelley wrote: > > > I really do not want to expose vmap_pages_range. Please try to come up > > > with a good way to encapsulate your map at a certain address primitive > > > and implement it in vmalloc.c. > > > > To clarify, is your concern narrowly about vmap_pages_range() > > specifically? > > The prime concern is that it took a lot of effort to make > vmap_pages_range static and remove all the abuses. I absolutely > object to undoing that. OK, so I assume that means a new variant of vmap_pages_range(), such as one that always sets the page_shift parameter to PAGE_SIZE, is also disallowed because of the same potential for abuse. So the only way to map a system memory page to a vmalloc vaddr is via vmap() or some vmap() variant, which always creates a new vmalloc area via get_vm_area(). I've done the perf measurements, and that approach won't work for this use case. Independent of the alignment requirements, the churn in creating and removing a lot of vmalloc areas has too much perf impact. The use case needs to create a single vmalloc area, and then repeatedly map/unmap a page in that existing area. I'll have to handle the top-level problem in this patch set in a completely different way. Michael
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index c720be70c8dd..ee12f5226a45 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h @@ -233,6 +233,8 @@ static inline bool is_vm_area_hugepages(const void *addr) #ifdef CONFIG_MMU void vunmap_range(unsigned long addr, unsigned long end); +int vmap_pages_range(unsigned long addr, unsigned long end, pgprot_t prot, + struct page **pages, unsigned int page_shift); static inline void set_vm_flush_reset_perms(void *addr) { struct vm_struct *vm = find_vm_area(addr); diff --git a/mm/vmalloc.c b/mm/vmalloc.c index d12a17fc0c17..b2a72bd317c6 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -625,7 +625,7 @@ int vmap_pages_range_noflush(unsigned long addr, unsigned long end, * RETURNS: * 0 on success, -errno on failure. */ -static int vmap_pages_range(unsigned long addr, unsigned long end, +int vmap_pages_range(unsigned long addr, unsigned long end, pgprot_t prot, struct page **pages, unsigned int page_shift) { int err;