cpu: Move watchpoint fields from CPU_COMMON to CPUState
authorAndreas Färber <afaerber@suse.de>
Mon, 26 Aug 2013 16:23:18 +0000 (18:23 +0200)
committerAndreas Färber <afaerber@suse.de>
Thu, 13 Mar 2014 18:20:47 +0000 (19:20 +0100)
Signed-off-by: Andreas Färber <afaerber@suse.de>
13 files changed:
cpu-exec.c
exec.c
gdbstub.c
include/exec/cpu-defs.h
include/qom/cpu.h
linux-user/main.c
target-i386/cpu.h
target-i386/helper.c
target-i386/kvm.c
target-lm32/cpu.h
target-lm32/helper.c
target-xtensa/cpu.h
target-xtensa/helper.c

index 798dc084d93eb3d751fe6102607568a970fd13a6..d7c21d35e50e466f76a0b0be8961ab659ab32c33 100644 (file)
@@ -200,10 +200,11 @@ void cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler)
 
 static void cpu_handle_debug_exception(CPUArchState *env)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
     CPUWatchpoint *wp;
 
-    if (!env->watchpoint_hit) {
-        QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
+    if (!cpu->watchpoint_hit) {
+        QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
             wp->flags &= ~BP_WATCHPOINT_HIT;
         }
     }
diff --git a/exec.c b/exec.c
index 26ed9ccd0c81c376865200f678831a2caaa23958..ee5eff77340a152b1489fd897a420b482224c052 100644 (file)
--- a/exec.c
+++ b/exec.c
@@ -485,7 +485,7 @@ void cpu_exec_init(CPUArchState *env)
     cpu->cpu_index = cpu_index;
     cpu->numa_node = 0;
     QTAILQ_INIT(&env->breakpoints);
-    QTAILQ_INIT(&env->watchpoints);
+    QTAILQ_INIT(&cpu->watchpoints);
 #ifndef CONFIG_USER_ONLY
     cpu->as = &address_space_memory;
     cpu->thread_id = qemu_get_thread_id();
