Ensure that imports into per-domain kmem arenas are KVA_QUANTUM-aligned.
The old code appears to assume that vmem_alloc() would import size-aligned KVA chunks from the parent kernel_arena, but vmem doesn't provide this guarantee. Also remove the unused global RWX arena and add comments explaining why we have per-domain arenas. Reported by: alc Reviewed by: alc, kib (previous version) Approved by: re (gjb) Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D17249
This commit is contained in:
parent
846a8dd029
commit
c030a808b9
@ -241,9 +241,6 @@ static struct vmem buffer_arena_storage;
|
||||
static struct vmem transient_arena_storage;
|
||||
/* kernel and kmem arenas are aliased for backwards KPI compat. */
|
||||
vmem_t *kernel_arena = &kernel_arena_storage;
|
||||
#if VM_NRESERVLEVEL > 0
|
||||
vmem_t *kernel_rwx_arena = NULL;
|
||||
#endif
|
||||
vmem_t *kmem_arena = &kernel_arena_storage;
|
||||
vmem_t *buffer_arena = &buffer_arena_storage;
|
||||
vmem_t *transient_arena = &transient_arena_storage;
|
||||
|
@ -669,7 +669,7 @@ kmem_init_zero_region(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* Import kva into the kernel arena.
|
||||
* Import KVA from the kernel map into the kernel arena.
|
||||
*/
|
||||
static int
|
||||
kva_import(void *unused, vmem_size_t size, int flags, vmem_addr_t *addrp)
|
||||
@ -691,22 +691,20 @@ kva_import(void *unused, vmem_size_t size, int flags, vmem_addr_t *addrp)
|
||||
return (0);
|
||||
}
|
||||
|
||||
#if VM_NRESERVLEVEL > 0
|
||||
/*
|
||||
* Import a superpage from the normal kernel arena into the special
|
||||
* arena for allocations with different permissions.
|
||||
* Import KVA from a parent arena into a per-domain arena. Imports must be
|
||||
* KVA_QUANTUM-aligned and a multiple of KVA_QUANTUM in size.
|
||||
*/
|
||||
static int
|
||||
kernel_rwx_alloc(void *arena, vmem_size_t size, int flags, vmem_addr_t *addrp)
|
||||
kva_import_domain(void *arena, vmem_size_t size, int flags, vmem_addr_t *addrp)
|
||||
{
|
||||
|
||||
KASSERT((size % KVA_QUANTUM) == 0,
|
||||
("kernel_rwx_alloc: Size %jd is not a multiple of %d",
|
||||
("kva_import_domain: Size %jd is not a multiple of %d",
|
||||
(intmax_t)size, (int)KVA_QUANTUM));
|
||||
return (vmem_xalloc(arena, size, KVA_QUANTUM, 0, 0, VMEM_ADDR_MIN,
|
||||
VMEM_ADDR_MAX, flags, addrp));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* kmem_init:
|
||||
@ -744,30 +742,30 @@ kmem_init(vm_offset_t start, vm_offset_t end)
|
||||
vmem_init(kernel_arena, "kernel arena", 0, 0, PAGE_SIZE, 0, 0);
|
||||
vmem_set_import(kernel_arena, kva_import, NULL, NULL, KVA_QUANTUM);
|
||||
|
||||
#if VM_NRESERVLEVEL > 0
|
||||
/*
|
||||
* In an architecture with superpages, maintain a separate arena
|
||||
* for allocations with permissions that differ from the "standard"
|
||||
* read/write permissions used for memory in the kernel_arena.
|
||||
*/
|
||||
kernel_rwx_arena = vmem_create("kernel rwx arena", 0, 0, PAGE_SIZE,
|
||||
0, M_WAITOK);
|
||||
vmem_set_import(kernel_rwx_arena, kernel_rwx_alloc,
|
||||
(vmem_release_t *)vmem_xfree, kernel_arena, KVA_QUANTUM);
|
||||
#endif
|
||||
|
||||
for (domain = 0; domain < vm_ndomains; domain++) {
|
||||
/*
|
||||
* Initialize the per-domain arenas. These are used to color
|
||||
* the KVA space in a way that ensures that virtual large pages
|
||||
* are backed by memory from the same physical domain,
|
||||
* maximizing the potential for superpage promotion.
|
||||
*/
|
||||
vm_dom[domain].vmd_kernel_arena = vmem_create(
|
||||
"kernel arena domain", 0, 0, PAGE_SIZE, 0, M_WAITOK);
|
||||
vmem_set_import(vm_dom[domain].vmd_kernel_arena,
|
||||
(vmem_import_t *)vmem_alloc, NULL, kernel_arena,
|
||||
KVA_QUANTUM);
|
||||
kva_import_domain, NULL, kernel_arena, KVA_QUANTUM);
|
||||
|
||||
/*
|
||||
* In architectures with superpages, maintain separate arenas
|
||||
* for allocations with permissions that differ from the
|
||||
* "standard" read/write permissions used for kernel memory,
|
||||
* so as not to inhibit superpage promotion.
|
||||
*/
|
||||
#if VM_NRESERVLEVEL > 0
|
||||
vm_dom[domain].vmd_kernel_rwx_arena = vmem_create(
|
||||
"kernel rwx arena domain", 0, 0, PAGE_SIZE, 0, M_WAITOK);
|
||||
vmem_set_import(vm_dom[domain].vmd_kernel_rwx_arena,
|
||||
kernel_rwx_alloc, (vmem_release_t *)vmem_xfree,
|
||||
vm_dom[domain].vmd_kernel_arena, KVA_QUANTUM);
|
||||
kva_import_domain, (vmem_release_t *)vmem_xfree,
|
||||
kernel_arena, KVA_QUANTUM);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -70,7 +70,6 @@ extern vm_map_t kernel_map;
|
||||
extern vm_map_t exec_map;
|
||||
extern vm_map_t pipe_map;
|
||||
extern struct vmem *kernel_arena;
|
||||
extern struct vmem *kernel_rwx_arena;
|
||||
extern struct vmem *kmem_arena;
|
||||
extern struct vmem *buffer_arena;
|
||||
extern struct vmem *transient_arena;
|
||||
|
Loading…
Reference in New Issue
Block a user