@@ -700,6 +700,22 @@ static MemoryRegion *memory_region_get_flatview_root(MemoryRegion *mr)
return NULL;
}
+static bool skip_simplify(void)
+{
+#ifdef I386_CPU_H
+ char vendor[CPUID_VENDOR_SZ + 1] = { 0 };
+ host_get_vendor(vendor);
+ if (!strncmp(vendor, CPUID_VENDOR_VIA, strlen(CPUID_VENDOR_VIA))
+ || !strncmp(vendor, CPUID_VENDOR_ZHAOXIN,
+ strlen(CPUID_VENDOR_ZHAOXIN))) {
+ return true;
+ }
+ return false;
+#else
+ return false;
+#endif
+}
+
/* Render a memory topology into a list of disjoint absolute ranges. */
static FlatView *generate_memory_topology(MemoryRegion *mr)
{
@@ -713,7 +729,9 @@ static FlatView *generate_memory_topology(MemoryRegion *mr)
addrrange_make(int128_zero(), int128_2_64()),
false, false);
}
- flatview_simplify(view);
+ if (!skip_simplify()) {
+ flatview_simplify(view);
+ }
view->dispatch = address_space_dispatch_new(view);
for (i = 0; i < view->nr; i++) {
@@ -1559,6 +1559,13 @@ void host_cpuid(uint32_t function, uint32_t count,
if (edx)
*edx = vec[3];
}
+void host_get_vendor(char *vendor)
+{
+ uint32_t eax, ebx, ecx, edx;
+
+ host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
+ x86_cpu_vendor_words2str(vendor, ebx, edx, ecx);
+}
void host_vendor_fms(char *vendor, int *family, int *model, int *stepping)
{
@@ -832,6 +832,8 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
#define CPUID_VENDOR_VIA "CentaurHauls"
+#define CPUID_VENDOR_ZHAOXIN " Shanghai "
+
#define CPUID_VENDOR_HYGON "HygonGenuine"
#define IS_INTEL_CPU(env) ((env)->cpuid_vendor1 == CPUID_VENDOR_INTEL_1 && \
@@ -1918,6 +1920,7 @@ void cpu_clear_apic_feature(CPUX86State *env);
void host_cpuid(uint32_t function, uint32_t count,
uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx);
void host_vendor_fms(char *vendor, int *family, int *model, int *stepping);
+void host_get_vendor(char *vendor);
/* helper.c */
bool x86_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
The issue here is that an assinged EHCI device accesses an adjacent mapping between the delete and add phases of the VFIO MemoryListener. We want to skip flatview_simplify() is to prevent EHCI device IOVA mappings from being unmapped. Signed-off-by: FelixCuioc <FelixCui-oc@zhaoxin.com> --- softmmu/memory.c | 20 +++++++++++++++++++- target/i386/cpu.c | 7 +++++++ target/i386/cpu.h | 3 +++ 3 files changed, 29 insertions(+), 1 deletion(-)