@@ -542,6 +542,7 @@ int cpu_watchpoint_insert(CPUArchState *env, target_ulong addr, target_ulong len
 int cpu_watchpoint_insert(CPUArchState *env, target_ulong addr, target_ulong len,
                           int flags, CPUWatchpoint **watchpoint)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
     target_ulong len_mask = ~(len - 1);
     CPUWatchpoint *wp;
 
@@ -559,10 +560,11 @@ int cpu_watchpoint_insert(CPUArchState *env, target_ulong addr, target_ulong len
     wp->flags = flags;
 
     /* keep all GDB-injected watchpoints in front */
-    if (flags & BP_GDB)
-        QTAILQ_INSERT_HEAD(&env->watchpoints, wp, entry);
-    else
-        QTAILQ_INSERT_TAIL(&env->watchpoints, wp, entry);
+    if (flags & BP_GDB) {
+        QTAILQ_INSERT_HEAD(&cpu->watchpoints, wp, entry);
+    } else {
+        QTAILQ_INSERT_TAIL(&cpu->watchpoints, wp, entry);
+    }
 
     tlb_flush_page(env, addr);
 
@@ -575,10 +577,11 @@ int cpu_watchpoint_insert(CPUArchState *env, target_ulong addr, target_ulong len
 int cpu_watchpoint_remove(CPUArchState *env, target_ulong addr, target_ulong len,
                           int flags)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
     target_ulong len_mask = ~(len - 1);
     CPUWatchpoint *wp;
 
-    QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
+    QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
         if (addr == wp->vaddr && len_mask == wp->len_mask
                 && flags == (wp->flags & ~BP_WATCHPOINT_HIT)) {
             cpu_watchpoint_remove_by_ref(env, wp);
@@ -591,7 +594,9 @@ int cpu_watchpoint_remove(CPUArchState *env, target_ulong addr, target_ulong len
 /* Remove a specific watchpoint by reference.  */
 void cpu_watchpoint_remove_by_ref(CPUArchState *env, CPUWatchpoint *watchpoint)
 {
-    QTAILQ_REMOVE(&env->watchpoints, watchpoint, entry);
+    CPUState *cpu = ENV_GET_CPU(env);
+
+    QTAILQ_REMOVE(&cpu->watchpoints, watchpoint, entry);
 
     tlb_flush_page(env, watchpoint->vaddr);
 
@@ -601,9 +606,10 @@ void cpu_watchpoint_remove_by_ref(CPUArchState *env, CPUWatchpoint *watchpoint)
 /* Remove all matching watchpoints.  */
 void cpu_watchpoint_remove_all(CPUArchState *env, int mask)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
     CPUWatchpoint *wp, *next;
 
-    QTAILQ_FOREACH_SAFE(wp, &env->watchpoints, entry, next) {
+    QTAILQ_FOREACH_SAFE(wp, &cpu->watchpoints, entry, next) {
         if (wp->flags & mask)
             cpu_watchpoint_remove_by_ref(env, wp);
     }
@@ -799,6 +805,7 @@ hwaddr memory_region_section_get_iotlb(CPUArchState *env,
                                        int prot,
                                        target_ulong *address)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
     hwaddr iotlb;
     CPUWatchpoint *wp;
 
@@ -818,7 +825,7 @@ hwaddr memory_region_section_get_iotlb(CPUArchState *env,
 
     /* Make accesses to pages with watchpoints go via the
        watchpoint trap routines.  */
-    QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
+    QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
         if (vaddr == (wp->vaddr & TARGET_PAGE_MASK)) {
             /* Avoid trapping reads of pages with a write breakpoint. */
             if ((prot & PAGE_WRITE) || (wp->flags & BP_MEM_READ)) {
@@ -1579,7 +1586,7 @@ static void check_watchpoint(int offset, int len_mask, int flags)
     CPUWatchpoint *wp;
     int cpu_flags;
 
-    if (env->watchpoint_hit) {
+    if (cpu->watchpoint_hit) {
         /* We re-entered the check after replacing the TB. Now raise
          * the debug interrupt so that is will trigger after the
          * current instruction. */
@@ -1587,12 +1594,12 @@ static void check_watchpoint(int offset, int len_mask, int flags)
         return;
     }
     vaddr = (cpu->mem_io_vaddr & TARGET_PAGE_MASK) + offset;
-    QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
+    QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
         if ((vaddr == (wp->vaddr & len_mask) ||
              (vaddr & wp->len_mask) == wp->vaddr) && (wp->flags & flags)) {
             wp->flags |= BP_WATCHPOINT_HIT;
-            if (!env->watchpoint_hit) {
-                env->watchpoint_hit = wp;
+            if (!cpu->watchpoint_hit) {
+                cpu->watchpoint_hit = wp;
                 tb_check_watchpoint(env);
                 if (wp->flags & BP_STOP_BEFORE_ACCESS) {
                     cpu->exception_index = EXCP_DEBUG;
index c5ab73fb1db34a52626e270cc21a981191d14bab..0176b3f80ed3e380dab0590dee941cdee2e6d08b 100644 (file)
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1204,8 +1204,8 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state)
     }
     switch (state) {
     case RUN_STATE_DEBUG:
-        if (env->watchpoint_hit) {
-            switch (env->watchpoint_hit->flags & BP_MEM_ACCESS) {
+        if (cpu->watchpoint_hit) {
+            switch (cpu->watchpoint_hit->flags & BP_MEM_ACCESS) {
             case BP_MEM_READ:
                 type = "r";
                 break;
@@ -1219,8 +1219,8 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state)
             snprintf(buf, sizeof(buf),
                      "T%02xthread:%02x;%swatch:" TARGET_FMT_lx ";",
                      GDB_SIGNAL_TRAP, cpu_index(cpu), type,
-                     env->watchpoint_hit->vaddr);
-            env->watchpoint_hit = NULL;
+                     (target_ulong)cpu->watchpoint_hit->vaddr);
+            cpu->watchpoint_hit = NULL;
             goto send_packet;
         }
         tb_flush(env);
index 8af85476fcd85dfeb9496f1353c6e9d012a8f856..31aac691c506b3acdaef6e1d4a6e99cafa69ecc7 100644 (file)
@@ -120,13 +120,6 @@ typedef struct CPUBreakpoint {
     QTAILQ_ENTRY(CPUBreakpoint) entry;
 } CPUBreakpoint;
 
-typedef struct CPUWatchpoint {
-    target_ulong vaddr;
-    target_ulong len_mask;
-    int flags; /* BP_* */
-    QTAILQ_ENTRY(CPUWatchpoint) entry;
-} CPUWatchpoint;
-
 #define CPU_TEMP_BUF_NLONGS 128
 #define CPU_COMMON                                                      \
     /* soft mmu support */                                              \
@@ -135,8 +128,5 @@ typedef struct CPUWatchpoint {
     /* from this point: preserved by CPU reset */                       \
     /* ice debug support */                                             \
     QTAILQ_HEAD(breakpoints_head, CPUBreakpoint) breakpoints;            \
-                                                                        \
-    QTAILQ_HEAD(watchpoints_head, CPUWatchpoint) watchpoints;            \
-    CPUWatchpoint *watchpoint_hit;                                      \
 
 #endif
index 4d1ea35ca474f2a767611caf0b1f76e0e7978c05..c7420e070b352e069f793fa3e28741cfdc22eb6e 100644 (file)
@@ -151,6 +151,13 @@ typedef struct icount_decr_u16 {
 } icount_decr_u16;
 #endif
 
+typedef struct CPUWatchpoint {
+    vaddr vaddr;
+    vaddr len_mask;
+    int flags; /* BP_* */
+    QTAILQ_ENTRY(CPUWatchpoint) entry;
+} CPUWatchpoint;
+
 struct KVMState;
 struct kvm_run;
 
@@ -231,6 +238,9 @@ struct CPUState {
     int gdb_num_g_regs;
     QTAILQ_ENTRY(CPUState) node;
 
+    QTAILQ_HEAD(watchpoints_head, CPUWatchpoint) watchpoints;
+    CPUWatchpoint *watchpoint_hit;
+
     void *opaque;
 
     /* In order to avoid passing too many arguments to the MMIO helpers,
index 6e62b8babd319de15ac164ad9fcce263eb47152d..5a06192ec421fca715551771cf0d0f3b301c3d22 100644 (file)
@@ -3435,6 +3435,7 @@ void init_task_state(TaskState *ts)
 
 CPUArchState *cpu_copy(CPUArchState *env)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
     CPUArchState *new_env = cpu_init(cpu_model);
 #if defined(TARGET_HAS_ICE)
     CPUBreakpoint *bp;
@@ -3450,12 +3451,12 @@ CPUArchState *cpu_copy(CPUArchState *env)
        Note: Once we support ptrace with hw-debug register access, make sure
        BP_CPU break/watchpoints are handled correctly on clone. */
     QTAILQ_INIT(&env->breakpoints);
-    QTAILQ_INIT(&env->watchpoints);
+    QTAILQ_INIT(&cpu->watchpoints);
 #if defined(TARGET_HAS_ICE)
     QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
         cpu_breakpoint_insert(new_env, bp->pc, bp->flags, NULL);
     }
-    QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
+    QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
         cpu_watchpoint_insert(new_env, wp->vaddr, (~wp->len_mask) + 1,
                               wp->flags, NULL);
     }
index 62641af77e6008f2d85da5291f8283762e374725..906018757d71a57cafae131f87531fd69d18dd60 100644 (file)
@@ -876,7 +876,7 @@ typedef struct CPUX86State {
     target_ulong dr[8]; /* debug registers */
     union {
         CPUBreakpoint *cpu_breakpoint[4];
-        CPUWatchpoint *cpu_watchpoint[4];
+        struct CPUWatchpoint *cpu_watchpoint[4];
     }; /* break/watchpoints for dr[0..3] */
     uint32_t smbase;
     int old_exception;  /* exception in flight */
index 6d9bd71a3a1c2cf8ddd9923709385812ad418bbd..bd8da20946d3274befed749077a1f336160d1571 100644 (file)
@@ -1088,11 +1088,12 @@ bool check_hw_breakpoints(CPUX86State *env, bool force_dr6_update)
 
 void breakpoint_handler(CPUX86State *env)
 {
+    CPUState *cs = CPU(x86_env_get_cpu(env));
     CPUBreakpoint *bp;
 
-    if (env->watchpoint_hit) {
-        if (env->watchpoint_hit->flags & BP_CPU) {
-            env->watchpoint_hit = NULL;
+    if (cs->watchpoint_hit) {
+        if (cs->watchpoint_hit->flags & BP_CPU) {
+            cs->watchpoint_hit = NULL;
             if (check_hw_breakpoints(env, false)) {
                 raise_exception(env, EXCP01_DB);
             } else {
index e555040a97121e1b54765047c02244dd35cbed63..7a295f6f20e350a1b1ae0a639965daf2dd60c7c1 100644 (file)
@@ -2277,13 +2277,13 @@ static int kvm_handle_debug(X86CPU *cpu,
                         break;
                     case 0x1:
                         ret = EXCP_DEBUG;
-                        env->watchpoint_hit = &hw_watchpoint;
+                        cs->watchpoint_hit = &hw_watchpoint;
                         hw_watchpoint.vaddr = hw_breakpoint[n].addr;
                         hw_watchpoint.flags = BP_MEM_WRITE;
                         break;
                     case 0x3:
                         ret = EXCP_DEBUG;
-                        env->watchpoint_hit = &hw_watchpoint;
+                        cs->watchpoint_hit = &hw_watchpoint;
                         hw_watchpoint.vaddr = hw_breakpoint[n].addr;
                         hw_watchpoint.flags = BP_MEM_ACCESS;
                         break;
@@ -2291,11 +2291,11 @@ static int kvm_handle_debug(X86CPU *cpu,
                 }
             }
         }
-    } else if (kvm_find_sw_breakpoint(CPU(cpu), arch_info->pc)) {
+    } else if (kvm_find_sw_breakpoint(cs, arch_info->pc)) {
         ret = EXCP_DEBUG;
     }
     if (ret == 0) {
-        cpu_synchronize_state(CPU(cpu));
+        cpu_synchronize_state(cs);
         assert(env->exception_injected == -1);
 
         /* pass to guest */
index b94d9b007ec3eac0c03e897d8a9c67bbdc16c0c6..d50726bce7d595d7ff2fddb3c8477bc141fccbfe 100644 (file)
@@ -167,7 +167,7 @@ struct CPULM32State {
     uint32_t wp[4];     /* watchpoints */
 
     CPUBreakpoint * cpu_breakpoint[4];
-    CPUWatchpoint * cpu_watchpoint[4];
+    struct CPUWatchpoint *cpu_watchpoint[4];
 
     CPU_COMMON
 
index e5536c0ecbca47e8377fddcc4a76eb0b893e68e2..67ba278e2752a981477c7d7e6ec2c280cfe4ec0f 100644 (file)
@@ -118,11 +118,12 @@ static bool check_watchpoints(CPULM32State *env)
 
 void lm32_debug_excp_handler(CPULM32State *env)
 {
+    CPUState *cs = CPU(lm32_env_get_cpu(env));
     CPUBreakpoint *bp;
 
-    if (env->watchpoint_hit) {
-        if (env->watchpoint_hit->flags & BP_CPU) {
-            env->watchpoint_hit = NULL;
+    if (cs->watchpoint_hit) {
+        if (cs->watchpoint_hit->flags & BP_CPU) {
+            cs->watchpoint_hit = NULL;
             if (check_watchpoints(env)) {
                 raise_exception(env, EXCP_WATCHPOINT);
             } else {
index 4bae693c6d6e16b61c16e62074ab334f50585063..e210bacdffa59860d3b19507fdcff9a6b3bb7261 100644 (file)
@@ -359,7 +359,7 @@ typedef struct CPUXtensaState {
     int exception_taken;
 
     /* Watchpoints for DBREAK registers */
-    CPUWatchpoint *cpu_watchpoint[MAX_NDBREAK];
+    struct CPUWatchpoint *cpu_watchpoint[MAX_NDBREAK];
 
     CPU_COMMON
 } CPUXtensaState;
index 259878837fd7e53c254115987862cf43d075ff5a..8a9cb0a825276ae01b68b8bb526a3afb423e56ad 100644 (file)
@@ -81,11 +81,13 @@ static uint32_t check_hw_breakpoints(CPUXtensaState *env)
 
 void xtensa_breakpoint_handler(CPUXtensaState *env)
 {
-    if (env->watchpoint_hit) {
-        if (env->watchpoint_hit->flags & BP_CPU) {
+    CPUState *cs = CPU(xtensa_env_get_cpu(env));
+
+    if (cs->watchpoint_hit) {
+        if (cs->watchpoint_hit->flags & BP_CPU) {
             uint32_t cause;
 
-            env->watchpoint_hit = NULL;
+            cs->watchpoint_hit = NULL;
             cause = check_hw_breakpoints(env);
             if (cause) {
                 debug_exception_env(env, cause);