[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 2/5] hvf: non-RAM, non-ROMD memory ranges are now correctly mapped
From: |
Paolo Bonzini |
Subject: |
[PULL 2/5] hvf: non-RAM, non-ROMD memory ranges are now correctly mapped in |
Date: |
Tue, 26 Nov 2019 09:59:33 +0100 |
From: Cameron Esfahani <address@hidden>
If an area is non-RAM and non-ROMD, then remove mappings so accesses
will trap and can be emulated. Change hvf_find_overlap_slot() to take
a size instead of an end address: it wouldn't return a slot because
callers would pass the same address for start and end. Don't always
map area as read/write/execute, respect area flags.
Signed-off-by: Cameron Esfahani <address@hidden>
Message-Id: <address@hidden>
Signed-off-by: Paolo Bonzini <address@hidden>
---
target/i386/hvf/hvf.c | 50 ++++++++++++++++++++++++++++++-------------
1 file changed, 35 insertions(+), 15 deletions(-)
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
index 231732aaf7..0b50cfcbc6 100644
--- a/target/i386/hvf/hvf.c
+++ b/target/i386/hvf/hvf.c
@@ -107,14 +107,14 @@ static void assert_hvf_ok(hv_return_t ret)
}
/* Memory slots */
-hvf_slot *hvf_find_overlap_slot(uint64_t start, uint64_t end)
+hvf_slot *hvf_find_overlap_slot(uint64_t start, uint64_t size)
{
hvf_slot *slot;
int x;
for (x = 0; x < hvf_state->num_slots; ++x) {
slot = &hvf_state->slots[x];
if (slot->size && start < (slot->start + slot->size) &&
- end > slot->start) {
+ (start + size) > slot->start) {
return slot;
}
}
@@ -129,12 +129,10 @@ struct mac_slot {
};
struct mac_slot mac_slots[32];
-#define ALIGN(x, y) (((x) + (y) - 1) & ~((y) - 1))
-static int do_hvf_set_memory(hvf_slot *slot)
+static int do_hvf_set_memory(hvf_slot *slot, hv_memory_flags_t flags)
{
struct mac_slot *macslot;
- hv_memory_flags_t flags;
hv_return_t ret;
macslot = &mac_slots[slot->slot_id];
@@ -151,8 +149,6 @@ static int do_hvf_set_memory(hvf_slot *slot)
return 0;
}
- flags = HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC;
-
macslot->present = 1;
macslot->gpa_start = slot->start;
macslot->size = slot->size;
@@ -165,14 +161,24 @@ void hvf_set_phys_mem(MemoryRegionSection *section, bool
add)
{
hvf_slot *mem;
MemoryRegion *area = section->mr;
+ bool writeable = !area->readonly && !area->rom_device;
+ hv_memory_flags_t flags;
if (!memory_region_is_ram(area)) {
- return;
+ if (writeable) {
+ return;
+ } else if (!memory_region_is_romd(area)) {
+ /*
+ * If the memory device is not in romd_mode, then we actually want
+ * to remove the hvf memory slot so all accesses will trap.
+ */
+ add = false;
+ }
}
mem = hvf_find_overlap_slot(
section->offset_within_address_space,
- section->offset_within_address_space +
int128_get64(section->size));
+ int128_get64(section->size));
if (mem && add) {
if (mem->size == int128_get64(section->size) &&
@@ -186,7 +192,7 @@ void hvf_set_phys_mem(MemoryRegionSection *section, bool
add)
/* Region needs to be reset. set the size to 0 and remap it. */
if (mem) {
mem->size = 0;
- if (do_hvf_set_memory(mem)) {
+ if (do_hvf_set_memory(mem, 0)) {
error_report("Failed to reset overlapping slot");
abort();
}
@@ -196,6 +202,13 @@ void hvf_set_phys_mem(MemoryRegionSection *section, bool
add)
return;
}
+ if (area->readonly ||
+ (!memory_region_is_ram(area) && memory_region_is_romd(area))) {
+ flags = HV_MEMORY_READ | HV_MEMORY_EXEC;
+ } else {
+ flags = HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC;
+ }
+
/* Now make a new slot. */
int x;
@@ -216,7 +229,7 @@ void hvf_set_phys_mem(MemoryRegionSection *section, bool
add)
mem->start = section->offset_within_address_space;
mem->region = area;
- if (do_hvf_set_memory(mem)) {
+ if (do_hvf_set_memory(mem, flags)) {
error_report("Error registering new memory slot");
abort();
}
@@ -345,7 +358,14 @@ static bool ept_emulation_fault(hvf_slot *slot, uint64_t
gpa, uint64_t ept_qual)
return false;
}
- return !slot;
+ if (!slot) {
+ return true;
+ }
+ if (!memory_region_is_ram(slot->region) &&
+ !(read && memory_region_is_romd(slot->region))) {
+ return true;
+ }
+ return false;
}
static void hvf_set_dirty_tracking(MemoryRegionSection *section, bool on)
@@ -354,7 +374,7 @@ static void hvf_set_dirty_tracking(MemoryRegionSection
*section, bool on)
slot = hvf_find_overlap_slot(
section->offset_within_address_space,
- section->offset_within_address_space +
int128_get64(section->size));
+ int128_get64(section->size));
/* protect region against writes; begin tracking it */
if (on) {
@@ -720,7 +740,7 @@ int hvf_vcpu_exec(CPUState *cpu)
ret = EXCP_INTERRUPT;
break;
}
- /* Need to check if MMIO or unmmaped fault */
+ /* Need to check if MMIO or unmapped fault */
case EXIT_REASON_EPT_FAULT:
{
hvf_slot *slot;
@@ -731,7 +751,7 @@ int hvf_vcpu_exec(CPUState *cpu)
vmx_set_nmi_blocking(cpu);
}
- slot = hvf_find_overlap_slot(gpa, gpa);
+ slot = hvf_find_overlap_slot(gpa, 1);
/* mmio */
if (ept_emulation_fault(slot, gpa, exit_qual)) {
struct x86_decode decode;
--
2.21.0
- [PULL 0/5] i386 patches for QEMU 4.2-rc, Paolo Bonzini, 2019/11/26
- [PULL 1/5] target/i386: add two missing VMX features for Skylake and CascadeLake Server, Paolo Bonzini, 2019/11/26
- [PULL 2/5] hvf: non-RAM, non-ROMD memory ranges are now correctly mapped in,
Paolo Bonzini <=
- [PULL 3/5] hvf: remove TSC synchronization code because it isn't fully complete, Paolo Bonzini, 2019/11/26
- [PULL 4/5] hvf: correctly handle REX prefix in relation to legacy prefixes, Paolo Bonzini, 2019/11/26
- [PULL 5/5] hvf: more accurately match SDM when setting CR0 and PDPTE registers, Paolo Bonzini, 2019/11/26
- Re: [PULL 0/5] i386 patches for QEMU 4.2-rc, no-reply, 2019/11/26
- Re: [PULL 0/5] i386 patches for QEMU 4.2-rc, Peter Maydell, 2019/11/26