Allocate memory pages for the guest from the host's free page queue.

It is no longer necessary to hard-partition the memory between the host
and guests at boot time.
This commit is contained in:
Neel Natu 2012-10-08 23:41:26 +00:00
parent a16232b6c3
commit 7ce04d0ad9
8 changed files with 193 additions and 374 deletions

View File

@ -230,6 +230,14 @@ amd_iommu_create_mapping(void *domain, vm_paddr_t gpa, vm_paddr_t hpa,
return (0);
}
static uint64_t
amd_iommu_remove_mapping(void *domain, vm_paddr_t gpa, uint64_t len)
{
printf("amd_iommu_remove_mapping: not implemented\n");
return (0);
}
static void
amd_iommu_add_device(void *domain, int bus, int slot, int func)
{
@ -244,6 +252,13 @@ amd_iommu_remove_device(void *domain, int bus, int slot, int func)
printf("amd_iommu_remove_device: not implemented\n");
}
static void
amd_iommu_invalidate_tlb(void *domain)
{
printf("amd_iommu_invalidate_tlb: not implemented\n");
}
struct iommu_ops iommu_ops_amd = {
amd_iommu_init,
amd_iommu_cleanup,
@ -252,6 +267,8 @@ struct iommu_ops iommu_ops_amd = {
amd_iommu_create_domain,
amd_iommu_destroy_domain,
amd_iommu_create_mapping,
amd_iommu_remove_mapping,
amd_iommu_add_device,
amd_iommu_remove_device,
amd_iommu_invalidate_tlb,
};

View File

@ -444,8 +444,12 @@ vtd_remove_device(void *arg, int bus, int slot, int func)
}
}
#define CREATE_MAPPING 0
#define REMOVE_MAPPING 1
static uint64_t
vtd_create_mapping(void *arg, vm_paddr_t gpa, vm_paddr_t hpa, uint64_t len)
vtd_update_mapping(void *arg, vm_paddr_t gpa, vm_paddr_t hpa, uint64_t len,
int remove)
{
struct domain *dom;
int i, spshift, ptpshift, ptpindex, nlevels;
@ -513,16 +517,50 @@ vtd_create_mapping(void *arg, vm_paddr_t gpa, vm_paddr_t hpa, uint64_t len)
panic("gpa 0x%lx and ptpshift %d mismatch", gpa, ptpshift);
/*
* Create a 'gpa' -> 'hpa' mapping
* Update the 'gpa' -> 'hpa' mapping
*/
ptp[ptpindex] = hpa | VTD_PTE_RD | VTD_PTE_WR;
if (remove) {
ptp[ptpindex] = 0;
} else {
ptp[ptpindex] = hpa | VTD_PTE_RD | VTD_PTE_WR;
if (nlevels > 0)
ptp[ptpindex] |= VTD_PTE_SUPERPAGE;
if (nlevels > 0)
ptp[ptpindex] |= VTD_PTE_SUPERPAGE;
}
return (1UL << ptpshift);
}
static uint64_t
vtd_create_mapping(void *arg, vm_paddr_t gpa, vm_paddr_t hpa, uint64_t len)
{
return (vtd_update_mapping(arg, gpa, hpa, len, CREATE_MAPPING));
}
static uint64_t
vtd_remove_mapping(void *arg, vm_paddr_t gpa, uint64_t len)
{
return (vtd_update_mapping(arg, gpa, 0, len, REMOVE_MAPPING));
}
static void
vtd_invalidate_tlb(void *dom)
{
int i;
struct vtdmap *vtdmap;
/*
* Invalidate the IOTLB.
* XXX use domain-selective invalidation for IOTLB
*/
for (i = 0; i < drhd_num; i++) {
vtdmap = vtdmaps[i];
vtd_iotlb_global_invalidate(vtdmap);
}
}
static void *
vtd_create_domain(vm_paddr_t maxaddr)
{
@ -632,6 +670,8 @@ struct iommu_ops iommu_ops_intel = {
vtd_create_domain,
vtd_destroy_domain,
vtd_create_mapping,
vtd_remove_mapping,
vtd_add_device,
vtd_remove_device,
vtd_invalidate_tlb,
};

View File

@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <machine/md_var.h>
#include "vmm_util.h"
#include "vmm_mem.h"
#include "iommu.h"
static boolean_t iommu_avail;
@ -90,6 +91,16 @@ IOMMU_CREATE_MAPPING(void *domain, vm_paddr_t gpa, vm_paddr_t hpa, uint64_t len)
return (len); /* XXX */
}
static __inline uint64_t
IOMMU_REMOVE_MAPPING(void *domain, vm_paddr_t gpa, uint64_t len)
{
if (ops != NULL && iommu_avail)
return ((*ops->remove_mapping)(domain, gpa, len));
else
return (len); /* XXX */
}
static __inline void
IOMMU_ADD_DEVICE(void *domain, int bus, int slot, int func)
{
@ -106,6 +117,14 @@ IOMMU_REMOVE_DEVICE(void *domain, int bus, int slot, int func)
(*ops->remove_device)(domain, bus, slot, func);
}
static __inline void
IOMMU_INVALIDATE_TLB(void *domain)
{
if (ops != NULL && iommu_avail)
(*ops->invalidate_tlb)(domain);
}
static __inline void
IOMMU_ENABLE(void)
{
@ -146,13 +165,13 @@ iommu_init(void)
/*
* Create a domain for the devices owned by the host
*/
maxaddr = ptoa(Maxmem);
maxaddr = vmm_mem_maxaddr();
host_domain = IOMMU_CREATE_DOMAIN(maxaddr);
if (host_domain == NULL)
panic("iommu_init: unable to create a host domain");
/*
* Create 1:1 mappings from '0' to 'Maxmem' for devices assigned to
* Create 1:1 mappings from '0' to 'maxaddr' for devices assigned to
* the host
*/
iommu_create_mapping(host_domain, 0, 0, maxaddr);
@ -215,6 +234,27 @@ iommu_create_mapping(void *dom, vm_paddr_t gpa, vm_paddr_t hpa, size_t len)
}
}
void
iommu_remove_mapping(void *dom, vm_paddr_t gpa, size_t len)
{
uint64_t unmapped, remaining;
remaining = len;
while (remaining > 0) {
unmapped = IOMMU_REMOVE_MAPPING(dom, gpa, remaining);
gpa += unmapped;
remaining -= unmapped;
}
}
void *
iommu_host_domain(void)
{
return (host_domain);
}
void
iommu_add_device(void *dom, int bus, int slot, int func)
{
@ -228,3 +268,10 @@ iommu_remove_device(void *dom, int bus, int slot, int func)
IOMMU_REMOVE_DEVICE(dom, bus, slot, func);
}
void
iommu_invalidate_tlb(void *domain)
{
IOMMU_INVALIDATE_TLB(domain);
}

