117 lines
4.2 KiB
Diff
117 lines
4.2 KiB
Diff
From a09c3928b33b0c53831bd9eeb56f8171c26057bc Mon Sep 17 00:00:00 2001
|
|
From: Jiajie Li <lijiajie11@huawei.com>
|
|
Date: Tue, 8 Feb 2022 09:46:53 +0800
|
|
Subject: [PATCH 2/2] target-i386: Modify the VM's physical bits value set
|
|
policy.
|
|
|
|
To resolve the problem that a VM with large memory capacity fails
|
|
to be live migrated, determine whether the VM is a large memory
|
|
capacity based on the memory size (4 TB). If yes, set the bus width
|
|
of the VM address to 46 bits. If no, set the bus width to 42 bits.
|
|
|
|
Signed-off-by: Jinhua Cao <caojinhua1@huawei.com>
|
|
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
|
|
---
|
|
target/i386/cpu.c | 19 ++++++++++++++++++-
|
|
target/i386/cpu.h | 6 ++++++
|
|
target/i386/host-cpu.c | 13 +++++++------
|
|
3 files changed, 31 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
|
|
index aa9e636800..868cf3e7e8 100644
|
|
--- a/target/i386/cpu.c
|
|
+++ b/target/i386/cpu.c
|
|
@@ -6678,6 +6678,23 @@ static void x86_cpu_set_pc(CPUState *cs, vaddr value)
|
|
cpu->env.eip = value;
|
|
}
|
|
|
|
+/* At present, we check the vm is *LARGE* or not, i.e. whether
|
|
+ * the memory size is more than 4T or not.
|
|
+ */
|
|
+const uint64_t large_vm_mem_size = 0x40000000000UL;
|
|
+void x86_cpu_adjuest_by_ram_size(ram_addr_t ram_size, X86CPU *cpu)
|
|
+{
|
|
+ /* If there is not a large vm, we set the phys_bits to 42 bits,
|
|
+ * otherwise, we increase the phys_bits to 46 bits.
|
|
+ */
|
|
+ if (ram_size < large_vm_mem_size) {
|
|
+ cpu->phys_bits = DEFAULT_VM_CPU_PHYS_BITS;
|
|
+ } else {
|
|
+ cpu->phys_bits = LARGE_VM_CPU_PHYS_BITS;
|
|
+ cpu->fill_mtrr_mask = true;
|
|
+ }
|
|
+}
|
|
+
|
|
int x86_cpu_pending_interrupt(CPUState *cs, int interrupt_request)
|
|
{
|
|
X86CPU *cpu = X86_CPU(cs);
|
|
@@ -6862,7 +6879,7 @@ static Property x86_cpu_properties[] = {
|
|
DEFINE_PROP_UINT32("phys-bits", X86CPU, phys_bits, 0),
|
|
DEFINE_PROP_BOOL("host-phys-bits", X86CPU, host_phys_bits, false),
|
|
DEFINE_PROP_UINT8("host-phys-bits-limit", X86CPU, host_phys_bits_limit, 0),
|
|
- DEFINE_PROP_BOOL("fill-mtrr-mask", X86CPU, fill_mtrr_mask, true),
|
|
+ DEFINE_PROP_BOOL("fill-mtrr-mask", X86CPU, fill_mtrr_mask, false),
|
|
DEFINE_PROP_UINT32("level-func7", X86CPU, env.cpuid_level_func7,
|
|
UINT32_MAX),
|
|
DEFINE_PROP_UINT32("level", X86CPU, env.cpuid_level, UINT32_MAX),
|
|
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
|
|
index 04f2b790c9..6f777fd6ca 100644
|
|
--- a/target/i386/cpu.h
|
|
+++ b/target/i386/cpu.h
|
|
@@ -24,6 +24,7 @@
|
|
#include "cpu-qom.h"
|
|
#include "kvm/hyperv-proto.h"
|
|
#include "exec/cpu-defs.h"
|
|
+#include "exec/cpu-common.h"
|
|
#include "qapi/qapi-types-common.h"
|
|
|
|
/* The x86 has a strong memory model with some store-after-load re-ordering */
|
|
@@ -1841,6 +1842,11 @@ struct X86CPU {
|
|
extern const VMStateDescription vmstate_x86_cpu;
|
|
#endif
|
|
|
|
+#define DEFAULT_VM_CPU_PHYS_BITS 42
|
|
+#define LARGE_VM_CPU_PHYS_BITS 46
|
|
+
|
|
+void x86_cpu_adjuest_by_ram_size(ram_addr_t ram_size, X86CPU *cpu);
|
|
+
|
|
int x86_cpu_pending_interrupt(CPUState *cs, int interrupt_request);
|
|
|
|
int x86_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu,
|
|
diff --git a/target/i386/host-cpu.c b/target/i386/host-cpu.c
|
|
index 10f8aba86e..5a1bbefa36 100644
|
|
--- a/target/i386/host-cpu.c
|
|
+++ b/target/i386/host-cpu.c
|
|
@@ -12,6 +12,7 @@
|
|
#include "host-cpu.h"
|
|
#include "qapi/error.h"
|
|
#include "sysemu/sysemu.h"
|
|
+#include "hw/boards.h"
|
|
|
|
/* Note: Only safe for use on x86(-64) hosts */
|
|
static uint32_t host_cpu_phys_bits(void)
|
|
@@ -56,14 +57,14 @@ static uint32_t host_cpu_adjust_phys_bits(X86CPU *cpu)
|
|
uint32_t phys_bits = cpu->phys_bits;
|
|
static bool warned;
|
|
|
|
- /*
|
|
- * Print a warning if the user set it to a value that's not the
|
|
- * host value.
|
|
- */
|
|
- if (phys_bits != host_phys_bits && phys_bits != 0 &&
|
|
+ /* adjust x86 cpu phys_bits according to ram_size. */
|
|
+ x86_cpu_adjuest_by_ram_size(current_machine->ram_size, cpu);
|
|
+
|
|
+ /* Print a warning if the host value less than the user set. */
|
|
+ if (phys_bits > host_phys_bits && phys_bits != 0 &&
|
|
!warned) {
|
|
warn_report("Host physical bits (%u)"
|
|
- " does not match phys-bits property (%u)",
|
|
+ " less than phys-bits property (%u)",
|
|
host_phys_bits, phys_bits);
|
|
warned = true;
|
|
}
|
|
--
|
|
2.27.0
|
|
|