Message ID | 20240325141422.1380087-3-pbonzini@redhat.com |
---|---|
State | New |
Headers | show |
Series | kvm: add support for guest physical bits | expand |
On 3/25/2024 10:14 PM, Paolo Bonzini wrote: > From: Gerd Hoffmann <kraxel@redhat.com> > > Allows to set guest-phys-bits (cpuid leaf 80000008, eax[23:16]) > via -cpu $model,guest-phys-bits=$nr. > > Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> > Message-ID: <20240318155336.156197-3-kraxel@redhat.com> > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com> > --- > v4->v5: > - move here all non-KVM parts > - add compat property and support for special value "-1" (accelerator > defines value) > > target/i386/cpu.h | 1 + > hw/i386/pc.c | 4 +++- > target/i386/cpu.c | 22 ++++++++++++++++++++++ > 3 files changed, 26 insertions(+), 1 deletion(-) > > diff --git a/target/i386/cpu.h b/target/i386/cpu.h > index 6b057380791..83e47358451 100644 > --- a/target/i386/cpu.h > +++ b/target/i386/cpu.h > @@ -2026,6 +2026,7 @@ struct ArchCPU { > > /* Number of physical address bits supported */ > uint32_t phys_bits; > + uint32_t guest_phys_bits; > > /* in order to simplify APIC support, we leave this pointer to the > user */ > diff --git a/hw/i386/pc.c b/hw/i386/pc.c > index 461fcaa1b48..9c4b3969cc8 100644 > --- a/hw/i386/pc.c > +++ b/hw/i386/pc.c > @@ -78,7 +78,9 @@ > { "qemu64-" TYPE_X86_CPU, "model-id", "QEMU Virtual CPU version " v, },\ > { "athlon-" TYPE_X86_CPU, "model-id", "QEMU Virtual CPU version " v, }, > > -GlobalProperty pc_compat_9_0[] = {}; > +GlobalProperty pc_compat_9_0[] = { > + { TYPE_X86_CPU, "guest-phys-bits", "0" }, > +}; > const size_t pc_compat_9_0_len = G_N_ELEMENTS(pc_compat_9_0); > > GlobalProperty pc_compat_8_2[] = {}; > diff --git a/target/i386/cpu.c b/target/i386/cpu.c > index 33760a2ee16..eef3d08473e 100644 > --- a/target/i386/cpu.c > +++ b/target/i386/cpu.c > @@ -6570,6 +6570,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, > if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) { > /* 64 bit processor */ > *eax |= (cpu_x86_virtual_addr_width(env) << 8); > + *eax |= (cpu->guest_phys_bits << 16); > } > *ebx = env->features[FEAT_8000_0008_EBX]; > if (cs->nr_cores * cs->nr_threads > 1) { > @@ -7329,6 +7330,14 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) > goto out; > } > > + if (cpu->guest_phys_bits == -1) { > + /* > + * If it was not set by the user, or by the accelerator via > + * cpu_exec_realizefn, clear. > + */ > + cpu->guest_phys_bits = 0; > + } > + > if (cpu->ucode_rev == 0) { > /* > * The default is the same as KVM's. Note that this check > @@ -7379,6 +7388,14 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) > if (cpu->phys_bits == 0) { > cpu->phys_bits = TCG_PHYS_ADDR_BITS; > } > + if (cpu->guest_phys_bits && > + (cpu->guest_phys_bits > cpu->phys_bits || > + cpu->guest_phys_bits < 32)) { > + error_setg(errp, "guest-phys-bits should be between 32 and %u " > + " (but is %u)", > + cpu->phys_bits, cpu->guest_phys_bits); > + return; > + } > } else { > /* For 32 bit systems don't use the user set value, but keep > * phys_bits consistent with what we tell the guest. > @@ -7387,6 +7404,10 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) > error_setg(errp, "phys-bits is not user-configurable in 32 bit"); > return; > } > + if (cpu->guest_phys_bits != 0) { > + error_setg(errp, "guest-phys-bits is not user-configurable in 32 bit"); > + return; > + } > > if (env->features[FEAT_1_EDX] & (CPUID_PSE36 | CPUID_PAE)) { > cpu->phys_bits = 36; > @@ -7887,6 +7908,7 @@ static Property x86_cpu_properties[] = { > DEFINE_PROP_BOOL("x-force-features", X86CPU, force_features, false), > DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true), > DEFINE_PROP_UINT32("phys-bits", X86CPU, phys_bits, 0), > + DEFINE_PROP_UINT32("guest-phys-bits", X86CPU, guest_phys_bits, -1), > 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),
Hi Paolo, On Mon, Mar 25, 2024 at 03:14:21PM +0100, Paolo Bonzini wrote: > Date: Mon, 25 Mar 2024 15:14:21 +0100 > From: Paolo Bonzini <pbonzini@redhat.com> > Subject: [PATCH for-9.1 v5 2/3] target/i386: add guest-phys-bits cpu > property > X-Mailer: git-send-email 2.44.0 > > From: Gerd Hoffmann <kraxel@redhat.com> > > Allows to set guest-phys-bits (cpuid leaf 80000008, eax[23:16]) > via -cpu $model,guest-phys-bits=$nr. > > Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> > Message-ID: <20240318155336.156197-3-kraxel@redhat.com> > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> > --- > v4->v5: > - move here all non-KVM parts > - add compat property and support for special value "-1" (accelerator > defines value) > > target/i386/cpu.h | 1 + > hw/i386/pc.c | 4 +++- > target/i386/cpu.c | 22 ++++++++++++++++++++++ > 3 files changed, 26 insertions(+), 1 deletion(-) > > diff --git a/target/i386/cpu.h b/target/i386/cpu.h > index 6b057380791..83e47358451 100644 > --- a/target/i386/cpu.h > +++ b/target/i386/cpu.h > @@ -2026,6 +2026,7 @@ struct ArchCPU { > > /* Number of physical address bits supported */ > uint32_t phys_bits; > + uint32_t guest_phys_bits; Maybe here it deserves a comment, just as most any other fields...what about copying commit message of patch 3 like: /* * Number of guest physical address bits supported. Usually this is * identical to host physical address bits. With NPT or EPT being used * this might be restricted to 48 (max 4-level paging address space * size) even if the host cpu supports more physical address bits. */ Otherwise, Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 6b057380791..83e47358451 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -2026,6 +2026,7 @@ struct ArchCPU { /* Number of physical address bits supported */ uint32_t phys_bits; + uint32_t guest_phys_bits; /* in order to simplify APIC support, we leave this pointer to the user */ diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 461fcaa1b48..9c4b3969cc8 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -78,7 +78,9 @@ { "qemu64-" TYPE_X86_CPU, "model-id", "QEMU Virtual CPU version " v, },\ { "athlon-" TYPE_X86_CPU, "model-id", "QEMU Virtual CPU version " v, }, -GlobalProperty pc_compat_9_0[] = {}; +GlobalProperty pc_compat_9_0[] = { + { TYPE_X86_CPU, "guest-phys-bits", "0" }, +}; const size_t pc_compat_9_0_len = G_N_ELEMENTS(pc_compat_9_0); GlobalProperty pc_compat_8_2[] = {}; diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 33760a2ee16..eef3d08473e 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -6570,6 +6570,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) { /* 64 bit processor */ *eax |= (cpu_x86_virtual_addr_width(env) << 8); + *eax |= (cpu->guest_phys_bits << 16); } *ebx = env->features[FEAT_8000_0008_EBX]; if (cs->nr_cores * cs->nr_threads > 1) { @@ -7329,6 +7330,14 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) goto out; } + if (cpu->guest_phys_bits == -1) { + /* + * If it was not set by the user, or by the accelerator via + * cpu_exec_realizefn, clear. + */ + cpu->guest_phys_bits = 0; + } + if (cpu->ucode_rev == 0) { /* * The default is the same as KVM's. Note that this check @@ -7379,6 +7388,14 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) if (cpu->phys_bits == 0) { cpu->phys_bits = TCG_PHYS_ADDR_BITS; } + if (cpu->guest_phys_bits && + (cpu->guest_phys_bits > cpu->phys_bits || + cpu->guest_phys_bits < 32)) { + error_setg(errp, "guest-phys-bits should be between 32 and %u " + " (but is %u)", + cpu->phys_bits, cpu->guest_phys_bits); + return; + } } else { /* For 32 bit systems don't use the user set value, but keep * phys_bits consistent with what we tell the guest. @@ -7387,6 +7404,10 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) error_setg(errp, "phys-bits is not user-configurable in 32 bit"); return; } + if (cpu->guest_phys_bits != 0) { + error_setg(errp, "guest-phys-bits is not user-configurable in 32 bit"); + return; + } if (env->features[FEAT_1_EDX] & (CPUID_PSE36 | CPUID_PAE)) { cpu->phys_bits = 36; @@ -7887,6 +7908,7 @@ static Property x86_cpu_properties[] = { DEFINE_PROP_BOOL("x-force-features", X86CPU, force_features, false), DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true), DEFINE_PROP_UINT32("phys-bits", X86CPU, phys_bits, 0), + DEFINE_PROP_UINT32("guest-phys-bits", X86CPU, guest_phys_bits, -1), 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),