qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v5] x86: host physical bits
@ 2016-07-11 19:28 Dr. David Alan Gilbert (git)
  2016-07-11 19:28 ` [Qemu-devel] [PATCH v5] x86: Set physical address bits based on host Dr. David Alan Gilbert (git)
  0 siblings, 1 reply; 3+ messages in thread
From: Dr. David Alan Gilbert (git) @ 2016-07-11 19:28 UTC (permalink / raw)
  To: qemu-devel, pbonzini, ehabkost, marcel, mst, kraxel

From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>

This is the last one of the patches in my previous physical address
bits set; all the others are in x86-next and this patch is based
off x86-next.

v5:
  Remove error/warning on host-phys-bits in TCG/32bit mode, so letting
  a machine type turn host-phys-bits on.

Dr. David Alan Gilbert (1):
  x86: Set physical address bits based on host

 target-i386/cpu.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++---------
 target-i386/cpu.h |  3 +++
 2 files changed, 65 insertions(+), 10 deletions(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Qemu-devel] [PATCH v5] x86: Set physical address bits based on host
  2016-07-11 19:28 [Qemu-devel] [PATCH v5] x86: host physical bits Dr. David Alan Gilbert (git)
@ 2016-07-11 19:28 ` Dr. David Alan Gilbert (git)
  2016-07-13 14:20   ` Eduardo Habkost
  0 siblings, 1 reply; 3+ messages in thread
From: Dr. David Alan Gilbert (git) @ 2016-07-11 19:28 UTC (permalink / raw)
  To: qemu-devel, pbonzini, ehabkost, marcel, mst, kraxel

From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>

Add the host-phys-bits boolean property, if true, take phys-bits
from the hosts physical bits value, overriding either the default
or the user specified value.

We can also use the value we read from the host to check the users
explicitly set value and warn them if it doesn't match.

Note:
   a) We only read the hosts value in KVM mode (because on non-x86
      we get an abort if we try)
   b) We don't warn about trying to use host-phys-bits in TCG mode,
      we just fall back to the TCG default.  This allows the machine
      type to set the host-phys-bits flag if it wants and then to
      work in both TCG and KVM.

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
 target-i386/cpu.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++--------
 target-i386/cpu.h |  3 +++
 2 files changed, 65 insertions(+), 10 deletions(-)

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 73304c4..8047dad 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2925,6 +2925,31 @@ static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
 }
 #endif
 
+/* Note: Only safe for use on x86(-64) hosts */
+static uint32_t x86_host_phys_bits(void)
+{
+    uint32_t eax;
+    uint32_t host_phys_bits;
+
+    host_cpuid(0x80000000, 0, &eax, NULL, NULL, NULL);
+    if (eax >= 0x80000008) {
+        host_cpuid(0x80000008, 0, &eax, NULL, NULL, NULL);
+        /* Note: According to AMD doc 25481 rev 2.34 they have a field
+         * at 23:16 that can specify a maximum physical address bits for
+         * the guest that can override this value; but I've not seen
+         * anything with that set.
+         */
+        host_phys_bits = eax & 0xff;
+    } else {
+        /* It's an odd 64 bit machine that doesn't have the leaf for
+         * physical address bits; fall back to 36 that's most older
+         * Intel.
+         */
+        host_phys_bits = 36;
+    }
+
+    return host_phys_bits;
+}
 
 #define IS_INTEL_CPU(env) ((env)->cpuid_vendor1 == CPUID_VENDOR_INTEL_1 && \
                            (env)->cpuid_vendor2 == CPUID_VENDOR_INTEL_2 && \
@@ -2992,29 +3017,55 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
            & CPUID_EXT2_AMD_ALIASES);
     }
 
+    /* For 64bit systems think about the number of physical bits to present.
+     * ideally this should be the same as the host; anything other than matching
+     * the host can cause incorrect guest behaviour.
+     * QEMU used to pick the magic value of 40 bits that corresponds to
+     * consumer AMD devices but nothing else.
+     */
     if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
-        /* 0 means it was not explicitly set by the user (or by machine
-         * compat_props). In this case, the default is the value used by
-         * TCG (40).
-         */
-        if (cpu->phys_bits == 0) {
-            cpu->phys_bits = TCG_PHYS_ADDR_BITS;
-        }
         if (kvm_enabled()) {
-            if (cpu->phys_bits > TARGET_PHYS_ADDR_SPACE_BITS ||
-                cpu->phys_bits < 32) {
+            uint32_t host_phys_bits = x86_host_phys_bits();
+            static bool warned;
+
+            if (cpu->host_phys_bits) {
+                /* The user asked for us to use the host physical bits */
+                cpu->phys_bits = host_phys_bits;
+            }
+
+            /* Print a warning if the user set it to a value that's not the
+             * host value.
+             */
+            if (cpu->phys_bits != host_phys_bits && cpu->phys_bits != 0 &&
+                !warned) {
+                error_report("Warning: Host physical bits (%u)"
+                                 " does not match phys-bits property (%u)",
+                                 host_phys_bits, cpu->phys_bits);
+                warned = true;
+            }
+
+            if (cpu->phys_bits &&
+                (cpu->phys_bits > TARGET_PHYS_ADDR_SPACE_BITS ||
+                cpu->phys_bits < 32)) {
                 error_setg(errp, "phys-bits should be between 32 and %u "
                                  " (but is %u)",
                                  TARGET_PHYS_ADDR_SPACE_BITS, cpu->phys_bits);
                 return;
             }
         } else {
-            if (cpu->phys_bits != TCG_PHYS_ADDR_BITS) {
+            if (cpu->phys_bits && cpu->phys_bits != TCG_PHYS_ADDR_BITS) {
                 error_setg(errp, "TCG only supports phys-bits=%u",
                                   TCG_PHYS_ADDR_BITS);
                 return;
             }
         }
+        /* 0 means it was not explicitly set by the user (or by machine
+         * compat_props or by the host code above). In this case, the default
+         * is the value used by TCG (40).
+         */
+        if (cpu->phys_bits == 0) {
+            cpu->phys_bits = TCG_PHYS_ADDR_BITS;
+        }
     } else {
         /* For 32 bit systems don't use the user set value, but keep
          * phys_bits consistent with what we tell the guest.
@@ -3331,6 +3382,7 @@ static Property x86_cpu_properties[] = {
     DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false),
     DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true),
     DEFINE_PROP_UINT32("phys-bits", X86CPU, phys_bits, 0),
+    DEFINE_PROP_BOOL("host-phys-bits", X86CPU, host_phys_bits, false),
     DEFINE_PROP_BOOL("fill-mtrr-mask", X86CPU, fill_mtrr_mask, true),
     DEFINE_PROP_UINT32("level", X86CPU, env.cpuid_level, 0),
     DEFINE_PROP_UINT32("xlevel", X86CPU, env.cpuid_xlevel, 0),
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index ab0cb11..3ee18ca 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1203,6 +1203,9 @@ struct X86CPU {
     /* if true fill the top bits of the MTRR_PHYSMASKn variable range */
     bool fill_mtrr_mask;
 
+    /* if true override the phys_bits value with a value read from the host */
+    bool host_phys_bits;
+
     /* Number of physical address bits supported */
     uint32_t phys_bits;
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [Qemu-devel] [PATCH v5] x86: Set physical address bits based on host
  2016-07-11 19:28 ` [Qemu-devel] [PATCH v5] x86: Set physical address bits based on host Dr. David Alan Gilbert (git)
