All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/13] X86 queue, 2015-10-23
@ 2015-10-23 15:32 Eduardo Habkost
  2015-10-23 15:33 ` [Qemu-devel] [PULL 01/13] target-i386: allow any alignment for SMBASE Eduardo Habkost
                   ` (13 more replies)
  0 siblings, 14 replies; 15+ messages in thread
From: Eduardo Habkost @ 2015-10-23 15:32 UTC (permalink / raw)
  To: Peter Maydell
  Cc: qemu-devel, Paolo Bonzini, Andreas Färber, Richard Henderson

Sorry for not submitting this a few days earlier.

The following changes since commit 147482ae35b896808af68c0051ad86d3aae12979:

  Merge remote-tracking branch 'remotes/dgibson/tags/ppc-next-20151023' into staging (2015-10-23 13:09:09 +0100)

are available in the git repository at:

  git://github.com/ehabkost/qemu.git tags/x86-pull-request

for you to fetch changes up to 31bfa2a40004204aee503c6417fbafb5d17e0a51:

  vl: trivial: minor tweaks to a max-cpu error msg (2015-10-23 13:11:52 -0200)

----------------------------------------------------------------
X86 queue, 2015-10-23

----------------------------------------------------------------

Andrew Jones (1):
  vl: trivial: minor tweaks to a max-cpu error msg

Eduardo Habkost (6):
  target-i386: Disable cache info passthrough by default
  target-i386: Ensure bit 10 on DR7 is never cleared
  target-i386: Handle I/O breakpoints
  target-i386: Ensure always-1 bits on DR6 can't be cleared
  target-i386: Add DE to TCG_FEATURES
  target-i386: Use 1UL for bit shift

Paolo Bonzini (1):
  target-i386: allow any alignment for SMBASE

Richard Henderson (5):
  target-i386: Introduce cpu_x86_update_dr7
  target-i386: Re-introduce optimal breakpoint removal
  target-i386: Move hw_*breakpoint_* functions
  target-i386: Optimize setting dr[0-3]
  target-i386: Check CR4[DE] for processing DR4/DR5

 include/hw/i386/pc.h     |   5 ++
 target-i386/bpt_helper.c | 224 ++++++++++++++++++++++++++++++++++++++---------
 target-i386/cpu.c        |   8 +-
 target-i386/cpu.h        |  35 ++------
 target-i386/helper.h     |   4 +-
 target-i386/machine.c    |   8 +-
 target-i386/seg_helper.c |   8 +-
 target-i386/smm_helper.c |   4 +-
 target-i386/translate.c  |  30 +++++--
 vl.c                     |   4 +-
 10 files changed, 236 insertions(+), 94 deletions(-)

-- 
2.1.0

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

* [Qemu-devel] [PULL 01/13] target-i386: allow any alignment for SMBASE
  2015-10-23 15:32 [Qemu-devel] [PULL 00/13] X86 queue, 2015-10-23 Eduardo Habkost
@ 2015-10-23 15:33 ` Eduardo Habkost
  2015-10-23 15:33 ` [Qemu-devel] [PULL 02/13] target-i386: Disable cache info passthrough by default Eduardo Habkost
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Eduardo Habkost @ 2015-10-23 15:33 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Jordan Justen, qemu-devel, Paolo Bonzini, Laszlo Ersek,
	Andreas Färber, Richard Henderson

From: Paolo Bonzini <pbonzini@redhat.com>

Processors up to the Pentium (says Bochs---I do not have old enough
manuals) require a 32KiB alignment for the SMBASE, but newer processors
do not need that, and Tiano Core will use non-aligned SMBASE values.

Reported-by: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 target-i386/smm_helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target-i386/smm_helper.c b/target-i386/smm_helper.c
index 02e24b9..c272a98 100644
--- a/target-i386/smm_helper.c
+++ b/target-i386/smm_helper.c
@@ -266,7 +266,7 @@ void helper_rsm(CPUX86State *env)
 
     val = x86_ldl_phys(cs, sm_state + 0x7efc); /* revision ID */
     if (val & 0x20000) {
-        env->smbase = x86_ldl_phys(cs, sm_state + 0x7f00) & ~0x7fff;
+        env->smbase = x86_ldl_phys(cs, sm_state + 0x7f00);
     }
 #else
     cpu_x86_update_cr0(env, x86_ldl_phys(cs, sm_state + 0x7ffc));
