Provide APIs to directly get 'lowmem' and 'highmem' size directly.

Previously the sizes were inferred indirectly based on the size of the mappings
at 0 and 4GB respectively. This works fine as long as size of the allocation is
identical to the size of the mapping in the guest's address space. However, if
the mapping is disjoint then this assumption falls apart (e.g., due to the
legacy BIOS hole between 640KB and 1MB).
This commit is contained in:
Neel Natu 2014-06-24 02:02:51 +00:00
parent df2d82e003
commit be679db4cd
6 changed files with 26 additions and 21 deletions

View File

@ -274,6 +274,20 @@ vm_map_gpa(struct vmctx *ctx, vm_paddr_t gaddr, size_t len)
return (NULL);
}
size_t
vm_get_lowmem_size(struct vmctx *ctx)
{
return (ctx->lowmem);
}
size_t
vm_get_highmem_size(struct vmctx *ctx)
{
return (ctx->highmem);
}
int
vm_set_desc(struct vmctx *ctx, int vcpu, int reg,
uint64_t base, uint32_t limit, uint32_t access)

View File

@ -60,6 +60,8 @@ int vm_get_gpa_pmap(struct vmctx *, uint64_t gpa, uint64_t *pte, int *num);
uint32_t vm_get_lowmem_limit(struct vmctx *ctx);
void vm_set_lowmem_limit(struct vmctx *ctx, uint32_t limit);
void vm_set_memflags(struct vmctx *ctx, int flags);
size_t vm_get_lowmem_size(struct vmctx *ctx);
size_t vm_get_highmem_size(struct vmctx *ctx);
int vm_set_desc(struct vmctx *ctx, int vcpu, int reg,
uint64_t base, uint32_t limit, uint32_t access);
int vm_get_desc(struct vmctx *ctx, int vcpu, int reg,

View File

@ -1118,8 +1118,7 @@ init_pci(struct vmctx *ctx)
* Accesses to memory addresses that are not allocated to system
* memory or PCI devices return 0xff's.
*/
error = vm_get_memory_seg(ctx, 0, &lowmem, NULL);
assert(error == 0);
lowmem = vm_get_lowmem_size(ctx);
memset(&pci_mem_hole, 0, sizeof(struct mem_range));
pci_mem_hole.name = "PCI hole";

View File

@ -343,19 +343,14 @@ rtc_init(struct vmctx *ctx)
* 0x34/0x35 - 64KB chunks above 16MB, below 4GB
* 0x5b/0x5c/0x5d - 64KB chunks above 4GB
*/
err = vm_get_memory_seg(ctx, 0, &lomem, NULL);
assert(err == 0);
lomem = (lomem - m_16MB) / m_64KB;
lomem = (vm_get_lowmem_size(ctx) - m_16MB) / m_64KB;
rtc_nvram[nvoff(RTC_LMEM_LSB)] = lomem;
rtc_nvram[nvoff(RTC_LMEM_MSB)] = lomem >> 8;
if (vm_get_memory_seg(ctx, m_4GB, &himem, NULL) == 0) {
himem /= m_64KB;
rtc_nvram[nvoff(RTC_HMEM_LSB)] = himem;
rtc_nvram[nvoff(RTC_HMEM_SB)] = himem >> 8;
rtc_nvram[nvoff(RTC_HMEM_MSB)] = himem >> 16;
}
himem = vm_get_highmem_size(ctx) / m_64KB;
rtc_nvram[nvoff(RTC_HMEM_LSB)] = himem;
rtc_nvram[nvoff(RTC_HMEM_SB)] = himem >> 8;
rtc_nvram[nvoff(RTC_HMEM_MSB)] = himem >> 16;
}
INOUT_PORT(rtc, IO_RTC, IOPORT_F_INOUT, rtc_addr_handler);

View File

@ -779,13 +779,8 @@ smbios_build(struct vmctx *ctx)
int i;
int err;
err = vm_get_memory_seg(ctx, 0, &guest_lomem, NULL);
if (err != 0)
return (err);
err = vm_get_memory_seg(ctx, 4*GB, &guest_himem, NULL);
if (err != 0)
return (err);
guest_lomem = vm_get_lowmem_size(ctx);
guest_himem = vm_get_highmem_size(ctx);
startaddr = paddr_guest2host(ctx, SMBIOS_BASE, SMBIOS_MAX_LENGTH);
if (startaddr == NULL) {

View File

@ -505,8 +505,8 @@ static void
cb_getmem(void *arg, uint64_t *ret_lowmem, uint64_t *ret_highmem)
{
vm_get_memory_seg(ctx, 0, ret_lowmem, NULL);
vm_get_memory_seg(ctx, 4 * GB, ret_highmem, NULL);
*ret_lowmem = vm_get_lowmem_size(ctx);
*ret_highmem = vm_get_highmem_size(ctx);
}
struct env {