qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH qom-cpu v2 18/40] cpu: Move watchpoint fields from C


From: Andreas Färber
Subject: [Qemu-devel] [PATCH qom-cpu v2 18/40] cpu: Move watchpoint fields from CPU_COMMON to CPUState
Date: Mon, 10 Mar 2014 01:15:27 +0100

Signed-off-by: Andreas Färber <address@hidden>
---
 cpu-exec.c              |  5 +++--
 exec.c                  | 33 ++++++++++++++++++++-------------
 gdbstub.c               |  8 ++++----
 include/exec/cpu-defs.h | 10 ----------
 include/qom/cpu.h       | 10 ++++++++++
 linux-user/main.c       |  5 +++--
 target-i386/cpu.h       |  2 +-
 target-i386/helper.c    |  7 ++++---
 target-i386/kvm.c       |  8 ++++----
 target-lm32/cpu.h       |  2 +-
 target-lm32/helper.c    |  7 ++++---
 target-xtensa/cpu.h     |  2 +-
 target-xtensa/helper.c  |  8 +++++---
 13 files changed, 60 insertions(+), 47 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 798dc08..d7c21d3 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -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 9b02c6a..cf4a0ef 100644
--- 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)) {
@@ -1573,7 +1580,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. */
@@ -1581,12 +1588,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;
diff --git a/gdbstub.c b/gdbstub.c
index c5ab73f..0176b3f 100644
--- 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);
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index be9569c..338b8cb 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -119,13 +119,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 */                                              \
@@ -134,8 +127,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
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 4d1ea35..c7420e0 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -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,
diff --git a/linux-user/main.c b/linux-user/main.c
index 99220b3..3345a8f 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -3431,6 +3431,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;
@@ -3446,12 +3447,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);
     }
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 62641af..9060187 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -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 */
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 6d9bd71..bd8da20 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -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 {
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index e555040..7a295f6 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -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 */
diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h
index b94d9b0..d50726b 100644
--- a/target-lm32/cpu.h
+++ b/target-lm32/cpu.h
@@ -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
 
diff --git a/target-lm32/helper.c b/target-lm32/helper.c
index e5536c0..67ba278 100644
--- a/target-lm32/helper.c
+++ b/target-lm32/helper.c
@@ -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 {
diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h
index 4bae693..e210bac 100644
--- a/target-xtensa/cpu.h
+++ b/target-xtensa/cpu.h
@@ -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;
diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c
index 2598788..8a9cb0a 100644
--- a/target-xtensa/helper.c
+++ b/target-xtensa/helper.c
@@ -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);
-- 
1.8.4.5




reply via email to

[Prev in Thread] Current Thread [Next in Thread]