@ 2016-07-13 14:20   ` Eduardo Habkost
  0 siblings, 0 replies; 3+ messages in thread
From: Eduardo Habkost @ 2016-07-13 14:20 UTC (permalink / raw)
  To: Dr. David Alan Gilbert (git); +Cc: qemu-devel, pbonzini, marcel, mst, kraxel

On Mon, Jul 11, 2016 at 08:28:46PM +0100, Dr. David Alan Gilbert (git) wrote:
> From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
> 
> Add the host-phys-bits boolean property, if true, take phys-bits
> from the hosts physical bits value, overriding either the default
> or the user specified value.
> 
> We can also use the value we read from the host to check the users
> explicitly set value and warn them if it doesn't match.
> 
> Note:
>    a) We only read the hosts value in KVM mode (because on non-x86
>       we get an abort if we try)
>    b) We don't warn about trying to use host-phys-bits in TCG mode,
>       we just fall back to the TCG default.  This allows the machine
>       type to set the host-phys-bits flag if it wants and then to
>       work in both TCG and KVM.
> 
> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>

Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>

Applied to x86-next. Thanks!

-- 
Eduardo

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2016-07-13 14:21 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-07-11 19:28 [Qemu-devel] [PATCH v5] x86: host physical bits Dr. David Alan Gilbert (git)
2016-07-11 19:28 ` [Qemu-devel] [PATCH v5] x86: Set physical address bits based on host Dr. David Alan Gilbert (git)
2016-07-13 14:20   ` Eduardo Habkost

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).