diff options
author | jkim <jkim@FreeBSD.org> | 2012-02-15 21:32:05 +0000 |
---|---|---|
committer | jkim <jkim@FreeBSD.org> | 2012-02-15 21:32:05 +0000 |
commit | e89cddf37f8fadb0946c20ddaa7a6d0828f36285 (patch) | |
tree | acb8f5c8cc9d1cfc3ddb4d1d2589b10d5620364c /sys/amd64 | |
parent | 24393271fee36a45a67119022dc110706aed11fa (diff) | |
download | FreeBSD-src-e89cddf37f8fadb0946c20ddaa7a6d0828f36285.zip FreeBSD-src-e89cddf37f8fadb0946c20ddaa7a6d0828f36285.tar.gz |
Some BIOSes are known for corrupting low 64KB between suspend and resume.
Mask off the first 16 pages unless we appear to be running in a VM. This
address may be overridden by 'hw.physmem.start' tunable from loader.
Note Linux used to have a BIOS quirk table for this issue but it seems they
made it default recently.
Diffstat (limited to 'sys/amd64')
-rw-r--r-- | sys/amd64/amd64/machdep.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index bc14745..b45adde 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -1381,7 +1381,7 @@ getmemsize(caddr_t kmdp, u_int64_t first) { int i, physmap_idx, pa_indx, da_indx; vm_paddr_t pa, physmap[PHYSMAP_SIZE]; - u_long physmem_tunable, memtest; + u_long physmem_start, physmem_tunable, memtest; pt_entry_t *pte; struct bios_smap *smapbase, *smap, *smapend; u_int32_t smapsize; @@ -1469,8 +1469,19 @@ getmemsize(caddr_t kmdp, u_int64_t first) /* * Size up each available chunk of physical memory. + * + * XXX Some BIOSes corrupt low 64KB between suspend and resume. + * By default, mask off the first 16 pages unless we appear to be + * running in a VM. */ - physmap[0] = PAGE_SIZE; /* mask off page 0 */ + physmem_start = (vm_guest > VM_GUEST_NO ? 1 : 16) << PAGE_SHIFT; + TUNABLE_ULONG_FETCH("hw.physmem.start", &physmem_start); + if (physmem_start < PAGE_SIZE) + physmap[0] = PAGE_SIZE; + else if (physmem_start >= physmap[1]) + physmap[0] = round_page(physmap[1] - PAGE_SIZE); + else + physmap[0] = round_page(physmem_start); pa_indx = 0; da_indx = 1; phys_avail[pa_indx++] = physmap[0]; |