@@ -319,7 +319,7 @@ void helper_rsm(CPUX86State *env)
 
     val = x86_ldl_phys(cs, sm_state + 0x7efc); /* revision ID */
     if (val & 0x20000) {
-        env->smbase = x86_ldl_phys(cs, sm_state + 0x7ef8) & ~0x7fff;
+        env->smbase = x86_ldl_phys(cs, sm_state + 0x7ef8);
     }
 #endif
     if ((env->hflags2 & HF2_SMM_INSIDE_NMI_MASK) == 0) {
-- 
2.1.0

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

* [Qemu-devel] [PULL 02/13] target-i386: Disable cache info passthrough by default
  2015-10-23 15:32 [Qemu-devel] [PULL 00/13] X86 queue, 2015-10-23 Eduardo Habkost
  2015-10-23 15:33 ` [Qemu-devel] [PULL 01/13] target-i386: allow any alignment for SMBASE Eduardo Habkost
@ 2015-10-23 15:33 ` Eduardo Habkost
  2015-10-23 15:33 ` [Qemu-devel] [PULL 03/13] target-i386: Introduce cpu_x86_update_dr7 Eduardo Habkost
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Eduardo Habkost @ 2015-10-23 15:33 UTC (permalink / raw)
  To: Peter Maydell
  Cc: qemu-devel, Paolo Bonzini, Benoît Canet,
	Andreas Färber, Richard Henderson

The host cache information may not make sense for the guest if the VM
CPU topology doesn't match the host CPU topology. To make sure we won't
expose broken cache information to the guest, disable cache info
passthrough by default, and add a new "host-cache-info" property that
can be used to enable the old behavior for users that really need it.

Cc: Benoît Canet <benoit@irqsave.net>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 include/hw/i386/pc.h | 5 +++++
 target-i386/cpu.c    | 4 +---
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index c5961d7..7037de0 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -318,6 +318,11 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
             .driver   = "Broadwell-noTSX-" TYPE_X86_CPU,\
             .property = "abm",\
             .value    = "off",\
+        },\
+        {\
+            .driver   = "host" "-" TYPE_X86_CPU,\
+            .property = "host-cache-info",\
+            .value    = "on",\
         },
 
 #define PC_COMPAT_2_3 \
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 5f53af2..987253d 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -656,7 +656,6 @@ struct X86CPUDefinition {
     int stepping;
     FeatureWordArray features;
     char model_id[48];
-    bool cache_info_passthrough;
 };
 
 static X86CPUDefinition builtin_x86_defs[] = {
@@ -1420,6 +1419,7 @@ static X86CPUDefinition host_cpudef;
 
 static Property host_x86_cpu_properties[] = {
     DEFINE_PROP_BOOL("migratable", X86CPU, migratable, true),
+    DEFINE_PROP_BOOL("host-cache-info", X86CPU, cache_info_passthrough, false),
     DEFINE_PROP_END_OF_LIST()
 };
 
@@ -1446,7 +1446,6 @@ static void host_x86_cpu_class_init(ObjectClass *oc, void *data)
     cpu_x86_fill_model_id(host_cpudef.model_id);
 
     xcc->cpu_def = &host_cpudef;
-    host_cpudef.cache_info_passthrough = true;
 
     /* level, xlevel, xlevel2, and the feature words are initialized on
      * instance_init, because they require KVM to be initialized.
@@ -2094,7 +2093,6 @@ static void x86_cpu_load_def(X86CPU *cpu, X86CPUDefinition *def, Error **errp)
     object_property_set_int(OBJECT(cpu), def->stepping, "stepping", errp);
     object_property_set_int(OBJECT(cpu), def->xlevel, "xlevel", errp);
     object_property_set_int(OBJECT(cpu), def->xlevel2, "xlevel2", errp);
-    cpu->cache_info_passthrough = def->cache_info_passthrough;
     object_property_set_str(OBJECT(cpu), def->model_id, "model-id", errp);
     for (w = 0; w < FEATURE_WORDS; w++) {
         env->features[w] = def->features[w];
-- 
2.1.0

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

* [Qemu-devel] [PULL 03/13] target-i386: Introduce cpu_x86_update_dr7
  2015-10-23 15:32 [Qemu-devel] [PULL 00/13] X86 queue, 2015-10-23 Eduardo Habkost
  2015-10-23 15:33 ` [Qemu-devel] [PULL 01/13] target-i386: allow any alignment for SMBASE Eduardo Habkost
  2015-10-23 15:33 ` [Qemu-devel] [PULL 02/13] target-i386: Disable cache info passthrough by default Eduardo Habkost
@ 2015-10-23 15:33 ` Eduardo Habkost
  2015-10-23 15:33 ` [Qemu-devel] [PULL 04/13] target-i386: Re-introduce optimal breakpoint removal Eduardo Habkost
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Eduardo Habkost @ 2015-10-23 15:33 UTC (permalink / raw)
  To: Peter Maydell
  Cc: qemu-devel, Paolo Bonzini, Andreas Färber, Richard Henderson

From: Richard Henderson <rth@twiddle.net>

This moves the last of the iteration over breakpoints into
the bpt_helper.c file.  This also allows us to make several
breakpoint functions static.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 target-i386/bpt_helper.c | 29 ++++++++++++++++++-----------
 target-i386/cpu.h        |  4 ++--
 target-i386/machine.c    |  8 ++++++--
 target-i386/seg_helper.c |  8 +-------
 4 files changed, 27 insertions(+), 22 deletions(-)

diff --git a/target-i386/bpt_helper.c b/target-i386/bpt_helper.c
index c071c24..f14788a 100644
--- a/target-i386/bpt_helper.c
+++ b/target-i386/bpt_helper.c
@@ -21,7 +21,8 @@
 #include "exec/helper-proto.h"
 
 
-void hw_breakpoint_insert(CPUX86State *env, int index)
+#ifndef CONFIG_USER_ONLY
+static void hw_breakpoint_insert(CPUX86State *env, int index)
 {
     CPUState *cs = CPU(x86_env_get_cpu(env));
     int type = 0, err = 0;
@@ -55,7 +56,7 @@ void hw_breakpoint_insert(CPUX86State *env, int index)
     }
 }
 
-void hw_breakpoint_remove(CPUX86State *env, int index)
+static void hw_breakpoint_remove(CPUX86State *env, int index)
 {
     CPUState *cs;
 
@@ -79,6 +80,20 @@ void hw_breakpoint_remove(CPUX86State *env, int index)
     }
 }
 
+void cpu_x86_update_dr7(CPUX86State *env, uint32_t new_dr7)
+{
+    int i;
+
+    for (i = 0; i < DR7_MAX_BP; i++) {
+        hw_breakpoint_remove(env, i);
+    }
+    env->dr[7] = new_dr7;
+    for (i = 0; i < DR7_MAX_BP; i++) {
+        hw_breakpoint_insert(env, i);
+    }
+}
+#endif
+
 static bool check_hw_breakpoints(CPUX86State *env, bool force_dr6_update)
 {
     target_ulong dr6;
@@ -161,20 +176,12 @@ void helper_single_step(CPUX86State *env)
 void helper_movl_drN_T0(CPUX86State *env, int reg, target_ulong t0)
 {
 #ifndef CONFIG_USER_ONLY
-    int i;
-
     if (reg < 4) {
         hw_breakpoint_remove(env, reg);
         env->dr[reg] = t0;
         hw_breakpoint_insert(env, reg);
     } else if (reg == 7) {
-        for (i = 0; i < DR7_MAX_BP; i++) {
-            hw_breakpoint_remove(env, i);
-        }
-        env->dr[7] = t0;
-        for (i = 0; i < DR7_MAX_BP; i++) {
-            hw_breakpoint_insert(env, i);
-        }
+        cpu_x86_update_dr7(env, t0);
     } else {
         env->dr[reg] = t0;
     }
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index a395b4b..70d1b21 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -235,6 +235,7 @@
 #define DR7_TYPE_SHIFT  16
 #define DR7_LEN_SHIFT   18
 #define DR7_FIXED_1     0x00000400
+#define DR7_GLOBAL_BP_MASK   0xaa
 #define DR7_LOCAL_BP_MASK    0x55
 #define DR7_MAX_BP           4
 #define DR7_TYPE_BP_INST     0x0
@@ -1154,14 +1155,13 @@ static inline int hw_breakpoint_len(unsigned long dr7, int index)
     return (len == 2) ? 8 : len + 1;
 }
 
-void hw_breakpoint_insert(CPUX86State *env, int index);
-void hw_breakpoint_remove(CPUX86State *env, int index);
 void breakpoint_handler(CPUState *cs);
 
 /* will be suppressed */
 void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0);
 void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3);
 void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4);
+void cpu_x86_update_dr7(CPUX86State *env, uint32_t new_dr7);
 
 /* hw/pc.c */
 uint64_t cpu_get_tsc(CPUX86State *env);
diff --git a/target-i386/machine.c b/target-i386/machine.c
index 6737366..a18e16e 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -367,8 +367,12 @@ static int cpu_post_load(void *opaque, int version_id)
 
     cpu_breakpoint_remove_all(cs, BP_CPU);
     cpu_watchpoint_remove_all(cs, BP_CPU);
-    for (i = 0; i < DR7_MAX_BP; i++) {
-        hw_breakpoint_insert(env, i);
+    {
+        /* Indicate all breakpoints disabled, as they are, then
+           let the helper re-enable them.  */
+        target_ulong dr7 = env->dr[7];
+        env->dr[7] = dr7 & ~(DR7_GLOBAL_BP_MASK | DR7_LOCAL_BP_MASK);
+        cpu_x86_update_dr7(env, dr7);
     }
     tlb_flush(cs, 1);
 
diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index 1cbe559..20ee892 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -501,13 +501,7 @@ static void switch_tss_ra(CPUX86State *env, int tss_selector,
 #ifndef CONFIG_USER_ONLY
     /* reset local breakpoints */
     if (env->dr[7] & DR7_LOCAL_BP_MASK) {
-        for (i = 0; i < DR7_MAX_BP; i++) {
-            if (hw_local_breakpoint_enabled(env->dr[7], i) &&
-                !hw_global_breakpoint_enabled(env->dr[7], i)) {
-                hw_breakpoint_remove(env, i);
-            }
-        }
-        env->dr[7] &= ~DR7_LOCAL_BP_MASK;
+        cpu_x86_update_dr7(env, env->dr[7] & ~DR7_LOCAL_BP_MASK);
     }
 #endif
 }
-- 
2.1.0

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

* [Qemu-devel] [PULL 04/13] target-i386: Re-introduce optimal breakpoint removal
  2015-10-23 15:32 [Qemu-devel] [PULL 00/13] X86 queue, 2015-10-23 Eduardo Habkost
                   ` (2 preceding siblings ...)
  2015-10-23 15:33 ` [Qemu-devel] [PULL 03/13] target-i386: Introduce cpu_x86_update_dr7 Eduardo Habkost
@ 2015-10-23 15:33 ` Eduardo Habkost
  2015-10-23 15:33 ` [Qemu-devel] [PULL 05/13] target-i386: Ensure bit 10 on DR7 is never cleared Eduardo Habkost
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Eduardo Habkost @ 2015-10-23 15:33 UTC (permalink / raw)
  To: Peter Maydell
  Cc: qemu-devel, Paolo Bonzini, Andreas Färber, Richard Henderson

From: Richard Henderson <rth@twiddle.net>

Before the last patch, we had an efficient loop that disabled
local breakpoints on task switch.  Re-add that, but in a more
general way that handles changes to the global enable bits too.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 target-i386/bpt_helper.c | 34 ++++++++++++++++++++++++++++------
 1 file changed, 28 insertions(+), 6 deletions(-)

diff --git a/target-i386/bpt_helper.c b/target-i386/bpt_helper.c
index f14788a..23ce828 100644
--- a/target-i386/bpt_helper.c
+++ b/target-i386/bpt_helper.c
@@ -82,14 +82,36 @@ static void hw_breakpoint_remove(CPUX86State *env, int index)
 
 void cpu_x86_update_dr7(CPUX86State *env, uint32_t new_dr7)
 {
+    target_ulong old_dr7 = env->dr[7];
     int i;
 
-    for (i = 0; i < DR7_MAX_BP; i++) {
-        hw_breakpoint_remove(env, i);
-    }
-    env->dr[7] = new_dr7;
-    for (i = 0; i < DR7_MAX_BP; i++) {
-        hw_breakpoint_insert(env, i);
+    /* If nothing is changing except the global/local enable bits,
+       then we can make the change more efficient.  */
+    if (((old_dr7 ^ new_dr7) & ~0xff) == 0) {
+        /* Fold the global and local enable bits together into the
+           global fields, then xor to show which registers have
+           changed collective enable state.  */
+        int mod = ((old_dr7 | old_dr7 * 2) ^ (new_dr7 | new_dr7 * 2)) & 0xff;
+
+        for (i = 0; i < DR7_MAX_BP; i++) {
+            if ((mod & (2 << i * 2)) && !hw_breakpoint_enabled(new_dr7, i)) {
+                hw_breakpoint_remove(env, i);
+            }
+        }
+        env->dr[7] = new_dr7;
+        for (i = 0; i < DR7_MAX_BP; i++) {
+            if (mod & (2 << i * 2) && hw_breakpoint_enabled(new_dr7, i)) {
+                hw_breakpoint_insert(env, i);
+            }
+        }
+    } else {
+        for (i = 0; i < DR7_MAX_BP; i++) {
+            hw_breakpoint_remove(env, i);
+        }
+        env->dr[7] = new_dr7;
+        for (i = 0; i < DR7_MAX_BP; i++) {
+            hw_breakpoint_insert(env, i);
+        }
     }
 }
 #endif
-- 
2.1.0

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

* [Qemu-devel] [PULL 05/13] target-i386: Ensure bit 10 on DR7 is never cleared
  2015-10-23 15:32 [Qemu-devel] [PULL 00/13] X86 queue, 2015-10-23 Eduardo Habkost
                   ` (3 preceding siblings ...)
  2015-10-23 15:33 ` [Qemu-devel] [PULL 04/13] target-i386: Re-introduce optimal breakpoint removal Eduardo Habkost
@ 2015-10-23 15:33 ` Eduardo Habkost
  2015-10-23 15:33 ` [Qemu-devel] [PULL 06/13] target-i386: Move hw_*breakpoint_* functions Eduardo Habkost
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Eduardo Habkost @ 2015-10-23 15:33 UTC (permalink / raw)
  To: Peter Maydell
  Cc: qemu-devel, Paolo Bonzini, Andreas Färber, Richard Henderson

Bit 10 of DR7 is documented as always set to 1, so ensure that's
always the case.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 target-i386/bpt_helper.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/target-i386/bpt_helper.c b/target-i386/bpt_helper.c
index 23ce828..49472ea 100644
--- a/target-i386/bpt_helper.c
+++ b/target-i386/bpt_helper.c
@@ -85,6 +85,8 @@ void cpu_x86_update_dr7(CPUX86State *env, uint32_t new_dr7)
     target_ulong old_dr7 = env->dr[7];
     int i;
 
+    new_dr7 |= DR7_FIXED_1;
+
     /* If nothing is changing except the global/local enable bits,
        then we can make the change more efficient.  */
     if (((old_dr7 ^ new_dr7) & ~0xff) == 0) {
-- 
2.1.0

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

* [Qemu-devel] [PULL 06/13] target-i386: Move hw_*breakpoint_* functions
  2015-10-23 15:32 [Qemu-devel] [PULL 00/13] X86 queue, 2015-10-23 Eduardo Habkost
                   ` (4 preceding siblings ...)
  2015-10-23 15:33 ` [Qemu-devel] [PULL 05/13] target-i386: Ensure bit 10 on DR7 is never cleared Eduardo Habkost
@ 2015-10-23 15:33 ` Eduardo Habkost
  2015-10-23 15:33 ` [Qemu-devel] [PULL 07/13] target-i386: Optimize setting dr[0-3] Eduardo Habkost
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Eduardo Habkost @ 2015-10-23 15:33 UTC (permalink / raw)
  To: Peter Maydell
  Cc: qemu-devel, Paolo Bonzini, Andreas Färber, Richard Henderson

From: Richard Henderson <rth@twiddle.net>

They're only used from bpt_helper.c now.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 target-i386/bpt_helper.c | 29 ++++++++++++++++++++++++++++-
 target-i386/cpu.h        | 27 ---------------------------
 2 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/target-i386/bpt_helper.c b/target-i386/bpt_helper.c
index 49472ea..ca58ab7 100644
--- a/target-i386/bpt_helper.c
+++ b/target-i386/bpt_helper.c
@@ -22,6 +22,33 @@
 
 
 #ifndef CONFIG_USER_ONLY
+static inline bool hw_local_breakpoint_enabled(unsigned long dr7, int index)
+{
+    return (dr7 >> (index * 2)) & 1;
+}
+
+static inline bool hw_global_breakpoint_enabled(unsigned long dr7, int index)
+{
+    return (dr7 >> (index * 2)) & 2;
+
+}
+static inline bool hw_breakpoint_enabled(unsigned long dr7, int index)
+{
+    return hw_global_breakpoint_enabled(dr7, index) ||
+           hw_local_breakpoint_enabled(dr7, index);
+}
+
+static inline int hw_breakpoint_type(unsigned long dr7, int index)
+{
+    return (dr7 >> (DR7_TYPE_SHIFT + (index * 4))) & 3;
+}
+
+static inline int hw_breakpoint_len(unsigned long dr7, int index)
+{
+    int len = ((dr7 >> (DR7_LEN_SHIFT + (index * 4))) & 3);
+    return (len == 2) ? 8 : len + 1;
+}
+
 static void hw_breakpoint_insert(CPUX86State *env, int index)
 {
     CPUState *cs = CPU(x86_env_get_cpu(env));
@@ -116,7 +143,6 @@ void cpu_x86_update_dr7(CPUX86State *env, uint32_t new_dr7)
         }
     }
 }
-#endif
 
 static bool check_hw_breakpoints(CPUX86State *env, bool force_dr6_update)
 {
@@ -187,6 +213,7 @@ void breakpoint_handler(CPUState *cs)
         }
     }
 }
+#endif
 
 void helper_single_step(CPUX86State *env)
 {
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 70d1b21..0ccd513 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1128,33 +1128,6 @@ void x86_stl_phys(CPUState *cs, hwaddr addr, uint32_t val);
 void x86_stq_phys(CPUState *cs, hwaddr addr, uint64_t val);
 #endif
 
-static inline bool hw_local_breakpoint_enabled(unsigned long dr7, int index)
-{
-    return (dr7 >> (index * 2)) & 1;
-}
-
-static inline bool hw_global_breakpoint_enabled(unsigned long dr7, int index)
-{
-    return (dr7 >> (index * 2)) & 2;
-
-}
-static inline bool hw_breakpoint_enabled(unsigned long dr7, int index)
-{
-    return hw_global_breakpoint_enabled(dr7, index) ||
-           hw_local_breakpoint_enabled(dr7, index);
-}
-
-static inline int hw_breakpoint_type(unsigned long dr7, int index)
-{
-    return (dr7 >> (DR7_TYPE_SHIFT + (index * 4))) & 3;
-}
-
-static inline int hw_breakpoint_len(unsigned long dr7, int index)
-{
-    int len = ((dr7 >> (DR7_LEN_SHIFT + (index * 4))) & 3);
-    return (len == 2) ? 8 : len + 1;
-}
-
 void breakpoint_handler(CPUState *cs);
 
 /* will be suppressed */
-- 
2.1.0

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

* [Qemu-devel] [PULL 07/13] target-i386: Optimize setting dr[0-3]
  2015-10-23 15:32 [Qemu-devel] [PULL 00/13] X86 queue, 2015-10-23 Eduardo Habkost
                   ` (5 preceding siblings ...)
  2015-10-23 15:33 ` [Qemu-devel] [PULL 06/13] target-i386: Move hw_*breakpoint_* functions Eduardo Habkost
@ 2015-10-23 15:33 ` Eduardo Habkost
  2015-10-23 15:33 ` [Qemu-devel] [PULL 08/13] target-i386: Handle I/O breakpoints Eduardo Habkost
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Eduardo Habkost @ 2015-10-23 15:33 UTC (permalink / raw)
  To: Peter Maydell
  Cc: qemu-devel, Paolo Bonzini, Andreas Färber, Richard Henderson

From: Richard Henderson <rth@twiddle.net>

If the debug register is not enabled, we need
do nothing besides update the register.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 target-i386/bpt_helper.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/target-i386/bpt_helper.c b/target-i386/bpt_helper.c
index ca58ab7..7ff41a6 100644
--- a/target-i386/bpt_helper.c
+++ b/target-i386/bpt_helper.c
@@ -228,9 +228,14 @@ void helper_movl_drN_T0(CPUX86State *env, int reg, target_ulong t0)
 {
 #ifndef CONFIG_USER_ONLY
     if (reg < 4) {
-        hw_breakpoint_remove(env, reg);
-        env->dr[reg] = t0;
-        hw_breakpoint_insert(env, reg);
+        if (hw_breakpoint_enabled(env->dr[7], reg)
+            && hw_breakpoint_type(env->dr[7], reg) != DR7_TYPE_IO_RW) {
+            hw_breakpoint_remove(env, reg);
+            env->dr[reg] = t0;
+            hw_breakpoint_insert(env, reg);
+        } else {
+            env->dr[reg] = t0;
+        }
     } else if (reg == 7) {
         cpu_x86_update_dr7(env, t0);
     } else {
-- 
2.1.0

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

* [Qemu-devel] [PULL 08/13] target-i386: Handle I/O breakpoints
  2015-10-23 15:32 [Qemu-devel] [PULL 00/13] X86 queue, 2015-10-23 Eduardo Habkost
                   ` (6 preceding siblings ...)
  2015-10-23 15:33 ` [Qemu-devel] [PULL 07/13] target-i386: Optimize setting dr[0-3] Eduardo Habkost
@ 2015-10-23 15:33 ` Eduardo Habkost
  2015-10-23 15:33 ` [Qemu-devel] [PULL 09/13] target-i386: Check CR4[DE] for processing DR4/DR5 Eduardo Habkost
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Eduardo Habkost @ 2015-10-23 15:33 UTC (permalink / raw)
  To: Peter Maydell
  Cc: qemu-devel, Paolo Bonzini, Andreas Färber, Richard Henderson

Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 target-i386/bpt_helper.c | 99 +++++++++++++++++++++++++++++++++++-------------
 target-i386/cpu.h        |  2 +
 target-i386/helper.h     |  1 +
 target-i386/translate.c  | 20 +++++++++-
 4 files changed, 94 insertions(+), 28 deletions(-)

diff --git a/target-i386/bpt_helper.c b/target-i386/bpt_helper.c
index 7ff41a6..117cea2 100644
--- a/target-i386/bpt_helper.c
+++ b/target-i386/bpt_helper.c
@@ -49,60 +49,72 @@ static inline int hw_breakpoint_len(unsigned long dr7, int index)
     return (len == 2) ? 8 : len + 1;
 }
 
-static void hw_breakpoint_insert(CPUX86State *env, int index)
+static int hw_breakpoint_insert(CPUX86State *env, int index)
 {
     CPUState *cs = CPU(x86_env_get_cpu(env));
-    int type = 0, err = 0;
+    target_ulong dr7 = env->dr[7];
+    target_ulong drN = env->dr[index];
+    int err = 0;
 
-    switch (hw_breakpoint_type(env->dr[7], index)) {
+    switch (hw_breakpoint_type(dr7, index)) {
     case DR7_TYPE_BP_INST:
-        if (hw_breakpoint_enabled(env->dr[7], index)) {
-            err = cpu_breakpoint_insert(cs, env->dr[index], BP_CPU,
+        if (hw_breakpoint_enabled(dr7, index)) {
+            err = cpu_breakpoint_insert(cs, drN, BP_CPU,
                                         &env->cpu_breakpoint[index]);
         }
         break;
-    case DR7_TYPE_DATA_WR:
-        type = BP_CPU | BP_MEM_WRITE;
-        break;
+
     case DR7_TYPE_IO_RW:
-        /* No support for I/O watchpoints yet */
+        /* Notice when we should enable calls to bpt_io.  */
+        return hw_breakpoint_enabled(env->dr[7], index)
+               ? HF_IOBPT_MASK : 0;
+
+    case DR7_TYPE_DATA_WR:
+        if (hw_breakpoint_enabled(dr7, index)) {
+            err = cpu_watchpoint_insert(cs, drN,
+                                        hw_breakpoint_len(dr7, index),
+                                        BP_CPU | BP_MEM_WRITE,
+                                        &env->cpu_watchpoint[index]);
+        }
         break;
+
     case DR7_TYPE_DATA_RW:
-        type = BP_CPU | BP_MEM_ACCESS;
+        if (hw_breakpoint_enabled(dr7, index)) {
+            err = cpu_watchpoint_insert(cs, drN,
+                                        hw_breakpoint_len(dr7, index),
+                                        BP_CPU | BP_MEM_ACCESS,
+                                        &env->cpu_watchpoint[index]);
+        }
         break;
     }
-
-    if (type != 0) {
-        err = cpu_watchpoint_insert(cs, env->dr[index],
-                                    hw_breakpoint_len(env->dr[7], index),
-                                    type, &env->cpu_watchpoint[index]);
-    }
-
     if (err) {
         env->cpu_breakpoint[index] = NULL;
     }
+    return 0;
 }
 
 static void hw_breakpoint_remove(CPUX86State *env, int index)
 {
-    CPUState *cs;
+    CPUState *cs = CPU(x86_env_get_cpu(env));
 
-    if (!env->cpu_breakpoint[index]) {
-        return;
-    }
-    cs = CPU(x86_env_get_cpu(env));
     switch (hw_breakpoint_type(env->dr[7], index)) {
     case DR7_TYPE_BP_INST:
-        if (hw_breakpoint_enabled(env->dr[7], index)) {
+        if (env->cpu_breakpoint[index]) {
             cpu_breakpoint_remove_by_ref(cs, env->cpu_breakpoint[index]);
+            env->cpu_breakpoint[index] = NULL;
         }
         break;
+
     case DR7_TYPE_DATA_WR:
     case DR7_TYPE_DATA_RW:
-        cpu_watchpoint_remove_by_ref(cs, env->cpu_watchpoint[index]);
+        if (env->cpu_breakpoint[index]) {
+            cpu_watchpoint_remove_by_ref(cs, env->cpu_watchpoint[index]);
+            env->cpu_breakpoint[index] = NULL;
+        }
         break;
+
     case DR7_TYPE_IO_RW:
-        /* No support for I/O watchpoints yet */
+        /* HF_IOBPT_MASK cleared elsewhere.  */
         break;
     }
 }
@@ -110,6 +122,7 @@ static void hw_breakpoint_remove(CPUX86State *env, int index)
 void cpu_x86_update_dr7(CPUX86State *env, uint32_t new_dr7)
 {
     target_ulong old_dr7 = env->dr[7];
+    int iobpt = 0;
     int i;
 
     new_dr7 |= DR7_FIXED_1;
@@ -130,7 +143,10 @@ void cpu_x86_update_dr7(CPUX86State *env, uint32_t new_dr7)
         env->dr[7] = new_dr7;
         for (i = 0; i < DR7_MAX_BP; i++) {
             if (mod & (2 << i * 2) && hw_breakpoint_enabled(new_dr7, i)) {
-                hw_breakpoint_insert(env, i);
+                iobpt |= hw_breakpoint_insert(env, i);
+            } else if (hw_breakpoint_type(new_dr7, i) == DR7_TYPE_IO_RW
+                       && hw_breakpoint_enabled(new_dr7, i)) {
+                iobpt |= HF_IOBPT_MASK;
             }
         }
     } else {
@@ -139,9 +155,11 @@ void cpu_x86_update_dr7(CPUX86State *env, uint32_t new_dr7)
         }
         env->dr[7] = new_dr7;
         for (i = 0; i < DR7_MAX_BP; i++) {
-            hw_breakpoint_insert(env, i);
+            iobpt |= hw_breakpoint_insert(env, i);
         }
     }
+
+    env->hflags = (env->hflags & ~HF_IOBPT_MASK) | iobpt;
 }
 
 static bool check_hw_breakpoints(CPUX86State *env, bool force_dr6_update)
@@ -243,3 +261,30 @@ void helper_movl_drN_T0(CPUX86State *env, int reg, target_ulong t0)
     }
 #endif
 }
+
+/* Check if Port I/O is trapped by a breakpoint.  */
+void helper_bpt_io(CPUX86State *env, uint32_t port,
+                   uint32_t size, target_ulong next_eip)
+{
+#ifndef CONFIG_USER_ONLY
+    target_ulong dr7 = env->dr[7];
+    int i, hit = 0;
+
+    for (i = 0; i < DR7_MAX_BP; ++i) {
+        if (hw_breakpoint_type(dr7, i) == DR7_TYPE_IO_RW
+            && hw_breakpoint_enabled(dr7, i)) {
+            int bpt_len = hw_breakpoint_len(dr7, i);
+            if (port + size - 1 >= env->dr[i]
+                && port <= env->dr[i] + bpt_len - 1) {
+                hit |= 1 << i;
+            }
+        }
+    }
+
+    if (hit) {
+        env->dr[6] = (env->dr[6] & ~0xf) | hit;
+        env->eip = next_eip;
+        raise_exception(env, EXCP01_DB);
+    }
+#endif
+}
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 0ccd513..0bf6f88 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -155,6 +155,7 @@
 #define HF_SVMI_SHIFT       21 /* SVM intercepts are active */
 #define HF_OSFXSR_SHIFT     22 /* CR4.OSFXSR */
 #define HF_SMAP_SHIFT       23 /* CR4.SMAP */
+#define HF_IOBPT_SHIFT      24 /* an io breakpoint enabled */
 
 #define HF_CPL_MASK          (3 << HF_CPL_SHIFT)
 #define HF_SOFTMMU_MASK      (1 << HF_SOFTMMU_SHIFT)
@@ -178,6 +179,7 @@
 #define HF_SVMI_MASK         (1 << HF_SVMI_SHIFT)
 #define HF_OSFXSR_MASK       (1 << HF_OSFXSR_SHIFT)
 #define HF_SMAP_MASK         (1 << HF_SMAP_SHIFT)
+#define HF_IOBPT_MASK        (1 << HF_IOBPT_SHIFT)
 
 /* hflags2 */
 
diff --git a/target-i386/helper.h b/target-i386/helper.h
index 8454a04..e9858c0 100644
--- a/target-i386/helper.h
+++ b/target-i386/helper.h
@@ -92,6 +92,7 @@ DEF_HELPER_3(outw, void, env, i32, i32)
 DEF_HELPER_2(inw, tl, env, i32)
 DEF_HELPER_3(outl, void, env, i32, i32)
 DEF_HELPER_2(inl, tl, env, i32)
+DEF_HELPER_FLAGS_4(bpt_io, TCG_CALL_NO_WG, void, env, i32, i32, tl)
 
 DEF_HELPER_3(svm_check_intercept_param, void, env, i32, i64)
 DEF_HELPER_3(vmexit, void, env, i32, i64)
diff --git a/target-i386/translate.c b/target-i386/translate.c
index ef10e68..ceed4d1 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -1154,6 +1154,19 @@ static inline void gen_cmps(DisasContext *s, TCGMemOp ot)
     gen_op_add_reg_T0(s->aflag, R_EDI);
 }
 
+static void gen_bpt_io(DisasContext *s, TCGv_i32 t_port, int ot)
+{
+    if (s->flags & HF_IOBPT_MASK) {
+        TCGv_i32 t_size = tcg_const_i32(1 << ot);
+        TCGv t_next = tcg_const_tl(s->pc - s->cs_base);
+
+        gen_helper_bpt_io(cpu_env, t_port, t_size, t_next);
+        tcg_temp_free_i32(t_size);
+        tcg_temp_free(t_next);
+    }
+}
+
+
 static inline void gen_ins(DisasContext *s, TCGMemOp ot)
 {
     if (s->tb->cflags & CF_USE_ICOUNT) {
@@ -1170,6 +1183,7 @@ static inline void gen_ins(DisasContext *s, TCGMemOp ot)
     gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
     gen_op_movl_T0_Dshift(ot);
     gen_op_add_reg_T0(s->aflag, R_EDI);
+    gen_bpt_io(s, cpu_tmp2_i32, ot);
     if (s->tb->cflags & CF_USE_ICOUNT) {
         gen_io_end();
     }
@@ -1187,9 +1201,9 @@ static inline void gen_outs(DisasContext *s, TCGMemOp ot)
     tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
     tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[0]);
     gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
-
     gen_op_movl_T0_Dshift(ot);
     gen_op_add_reg_T0(s->aflag, R_ESI);
+    gen_bpt_io(s, cpu_tmp2_i32, ot);
     if (s->tb->cflags & CF_USE_ICOUNT) {
         gen_io_end();
     }
@@ -6269,6 +6283,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
         tcg_gen_movi_i32(cpu_tmp2_i32, val);
         gen_helper_in_func(ot, cpu_T[1], cpu_tmp2_i32);
         gen_op_mov_reg_v(ot, R_EAX, cpu_T[1]);
+        gen_bpt_io(s, cpu_tmp2_i32, ot);
         if (s->tb->cflags & CF_USE_ICOUNT) {
             gen_io_end();
             gen_jmp(s, s->pc - s->cs_base);
@@ -6289,6 +6304,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
         tcg_gen_movi_i32(cpu_tmp2_i32, val);
         tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
         gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
+        gen_bpt_io(s, cpu_tmp2_i32, ot);
         if (s->tb->cflags & CF_USE_ICOUNT) {
             gen_io_end();
             gen_jmp(s, s->pc - s->cs_base);
@@ -6306,6 +6322,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
         gen_helper_in_func(ot, cpu_T[1], cpu_tmp2_i32);
         gen_op_mov_reg_v(ot, R_EAX, cpu_T[1]);
+        gen_bpt_io(s, cpu_tmp2_i32, ot);
         if (s->tb->cflags & CF_USE_ICOUNT) {
             gen_io_end();
             gen_jmp(s, s->pc - s->cs_base);
@@ -6325,6 +6342,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
         tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
         gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
+        gen_bpt_io(s, cpu_tmp2_i32, ot);
         if (s->tb->cflags & CF_USE_ICOUNT) {
             gen_io_end();
             gen_jmp(s, s->pc - s->cs_base);
-- 
2.1.0

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

* [Qemu-devel] [PULL 09/13] target-i386: Check CR4[DE] for processing DR4/DR5
  2015-10-23 15:32 [Qemu-devel] [PULL 00/13] X86 queue, 2015-10-23 Eduardo Habkost
                   ` (7 preceding siblings ...)
  2015-10-23 15:33 ` [Qemu-devel] [PULL 08/13] target-i386: Handle I/O breakpoints Eduardo Habkost
@ 2015-10-23 15:33 ` Eduardo Habkost
  2015-10-23 15:33 ` [Qemu-devel] [PULL 10/13] target-i386: Ensure always-1 bits on DR6 can't be cleared Eduardo Habkost
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Eduardo Habkost @ 2015-10-23 15:33 UTC (permalink / raw)
  To: Peter Maydell
  Cc: qemu-devel, Paolo Bonzini, Andreas Färber, Richard Henderson

From: Richard Henderson <rth@twiddle.net>

Introduce helper_get_dr so that we don't have to put CR4[DE]
into the scarce HFLAGS resource.  At the same time, rename
helper_movl_drN_T0 to helper_set_dr and set the helper flags.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 target-i386/bpt_helper.c | 46 +++++++++++++++++++++++++++++++++++++++++-----
 target-i386/cpu.h        |  2 +-
 target-i386/helper.h     |  3 ++-
 target-i386/translate.c  | 10 ++++++----
 4 files changed, 50 insertions(+), 11 deletions(-)

diff --git a/target-i386/bpt_helper.c b/target-i386/bpt_helper.c
index 117cea2..144cfd4 100644
--- a/target-i386/bpt_helper.c
+++ b/target-i386/bpt_helper.c
@@ -242,10 +242,11 @@ void helper_single_step(CPUX86State *env)
     raise_exception(env, EXCP01_DB);
 }
 
-void helper_movl_drN_T0(CPUX86State *env, int reg, target_ulong t0)
+void helper_set_dr(CPUX86State *env, int reg, target_ulong t0)
 {
 #ifndef CONFIG_USER_ONLY
-    if (reg < 4) {
+    switch (reg) {
+    case 0: case 1: case 2: case 3:
         if (hw_breakpoint_enabled(env->dr[7], reg)
             && hw_breakpoint_type(env->dr[7], reg) != DR7_TYPE_IO_RW) {
             hw_breakpoint_remove(env, reg);
@@ -254,14 +255,49 @@ void helper_movl_drN_T0(CPUX86State *env, int reg, target_ulong t0)
         } else {
             env->dr[reg] = t0;
         }
-    } else if (reg == 7) {
+        return;
+    case 4:
+        if (env->cr[4] & CR4_DE_MASK) {
+            break;
+        }
+        /* fallthru */
+    case 6:
+        env->dr[6] = t0;
+        return;
+    case 5:
+        if (env->cr[4] & CR4_DE_MASK) {
+            break;
+        }
+        /* fallthru */
+    case 7:
         cpu_x86_update_dr7(env, t0);
-    } else {
-        env->dr[reg] = t0;
+        return;
     }
+    raise_exception_err_ra(env, EXCP06_ILLOP, 0, GETPC());
 #endif
 }
 
+target_ulong helper_get_dr(CPUX86State *env, int reg)
+{
+    switch (reg) {
+    case 0: case 1: case 2: case 3: case 6: case 7:
+        return env->dr[reg];
+    case 4:
+        if (env->cr[4] & CR4_DE_MASK) {
+            break;
+        } else {
+            return env->dr[6];
+        }
+    case 5:
+        if (env->cr[4] & CR4_DE_MASK) {
+            break;
+        } else {
+            return env->dr[7];
+        }
+    }
+    raise_exception_err_ra(env, EXCP06_ILLOP, 0, GETPC());
+}
+
 /* Check if Port I/O is trapped by a breakpoint.  */
 void helper_bpt_io(CPUX86State *env, uint32_t port,
                    uint32_t size, target_ulong next_eip)
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 0bf6f88..62f7879 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -920,7 +920,7 @@ typedef struct CPUX86State {
     int error_code;
     int exception_is_int;
     target_ulong exception_next_eip;
-    target_ulong dr[8]; /* debug registers */
+    target_ulong dr[8]; /* debug registers; note dr4 and dr5 are unused */
     union {
         struct CPUBreakpoint *cpu_breakpoint[4];
         struct CPUWatchpoint *cpu_watchpoint[4];
diff --git a/target-i386/helper.h b/target-i386/helper.h
index e9858c0..ecfcfd1 100644
--- a/target-i386/helper.h
+++ b/target-i386/helper.h
@@ -40,7 +40,8 @@ DEF_HELPER_2(read_crN, tl, env, int)
 DEF_HELPER_3(write_crN, void, env, int, tl)
 DEF_HELPER_2(lmsw, void, env, tl)
 DEF_HELPER_1(clts, void, env)
-DEF_HELPER_3(movl_drN_T0, void, env, int, tl)
+DEF_HELPER_FLAGS_3(set_dr, TCG_CALL_NO_WG, void, env, int, tl)
+DEF_HELPER_FLAGS_2(get_dr, TCG_CALL_NO_WG, tl, env, int)
 DEF_HELPER_2(invlpg, void, env, tl)
 
 DEF_HELPER_4(enter_level, void, env, int, int, tl)
diff --git a/target-i386/translate.c b/target-i386/translate.c
index ceed4d1..764b1e4 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -7627,18 +7627,20 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
                 ot = MO_64;
             else
                 ot = MO_32;
-            /* XXX: do it dynamically with CR4.DE bit */
-            if (reg == 4 || reg == 5 || reg >= 8)
+            if (reg >= 8) {
                 goto illegal_op;
+            }
             if (b & 2) {
                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg);
                 gen_op_mov_v_reg(ot, cpu_T[0], rm);
-                gen_helper_movl_drN_T0(cpu_env, tcg_const_i32(reg), cpu_T[0]);
+                tcg_gen_movi_i32(cpu_tmp2_i32, reg);
+                gen_helper_set_dr(cpu_env, cpu_tmp2_i32, cpu_T[0]);
                 gen_jmp_im(s->pc - s->cs_base);
                 gen_eob(s);
             } else {
                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_DR0 + reg);
-                tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,dr[reg]));
+                tcg_gen_movi_i32(cpu_tmp2_i32, reg);
+                gen_helper_get_dr(cpu_T[0], cpu_env, cpu_tmp2_i32);
                 gen_op_mov_reg_v(ot, rm, cpu_T[0]);
             }
         }
-- 
2.1.0

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

* [Qemu-devel] [PULL 10/13] target-i386: Ensure always-1 bits on DR6 can't be cleared
  2015-10-23 15:32 [Qemu-devel] [PULL 00/13] X86 queue, 2015-10-23 Eduardo Habkost
                   ` (8 preceding siblings ...)
  2015-10-23 15:33 ` [Qemu-devel] [PULL 09/13] target-i386: Check CR4[DE] for processing DR4/DR5 Eduardo Habkost
@ 2015-10-23 15:33 ` Eduardo Habkost
  2015-10-23 15:33 ` [Qemu-devel] [PULL 11/13] target-i386: Add DE to TCG_FEATURES Eduardo Habkost
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Eduardo Habkost @ 2015-10-23 15:33 UTC (permalink / raw)
  To: Peter Maydell
  Cc: qemu-devel, Paolo Bonzini, Andreas Färber, Richard Henderson

Bits 4-11 and 16-31 on DR6 are documented as always 1, so ensure they
can't be cleared by software.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 target-i386/bpt_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target-i386/bpt_helper.c b/target-i386/bpt_helper.c
index 144cfd4..dac1b1a 100644
--- a/target-i386/bpt_helper.c
+++ b/target-i386/bpt_helper.c
@@ -262,7 +262,7 @@ void helper_set_dr(CPUX86State *env, int reg, target_ulong t0)
         }
         /* fallthru */
     case 6:
-        env->dr[6] = t0;
+        env->dr[6] = t0 | DR6_FIXED_1;
         return;
     case 5:
         if (env->cr[4] & CR4_DE_MASK) {
-- 
2.1.0

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

* [Qemu-devel] [PULL 11/13] target-i386: Add DE to TCG_FEATURES
  2015-10-23 15:32 [Qemu-devel] [PULL 00/13] X86 queue, 2015-10-23 Eduardo Habkost
                   ` (9 preceding siblings ...)
  2015-10-23 15:33 ` [Qemu-devel] [PULL 10/13] target-i386: Ensure always-1 bits on DR6 can't be cleared Eduardo Habkost
@ 2015-10-23 15:33 ` Eduardo Habkost
  2015-10-23 15:33 ` [Qemu-devel] [PULL 12/13] target-i386: Use 1UL for bit shift Eduardo Habkost
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Eduardo Habkost @ 2015-10-23 15:33 UTC (permalink / raw)
  To: Peter Maydell
  Cc: qemu-devel, Paolo Bonzini, Andreas Färber, Richard Henderson

Now DE is supported by TCG so it can be enabled in CPUID bits.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 target-i386/cpu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 987253d..c92dd06 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -312,7 +312,7 @@ static const char *cpuid_6_feature_name[] = {
           CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | CPUID_SEP | \
           CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
           CPUID_PSE36 | CPUID_CLFLUSH | CPUID_ACPI | CPUID_MMX | \
-          CPUID_FXSR | CPUID_SSE | CPUID_SSE2 | CPUID_SS)
+          CPUID_FXSR | CPUID_SSE | CPUID_SSE2 | CPUID_SS | CPUID_DE)
           /* partly implemented:
           CPUID_MTRR, CPUID_MCA, CPUID_CLFLUSH (needed for Win64) */
           /* missing:
-- 
2.1.0

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

* [Qemu-devel] [PULL 12/13] target-i386: Use 1UL for bit shift
  2015-10-23 15:32 [Qemu-devel] [PULL 00/13] X86 queue, 2015-10-23 Eduardo Habkost
                   ` (10 preceding siblings ...)
  2015-10-23 15:33 ` [Qemu-devel] [PULL 11/13] target-i386: Add DE to TCG_FEATURES Eduardo Habkost
@ 2015-10-23 15:33 ` Eduardo Habkost
  2015-10-23 15:33 ` [Qemu-devel] [PULL 13/13] vl: trivial: minor tweaks to a max-cpu error msg Eduardo Habkost
  2015-10-23 17:14 ` [Qemu-devel] [PULL 00/13] X86 queue, 2015-10-23 Peter Maydell
  13 siblings, 0 replies; 15+ messages in thread
From: Eduardo Habkost @ 2015-10-23 15:33 UTC (permalink / raw)
  To: Peter Maydell
  Cc: qemu-devel, Paolo Bonzini, Andreas Färber, Richard Henderson

Fix undefined behavior detected by clang runtime check:

  qemu/target-i386/cpu.c:1494:15: runtime error:
    left shift of 1 by 31 places cannot be represented in type 'int'

While doing that, add extra parenthesis for clarity.

Reported-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 target-i386/cpu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index c92dd06..c1a9e09 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1491,7 +1491,7 @@ static void report_unavailable_features(FeatureWord w, uint32_t mask)
     int i;
 
     for (i = 0; i < 32; ++i) {
-        if (1 << i & mask) {
+        if ((1UL << i) & mask) {
             const char *reg = get_register_name_32(f->cpuid_reg);
             assert(reg);
             fprintf(stderr, "warning: %s doesn't support requested feature: "
-- 
2.1.0

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

* [Qemu-devel] [PULL 13/13] vl: trivial: minor tweaks to a max-cpu error msg
  2015-10-23 15:32 [Qemu-devel] [PULL 00/13] X86 queue, 2015-10-23 Eduardo Habkost
                   ` (11 preceding siblings ...)
  2015-10-23 15:33 ` [Qemu-devel] [PULL 12/13] target-i386: Use 1UL for bit shift Eduardo Habkost
@ 2015-10-23 15:33 ` Eduardo Habkost
  2015-10-23 17:14 ` [Qemu-devel] [PULL 00/13] X86 queue, 2015-10-23 Peter Maydell
  13 siblings, 0 replies; 15+ messages in thread
From: Eduardo Habkost @ 2015-10-23 15:33 UTC (permalink / raw)
  To: Peter Maydell
  Cc: qemu-devel, Paolo Bonzini, Andrew Jones, Andreas Färber,
	Richard Henderson

From: Andrew Jones <drjones@redhat.com>

Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 vl.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/vl.c b/vl.c
index 332d828..dffaf09 100644
--- a/vl.c
+++ b/vl.c
@@ -4101,8 +4101,8 @@ int main(int argc, char **argv, char **envp)
 
     machine_class->max_cpus = machine_class->max_cpus ?: 1; /* Default to UP */
     if (max_cpus > machine_class->max_cpus) {
-        fprintf(stderr, "Number of SMP cpus requested (%d), exceeds max cpus "
-                "supported by machine `%s' (%d)\n", max_cpus,
+        fprintf(stderr, "Number of SMP CPUs requested (%d) exceeds max CPUs "
+                "supported by machine '%s' (%d)\n", max_cpus,
                 machine_class->name, machine_class->max_cpus);
         exit(1);
     }
-- 
2.1.0

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

* Re: [Qemu-devel] [PULL 00/13] X86 queue, 2015-10-23
  2015-10-23 15:32 [Qemu-devel] [PULL 00/13] X86 queue, 2015-10-23 Eduardo Habkost
                   ` (12 preceding siblings ...)
  2015-10-23 15:33 ` [Qemu-devel] [PULL 13/13] vl: trivial: minor tweaks to a max-cpu error msg Eduardo Habkost
@ 2015-10-23 17:14 ` Peter Maydell
  13 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2015-10-23 17:14 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: QEMU Developers, Paolo Bonzini, Andreas Färber, Richard Henderson

On 23 October 2015 at 16:32, Eduardo Habkost <ehabkost@redhat.com> wrote:
> Sorry for not submitting this a few days earlier.
>
> The following changes since commit 147482ae35b896808af68c0051ad86d3aae12979:
>
>   Merge remote-tracking branch 'remotes/dgibson/tags/ppc-next-20151023' into staging (2015-10-23 13:09:09 +0100)
>
> are available in the git repository at:
>
>   git://github.com/ehabkost/qemu.git tags/x86-pull-request
>
> for you to fetch changes up to 31bfa2a40004204aee503c6417fbafb5d17e0a51:
>
>   vl: trivial: minor tweaks to a max-cpu error msg (2015-10-23 13:11:52 -0200)
>
> ----------------------------------------------------------------
> X86 queue, 2015-10-23
>
> ----------------------------------------------------------------
>
> Andrew Jones (1):
>   vl: trivial: minor tweaks to a max-cpu error msg
>
> Eduardo Habkost (6):
>   target-i386: Disable cache info passthrough by default
>   target-i386: Ensure bit 10 on DR7 is never cleared
>   target-i386: Handle I/O breakpoints
>   target-i386: Ensure always-1 bits on DR6 can't be cleared
>   target-i386: Add DE to TCG_FEATURES
>   target-i386: Use 1UL for bit shift
>
> Paolo Bonzini (1):
>   target-i386: allow any alignment for SMBASE
>
> Richard Henderson (5):
>   target-i386: Introduce cpu_x86_update_dr7
>   target-i386: Re-introduce optimal breakpoint removal
>   target-i386: Move hw_*breakpoint_* functions
>   target-i386: Optimize setting dr[0-3]
>   target-i386: Check CR4[DE] for processing DR4/DR5

Applied, thanks.

-- PMM

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

end of thread, other threads:[~2015-10-23 17:14 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-23 15:32 [Qemu-devel] [PULL 00/13] X86 queue, 2015-10-23 Eduardo Habkost
2015-10-23 15:33 ` [Qemu-devel] [PULL 01/13] target-i386: allow any alignment for SMBASE Eduardo Habkost
2015-10-23 15:33 ` [Qemu-devel] [PULL 02/13] target-i386: Disable cache info passthrough by default Eduardo Habkost
2015-10-23 15:33 ` [Qemu-devel] [PULL 03/13] target-i386: Introduce cpu_x86_update_dr7 Eduardo Habkost
2015-10-23 15:33 ` [Qemu-devel] [PULL 04/13] target-i386: Re-introduce optimal breakpoint removal Eduardo Habkost
2015-10-23 15:33 ` [Qemu-devel] [PULL 05/13] target-i386: Ensure bit 10 on DR7 is never cleared Eduardo Habkost
2015-10-23 15:33 ` [Qemu-devel] [PULL 06/13] target-i386: Move hw_*breakpoint_* functions Eduardo Habkost
2015-10-23 15:33 ` [Qemu-devel] [PULL 07/13] target-i386: Optimize setting dr[0-3] Eduardo Habkost
2015-10-23 15:33 ` [Qemu-devel] [PULL 08/13] target-i386: Handle I/O breakpoints Eduardo Habkost
2015-10-23 15:33 ` [Qemu-devel] [PULL 09/13] target-i386: Check CR4[DE] for processing DR4/DR5 Eduardo Habkost
2015-10-23 15:33 ` [Qemu-devel] [PULL 10/13] target-i386: Ensure always-1 bits on DR6 can't be cleared Eduardo Habkost
2015-10-23 15:33 ` [Qemu-devel] [PULL 11/13] target-i386: Add DE to TCG_FEATURES Eduardo Habkost
2015-10-23 15:33 ` [Qemu-devel] [PULL 12/13] target-i386: Use 1UL for bit shift Eduardo Habkost
2015-10-23 15:33 ` [Qemu-devel] [PULL 13/13] vl: trivial: minor tweaks to a max-cpu error msg Eduardo Habkost
2015-10-23 17:14 ` [Qemu-devel] [PULL 00/13] X86 queue, 2015-10-23 Peter Maydell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.