Fix a regression in "movs" emulation after r284539. The regression was caused

due to a change in behavior of the 'vm_map_gpa()'.

Prior to r284539 if 'vm_map_gpa()' was called to map an address range in the
guest MMIO region then it would return NULL. This was used by the "movs"
emulation to detect if the 'src' or 'dst' operand was in MMIO space.

Post r284539 'vm_map_gpa()' started returning a non-NULL pointer even when
mapping the guest MMIO region.

Fix this by returning non-NULL only if [gaddr, gaddr+len) is entirely
within the 'lowmem' or 'highmem' regions and NULL otherwise.

Pointy hat to:	neel
Reviewed by:	grehan
Reported by:	tychon, Ben Perrault (ben.perrault@gmail.com)
MFC after:	1 week
This commit is contained in:
Neel Natu 2015-06-22 00:30:34 +00:00
parent 0f20a3cdd8
commit 36e8356e99
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=284688

View File

@ -415,19 +415,28 @@ vm_setup_memory(struct vmctx *ctx, size_t memsize, enum vm_mmap_style vms)
return (0);
}
/*
* Returns a non-NULL pointer if [gaddr, gaddr+len) is entirely contained in
* the lowmem or highmem regions.
*
* In particular return NULL if [gaddr, gaddr+len) falls in guest MMIO region.
* The instruction emulation code depends on this behavior.
*/
void *
vm_map_gpa(struct vmctx *ctx, vm_paddr_t gaddr, size_t len)
{
vm_paddr_t start, end, mapend;
start = gaddr;
end = gaddr + len;
mapend = ctx->highmem ? 4*GB + ctx->highmem : ctx->lowmem;
if (ctx->lowmem > 0) {
if (gaddr < ctx->lowmem && gaddr + len <= ctx->lowmem)
return (ctx->baseaddr + gaddr);
}
if (start <= end && end <= mapend)
return (ctx->baseaddr + start);
else
return (NULL);
if (ctx->highmem > 0) {
if (gaddr >= 4*GB && gaddr + len <= 4*GB + ctx->highmem)
return (ctx->baseaddr + gaddr);
}
return (NULL);
}
size_t