On ARM we want to be able to blacklist registers that are exposed by KVM. To mitigate some mitigation failures that occur when a new register is exposed and does not exist on the destination, some registers are tagged "hidden" and their state won't be saved. As the state is not saved and they are expected not to be used, we want to enforce they aren't. So let's check this. The new CPUClass hide_reg() callback is optional and will be implemented on ARM in a subsequent patch.
Signed-off-by: Eric Auger <[email protected]> --- include/hw/core/cpu.h | 2 ++ accel/kvm/kvm-all.c | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h index e79e8e0a8e..8efd555f36 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h @@ -142,6 +142,7 @@ struct SysemuCPUOps; * the caller will not g_free() it. * @disas_set_info: Setup architecture specific components of disassembly info * @adjust_watchpoint_address: Perform a target-specific adjustment to an + * @hide_reg: Check if a register must be hidden (optional) * address before attempting to match it against watchpoints. * @deprecation_note: If this CPUClass is deprecated, this field provides * related information. @@ -167,6 +168,7 @@ struct CPUClass { int (*gdb_read_register)(CPUState *cpu, GByteArray *buf, int reg); int (*gdb_write_register)(CPUState *cpu, uint8_t *buf, int reg); vaddr (*gdb_adjust_breakpoint)(CPUState *cpu, vaddr addr); + bool (*hide_reg)(CPUState *cpu, uint64_t regidex); const char *gdb_core_xml_file; const char * (*gdb_arch_name)(CPUState *cpu); diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 56031925c4..610f05fd0d 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -3783,9 +3783,15 @@ bool kvm_device_supported(int vmfd, uint64_t type) int kvm_set_one_reg(CPUState *cs, uint64_t id, void *source) { + CPUClass *cc = CPU_GET_CLASS(cs); struct kvm_one_reg reg; int r; + if (cc->hide_reg && cc->hide_reg(cs, id)) { + error_report("%s reg 0x%"PRIx64" is hidden and shall never been accessed", + __func__, id); + g_assert_not_reached(); + } reg.id = id; reg.addr = (uintptr_t) source; r = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); @@ -3797,9 +3803,15 @@ int kvm_set_one_reg(CPUState *cs, uint64_t id, void *source) int kvm_get_one_reg(CPUState *cs, uint64_t id, void *target) { + CPUClass *cc = CPU_GET_CLASS(cs); struct kvm_one_reg reg; int r; + if (cc->hide_reg && cc->hide_reg(cs, id)) { + error_report("%s reg 0x%"PRIx64" is hidden and shall never been accessed", + __func__, id); + g_assert_not_reached(); + } reg.id = id; reg.addr = (uintptr_t) target; r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); -- 2.49.0
