We are able to eliminate some NOP implementations with a default
fallback.
Signed-off-by: Alex Bennée <[email protected]>
---
include/accel/kvm/cpu-ops.h | 15 +++++++++++++++
include/system/kvm.h | 6 ------
target/i386/kvm/kvm_i386.h | 5 +++++
accel/kvm/kvm-all.c | 18 ++++++++++++++----
target/arm/kvm.c | 13 ++++++++-----
target/i386/kvm/kvm-cpu.c | 3 +++
target/i386/kvm/kvm.c | 10 +++++-----
target/loongarch/kvm/kvm.c | 16 ----------------
target/ppc/kvm.c | 13 ++++++++-----
target/riscv/kvm/kvm-cpu.c | 19 -------------------
target/s390x/kvm/kvm.c | 9 ++++++---
11 files changed, 64 insertions(+), 63 deletions(-)
diff --git a/include/accel/kvm/cpu-ops.h b/include/accel/kvm/cpu-ops.h
index d2374e91cef..23a83eee6ed 100644
--- a/include/accel/kvm/cpu-ops.h
+++ b/include/accel/kvm/cpu-ops.h
@@ -85,6 +85,16 @@ struct kvm_run;
* software breakpoint, restoring @bp->saved_insn at
* @bp->pc.
* Returns 0 on success, or a negative errno on failure.
+ * @insert_hw_breakpoint: Optional callback to insert an architecture-specific
+ * hardware breakpoint or watchpoint at address @addr
+ * with length @len and type @type.
+ * Returns 0 on success, or a negative errno on failure.
+ * @remove_hw_breakpoint: Optional callback to remove an architecture-specific
+ * hardware breakpoint or watchpoint at address @addr
+ * with length @len and type @type.
+ * Returns 0 on success, or a negative errno on failure.
+ * @remove_all_hw_breakpoints: Optional callback to remove all architecture-
+ * specific hardware breakpoints and watchpoints.
*/
typedef struct KVMCPUOps {
int (*pre_create_vcpu)(CPUState *cpu, Error **errp);
@@ -100,6 +110,11 @@ typedef struct KVMCPUOps {
void (*update_guest_debug)(CPUState *cpu, struct kvm_guest_debug *dbg);
int (*insert_sw_breakpoint)(CPUState *cpu, struct kvm_sw_breakpoint *bp);
int (*remove_sw_breakpoint)(CPUState *cpu, struct kvm_sw_breakpoint *bp);
+ int (*insert_hw_breakpoint)(CPUState *cpu, vaddr addr, vaddr len,
+ GdbBreakpointType type);
+ int (*remove_hw_breakpoint)(CPUState *cpu, vaddr addr, vaddr len,
+ GdbBreakpointType type);
+ void (*remove_all_hw_breakpoints)(CPUState *cpu);
} KVMCPUOps;
#define TYPE_KVM_ACCEL_CPU "kvm-accel-cpu"
diff --git a/include/system/kvm.h b/include/system/kvm.h
index 52b7a63a0b3..cfc0144d9a5 100644
--- a/include/system/kvm.h
+++ b/include/system/kvm.h
@@ -394,12 +394,6 @@ struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUState
*cpu,
int kvm_sw_breakpoints_active(CPUState *cpu);
-int kvm_arch_insert_gdbstub_hw_breakpoint(vaddr addr, vaddr len,
- GdbBreakpointType type);
-int kvm_arch_remove_gdbstub_hw_breakpoint(vaddr addr, vaddr len,
- GdbBreakpointType type);
-void kvm_arch_remove_all_gdbstub_hw_breakpoints(void);
-
bool kvm_arch_stop_on_emulation_error(CPUState *cpu);
int kvm_vm_check_extension(KVMState *s, unsigned int extension);
diff --git a/target/i386/kvm/kvm_i386.h b/target/i386/kvm/kvm_i386.h
index 27eea1f65ff..e2ae601100c 100644
--- a/target/i386/kvm/kvm_i386.h
+++ b/target/i386/kvm/kvm_i386.h
@@ -46,6 +46,11 @@ int x86_kvm_process_async_events(CPUState *cs);
void x86_kvm_update_guest_debug(CPUState *cpu, struct kvm_guest_debug *dbg);
int x86_kvm_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp);
int x86_kvm_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp);
+int x86_kvm_insert_hw_breakpoint(CPUState *cs, vaddr addr, vaddr len,
+ GdbBreakpointType type);
+int x86_kvm_remove_hw_breakpoint(CPUState *cs, vaddr addr, vaddr len,
+ GdbBreakpointType type);
+void x86_kvm_remove_all_hw_breakpoints(CPUState *cs);
void kvm_arch_after_reset_vcpu(X86CPU *cpu);
void kvm_arch_do_init_vcpu(X86CPU *cs);
uint32_t kvm_arch_get_supported_cpuid(KVMState *env, uint32_t function,
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 24ded4b1804..3bd61264a7e 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -3917,7 +3917,12 @@ int kvm_insert_gdbstub_breakpoint(CPUState *cpu,
GdbBreakpointType type,
QTAILQ_INSERT_HEAD(&cpu->kvm_state->kvm_sw_breakpoints, bp, entry);
} else {
- err = kvm_arch_insert_gdbstub_hw_breakpoint(addr, len, type);
+ const KVMCPUOps *ops = kvm_get_cpu_ops(cpu);
+
+ if (!ops || !ops->insert_hw_breakpoint) {
+ return -ENOSYS;
+ }
+ err = ops->insert_hw_breakpoint(cpu, addr, len, type);
if (err) {
return err;
}
@@ -3937,9 +3942,9 @@ int kvm_remove_gdbstub_breakpoint(CPUState *cpu,
GdbBreakpointType type,
{
struct kvm_sw_breakpoint *bp;
int err;
+ const KVMCPUOps *ops = kvm_get_cpu_ops(cpu);
if (type == GDB_BREAKPOINT_SW) {
- const KVMCPUOps *ops = kvm_get_cpu_ops(cpu);
bp = kvm_find_sw_breakpoint(cpu, addr);
if (!bp) {
@@ -3963,7 +3968,10 @@ int kvm_remove_gdbstub_breakpoint(CPUState *cpu,
GdbBreakpointType type,
QTAILQ_REMOVE(&cpu->kvm_state->kvm_sw_breakpoints, bp, entry);
g_free(bp);
} else {
- err = kvm_arch_remove_gdbstub_hw_breakpoint(addr, len, type);
+ if (!ops || !ops->remove_hw_breakpoint) {
+ return -ENOSYS;
+ }
+ err = ops->remove_hw_breakpoint(cpu, addr, len, type);
if (err) {
return err;
}
@@ -4005,7 +4013,9 @@ void kvm_remove_all_gdbstub_breakpoints(CPUState *cpu)
QTAILQ_REMOVE(&s->kvm_sw_breakpoints, bp, entry);
g_free(bp);
}
- kvm_arch_remove_all_gdbstub_hw_breakpoints();
+ if (ops && ops->remove_all_hw_breakpoints) {
+ ops->remove_all_hw_breakpoints(cpu);
+ }
CPU_FOREACH(cpu) {
kvm_update_guest_debug(cpu, 0);
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index a4f063f2efb..5c0ccfc11cd 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -1821,8 +1821,8 @@ void kvm_arch_accel_class_init(ObjectClass *oc)
"Eager Page Split chunk size for hugepages. (default: 0, disabled)");
}
-int kvm_arch_insert_gdbstub_hw_breakpoint(vaddr addr, vaddr len,
- GdbBreakpointType type)
+static int arm_kvm_insert_hw_breakpoint(CPUState *cs, vaddr addr, vaddr len,
+ GdbBreakpointType type)
{
switch (type) {
case GDB_BREAKPOINT_HW:
@@ -1837,8 +1837,8 @@ int kvm_arch_insert_gdbstub_hw_breakpoint(vaddr addr,
vaddr len,
}
}
-int kvm_arch_remove_gdbstub_hw_breakpoint(vaddr addr, vaddr len,
- GdbBreakpointType type)
+static int arm_kvm_remove_hw_breakpoint(CPUState *cs, vaddr addr, vaddr len,
+ GdbBreakpointType type)
{
switch (type) {
case GDB_BREAKPOINT_HW:
@@ -1852,7 +1852,7 @@ int kvm_arch_remove_gdbstub_hw_breakpoint(vaddr addr,
vaddr len,
}
}
-void kvm_arch_remove_all_gdbstub_hw_breakpoints(void)
+static void arm_kvm_remove_all_hw_breakpoints(CPUState *cs)
{
if (cur_hw_wps > 0) {
g_array_remove_range(hw_watchpoints, 0, cur_hw_wps);
@@ -2658,6 +2658,9 @@ static const KVMCPUOps arm_kvm_cpu_ops = {
.update_guest_debug = arm_kvm_update_guest_debug,
.insert_sw_breakpoint = arm_kvm_insert_sw_breakpoint,
.remove_sw_breakpoint = arm_kvm_remove_sw_breakpoint,
+ .insert_hw_breakpoint = arm_kvm_insert_hw_breakpoint,
+ .remove_hw_breakpoint = arm_kvm_remove_hw_breakpoint,
+ .remove_all_hw_breakpoints = arm_kvm_remove_all_hw_breakpoints,
};
static void kvm_cpu_accel_class_init(ObjectClass *oc, const void *data)
diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c
index 0cd0884be30..baaee0c7e71 100644
--- a/target/i386/kvm/kvm-cpu.c
+++ b/target/i386/kvm/kvm-cpu.c
@@ -248,6 +248,9 @@ static const KVMCPUOps x86_kvm_cpu_ops = {
.update_guest_debug = x86_kvm_update_guest_debug,
.insert_sw_breakpoint = x86_kvm_insert_sw_breakpoint,
.remove_sw_breakpoint = x86_kvm_remove_sw_breakpoint,
+ .insert_hw_breakpoint = x86_kvm_insert_hw_breakpoint,
+ .remove_hw_breakpoint = x86_kvm_remove_hw_breakpoint,
+ .remove_all_hw_breakpoints = x86_kvm_remove_all_hw_breakpoints,
};
static void kvm_cpu_accel_class_init(ObjectClass *oc, const void *data)
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 4ee7f53c2a8..78c06a07bd6 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -6176,8 +6176,8 @@ static int find_hw_breakpoint(target_ulong addr, int len,
GdbBreakpointType type
return -1;
}
-int kvm_arch_insert_gdbstub_hw_breakpoint(vaddr addr, vaddr len,
- GdbBreakpointType type)
+int x86_kvm_insert_hw_breakpoint(CPUState *cs, vaddr addr, vaddr len,
+ GdbBreakpointType type)
{
switch (type) {
case GDB_BREAKPOINT_HW:
@@ -6217,8 +6217,8 @@ int kvm_arch_insert_gdbstub_hw_breakpoint(vaddr addr,
vaddr len,
return 0;
}
-int kvm_arch_remove_gdbstub_hw_breakpoint(vaddr addr, vaddr len,
- GdbBreakpointType type)
+int x86_kvm_remove_hw_breakpoint(CPUState *cs, vaddr addr, vaddr len,
+ GdbBreakpointType type)
{
int n;
@@ -6232,7 +6232,7 @@ int kvm_arch_remove_gdbstub_hw_breakpoint(vaddr addr,
vaddr len,
return 0;
}
-void kvm_arch_remove_all_gdbstub_hw_breakpoints(void)
+void x86_kvm_remove_all_hw_breakpoints(CPUState *cs)
{
nb_hw_breakpoint = 0;
}
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
index 0899aef552e..b15f60bd2c3 100644
--- a/target/loongarch/kvm/kvm.c
+++ b/target/loongarch/kvm/kvm.c
@@ -1551,22 +1551,6 @@ static int loongarch_kvm_remove_sw_breakpoint(CPUState
*cs,
return 0;
}
-int kvm_arch_insert_gdbstub_hw_breakpoint(vaddr addr, vaddr len,
- GdbBreakpointType type)
-{
- return -ENOSYS;
-}
-
-int kvm_arch_remove_gdbstub_hw_breakpoint(vaddr addr, vaddr len,
- GdbBreakpointType type)
-{
- return -ENOSYS;
-}
-
-void kvm_arch_remove_all_gdbstub_hw_breakpoints(void)
-{
-}
-
static bool kvm_loongarch_handle_debug(CPUState *cs, struct kvm_run *run)
{
LoongArchCPU *cpu = LOONGARCH_CPU(cs);
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 4b2e42ef163..548bf3e00ad 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -1438,8 +1438,8 @@ static int find_hw_watchpoint(target_ulong addr, int
*flag)
return -1;
}
-int kvm_arch_insert_gdbstub_hw_breakpoint(vaddr addr, vaddr len,
- GdbBreakpointType type)
+static int ppc_kvm_insert_hw_breakpoint(CPUState *cs, vaddr addr, vaddr len,
+ GdbBreakpointType type)
{
const unsigned breakpoint_index = nb_hw_breakpoint + nb_hw_watchpoint;
if (breakpoint_index >= ARRAY_SIZE(hw_debug_points)) {
@@ -1483,8 +1483,8 @@ int kvm_arch_insert_gdbstub_hw_breakpoint(vaddr addr,
vaddr len,
return 0;
}
-int kvm_arch_remove_gdbstub_hw_breakpoint(vaddr addr, vaddr len,
- GdbBreakpointType type)
+static int ppc_kvm_remove_hw_breakpoint(CPUState *cs, vaddr addr, vaddr len,
+ GdbBreakpointType type)
{
int n;
@@ -1512,7 +1512,7 @@ int kvm_arch_remove_gdbstub_hw_breakpoint(vaddr addr,
vaddr len,
return 0;
}
-void kvm_arch_remove_all_gdbstub_hw_breakpoints(void)
+static void ppc_kvm_remove_all_hw_breakpoints(CPUState *cs)
{
nb_hw_breakpoint = nb_hw_watchpoint = 0;
}
@@ -3075,6 +3075,9 @@ static const KVMCPUOps ppc_kvm_cpu_ops = {
.update_guest_debug = ppc_kvm_update_guest_debug,
.insert_sw_breakpoint = ppc_kvm_insert_sw_breakpoint,
.remove_sw_breakpoint = ppc_kvm_remove_sw_breakpoint,
+ .insert_hw_breakpoint = ppc_kvm_insert_hw_breakpoint,
+ .remove_hw_breakpoint = ppc_kvm_remove_hw_breakpoint,
+ .remove_all_hw_breakpoints = ppc_kvm_remove_all_hw_breakpoints,
};
static void kvm_cpu_accel_class_init(ObjectClass *oc, const void *data)
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
index 8a82160a7bf..aeb049c0c71 100644
--- a/target/riscv/kvm/kvm-cpu.c
+++ b/target/riscv/kvm/kvm-cpu.c
@@ -2279,25 +2279,6 @@ static int riscv_kvm_remove_sw_breakpoint(CPUState *cs,
return 0;
}
-int kvm_arch_insert_gdbstub_hw_breakpoint(vaddr addr, vaddr len,
- GdbBreakpointType type)
-{
- /* TODO; To be implemented later. */
- return -EINVAL;
-}
-
-int kvm_arch_remove_gdbstub_hw_breakpoint(vaddr addr, vaddr len,
- GdbBreakpointType type)
-{
- /* TODO; To be implemented later. */
- return -EINVAL;
-}
-
-void kvm_arch_remove_all_gdbstub_hw_breakpoints(void)
-{
- /* TODO; To be implemented later. */
-}
-
static void riscv_kvm_update_guest_debug(CPUState *cs,
struct kvm_guest_debug *dbg)
{
diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c
index 12695376442..ccdc85900ba 100644
--- a/target/s390x/kvm/kvm.c
+++ b/target/s390x/kvm/kvm.c
@@ -902,7 +902,7 @@ static int insert_hw_breakpoint(vaddr addr, int len, int
type)
return 0;
}
-int kvm_arch_insert_gdbstub_hw_breakpoint(vaddr addr, vaddr len,
+static int s390x_kvm_insert_hw_breakpoint(CPUState *cs, vaddr addr, vaddr len,
GdbBreakpointType type)
{
switch (type) {
@@ -921,7 +921,7 @@ int kvm_arch_insert_gdbstub_hw_breakpoint(vaddr addr, vaddr
len,
return insert_hw_breakpoint(addr, len, type);
}
-int kvm_arch_remove_gdbstub_hw_breakpoint(vaddr addr, vaddr len,
+static int s390x_kvm_remove_hw_breakpoint(CPUState *cs, vaddr addr, vaddr len,
GdbBreakpointType type)
{
int size;
@@ -951,7 +951,7 @@ int kvm_arch_remove_gdbstub_hw_breakpoint(vaddr addr, vaddr
len,
return 0;
}
-void kvm_arch_remove_all_gdbstub_hw_breakpoints(void)
+static void s390x_kvm_remove_all_hw_breakpoints(CPUState *cs)
{
nb_hw_breakpoints = 0;
g_free(hw_breakpoints);
@@ -2653,6 +2653,9 @@ static const KVMCPUOps s390x_kvm_cpu_ops = {
.update_guest_debug = s390x_kvm_update_guest_debug,
.insert_sw_breakpoint = s390x_kvm_insert_sw_breakpoint,
.remove_sw_breakpoint = s390x_kvm_remove_sw_breakpoint,
+ .insert_hw_breakpoint = s390x_kvm_insert_hw_breakpoint,
+ .remove_hw_breakpoint = s390x_kvm_remove_hw_breakpoint,
+ .remove_all_hw_breakpoints = s390x_kvm_remove_all_hw_breakpoints,
};
static void kvm_cpu_accel_class_init(ObjectClass *oc, const void *data)
--
2.47.3