View File

@ -37,8 +37,11 @@ typedef void *(*iommu_create_domain_t)(vm_paddr_t maxaddr);
typedef void (*iommu_destroy_domain_t)(void *domain);
typedef uint64_t (*iommu_create_mapping_t)(void *domain, vm_paddr_t gpa,
vm_paddr_t hpa, uint64_t len);
typedef uint64_t (*iommu_remove_mapping_t)(void *domain, vm_paddr_t gpa,
uint64_t len);
typedef void (*iommu_add_device_t)(void *domain, int bus, int slot, int func);
typedef void (*iommu_remove_device_t)(void *dom, int bus, int slot, int func);
typedef void (*iommu_invalidate_tlb_t)(void *dom);
struct iommu_ops {
iommu_init_func_t init; /* module wide */
@ -49,8 +52,10 @@ struct iommu_ops {
iommu_create_domain_t create_domain; /* domain-specific */
iommu_destroy_domain_t destroy_domain;
iommu_create_mapping_t create_mapping;
iommu_remove_mapping_t remove_mapping;
iommu_add_device_t add_device;
iommu_remove_device_t remove_device;
iommu_invalidate_tlb_t invalidate_tlb;
};
extern struct iommu_ops iommu_ops_intel;
@ -58,10 +63,13 @@ extern struct iommu_ops iommu_ops_amd;
void iommu_init(void);
void iommu_cleanup(void);
void *iommu_host_domain(void);
void *iommu_create_domain(vm_paddr_t maxaddr);
void iommu_destroy_domain(void *dom);
void iommu_create_mapping(void *dom, vm_paddr_t gpa, vm_paddr_t hpa,
size_t len);
void iommu_remove_mapping(void *dom, vm_paddr_t gpa, size_t len);
void iommu_add_device(void *dom, int bus, int slot, int func);
void iommu_remove_device(void *dom, int bus, int slot, int func);
void iommu_invalidate_tlb(void *domain);
#endif

View File

@ -280,6 +280,9 @@ vm_free_mem_seg(struct vm *vm, struct vm_memory_segment *seg)
{
size_t len;
vm_paddr_t hpa;
void *host_domain;
host_domain = iommu_host_domain();
len = 0;
while (len < seg->len) {
@ -289,11 +292,24 @@ vm_free_mem_seg(struct vm *vm, struct vm_memory_segment *seg)
"associated with gpa 0x%016lx", seg->gpa + len);
}
/*
* Remove the 'gpa' to 'hpa' mapping in VMs domain.
* And resurrect the 1:1 mapping for 'hpa' in 'host_domain'.
*/
iommu_remove_mapping(vm->iommu, seg->gpa + len, PAGE_SIZE);
iommu_create_mapping(host_domain, hpa, hpa, PAGE_SIZE);
vmm_mem_free(hpa, PAGE_SIZE);
len += PAGE_SIZE;
}
/*
* Invalidate cached translations associated with 'vm->iommu' since
* we have now moved some pages from it.
*/
iommu_invalidate_tlb(vm->iommu);
bzero(seg, sizeof(struct vm_memory_segment));
}
@ -371,6 +387,7 @@ vm_malloc(struct vm *vm, vm_paddr_t gpa, size_t len)
int error, available, allocated;
struct vm_memory_segment *seg;
vm_paddr_t g, hpa;
void *host_domain;
const boolean_t spok = TRUE; /* superpage mappings are ok */
@ -405,8 +422,11 @@ vm_malloc(struct vm *vm, vm_paddr_t gpa, size_t len)
if (vm->num_mem_segs >= VM_MAX_MEMORY_SEGMENTS)
return (E2BIG);
host_domain = iommu_host_domain();
seg = &vm->mem_segs[vm->num_mem_segs];
error = 0;
seg->gpa = gpa;
seg->len = 0;
while (seg->len < len) {
@ -421,16 +441,27 @@ vm_malloc(struct vm *vm, vm_paddr_t gpa, size_t len)
if (error)
break;
/*
* Remove the 1:1 mapping for 'hpa' from the 'host_domain'.
* Add mapping for 'gpa + seg->len' to 'hpa' in the VMs domain.
*/
iommu_remove_mapping(host_domain, hpa, PAGE_SIZE);
iommu_create_mapping(vm->iommu, gpa + seg->len, hpa, PAGE_SIZE);
seg->len += PAGE_SIZE;
}
if (seg->len != len) {
if (error) {
vm_free_mem_seg(vm, seg);
return (error);
}
/*
* Invalidate cached translations associated with 'host_domain' since
* we have now moved some pages from it.
*/
iommu_invalidate_tlb(host_domain);
vm->num_mem_segs++;
return (0);

View File

@ -471,24 +471,6 @@ sysctl_vmm_create(SYSCTL_HANDLER_ARGS)
SYSCTL_PROC(_hw_vmm, OID_AUTO, create, CTLTYPE_STRING | CTLFLAG_RW,
NULL, 0, sysctl_vmm_create, "A", NULL);
static int
sysctl_vmm_mem_total(SYSCTL_HANDLER_ARGS)
{
size_t val = vmm_mem_get_mem_total();
return sysctl_handle_long(oidp, &val, 0, req);
}
SYSCTL_PROC(_hw_vmm, OID_AUTO, mem_total, CTLTYPE_LONG | CTLFLAG_RD,
0, 0, sysctl_vmm_mem_total, "LU", "Amount of Total memory");
static int
sysctl_vmm_mem_free(SYSCTL_HANDLER_ARGS)
{
size_t val = vmm_mem_get_mem_free();
return sysctl_handle_long(oidp, &val, 0, req);
}
SYSCTL_PROC(_hw_vmm, OID_AUTO, mem_free, CTLTYPE_LONG | CTLFLAG_RD,
0, 0, sysctl_vmm_mem_free, "LU", "Amount of Free memory");
void
vmmdev_init(void)
{

View File

@ -36,9 +36,12 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/sysctl.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <vm/vm_page.h>
#include <vm/vm_pageout.h>
#include <machine/md_var.h>
#include <machine/metadata.h>
@ -49,265 +52,21 @@ __FBSDID("$FreeBSD$");
#include "vmm_util.h"
#include "vmm_mem.h"
static MALLOC_DEFINE(M_VMM_MEM, "vmm memory", "vmm memory");
SYSCTL_DECL(_hw_vmm);
#define MB (1024 * 1024)
#define GB (1024 * MB)
#define VMM_MEM_MAXSEGS 64
/* protected by vmm_mem_mtx */
static struct {
vm_paddr_t base;
vm_size_t length;
} vmm_mem_avail[VMM_MEM_MAXSEGS];
static int vmm_mem_nsegs;
size_t vmm_mem_total_bytes;
static vm_paddr_t maxaddr;
static struct mtx vmm_mem_mtx;
/*
* Steal any memory that was deliberately hidden from FreeBSD either by
* the use of MAXMEM kernel config option or the hw.physmem loader tunable.
*/
static int
vmm_mem_steal_memory(void)
{
int nsegs;
caddr_t kmdp;
uint32_t smapsize;
uint64_t base, length;
struct bios_smap *smapbase, *smap, *smapend;
/*
* Borrowed from hammer_time() and getmemsize() in machdep.c
*/
kmdp = preload_search_by_type("elf kernel");
if (kmdp == NULL)
kmdp = preload_search_by_type("elf64 kernel");
smapbase = (struct bios_smap *)preload_search_info(kmdp,
MODINFO_METADATA | MODINFOMD_SMAP);
if (smapbase == NULL)
panic("No BIOS smap info from loader!");
smapsize = *((uint32_t *)smapbase - 1);
smapend = (struct bios_smap *)((uintptr_t)smapbase + smapsize);
vmm_mem_total_bytes = 0;
nsegs = 0;
for (smap = smapbase; smap < smapend; smap++) {
/*
* XXX
* Assuming non-overlapping, monotonically increasing
* memory segments.
*/
if (smap->type != SMAP_TYPE_MEMORY)
continue;
if (smap->length == 0)
break;
base = roundup(smap->base, NBPDR);
length = rounddown(smap->length, NBPDR);
/* Skip this segment if FreeBSD is using all of it. */
if (base + length <= ptoa(Maxmem))
continue;
/*
* If FreeBSD is using part of this segment then adjust
* 'base' and 'length' accordingly.
*/
if (base < ptoa(Maxmem)) {
uint64_t used;
used = roundup(ptoa(Maxmem), NBPDR) - base;
base += used;
length -= used;
}
if (length == 0)
continue;
vmm_mem_avail[nsegs].base = base;
vmm_mem_avail[nsegs].length = length;
vmm_mem_total_bytes += length;
if (base + length > maxaddr)
maxaddr = base + length;
if (0 && bootverbose) {
printf("vmm_mem_populate: index %d, base 0x%0lx, "
"length %ld\n",
nsegs, vmm_mem_avail[nsegs].base,
vmm_mem_avail[nsegs].length);
}
nsegs++;
if (nsegs >= VMM_MEM_MAXSEGS) {
printf("vmm_mem_populate: maximum number of vmm memory "
"segments reached!\n");
return (ENOSPC);
}
}
vmm_mem_nsegs = nsegs;
return (0);
}
static u_long pages_allocated;
SYSCTL_ULONG(_hw_vmm, OID_AUTO, pages_allocated, CTLFLAG_RD,
&pages_allocated, 0, "4KB pages allocated");
static void
vmm_mem_direct_map(vm_paddr_t start, vm_paddr_t end)
update_pages_allocated(int howmany)
{
vm_paddr_t addr, remaining;
int pdpi, pdi, superpage_size;
pml4_entry_t *pml4p;
pdp_entry_t *pdp;
pd_entry_t *pd;
uint64_t page_attr_bits;
if (end >= NBPML4)
panic("Cannot map memory beyond %ldGB", NBPML4 / GB);
if (vmm_supports_1G_pages())
superpage_size = NBPDP;
else
superpage_size = NBPDR;
/*
* Get the page directory pointer page that contains the direct
* map address mappings.
*/
pml4p = kernel_pmap->pm_pml4;
pdp = (pdp_entry_t *)PHYS_TO_DMAP(pml4p[DMPML4I] & ~PAGE_MASK);
page_attr_bits = PG_RW | PG_V | PG_PS | PG_G;
addr = start;
while (addr < end) {
remaining = end - addr;
pdpi = addr / NBPDP;
if (superpage_size == NBPDP &&
remaining >= NBPDP &&
addr % NBPDP == 0) {
/*
* If there isn't a mapping for this address then
* create one but if there is one already make sure
* it matches what we expect it to be.
*/
if (pdp[pdpi] == 0) {
pdp[pdpi] = addr | page_attr_bits;
if (0 && bootverbose) {
printf("vmm_mem_populate: mapping "
"0x%lx with 1GB page at "
"pdpi %d\n", addr, pdpi);
}
} else {
pdp_entry_t pdpe = pdp[pdpi];
if ((pdpe & ~PAGE_MASK) != addr ||
(pdpe & page_attr_bits) != page_attr_bits) {
panic("An invalid mapping 0x%016lx "
"already exists for 0x%016lx\n",
pdpe, addr);
}
}
addr += NBPDP;
} else {
if (remaining < NBPDR) {
panic("vmm_mem_populate: remaining (%ld) must "
"be greater than NBPDR (%d)\n",
remaining, NBPDR);
}
if (pdp[pdpi] == 0) {
/*
* XXX we lose this memory forever because
* we do not keep track of the virtual address
* that would be required to free this page.
*/
pd = malloc(PAGE_SIZE, M_VMM_MEM,
M_WAITOK | M_ZERO);
if ((uintptr_t)pd & PAGE_MASK) {
panic("vmm_mem_populate: page directory"
"page not aligned on %d "
"boundary\n", PAGE_SIZE);
}
pdp[pdpi] = vtophys(pd);
pdp[pdpi] |= PG_RW | PG_V | PG_U;
if (0 && bootverbose) {
printf("Creating page directory "
"at pdp index %d for 0x%016lx\n",
pdpi, addr);
}
}
pdi = (addr % NBPDP) / NBPDR;
pd = (pd_entry_t *)PHYS_TO_DMAP(pdp[pdpi] & ~PAGE_MASK);
/*
* Create a new mapping if one doesn't already exist
* or validate it if it does.
*/
if (pd[pdi] == 0) {
pd[pdi] = addr | page_attr_bits;
if (0 && bootverbose) {
printf("vmm_mem_populate: mapping "
"0x%lx with 2MB page at "
"pdpi %d, pdi %d\n",
addr, pdpi, pdi);
}
} else {
pd_entry_t pde = pd[pdi];
if ((pde & ~PAGE_MASK) != addr ||
(pde & page_attr_bits) != page_attr_bits) {
panic("An invalid mapping 0x%016lx "
"already exists for 0x%016lx\n",
pde, addr);
}
}
addr += NBPDR;
}
}
}
static int
vmm_mem_populate(void)
{
int seg, error;
vm_paddr_t start, end;
/* populate the vmm_mem_avail[] array */
error = vmm_mem_steal_memory();
if (error)
return (error);
/*
* Now map the memory that was hidden from FreeBSD in
* the direct map VA space.
*/
for (seg = 0; seg < vmm_mem_nsegs; seg++) {
start = vmm_mem_avail[seg].base;
end = start + vmm_mem_avail[seg].length;
if ((start & PDRMASK) != 0 || (end & PDRMASK) != 0) {
panic("start (0x%016lx) and end (0x%016lx) must be "
"aligned on a %dMB boundary\n",
start, end, NBPDR / MB);
}
vmm_mem_direct_map(start, end);
}
return (0);
pages_allocated += howmany; /* XXX locking? */
}
int
vmm_mem_init(void)
{
int error;
mtx_init(&vmm_mem_mtx, "vmm_mem_mtx", NULL, MTX_DEF);
error = vmm_mem_populate();
if (error)
return (error);
return (0);
}
@ -315,122 +74,61 @@ vmm_mem_init(void)
vm_paddr_t
vmm_mem_alloc(size_t size)
{
int i;
vm_paddr_t addr;
int flags;
vm_page_t m;
vm_paddr_t pa;
if ((size & PAGE_MASK) != 0) {
panic("vmm_mem_alloc: size 0x%0lx must be "
"aligned on a 0x%0x boundary\n", size, PAGE_SIZE);
}
if (size != PAGE_SIZE)
panic("vmm_mem_alloc: invalid allocation size %lu", size);
addr = 0;
flags = VM_ALLOC_NORMAL | VM_ALLOC_NOOBJ | VM_ALLOC_WIRED |
VM_ALLOC_ZERO;
mtx_lock(&vmm_mem_mtx);
for (i = 0; i < vmm_mem_nsegs; i++) {
if (vmm_mem_avail[i].length >= size) {
addr = vmm_mem_avail[i].base;
vmm_mem_avail[i].base += size;
vmm_mem_avail[i].length -= size;
/* remove a zero length segment */
if (vmm_mem_avail[i].length == 0) {
memmove(&vmm_mem_avail[i],
&vmm_mem_avail[i + 1],
(vmm_mem_nsegs - (i + 1)) *
sizeof(vmm_mem_avail[0]));
vmm_mem_nsegs--;
}
while (1) {
/*
* XXX need policy to determine when to back off the allocation
*/
m = vm_page_alloc(NULL, 0, flags);
if (m == NULL)
VM_WAIT;
else
break;
}
}
mtx_unlock(&vmm_mem_mtx);
return (addr);
}
pa = VM_PAGE_TO_PHYS(m);
if ((m->flags & PG_ZERO) == 0)
pagezero((void *)PHYS_TO_DMAP(pa));
size_t
vmm_mem_get_mem_total(void)
{
return vmm_mem_total_bytes;
}
update_pages_allocated(1);
size_t
vmm_mem_get_mem_free(void)
{
size_t length = 0;
int i;
mtx_lock(&vmm_mem_mtx);
for (i = 0; i < vmm_mem_nsegs; i++) {
length += vmm_mem_avail[i].length;
}
mtx_unlock(&vmm_mem_mtx);
return(length);
return (pa);
}
void
vmm_mem_free(vm_paddr_t base, size_t length)
{
int i;
vm_page_t m;
if ((base & PAGE_MASK) != 0 || (length & PAGE_MASK) != 0) {
panic("vmm_mem_free: base 0x%0lx and length 0x%0lx must be "
"aligned on a 0x%0x boundary\n", base, length, PAGE_SIZE);
if (base & PAGE_MASK) {
panic("vmm_mem_free: base 0x%0lx must be aligned on a "
"0x%0x boundary\n", base, PAGE_SIZE);
}
mtx_lock(&vmm_mem_mtx);
if (length != PAGE_SIZE)
panic("vmm_mem_free: invalid length %lu", length);
for (i = 0; i < vmm_mem_nsegs; i++) {
if (vmm_mem_avail[i].base > base)
break;
}
m = PHYS_TO_VM_PAGE(base);
m->wire_count--;
vm_page_free(m);
atomic_subtract_int(&cnt.v_wire_count, 1);
if (vmm_mem_nsegs >= VMM_MEM_MAXSEGS)
panic("vmm_mem_free: cannot free any more segments");
/* Create a new segment at index 'i' */
memmove(&vmm_mem_avail[i + 1], &vmm_mem_avail[i],
(vmm_mem_nsegs - i) * sizeof(vmm_mem_avail[0]));
vmm_mem_avail[i].base = base;
vmm_mem_avail[i].length = length;
vmm_mem_nsegs++;
coalesce_some_more:
for (i = 0; i < vmm_mem_nsegs - 1; i++) {
if (vmm_mem_avail[i].base + vmm_mem_avail[i].length ==
vmm_mem_avail[i + 1].base) {
vmm_mem_avail[i].length += vmm_mem_avail[i + 1].length;
memmove(&vmm_mem_avail[i + 1], &vmm_mem_avail[i + 2],
(vmm_mem_nsegs - (i + 2)) * sizeof(vmm_mem_avail[0]));
vmm_mem_nsegs--;
goto coalesce_some_more;
}
}
mtx_unlock(&vmm_mem_mtx);
update_pages_allocated(-1);
}
vm_paddr_t
vmm_mem_maxaddr(void)
{
return (maxaddr);
}
void
vmm_mem_dump(void)
{
int i;
vm_paddr_t base;
vm_size_t length;
mtx_lock(&vmm_mem_mtx);
for (i = 0; i < vmm_mem_nsegs; i++) {
base = vmm_mem_avail[i].base;
length = vmm_mem_avail[i].length;
printf("%-4d0x%016lx 0x%016lx\n", i, base, base + length);
}
mtx_unlock(&vmm_mem_mtx);
return (ptoa(Maxmem));
}

View File

@ -33,9 +33,5 @@ int vmm_mem_init(void);
vm_paddr_t vmm_mem_alloc(size_t size);
void vmm_mem_free(vm_paddr_t start, size_t size);
vm_paddr_t vmm_mem_maxaddr(void);
void vmm_mem_dump(void);
size_t vmm_mem_get_mem_total(void);
size_t vmm_mem_get_mem_free(void);
#endif