Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch kvm-arm64/debug-6.14 into kvmarm-master/next

* kvm-arm64/debug-6.14:
: .
: Large rework of the debug code to make it a bit less horrid,
: courtesy of Oliver Upton. From the original cover letter:
:
: "The debug code has become a bit difficult to reason about, especially
: all the hacks and bandaids for state tracking + trap configuration.
:
: This series reworks the entire mess around using a single enumeration to
: track the state of the debug registers (free, guest-owned, host-owned),
: using that to drive trap configuration and save/restore.
:
: On top of that, this series wires most of the implementation into vCPU
: load/put rather than the main KVM_RUN loop. This has been a long time
: coming for VHE, as a lot of the trap configuration and EL1 state gets
: loaded into hardware at that point anyway.
:
: The save/restore of the debug registers is simplified quite a bit as
: well. KVM will now restore the registers for *any* access rather than
: just writes, and keep doing so until the next vcpu_put() instead of
: dropping it on the floor after the next exception."
: .
KVM: arm64: Promote guest ownership for DBGxVR/DBGxCR reads
KVM: arm64: Fold DBGxVR/DBGxCR accessors into common set
KVM: arm64: Avoid reading ID_AA64DFR0_EL1 for debug save/restore
KVM: arm64: nv: Honor MDCR_EL2.TDE routing for debug exceptions
KVM: arm64: Manage software step state at load/put
KVM: arm64: Don't hijack guest context MDSCR_EL1
KVM: arm64: Compute MDCR_EL2 at vcpu_load()
KVM: arm64: Reload vCPU for accesses to OSLAR_EL1
KVM: arm64: Use debug_owner to track if debug regs need save/restore
KVM: arm64: Remove vestiges of debug_ptr
KVM: arm64: Remove debug tracepoints
KVM: arm64: Select debug state to save/restore based on debug owner
KVM: arm64: Clean up KVM_SET_GUEST_DEBUG handler
KVM: arm64: Evaluate debug owner at vcpu_load()
KVM: arm64: Write MDCR_EL2 directly from kvm_arm_setup_mdcr_el2()
KVM: arm64: Move host SME/SVE tracking flags to host data
KVM: arm64: Track presence of SPE/TRBE in kvm_host_data instead of vCPU
KVM: arm64: Get rid of __kvm_get_mdcr_el2() and related warts
KVM: arm64: Drop MDSCR_EL1_DEBUG_MASK

Signed-off-by: Marc Zyngier <maz@kernel.org>

+380 -680
+1 -4
arch/arm64/include/asm/kvm_asm.h
··· 53 53 enum __kvm_host_smccc_func { 54 54 /* Hypercalls available only prior to pKVM finalisation */ 55 55 /* __KVM_HOST_SMCCC_FUNC___kvm_hyp_init */ 56 - __KVM_HOST_SMCCC_FUNC___kvm_get_mdcr_el2 = __KVM_HOST_SMCCC_FUNC___kvm_hyp_init + 1, 57 - __KVM_HOST_SMCCC_FUNC___pkvm_init, 56 + __KVM_HOST_SMCCC_FUNC___pkvm_init = __KVM_HOST_SMCCC_FUNC___kvm_hyp_init + 1, 58 57 __KVM_HOST_SMCCC_FUNC___pkvm_create_private_mapping, 59 58 __KVM_HOST_SMCCC_FUNC___pkvm_cpu_set_vector, 60 59 __KVM_HOST_SMCCC_FUNC___kvm_enable_ssbs, ··· 245 246 246 247 extern u64 __vgic_v3_get_gic_config(void); 247 248 extern void __vgic_v3_init_lrs(void); 248 - 249 - extern u64 __kvm_get_mdcr_el2(void); 250 249 251 250 #define __KVM_EXTABLE(from, to) \ 252 251 " .pushsection __kvm_ex_table, \"a\"\n" \
+49 -43
arch/arm64/include/asm/kvm_host.h
··· 610 610 * field. 611 611 */ 612 612 struct kvm_host_data { 613 + #define KVM_HOST_DATA_FLAG_HAS_SPE 0 614 + #define KVM_HOST_DATA_FLAG_HAS_TRBE 1 615 + #define KVM_HOST_DATA_FLAG_HOST_SVE_ENABLED 2 616 + #define KVM_HOST_DATA_FLAG_HOST_SME_ENABLED 3 617 + unsigned long flags; 618 + 613 619 struct kvm_cpu_context host_ctxt; 614 620 615 621 /* ··· 648 642 * host_debug_state contains the host registers which are 649 643 * saved and restored during world switches. 650 644 */ 651 - struct { 645 + struct { 652 646 /* {Break,watch}point registers */ 653 647 struct kvm_guest_debug_arch regs; 654 648 /* Statistical profiling extension */ ··· 658 652 /* Values of trap registers for the host before guest entry. */ 659 653 u64 mdcr_el2; 660 654 } host_debug_state; 655 + 656 + /* Number of programmable event counters (PMCR_EL0.N) for this CPU */ 657 + unsigned int nr_event_counters; 658 + 659 + /* Number of debug breakpoints/watchpoints for this CPU (minus 1) */ 660 + unsigned int debug_brps; 661 + unsigned int debug_wrps; 661 662 }; 662 663 663 664 struct kvm_host_psci_config { ··· 752 739 * 753 740 * external_debug_state contains the debug values we want to debug the 754 741 * guest. This is set via the KVM_SET_GUEST_DEBUG ioctl. 755 - * 756 - * debug_ptr points to the set of debug registers that should be loaded 757 - * onto the hardware when running the guest. 758 742 */ 759 - struct kvm_guest_debug_arch *debug_ptr; 760 743 struct kvm_guest_debug_arch vcpu_debug_state; 761 744 struct kvm_guest_debug_arch external_debug_state; 745 + u64 external_mdscr_el1; 746 + 747 + enum { 748 + VCPU_DEBUG_FREE, 749 + VCPU_DEBUG_HOST_OWNED, 750 + VCPU_DEBUG_GUEST_OWNED, 751 + } debug_owner; 762 752 763 753 /* VGIC state */ 764 754 struct vgic_cpu vgic_cpu; 765 755 struct arch_timer_cpu timer_cpu; 766 756 struct kvm_pmu pmu; 767 - 768 - /* 769 - * Guest registers we preserve during guest debugging. 770 - * 771 - * These shadow registers are updated by the kvm_handle_sys_reg 772 - * trap handler if the guest accesses or updates them while we 773 - * are using guest debug. 774 - */ 775 - struct { 776 - u32 mdscr_el1; 777 - bool pstate_ss; 778 - } guest_debug_preserved; 779 757 780 758 /* vcpu power state */ 781 759 struct kvm_mp_state mp_state; ··· 910 906 #define EXCEPT_AA64_EL2_IRQ __vcpu_except_flags(5) 911 907 #define EXCEPT_AA64_EL2_FIQ __vcpu_except_flags(6) 912 908 #define EXCEPT_AA64_EL2_SERR __vcpu_except_flags(7) 913 - /* Guest debug is live */ 914 - #define DEBUG_DIRTY __vcpu_single_flag(iflags, BIT(4)) 915 - /* Save SPE context if active */ 916 - #define DEBUG_STATE_SAVE_SPE __vcpu_single_flag(iflags, BIT(5)) 917 - /* Save TRBE context if active */ 918 - #define DEBUG_STATE_SAVE_TRBE __vcpu_single_flag(iflags, BIT(6)) 919 909 920 - /* SVE enabled for host EL0 */ 921 - #define HOST_SVE_ENABLED __vcpu_single_flag(sflags, BIT(0)) 922 - /* SME enabled for EL0 */ 923 - #define HOST_SME_ENABLED __vcpu_single_flag(sflags, BIT(1)) 924 910 /* Physical CPU not in supported_cpus */ 925 - #define ON_UNSUPPORTED_CPU __vcpu_single_flag(sflags, BIT(2)) 911 + #define ON_UNSUPPORTED_CPU __vcpu_single_flag(sflags, BIT(0)) 926 912 /* WFIT instruction trapped */ 927 - #define IN_WFIT __vcpu_single_flag(sflags, BIT(3)) 913 + #define IN_WFIT __vcpu_single_flag(sflags, BIT(1)) 928 914 /* vcpu system registers loaded on physical CPU */ 929 - #define SYSREGS_ON_CPU __vcpu_single_flag(sflags, BIT(4)) 930 - /* Software step state is Active-pending */ 931 - #define DBG_SS_ACTIVE_PENDING __vcpu_single_flag(sflags, BIT(5)) 915 + #define SYSREGS_ON_CPU __vcpu_single_flag(sflags, BIT(2)) 916 + /* Software step state is Active-pending for external debug */ 917 + #define HOST_SS_ACTIVE_PENDING __vcpu_single_flag(sflags, BIT(3)) 918 + /* Software step state is Active pending for guest debug */ 919 + #define GUEST_SS_ACTIVE_PENDING __vcpu_single_flag(sflags, BIT(4)) 932 920 /* PMUSERENR for the guest EL0 is on physical CPU */ 933 - #define PMUSERENR_ON_CPU __vcpu_single_flag(sflags, BIT(6)) 921 + #define PMUSERENR_ON_CPU __vcpu_single_flag(sflags, BIT(5)) 934 922 /* WFI instruction trapped */ 935 - #define IN_WFI __vcpu_single_flag(sflags, BIT(7)) 923 + #define IN_WFI __vcpu_single_flag(sflags, BIT(6)) 936 924 937 925 938 926 /* Pointer to the vcpu's SVE FFR for sve_{save,load}_state() */ ··· 1303 1307 &this_cpu_ptr_hyp_sym(kvm_host_data)->f) 1304 1308 #endif 1305 1309 1310 + #define host_data_test_flag(flag) \ 1311 + (test_bit(KVM_HOST_DATA_FLAG_##flag, host_data_ptr(flags))) 1312 + #define host_data_set_flag(flag) \ 1313 + set_bit(KVM_HOST_DATA_FLAG_##flag, host_data_ptr(flags)) 1314 + #define host_data_clear_flag(flag) \ 1315 + clear_bit(KVM_HOST_DATA_FLAG_##flag, host_data_ptr(flags)) 1316 + 1306 1317 /* Check whether the FP regs are owned by the guest */ 1307 1318 static inline bool guest_owns_fp_regs(void) 1308 1319 { ··· 1335 1332 1336 1333 static inline void kvm_arch_sync_events(struct kvm *kvm) {} 1337 1334 1338 - void kvm_arm_init_debug(void); 1339 - void kvm_arm_vcpu_init_debug(struct kvm_vcpu *vcpu); 1340 - void kvm_arm_setup_debug(struct kvm_vcpu *vcpu); 1341 - void kvm_arm_clear_debug(struct kvm_vcpu *vcpu); 1342 - void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu); 1335 + void kvm_init_host_debug_data(void); 1336 + void kvm_vcpu_load_debug(struct kvm_vcpu *vcpu); 1337 + void kvm_vcpu_put_debug(struct kvm_vcpu *vcpu); 1338 + void kvm_debug_set_guest_ownership(struct kvm_vcpu *vcpu); 1339 + void kvm_debug_handle_oslar(struct kvm_vcpu *vcpu, u64 val); 1343 1340 1344 1341 #define kvm_vcpu_os_lock_enabled(vcpu) \ 1345 1342 (!!(__vcpu_sys_reg(vcpu, OSLSR_EL1) & OSLSR_EL1_OSLK)) 1343 + 1344 + #define kvm_debug_regs_in_use(vcpu) \ 1345 + ((vcpu)->arch.debug_owner != VCPU_DEBUG_FREE) 1346 + #define kvm_host_owns_debug_regs(vcpu) \ 1347 + ((vcpu)->arch.debug_owner == VCPU_DEBUG_HOST_OWNED) 1348 + #define kvm_guest_owns_debug_regs(vcpu) \ 1349 + ((vcpu)->arch.debug_owner == VCPU_DEBUG_GUEST_OWNED) 1346 1350 1347 1351 int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu, 1348 1352 struct kvm_device_attr *attr); ··· 1376 1366 { 1377 1367 return (!has_vhe() && attr->exclude_host); 1378 1368 } 1379 - 1380 - /* Flags for host debug state */ 1381 - void kvm_arch_vcpu_load_debug_state_flags(struct kvm_vcpu *vcpu); 1382 - void kvm_arch_vcpu_put_debug_state_flags(struct kvm_vcpu *vcpu); 1383 1369 1384 1370 #ifdef CONFIG_KVM 1385 1371 void kvm_set_pmu_events(u64 set, struct perf_event_attr *attr);
+1
arch/arm64/include/asm/kvm_nested.h
··· 64 64 } 65 65 66 66 extern bool forward_smc_trap(struct kvm_vcpu *vcpu); 67 + extern bool forward_debug_exception(struct kvm_vcpu *vcpu); 67 68 extern void kvm_init_nested(struct kvm *kvm); 68 69 extern int kvm_vcpu_init_nested(struct kvm_vcpu *vcpu); 69 70 extern void kvm_init_nested_s2_mmu(struct kvm_s2_mmu *mmu);
+3 -11
arch/arm64/kvm/arm.c
··· 476 476 477 477 kvm_pmu_vcpu_init(vcpu); 478 478 479 - kvm_arm_reset_debug_ptr(vcpu); 480 - 481 479 kvm_arm_pvtime_vcpu_init(&vcpu->arch); 482 480 483 481 vcpu->arch.hw_mmu = &vcpu->kvm->arch.mmu; ··· 596 598 597 599 kvm_vgic_load(vcpu); 598 600 kvm_timer_vcpu_load(vcpu); 601 + kvm_vcpu_load_debug(vcpu); 599 602 if (has_vhe()) 600 603 kvm_vcpu_load_vhe(vcpu); 601 604 kvm_arch_vcpu_load_fp(vcpu); ··· 616 617 617 618 vcpu_set_pauth_traps(vcpu); 618 619 619 - kvm_arch_vcpu_load_debug_state_flags(vcpu); 620 - 621 620 if (!cpumask_test_cpu(cpu, vcpu->kvm->arch.supported_cpus)) 622 621 vcpu_set_on_unsupported_cpu(vcpu); 623 622 } 624 623 625 624 void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) 626 625 { 627 - kvm_arch_vcpu_put_debug_state_flags(vcpu); 626 + kvm_vcpu_put_debug(vcpu); 628 627 kvm_arch_vcpu_put_fp(vcpu); 629 628 if (has_vhe()) 630 629 kvm_vcpu_put_vhe(vcpu); ··· 804 807 return 0; 805 808 806 809 kvm_init_mpidr_data(kvm); 807 - 808 - kvm_arm_vcpu_init_debug(vcpu); 809 810 810 811 if (likely(irqchip_in_kernel(kvm))) { 811 812 /* ··· 1182 1187 continue; 1183 1188 } 1184 1189 1185 - kvm_arm_setup_debug(vcpu); 1186 1190 kvm_arch_vcpu_ctxflush_fp(vcpu); 1187 1191 1188 1192 /************************************************************** ··· 1197 1203 /* 1198 1204 * Back from guest 1199 1205 *************************************************************/ 1200 - 1201 - kvm_arm_clear_debug(vcpu); 1202 1206 1203 1207 /* 1204 1208 * We must sync the PMU state before the vgic state so ··· 2101 2109 static void cpu_hyp_init_context(void) 2102 2110 { 2103 2111 kvm_init_host_cpu_context(host_data_ptr(host_ctxt)); 2112 + kvm_init_host_debug_data(); 2104 2113 2105 2114 if (!is_kernel_in_hyp_mode()) 2106 2115 cpu_init_hyp_mode(); ··· 2110 2117 static void cpu_hyp_init_features(void) 2111 2118 { 2112 2119 cpu_set_hyp_vector(); 2113 - kvm_arm_init_debug(); 2114 2120 2115 2121 if (is_kernel_in_hyp_mode()) 2116 2122 kvm_timer_init_vhe();
+152 -276
arch/arm64/kvm/debug.c
··· 3 3 * Debug and Guest Debug support 4 4 * 5 5 * Copyright (C) 2015 - Linaro Ltd 6 - * Author: Alex Bennée <alex.bennee@linaro.org> 6 + * Authors: Alex Bennée <alex.bennee@linaro.org> 7 + * Oliver Upton <oliver.upton@linux.dev> 7 8 */ 8 9 9 10 #include <linux/kvm_host.h> ··· 14 13 #include <asm/kvm_asm.h> 15 14 #include <asm/kvm_arm.h> 16 15 #include <asm/kvm_emulate.h> 17 - 18 - #include "trace.h" 19 - 20 - /* These are the bits of MDSCR_EL1 we may manipulate */ 21 - #define MDSCR_EL1_DEBUG_MASK (DBG_MDSCR_SS | \ 22 - DBG_MDSCR_KDE | \ 23 - DBG_MDSCR_MDE) 24 - 25 - static DEFINE_PER_CPU(u64, mdcr_el2); 26 - 27 - /* 28 - * save/restore_guest_debug_regs 29 - * 30 - * For some debug operations we need to tweak some guest registers. As 31 - * a result we need to save the state of those registers before we 32 - * make those modifications. 33 - * 34 - * Guest access to MDSCR_EL1 is trapped by the hypervisor and handled 35 - * after we have restored the preserved value to the main context. 36 - * 37 - * When single-step is enabled by userspace, we tweak PSTATE.SS on every 38 - * guest entry. Preserve PSTATE.SS so we can restore the original value 39 - * for the vcpu after the single-step is disabled. 40 - */ 41 - static void save_guest_debug_regs(struct kvm_vcpu *vcpu) 42 - { 43 - u64 val = vcpu_read_sys_reg(vcpu, MDSCR_EL1); 44 - 45 - vcpu->arch.guest_debug_preserved.mdscr_el1 = val; 46 - 47 - trace_kvm_arm_set_dreg32("Saved MDSCR_EL1", 48 - vcpu->arch.guest_debug_preserved.mdscr_el1); 49 - 50 - vcpu->arch.guest_debug_preserved.pstate_ss = 51 - (*vcpu_cpsr(vcpu) & DBG_SPSR_SS); 52 - } 53 - 54 - static void restore_guest_debug_regs(struct kvm_vcpu *vcpu) 55 - { 56 - u64 val = vcpu->arch.guest_debug_preserved.mdscr_el1; 57 - 58 - vcpu_write_sys_reg(vcpu, val, MDSCR_EL1); 59 - 60 - trace_kvm_arm_set_dreg32("Restored MDSCR_EL1", 61 - vcpu_read_sys_reg(vcpu, MDSCR_EL1)); 62 - 63 - if (vcpu->arch.guest_debug_preserved.pstate_ss) 64 - *vcpu_cpsr(vcpu) |= DBG_SPSR_SS; 65 - else 66 - *vcpu_cpsr(vcpu) &= ~DBG_SPSR_SS; 67 - } 68 - 69 - /** 70 - * kvm_arm_init_debug - grab what we need for debug 71 - * 72 - * Currently the sole task of this function is to retrieve the initial 73 - * value of mdcr_el2 so we can preserve MDCR_EL2.HPMN which has 74 - * presumably been set-up by some knowledgeable bootcode. 75 - * 76 - * It is called once per-cpu during CPU hyp initialisation. 77 - */ 78 - 79 - void kvm_arm_init_debug(void) 80 - { 81 - __this_cpu_write(mdcr_el2, kvm_call_hyp_ret(__kvm_get_mdcr_el2)); 82 - } 83 16 84 17 /** 85 18 * kvm_arm_setup_mdcr_el2 - configure vcpu mdcr_el2 value ··· 30 95 */ 31 96 static void kvm_arm_setup_mdcr_el2(struct kvm_vcpu *vcpu) 32 97 { 98 + preempt_disable(); 99 + 33 100 /* 34 101 * This also clears MDCR_EL2_E2PB_MASK and MDCR_EL2_E2TB_MASK 35 102 * to disable guest access to the profiling and trace buffers 36 103 */ 37 - vcpu->arch.mdcr_el2 = __this_cpu_read(mdcr_el2) & MDCR_EL2_HPMN_MASK; 104 + vcpu->arch.mdcr_el2 = FIELD_PREP(MDCR_EL2_HPMN, 105 + *host_data_ptr(nr_event_counters)); 38 106 vcpu->arch.mdcr_el2 |= (MDCR_EL2_TPM | 39 107 MDCR_EL2_TPMS | 40 108 MDCR_EL2_TTRF | ··· 51 113 vcpu->arch.mdcr_el2 |= MDCR_EL2_TDE; 52 114 53 115 /* 54 - * Trap debug register access when one of the following is true: 55 - * - Userspace is using the hardware to debug the guest 56 - * (KVM_GUESTDBG_USE_HW is set). 57 - * - The guest is not using debug (DEBUG_DIRTY clear). 58 - * - The guest has enabled the OS Lock (debug exceptions are blocked). 116 + * Trap debug registers if the guest doesn't have ownership of them. 59 117 */ 60 - if ((vcpu->guest_debug & KVM_GUESTDBG_USE_HW) || 61 - !vcpu_get_flag(vcpu, DEBUG_DIRTY) || 62 - kvm_vcpu_os_lock_enabled(vcpu)) 118 + if (!kvm_guest_owns_debug_regs(vcpu)) 63 119 vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA; 64 120 65 - trace_kvm_arm_set_dreg32("MDCR_EL2", vcpu->arch.mdcr_el2); 66 - } 121 + /* Write MDCR_EL2 directly if we're already at EL2 */ 122 + if (has_vhe()) 123 + write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2); 67 124 68 - /** 69 - * kvm_arm_vcpu_init_debug - setup vcpu debug traps 70 - * 71 - * @vcpu: the vcpu pointer 72 - * 73 - * Set vcpu initial mdcr_el2 value. 74 - */ 75 - void kvm_arm_vcpu_init_debug(struct kvm_vcpu *vcpu) 76 - { 77 - preempt_disable(); 78 - kvm_arm_setup_mdcr_el2(vcpu); 79 125 preempt_enable(); 80 126 } 81 127 82 - /** 83 - * kvm_arm_reset_debug_ptr - reset the debug ptr to point to the vcpu state 84 - * @vcpu: the vcpu pointer 85 - */ 86 - 87 - void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) 128 + void kvm_init_host_debug_data(void) 88 129 { 89 - vcpu->arch.debug_ptr = &vcpu->arch.vcpu_debug_state; 90 - } 130 + u64 dfr0 = read_sysreg(id_aa64dfr0_el1); 91 131 92 - /** 93 - * kvm_arm_setup_debug - set up debug related stuff 94 - * 95 - * @vcpu: the vcpu pointer 96 - * 97 - * This is called before each entry into the hypervisor to setup any 98 - * debug related registers. 99 - * 100 - * Additionally, KVM only traps guest accesses to the debug registers if 101 - * the guest is not actively using them (see the DEBUG_DIRTY 102 - * flag on vcpu->arch.iflags). Since the guest must not interfere 103 - * with the hardware state when debugging the guest, we must ensure that 104 - * trapping is enabled whenever we are debugging the guest using the 105 - * debug registers. 106 - */ 132 + if (cpuid_feature_extract_signed_field(dfr0, ID_AA64DFR0_EL1_PMUVer_SHIFT) > 0) 133 + *host_data_ptr(nr_event_counters) = FIELD_GET(ARMV8_PMU_PMCR_N, 134 + read_sysreg(pmcr_el0)); 107 135 108 - void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) 109 - { 110 - unsigned long mdscr, orig_mdcr_el2 = vcpu->arch.mdcr_el2; 136 + *host_data_ptr(debug_brps) = SYS_FIELD_GET(ID_AA64DFR0_EL1, BRPs, dfr0); 137 + *host_data_ptr(debug_wrps) = SYS_FIELD_GET(ID_AA64DFR0_EL1, WRPs, dfr0); 111 138 112 - trace_kvm_arm_setup_debug(vcpu, vcpu->guest_debug); 113 - 114 - kvm_arm_setup_mdcr_el2(vcpu); 115 - 116 - /* Check if we need to use the debug registers. */ 117 - if (vcpu->guest_debug || kvm_vcpu_os_lock_enabled(vcpu)) { 118 - /* Save guest debug state */ 119 - save_guest_debug_regs(vcpu); 120 - 121 - /* 122 - * Single Step (ARM ARM D2.12.3 The software step state 123 - * machine) 124 - * 125 - * If we are doing Single Step we need to manipulate 126 - * the guest's MDSCR_EL1.SS and PSTATE.SS. Once the 127 - * step has occurred the hypervisor will trap the 128 - * debug exception and we return to userspace. 129 - * 130 - * If the guest attempts to single step its userspace 131 - * we would have to deal with a trapped exception 132 - * while in the guest kernel. Because this would be 133 - * hard to unwind we suppress the guest's ability to 134 - * do so by masking MDSCR_EL.SS. 135 - * 136 - * This confuses guest debuggers which use 137 - * single-step behind the scenes but everything 138 - * returns to normal once the host is no longer 139 - * debugging the system. 140 - */ 141 - if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) { 142 - /* 143 - * If the software step state at the last guest exit 144 - * was Active-pending, we don't set DBG_SPSR_SS so 145 - * that the state is maintained (to not run another 146 - * single-step until the pending Software Step 147 - * exception is taken). 148 - */ 149 - if (!vcpu_get_flag(vcpu, DBG_SS_ACTIVE_PENDING)) 150 - *vcpu_cpsr(vcpu) |= DBG_SPSR_SS; 151 - else 152 - *vcpu_cpsr(vcpu) &= ~DBG_SPSR_SS; 153 - 154 - mdscr = vcpu_read_sys_reg(vcpu, MDSCR_EL1); 155 - mdscr |= DBG_MDSCR_SS; 156 - vcpu_write_sys_reg(vcpu, mdscr, MDSCR_EL1); 157 - } else { 158 - mdscr = vcpu_read_sys_reg(vcpu, MDSCR_EL1); 159 - mdscr &= ~DBG_MDSCR_SS; 160 - vcpu_write_sys_reg(vcpu, mdscr, MDSCR_EL1); 161 - } 162 - 163 - trace_kvm_arm_set_dreg32("SPSR_EL2", *vcpu_cpsr(vcpu)); 164 - 165 - /* 166 - * HW Breakpoints and watchpoints 167 - * 168 - * We simply switch the debug_ptr to point to our new 169 - * external_debug_state which has been populated by the 170 - * debug ioctl. The existing DEBUG_DIRTY mechanism ensures 171 - * the registers are updated on the world switch. 172 - */ 173 - if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW) { 174 - /* Enable breakpoints/watchpoints */ 175 - mdscr = vcpu_read_sys_reg(vcpu, MDSCR_EL1); 176 - mdscr |= DBG_MDSCR_MDE; 177 - vcpu_write_sys_reg(vcpu, mdscr, MDSCR_EL1); 178 - 179 - vcpu->arch.debug_ptr = &vcpu->arch.external_debug_state; 180 - vcpu_set_flag(vcpu, DEBUG_DIRTY); 181 - 182 - trace_kvm_arm_set_regset("BKPTS", get_num_brps(), 183 - &vcpu->arch.debug_ptr->dbg_bcr[0], 184 - &vcpu->arch.debug_ptr->dbg_bvr[0]); 185 - 186 - trace_kvm_arm_set_regset("WAPTS", get_num_wrps(), 187 - &vcpu->arch.debug_ptr->dbg_wcr[0], 188 - &vcpu->arch.debug_ptr->dbg_wvr[0]); 189 - 190 - /* 191 - * The OS Lock blocks debug exceptions in all ELs when it is 192 - * enabled. If the guest has enabled the OS Lock, constrain its 193 - * effects to the guest. Emulate the behavior by clearing 194 - * MDSCR_EL1.MDE. In so doing, we ensure that host debug 195 - * exceptions are unaffected by guest configuration of the OS 196 - * Lock. 197 - */ 198 - } else if (kvm_vcpu_os_lock_enabled(vcpu)) { 199 - mdscr = vcpu_read_sys_reg(vcpu, MDSCR_EL1); 200 - mdscr &= ~DBG_MDSCR_MDE; 201 - vcpu_write_sys_reg(vcpu, mdscr, MDSCR_EL1); 202 - } 203 - } 204 - 205 - BUG_ON(!vcpu->guest_debug && 206 - vcpu->arch.debug_ptr != &vcpu->arch.vcpu_debug_state); 207 - 208 - /* If KDE or MDE are set, perform a full save/restore cycle. */ 209 - if (vcpu_read_sys_reg(vcpu, MDSCR_EL1) & (DBG_MDSCR_KDE | DBG_MDSCR_MDE)) 210 - vcpu_set_flag(vcpu, DEBUG_DIRTY); 211 - 212 - /* Write mdcr_el2 changes since vcpu_load on VHE systems */ 213 - if (has_vhe() && orig_mdcr_el2 != vcpu->arch.mdcr_el2) 214 - write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2); 215 - 216 - trace_kvm_arm_set_dreg32("MDSCR_EL1", vcpu_read_sys_reg(vcpu, MDSCR_EL1)); 217 - } 218 - 219 - void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) 220 - { 221 - trace_kvm_arm_clear_debug(vcpu->guest_debug); 222 - 223 - /* 224 - * Restore the guest's debug registers if we were using them. 225 - */ 226 - if (vcpu->guest_debug || kvm_vcpu_os_lock_enabled(vcpu)) { 227 - if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) { 228 - if (!(*vcpu_cpsr(vcpu) & DBG_SPSR_SS)) 229 - /* 230 - * Mark the vcpu as ACTIVE_PENDING 231 - * until Software Step exception is taken. 232 - */ 233 - vcpu_set_flag(vcpu, DBG_SS_ACTIVE_PENDING); 234 - } 235 - 236 - restore_guest_debug_regs(vcpu); 237 - 238 - /* 239 - * If we were using HW debug we need to restore the 240 - * debug_ptr to the guest debug state. 241 - */ 242 - if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW) { 243 - kvm_arm_reset_debug_ptr(vcpu); 244 - 245 - trace_kvm_arm_set_regset("BKPTS", get_num_brps(), 246 - &vcpu->arch.debug_ptr->dbg_bcr[0], 247 - &vcpu->arch.debug_ptr->dbg_bvr[0]); 248 - 249 - trace_kvm_arm_set_regset("WAPTS", get_num_wrps(), 250 - &vcpu->arch.debug_ptr->dbg_wcr[0], 251 - &vcpu->arch.debug_ptr->dbg_wvr[0]); 252 - } 253 - } 254 - } 255 - 256 - void kvm_arch_vcpu_load_debug_state_flags(struct kvm_vcpu *vcpu) 257 - { 258 - u64 dfr0; 259 - 260 - /* For VHE, there is nothing to do */ 261 139 if (has_vhe()) 262 140 return; 263 141 264 - dfr0 = read_sysreg(id_aa64dfr0_el1); 265 - /* 266 - * If SPE is present on this CPU and is available at current EL, 267 - * we may need to check if the host state needs to be saved. 268 - */ 269 142 if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_EL1_PMSVer_SHIFT) && 270 - !(read_sysreg_s(SYS_PMBIDR_EL1) & BIT(PMBIDR_EL1_P_SHIFT))) 271 - vcpu_set_flag(vcpu, DEBUG_STATE_SAVE_SPE); 143 + !(read_sysreg_s(SYS_PMBIDR_EL1) & PMBIDR_EL1_P)) 144 + host_data_set_flag(HAS_SPE); 272 145 273 - /* Check if we have TRBE implemented and available at the host */ 274 146 if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_EL1_TraceBuffer_SHIFT) && 275 147 !(read_sysreg_s(SYS_TRBIDR_EL1) & TRBIDR_EL1_P)) 276 - vcpu_set_flag(vcpu, DEBUG_STATE_SAVE_TRBE); 148 + host_data_set_flag(HAS_TRBE); 277 149 } 278 150 279 - void kvm_arch_vcpu_put_debug_state_flags(struct kvm_vcpu *vcpu) 151 + /* 152 + * Configures the 'external' MDSCR_EL1 value for the guest, i.e. when the host 153 + * has taken over MDSCR_EL1. 154 + * 155 + * - Userspace is single-stepping the guest, and MDSCR_EL1.SS is forced to 1. 156 + * 157 + * - Userspace is using the breakpoint/watchpoint registers to debug the 158 + * guest, and MDSCR_EL1.MDE is forced to 1. 159 + * 160 + * - The guest has enabled the OS Lock, and KVM is forcing MDSCR_EL1.MDE to 0, 161 + * masking all debug exceptions affected by the OS Lock. 162 + */ 163 + static void setup_external_mdscr(struct kvm_vcpu *vcpu) 280 164 { 281 - vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_SPE); 282 - vcpu_clear_flag(vcpu, DEBUG_STATE_SAVE_TRBE); 165 + /* 166 + * Use the guest's MDSCR_EL1 as a starting point, since there are 167 + * several other features controlled by MDSCR_EL1 that are not relevant 168 + * to the host. 169 + * 170 + * Clear the bits that KVM may use which also satisfies emulation of 171 + * the OS Lock as MDSCR_EL1.MDE is cleared. 172 + */ 173 + u64 mdscr = vcpu_read_sys_reg(vcpu, MDSCR_EL1) & ~(MDSCR_EL1_SS | 174 + MDSCR_EL1_MDE | 175 + MDSCR_EL1_KDE); 176 + 177 + if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) 178 + mdscr |= MDSCR_EL1_SS; 179 + 180 + if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW) 181 + mdscr |= MDSCR_EL1_MDE | MDSCR_EL1_KDE; 182 + 183 + vcpu->arch.external_mdscr_el1 = mdscr; 184 + } 185 + 186 + void kvm_vcpu_load_debug(struct kvm_vcpu *vcpu) 187 + { 188 + u64 mdscr; 189 + 190 + /* Must be called before kvm_vcpu_load_vhe() */ 191 + KVM_BUG_ON(vcpu_get_flag(vcpu, SYSREGS_ON_CPU), vcpu->kvm); 192 + 193 + /* 194 + * Determine which of the possible debug states we're in: 195 + * 196 + * - VCPU_DEBUG_HOST_OWNED: KVM has taken ownership of the guest's 197 + * breakpoint/watchpoint registers, or needs to use MDSCR_EL1 to do 198 + * software step or emulate the effects of the OS Lock being enabled. 199 + * 200 + * - VCPU_DEBUG_GUEST_OWNED: The guest has debug exceptions enabled, and 201 + * the breakpoint/watchpoint registers need to be loaded eagerly. 202 + * 203 + * - VCPU_DEBUG_FREE: Neither of the above apply, no breakpoint/watchpoint 204 + * context needs to be loaded on the CPU. 205 + */ 206 + if (vcpu->guest_debug || kvm_vcpu_os_lock_enabled(vcpu)) { 207 + vcpu->arch.debug_owner = VCPU_DEBUG_HOST_OWNED; 208 + setup_external_mdscr(vcpu); 209 + 210 + /* 211 + * Steal the guest's single-step state machine if userspace wants 212 + * single-step the guest. 213 + */ 214 + if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) { 215 + if (*vcpu_cpsr(vcpu) & DBG_SPSR_SS) 216 + vcpu_clear_flag(vcpu, GUEST_SS_ACTIVE_PENDING); 217 + else 218 + vcpu_set_flag(vcpu, GUEST_SS_ACTIVE_PENDING); 219 + 220 + if (!vcpu_get_flag(vcpu, HOST_SS_ACTIVE_PENDING)) 221 + *vcpu_cpsr(vcpu) |= DBG_SPSR_SS; 222 + else 223 + *vcpu_cpsr(vcpu) &= ~DBG_SPSR_SS; 224 + } 225 + } else { 226 + mdscr = vcpu_read_sys_reg(vcpu, MDSCR_EL1); 227 + 228 + if (mdscr & (MDSCR_EL1_KDE | MDSCR_EL1_MDE)) 229 + vcpu->arch.debug_owner = VCPU_DEBUG_GUEST_OWNED; 230 + else 231 + vcpu->arch.debug_owner = VCPU_DEBUG_FREE; 232 + } 233 + 234 + kvm_arm_setup_mdcr_el2(vcpu); 235 + } 236 + 237 + void kvm_vcpu_put_debug(struct kvm_vcpu *vcpu) 238 + { 239 + if (likely(!(vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP))) 240 + return; 241 + 242 + /* 243 + * Save the host's software step state and restore the guest's before 244 + * potentially returning to userspace. 245 + */ 246 + if (!(*vcpu_cpsr(vcpu) & DBG_SPSR_SS)) 247 + vcpu_set_flag(vcpu, HOST_SS_ACTIVE_PENDING); 248 + else 249 + vcpu_clear_flag(vcpu, HOST_SS_ACTIVE_PENDING); 250 + 251 + if (vcpu_get_flag(vcpu, GUEST_SS_ACTIVE_PENDING)) 252 + *vcpu_cpsr(vcpu) &= ~DBG_SPSR_SS; 253 + else 254 + *vcpu_cpsr(vcpu) |= DBG_SPSR_SS; 255 + } 256 + 257 + /* 258 + * Updates ownership of the debug registers after a trapped guest access to a 259 + * breakpoint/watchpoint register. Host ownership of the debug registers is of 260 + * strictly higher priority, and it is the responsibility of the VMM to emulate 261 + * guest debug exceptions in this configuration. 262 + */ 263 + void kvm_debug_set_guest_ownership(struct kvm_vcpu *vcpu) 264 + { 265 + if (kvm_host_owns_debug_regs(vcpu)) 266 + return; 267 + 268 + vcpu->arch.debug_owner = VCPU_DEBUG_GUEST_OWNED; 269 + kvm_arm_setup_mdcr_el2(vcpu); 270 + } 271 + 272 + void kvm_debug_handle_oslar(struct kvm_vcpu *vcpu, u64 val) 273 + { 274 + if (val & OSLAR_EL1_OSLK) 275 + __vcpu_sys_reg(vcpu, OSLSR_EL1) |= OSLSR_EL1_OSLK; 276 + else 277 + __vcpu_sys_reg(vcpu, OSLSR_EL1) &= ~OSLSR_EL1_OSLK; 278 + 279 + preempt_disable(); 280 + kvm_arch_vcpu_put(vcpu); 281 + kvm_arch_vcpu_load(vcpu, smp_processor_id()); 282 + preempt_enable(); 283 283 }
+19 -4
arch/arm64/kvm/emulate-nested.c
··· 2345 2345 return true; 2346 2346 } 2347 2347 2348 - static bool forward_traps(struct kvm_vcpu *vcpu, u64 control_bit) 2348 + static bool __forward_traps(struct kvm_vcpu *vcpu, unsigned int reg, u64 control_bit) 2349 2349 { 2350 2350 bool control_bit_set; 2351 2351 2352 2352 if (!vcpu_has_nv(vcpu)) 2353 2353 return false; 2354 2354 2355 - control_bit_set = __vcpu_sys_reg(vcpu, HCR_EL2) & control_bit; 2355 + control_bit_set = __vcpu_sys_reg(vcpu, reg) & control_bit; 2356 2356 if (!is_hyp_ctxt(vcpu) && control_bit_set) { 2357 2357 kvm_inject_nested_sync(vcpu, kvm_vcpu_get_esr(vcpu)); 2358 2358 return true; ··· 2360 2360 return false; 2361 2361 } 2362 2362 2363 + static bool forward_hcr_traps(struct kvm_vcpu *vcpu, u64 control_bit) 2364 + { 2365 + return __forward_traps(vcpu, HCR_EL2, control_bit); 2366 + } 2367 + 2363 2368 bool forward_smc_trap(struct kvm_vcpu *vcpu) 2364 2369 { 2365 - return forward_traps(vcpu, HCR_TSC); 2370 + return forward_hcr_traps(vcpu, HCR_TSC); 2371 + } 2372 + 2373 + static bool forward_mdcr_traps(struct kvm_vcpu *vcpu, u64 control_bit) 2374 + { 2375 + return __forward_traps(vcpu, MDCR_EL2, control_bit); 2376 + } 2377 + 2378 + bool forward_debug_exception(struct kvm_vcpu *vcpu) 2379 + { 2380 + return forward_mdcr_traps(vcpu, MDCR_EL2_TDE); 2366 2381 } 2367 2382 2368 2383 static u64 kvm_check_illegal_exception_return(struct kvm_vcpu *vcpu, u64 spsr) ··· 2421 2406 * Forward this trap to the virtual EL2 if the virtual 2422 2407 * HCR_EL2.NV bit is set and this is coming from !EL2. 2423 2408 */ 2424 - if (forward_traps(vcpu, HCR_NV)) 2409 + if (forward_hcr_traps(vcpu, HCR_NV)) 2425 2410 return; 2426 2411 2427 2412 spsr = vcpu_read_sys_reg(vcpu, SPSR_EL2);
+6 -6
arch/arm64/kvm/fpsimd.c
··· 65 65 *host_data_ptr(fpsimd_state) = kern_hyp_va(&current->thread.uw.fpsimd_state); 66 66 *host_data_ptr(fpmr_ptr) = kern_hyp_va(&current->thread.uw.fpmr); 67 67 68 - vcpu_clear_flag(vcpu, HOST_SVE_ENABLED); 68 + host_data_clear_flag(HOST_SVE_ENABLED); 69 69 if (read_sysreg(cpacr_el1) & CPACR_EL1_ZEN_EL0EN) 70 - vcpu_set_flag(vcpu, HOST_SVE_ENABLED); 70 + host_data_set_flag(HOST_SVE_ENABLED); 71 71 72 72 if (system_supports_sme()) { 73 - vcpu_clear_flag(vcpu, HOST_SME_ENABLED); 73 + host_data_clear_flag(HOST_SME_ENABLED); 74 74 if (read_sysreg(cpacr_el1) & CPACR_EL1_SMEN_EL0EN) 75 - vcpu_set_flag(vcpu, HOST_SME_ENABLED); 75 + host_data_set_flag(HOST_SME_ENABLED); 76 76 77 77 /* 78 78 * If PSTATE.SM is enabled then save any pending FP ··· 168 168 */ 169 169 if (has_vhe() && system_supports_sme()) { 170 170 /* Also restore EL0 state seen on entry */ 171 - if (vcpu_get_flag(vcpu, HOST_SME_ENABLED)) 171 + if (host_data_test_flag(HOST_SME_ENABLED)) 172 172 sysreg_clear_set(CPACR_EL1, 0, CPACR_ELx_SMEN); 173 173 else 174 174 sysreg_clear_set(CPACR_EL1, ··· 227 227 * for EL0. To avoid spurious traps, restore the trap state 228 228 * seen by kvm_arch_vcpu_load_fp(): 229 229 */ 230 - if (vcpu_get_flag(vcpu, HOST_SVE_ENABLED)) 230 + if (host_data_test_flag(HOST_SVE_ENABLED)) 231 231 sysreg_clear_set(CPACR_EL1, 0, CPACR_EL1_ZEN_EL0EN); 232 232 else 233 233 sysreg_clear_set(CPACR_EL1, CPACR_EL1_ZEN_EL0EN, 0);
+12 -19
arch/arm64/kvm/guest.c
··· 917 917 int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, 918 918 struct kvm_guest_debug *dbg) 919 919 { 920 - int ret = 0; 921 - 922 920 trace_kvm_set_guest_debug(vcpu, dbg->control); 923 921 924 - if (dbg->control & ~KVM_GUESTDBG_VALID_MASK) { 925 - ret = -EINVAL; 926 - goto out; 927 - } 922 + if (dbg->control & ~KVM_GUESTDBG_VALID_MASK) 923 + return -EINVAL; 928 924 929 - if (dbg->control & KVM_GUESTDBG_ENABLE) { 930 - vcpu->guest_debug = dbg->control; 931 - 932 - /* Hardware assisted Break and Watch points */ 933 - if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW) { 934 - vcpu->arch.external_debug_state = dbg->arch; 935 - } 936 - 937 - } else { 938 - /* If not enabled clear all flags */ 925 + if (!(dbg->control & KVM_GUESTDBG_ENABLE)) { 939 926 vcpu->guest_debug = 0; 940 - vcpu_clear_flag(vcpu, DBG_SS_ACTIVE_PENDING); 927 + vcpu_clear_flag(vcpu, HOST_SS_ACTIVE_PENDING); 928 + return 0; 941 929 } 942 930 943 - out: 944 - return ret; 931 + vcpu->guest_debug = dbg->control; 932 + 933 + /* Hardware assisted Break and Watch points */ 934 + if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW) 935 + vcpu->arch.external_debug_state = dbg->arch; 936 + 937 + return 0; 945 938 } 946 939 947 940 int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu,
+4 -1
arch/arm64/kvm/handle_exit.c
··· 183 183 struct kvm_run *run = vcpu->run; 184 184 u64 esr = kvm_vcpu_get_esr(vcpu); 185 185 186 + if (!vcpu->guest_debug && forward_debug_exception(vcpu)) 187 + return 1; 188 + 186 189 run->exit_reason = KVM_EXIT_DEBUG; 187 190 run->debug.arch.hsr = lower_32_bits(esr); 188 191 run->debug.arch.hsr_high = upper_32_bits(esr); ··· 196 193 run->debug.arch.far = vcpu->arch.fault.far_el2; 197 194 break; 198 195 case ESR_ELx_EC_SOFTSTP_LOW: 199 - vcpu_clear_flag(vcpu, DBG_SS_ACTIVE_PENDING); 196 + *vcpu_cpsr(vcpu) |= DBG_SPSR_SS; 200 197 break; 201 198 } 202 199
+23 -19
arch/arm64/kvm/hyp/include/hyp/debug-sr.h
··· 88 88 default: write_debug(ptr[0], reg, 0); \ 89 89 } 90 90 91 + static struct kvm_guest_debug_arch *__vcpu_debug_regs(struct kvm_vcpu *vcpu) 92 + { 93 + switch (vcpu->arch.debug_owner) { 94 + case VCPU_DEBUG_FREE: 95 + WARN_ON_ONCE(1); 96 + fallthrough; 97 + case VCPU_DEBUG_GUEST_OWNED: 98 + return &vcpu->arch.vcpu_debug_state; 99 + case VCPU_DEBUG_HOST_OWNED: 100 + return &vcpu->arch.external_debug_state; 101 + } 102 + 103 + return NULL; 104 + } 105 + 91 106 static void __debug_save_state(struct kvm_guest_debug_arch *dbg, 92 107 struct kvm_cpu_context *ctxt) 93 108 { 94 - u64 aa64dfr0; 95 - int brps, wrps; 96 - 97 - aa64dfr0 = read_sysreg(id_aa64dfr0_el1); 98 - brps = (aa64dfr0 >> 12) & 0xf; 99 - wrps = (aa64dfr0 >> 20) & 0xf; 109 + int brps = *host_data_ptr(debug_brps); 110 + int wrps = *host_data_ptr(debug_wrps); 100 111 101 112 save_debug(dbg->dbg_bcr, dbgbcr, brps); 102 113 save_debug(dbg->dbg_bvr, dbgbvr, brps); ··· 120 109 static void __debug_restore_state(struct kvm_guest_debug_arch *dbg, 121 110 struct kvm_cpu_context *ctxt) 122 111 { 123 - u64 aa64dfr0; 124 - int brps, wrps; 125 - 126 - aa64dfr0 = read_sysreg(id_aa64dfr0_el1); 127 - 128 - brps = (aa64dfr0 >> 12) & 0xf; 129 - wrps = (aa64dfr0 >> 20) & 0xf; 112 + int brps = *host_data_ptr(debug_brps); 113 + int wrps = *host_data_ptr(debug_wrps); 130 114 131 115 restore_debug(dbg->dbg_bcr, dbgbcr, brps); 132 116 restore_debug(dbg->dbg_bvr, dbgbvr, brps); ··· 138 132 struct kvm_guest_debug_arch *host_dbg; 139 133 struct kvm_guest_debug_arch *guest_dbg; 140 134 141 - if (!vcpu_get_flag(vcpu, DEBUG_DIRTY)) 135 + if (!kvm_debug_regs_in_use(vcpu)) 142 136 return; 143 137 144 138 host_ctxt = host_data_ptr(host_ctxt); 145 139 guest_ctxt = &vcpu->arch.ctxt; 146 140 host_dbg = host_data_ptr(host_debug_state.regs); 147 - guest_dbg = kern_hyp_va(vcpu->arch.debug_ptr); 141 + guest_dbg = __vcpu_debug_regs(vcpu); 148 142 149 143 __debug_save_state(host_dbg, host_ctxt); 150 144 __debug_restore_state(guest_dbg, guest_ctxt); ··· 157 151 struct kvm_guest_debug_arch *host_dbg; 158 152 struct kvm_guest_debug_arch *guest_dbg; 159 153 160 - if (!vcpu_get_flag(vcpu, DEBUG_DIRTY)) 154 + if (!kvm_debug_regs_in_use(vcpu)) 161 155 return; 162 156 163 157 host_ctxt = host_data_ptr(host_ctxt); 164 158 guest_ctxt = &vcpu->arch.ctxt; 165 159 host_dbg = host_data_ptr(host_debug_state.regs); 166 - guest_dbg = kern_hyp_va(vcpu->arch.debug_ptr); 160 + guest_dbg = __vcpu_debug_regs(vcpu); 167 161 168 162 __debug_save_state(guest_dbg, guest_ctxt); 169 163 __debug_restore_state(host_dbg, host_ctxt); 170 - 171 - vcpu_clear_flag(vcpu, DEBUG_DIRTY); 172 164 } 173 165 174 166 #endif /* __ARM64_KVM_HYP_DEBUG_SR_H__ */
+29 -14
arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
··· 18 18 19 19 static inline bool ctxt_has_s1poe(struct kvm_cpu_context *ctxt); 20 20 21 + static inline struct kvm_vcpu *ctxt_to_vcpu(struct kvm_cpu_context *ctxt) 22 + { 23 + struct kvm_vcpu *vcpu = ctxt->__hyp_running_vcpu; 24 + 25 + if (!vcpu) 26 + vcpu = container_of(ctxt, struct kvm_vcpu, arch.ctxt); 27 + 28 + return vcpu; 29 + } 30 + 31 + static inline bool ctxt_is_guest(struct kvm_cpu_context *ctxt) 32 + { 33 + return host_data_ptr(host_ctxt) != ctxt; 34 + } 35 + 36 + static inline u64 *ctxt_mdscr_el1(struct kvm_cpu_context *ctxt) 37 + { 38 + struct kvm_vcpu *vcpu = ctxt_to_vcpu(ctxt); 39 + 40 + if (ctxt_is_guest(ctxt) && kvm_host_owns_debug_regs(vcpu)) 41 + return &vcpu->arch.external_mdscr_el1; 42 + 43 + return &ctxt_sys_reg(ctxt, MDSCR_EL1); 44 + } 45 + 21 46 static inline void __sysreg_save_common_state(struct kvm_cpu_context *ctxt) 22 47 { 23 - ctxt_sys_reg(ctxt, MDSCR_EL1) = read_sysreg(mdscr_el1); 48 + *ctxt_mdscr_el1(ctxt) = read_sysreg(mdscr_el1); 24 49 25 50 // POR_EL0 can affect uaccess, so must be saved/restored early. 26 51 if (ctxt_has_s1poe(ctxt)) ··· 56 31 { 57 32 ctxt_sys_reg(ctxt, TPIDR_EL0) = read_sysreg(tpidr_el0); 58 33 ctxt_sys_reg(ctxt, TPIDRRO_EL0) = read_sysreg(tpidrro_el0); 59 - } 60 - 61 - static inline struct kvm_vcpu *ctxt_to_vcpu(struct kvm_cpu_context *ctxt) 62 - { 63 - struct kvm_vcpu *vcpu = ctxt->__hyp_running_vcpu; 64 - 65 - if (!vcpu) 66 - vcpu = container_of(ctxt, struct kvm_vcpu, arch.ctxt); 67 - 68 - return vcpu; 69 34 } 70 35 71 36 static inline bool ctxt_has_mte(struct kvm_cpu_context *ctxt) ··· 154 139 155 140 static inline void __sysreg_restore_common_state(struct kvm_cpu_context *ctxt) 156 141 { 157 - write_sysreg(ctxt_sys_reg(ctxt, MDSCR_EL1), mdscr_el1); 142 + write_sysreg(*ctxt_mdscr_el1(ctxt), mdscr_el1); 158 143 159 144 // POR_EL0 can affect uaccess, so must be saved/restored early. 160 145 if (ctxt_has_s1poe(ctxt)) ··· 298 283 __vcpu_sys_reg(vcpu, DACR32_EL2) = read_sysreg(dacr32_el2); 299 284 __vcpu_sys_reg(vcpu, IFSR32_EL2) = read_sysreg(ifsr32_el2); 300 285 301 - if (has_vhe() || vcpu_get_flag(vcpu, DEBUG_DIRTY)) 286 + if (has_vhe() || kvm_debug_regs_in_use(vcpu)) 302 287 __vcpu_sys_reg(vcpu, DBGVCR32_EL2) = read_sysreg(dbgvcr32_el2); 303 288 } 304 289 ··· 315 300 write_sysreg(__vcpu_sys_reg(vcpu, DACR32_EL2), dacr32_el2); 316 301 write_sysreg(__vcpu_sys_reg(vcpu, IFSR32_EL2), ifsr32_el2); 317 302 318 - if (has_vhe() || vcpu_get_flag(vcpu, DEBUG_DIRTY)) 303 + if (has_vhe() || kvm_debug_regs_in_use(vcpu)) 319 304 write_sysreg(__vcpu_sys_reg(vcpu, DBGVCR32_EL2), dbgvcr32_el2); 320 305 } 321 306
+4 -9
arch/arm64/kvm/hyp/nvhe/debug-sr.c
··· 82 82 void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu) 83 83 { 84 84 /* Disable and flush SPE data generation */ 85 - if (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_SPE)) 85 + if (host_data_test_flag(HAS_SPE)) 86 86 __debug_save_spe(host_data_ptr(host_debug_state.pmscr_el1)); 87 87 /* Disable and flush Self-Hosted Trace generation */ 88 - if (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_TRBE)) 88 + if (host_data_test_flag(HAS_TRBE)) 89 89 __debug_save_trace(host_data_ptr(host_debug_state.trfcr_el1)); 90 90 } 91 91 ··· 96 96 97 97 void __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu) 98 98 { 99 - if (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_SPE)) 99 + if (host_data_test_flag(HAS_SPE)) 100 100 __debug_restore_spe(*host_data_ptr(host_debug_state.pmscr_el1)); 101 - if (vcpu_get_flag(vcpu, DEBUG_STATE_SAVE_TRBE)) 101 + if (host_data_test_flag(HAS_TRBE)) 102 102 __debug_restore_trace(*host_data_ptr(host_debug_state.trfcr_el1)); 103 103 } 104 104 105 105 void __debug_switch_to_host(struct kvm_vcpu *vcpu) 106 106 { 107 107 __debug_switch_to_host_common(vcpu); 108 - } 109 - 110 - u64 __kvm_get_mdcr_el2(void) 111 - { 112 - return read_sysreg(mdcr_el2); 113 108 }
-8
arch/arm64/kvm/hyp/nvhe/hyp-main.c
··· 112 112 113 113 hyp_vcpu->vcpu.arch.iflags = host_vcpu->arch.iflags; 114 114 115 - hyp_vcpu->vcpu.arch.debug_ptr = kern_hyp_va(host_vcpu->arch.debug_ptr); 116 - 117 115 hyp_vcpu->vcpu.arch.vsesr_el2 = host_vcpu->arch.vsesr_el2; 118 116 119 117 hyp_vcpu->vcpu.arch.vgic_cpu.vgic_v3 = host_vcpu->arch.vgic_cpu.vgic_v3; ··· 262 264 __vgic_v3_init_lrs(); 263 265 } 264 266 265 - static void handle___kvm_get_mdcr_el2(struct kvm_cpu_context *host_ctxt) 266 - { 267 - cpu_reg(host_ctxt, 1) = __kvm_get_mdcr_el2(); 268 - } 269 - 270 267 static void handle___vgic_v3_save_vmcr_aprs(struct kvm_cpu_context *host_ctxt) 271 268 { 272 269 DECLARE_REG(struct vgic_v3_cpu_if *, cpu_if, host_ctxt, 1); ··· 377 384 378 385 static const hcall_t host_hcall[] = { 379 386 /* ___kvm_hyp_init */ 380 - HANDLE_FUNC(__kvm_get_mdcr_el2), 381 387 HANDLE_FUNC(__pkvm_init), 382 388 HANDLE_FUNC(__pkvm_create_private_mapping), 383 389 HANDLE_FUNC(__pkvm_cpu_set_vector),
-5
arch/arm64/kvm/hyp/vhe/debug-sr.c
··· 19 19 { 20 20 __debug_switch_to_host_common(vcpu); 21 21 } 22 - 23 - u64 __kvm_get_mdcr_el2(void) 24 - { 25 - return read_sysreg(mdcr_el2); 26 - }
+77 -186
arch/arm64/kvm/sys_regs.c
··· 570 570 struct sys_reg_params *p, 571 571 const struct sys_reg_desc *r) 572 572 { 573 - u64 oslsr; 574 - 575 573 if (!p->is_write) 576 574 return read_from_write_only(vcpu, p, r); 577 575 578 - /* Forward the OSLK bit to OSLSR */ 579 - oslsr = __vcpu_sys_reg(vcpu, OSLSR_EL1) & ~OSLSR_EL1_OSLK; 580 - if (p->regval & OSLAR_EL1_OSLK) 581 - oslsr |= OSLSR_EL1_OSLK; 582 - 583 - __vcpu_sys_reg(vcpu, OSLSR_EL1) = oslsr; 576 + kvm_debug_handle_oslar(vcpu, p->regval); 584 577 return true; 585 578 } 586 579 ··· 614 621 } 615 622 } 616 623 617 - /* 618 - * We want to avoid world-switching all the DBG registers all the 619 - * time: 620 - * 621 - * - If we've touched any debug register, it is likely that we're 622 - * going to touch more of them. It then makes sense to disable the 623 - * traps and start doing the save/restore dance 624 - * - If debug is active (DBG_MDSCR_KDE or DBG_MDSCR_MDE set), it is 625 - * then mandatory to save/restore the registers, as the guest 626 - * depends on them. 627 - * 628 - * For this, we use a DIRTY bit, indicating the guest has modified the 629 - * debug registers, used as follow: 630 - * 631 - * On guest entry: 632 - * - If the dirty bit is set (because we're coming back from trapping), 633 - * disable the traps, save host registers, restore guest registers. 634 - * - If debug is actively in use (DBG_MDSCR_KDE or DBG_MDSCR_MDE set), 635 - * set the dirty bit, disable the traps, save host registers, 636 - * restore guest registers. 637 - * - Otherwise, enable the traps 638 - * 639 - * On guest exit: 640 - * - If the dirty bit is set, save guest registers, restore host 641 - * registers and clear the dirty bit. This ensure that the host can 642 - * now use the debug registers. 643 - */ 644 624 static bool trap_debug_regs(struct kvm_vcpu *vcpu, 645 625 struct sys_reg_params *p, 646 626 const struct sys_reg_desc *r) 647 627 { 648 628 access_rw(vcpu, p, r); 649 - if (p->is_write) 650 - vcpu_set_flag(vcpu, DEBUG_DIRTY); 651 629 652 - trace_trap_reg(__func__, r->reg, p->is_write, p->regval); 653 - 630 + kvm_debug_set_guest_ownership(vcpu); 654 631 return true; 655 632 } 656 633 ··· 629 666 * 630 667 * A 32 bit write to a debug register leave top bits alone 631 668 * A 32 bit read from a debug register only returns the bottom bits 632 - * 633 - * All writes will set the DEBUG_DIRTY flag to ensure the hyp code 634 - * switches between host and guest values in future. 635 669 */ 636 670 static void reg_to_dbg(struct kvm_vcpu *vcpu, 637 671 struct sys_reg_params *p, ··· 643 683 val &= ~mask; 644 684 val |= (p->regval & (mask >> shift)) << shift; 645 685 *dbg_reg = val; 646 - 647 - vcpu_set_flag(vcpu, DEBUG_DIRTY); 648 686 } 649 687 650 688 static void dbg_to_reg(struct kvm_vcpu *vcpu, ··· 656 698 p->regval = (*dbg_reg & mask) >> shift; 657 699 } 658 700 659 - static bool trap_bvr(struct kvm_vcpu *vcpu, 660 - struct sys_reg_params *p, 661 - const struct sys_reg_desc *rd) 701 + static u64 *demux_wb_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd) 662 702 { 663 - u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->CRm]; 703 + struct kvm_guest_debug_arch *dbg = &vcpu->arch.vcpu_debug_state; 704 + 705 + switch (rd->Op2) { 706 + case 0b100: 707 + return &dbg->dbg_bvr[rd->CRm]; 708 + case 0b101: 709 + return &dbg->dbg_bcr[rd->CRm]; 710 + case 0b110: 711 + return &dbg->dbg_wvr[rd->CRm]; 712 + case 0b111: 713 + return &dbg->dbg_wcr[rd->CRm]; 714 + default: 715 + KVM_BUG_ON(1, vcpu->kvm); 716 + return NULL; 717 + } 718 + } 719 + 720 + static bool trap_dbg_wb_reg(struct kvm_vcpu *vcpu, struct sys_reg_params *p, 721 + const struct sys_reg_desc *rd) 722 + { 723 + u64 *reg = demux_wb_reg(vcpu, rd); 724 + 725 + if (!reg) 726 + return false; 664 727 665 728 if (p->is_write) 666 - reg_to_dbg(vcpu, p, rd, dbg_reg); 729 + reg_to_dbg(vcpu, p, rd, reg); 667 730 else 668 - dbg_to_reg(vcpu, p, rd, dbg_reg); 731 + dbg_to_reg(vcpu, p, rd, reg); 669 732 670 - trace_trap_reg(__func__, rd->CRm, p->is_write, *dbg_reg); 671 - 733 + kvm_debug_set_guest_ownership(vcpu); 672 734 return true; 673 735 } 674 736 675 - static int set_bvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, 676 - u64 val) 737 + static int set_dbg_wb_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, 738 + u64 val) 677 739 { 678 - vcpu->arch.vcpu_debug_state.dbg_bvr[rd->CRm] = val; 740 + u64 *reg = demux_wb_reg(vcpu, rd); 741 + 742 + if (!reg) 743 + return -EINVAL; 744 + 745 + *reg = val; 679 746 return 0; 680 747 } 681 748 682 - static int get_bvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, 683 - u64 *val) 749 + static int get_dbg_wb_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, 750 + u64 *val) 684 751 { 685 - *val = vcpu->arch.vcpu_debug_state.dbg_bvr[rd->CRm]; 752 + u64 *reg = demux_wb_reg(vcpu, rd); 753 + 754 + if (!reg) 755 + return -EINVAL; 756 + 757 + *val = *reg; 686 758 return 0; 687 759 } 688 760 689 - static u64 reset_bvr(struct kvm_vcpu *vcpu, 690 - const struct sys_reg_desc *rd) 761 + static u64 reset_dbg_wb_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd) 691 762 { 692 - vcpu->arch.vcpu_debug_state.dbg_bvr[rd->CRm] = rd->val; 693 - return rd->val; 694 - } 763 + u64 *reg = demux_wb_reg(vcpu, rd); 695 764 696 - static bool trap_bcr(struct kvm_vcpu *vcpu, 697 - struct sys_reg_params *p, 698 - const struct sys_reg_desc *rd) 699 - { 700 - u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->CRm]; 765 + /* 766 + * Bail early if we couldn't find storage for the register, the 767 + * KVM_BUG_ON() in demux_wb_reg() will prevent this VM from ever 768 + * being run. 769 + */ 770 + if (!reg) 771 + return 0; 701 772 702 - if (p->is_write) 703 - reg_to_dbg(vcpu, p, rd, dbg_reg); 704 - else 705 - dbg_to_reg(vcpu, p, rd, dbg_reg); 706 - 707 - trace_trap_reg(__func__, rd->CRm, p->is_write, *dbg_reg); 708 - 709 - return true; 710 - } 711 - 712 - static int set_bcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, 713 - u64 val) 714 - { 715 - vcpu->arch.vcpu_debug_state.dbg_bcr[rd->CRm] = val; 716 - return 0; 717 - } 718 - 719 - static int get_bcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, 720 - u64 *val) 721 - { 722 - *val = vcpu->arch.vcpu_debug_state.dbg_bcr[rd->CRm]; 723 - return 0; 724 - } 725 - 726 - static u64 reset_bcr(struct kvm_vcpu *vcpu, 727 - const struct sys_reg_desc *rd) 728 - { 729 - vcpu->arch.vcpu_debug_state.dbg_bcr[rd->CRm] = rd->val; 730 - return rd->val; 731 - } 732 - 733 - static bool trap_wvr(struct kvm_vcpu *vcpu, 734 - struct sys_reg_params *p, 735 - const struct sys_reg_desc *rd) 736 - { 737 - u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm]; 738 - 739 - if (p->is_write) 740 - reg_to_dbg(vcpu, p, rd, dbg_reg); 741 - else 742 - dbg_to_reg(vcpu, p, rd, dbg_reg); 743 - 744 - trace_trap_reg(__func__, rd->CRm, p->is_write, 745 - vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm]); 746 - 747 - return true; 748 - } 749 - 750 - static int set_wvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, 751 - u64 val) 752 - { 753 - vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm] = val; 754 - return 0; 755 - } 756 - 757 - static int get_wvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, 758 - u64 *val) 759 - { 760 - *val = vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm]; 761 - return 0; 762 - } 763 - 764 - static u64 reset_wvr(struct kvm_vcpu *vcpu, 765 - const struct sys_reg_desc *rd) 766 - { 767 - vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm] = rd->val; 768 - return rd->val; 769 - } 770 - 771 - static bool trap_wcr(struct kvm_vcpu *vcpu, 772 - struct sys_reg_params *p, 773 - const struct sys_reg_desc *rd) 774 - { 775 - u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->CRm]; 776 - 777 - if (p->is_write) 778 - reg_to_dbg(vcpu, p, rd, dbg_reg); 779 - else 780 - dbg_to_reg(vcpu, p, rd, dbg_reg); 781 - 782 - trace_trap_reg(__func__, rd->CRm, p->is_write, *dbg_reg); 783 - 784 - return true; 785 - } 786 - 787 - static int set_wcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, 788 - u64 val) 789 - { 790 - vcpu->arch.vcpu_debug_state.dbg_wcr[rd->CRm] = val; 791 - return 0; 792 - } 793 - 794 - static int get_wcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, 795 - u64 *val) 796 - { 797 - *val = vcpu->arch.vcpu_debug_state.dbg_wcr[rd->CRm]; 798 - return 0; 799 - } 800 - 801 - static u64 reset_wcr(struct kvm_vcpu *vcpu, 802 - const struct sys_reg_desc *rd) 803 - { 804 - vcpu->arch.vcpu_debug_state.dbg_wcr[rd->CRm] = rd->val; 773 + *reg = rd->val; 805 774 return rd->val; 806 775 } 807 776 ··· 1237 1352 /* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */ 1238 1353 #define DBG_BCR_BVR_WCR_WVR_EL1(n) \ 1239 1354 { SYS_DESC(SYS_DBGBVRn_EL1(n)), \ 1240 - trap_bvr, reset_bvr, 0, 0, get_bvr, set_bvr }, \ 1355 + trap_dbg_wb_reg, reset_dbg_wb_reg, 0, 0, \ 1356 + get_dbg_wb_reg, set_dbg_wb_reg }, \ 1241 1357 { SYS_DESC(SYS_DBGBCRn_EL1(n)), \ 1242 - trap_bcr, reset_bcr, 0, 0, get_bcr, set_bcr }, \ 1358 + trap_dbg_wb_reg, reset_dbg_wb_reg, 0, 0, \ 1359 + get_dbg_wb_reg, set_dbg_wb_reg }, \ 1243 1360 { SYS_DESC(SYS_DBGWVRn_EL1(n)), \ 1244 - trap_wvr, reset_wvr, 0, 0, get_wvr, set_wvr }, \ 1361 + trap_dbg_wb_reg, reset_dbg_wb_reg, 0, 0, \ 1362 + get_dbg_wb_reg, set_dbg_wb_reg }, \ 1245 1363 { SYS_DESC(SYS_DBGWCRn_EL1(n)), \ 1246 - trap_wcr, reset_wcr, 0, 0, get_wcr, set_wcr } 1364 + trap_dbg_wb_reg, reset_dbg_wb_reg, 0, 0, \ 1365 + get_dbg_wb_reg, set_dbg_wb_reg } 1247 1366 1248 1367 #define PMU_SYS_REG(name) \ 1249 1368 SYS_DESC(SYS_##name), .reset = reset_pmu_reg, \ ··· 3461 3572 * None of the other registers share their location, so treat them as 3462 3573 * if they were 64bit. 3463 3574 */ 3464 - #define DBG_BCR_BVR_WCR_WVR(n) \ 3465 - /* DBGBVRn */ \ 3466 - { AA32(LO), Op1( 0), CRn( 0), CRm((n)), Op2( 4), trap_bvr, NULL, n }, \ 3467 - /* DBGBCRn */ \ 3468 - { Op1( 0), CRn( 0), CRm((n)), Op2( 5), trap_bcr, NULL, n }, \ 3469 - /* DBGWVRn */ \ 3470 - { Op1( 0), CRn( 0), CRm((n)), Op2( 6), trap_wvr, NULL, n }, \ 3471 - /* DBGWCRn */ \ 3472 - { Op1( 0), CRn( 0), CRm((n)), Op2( 7), trap_wcr, NULL, n } 3575 + #define DBG_BCR_BVR_WCR_WVR(n) \ 3576 + /* DBGBVRn */ \ 3577 + { AA32(LO), Op1( 0), CRn( 0), CRm((n)), Op2( 4), \ 3578 + trap_dbg_wb_reg, NULL, n }, \ 3579 + /* DBGBCRn */ \ 3580 + { Op1( 0), CRn( 0), CRm((n)), Op2( 5), trap_dbg_wb_reg, NULL, n }, \ 3581 + /* DBGWVRn */ \ 3582 + { Op1( 0), CRn( 0), CRm((n)), Op2( 6), trap_dbg_wb_reg, NULL, n }, \ 3583 + /* DBGWCRn */ \ 3584 + { Op1( 0), CRn( 0), CRm((n)), Op2( 7), trap_dbg_wb_reg, NULL, n } 3473 3585 3474 - #define DBGBXVR(n) \ 3475 - { AA32(HI), Op1( 0), CRn( 1), CRm((n)), Op2( 1), trap_bvr, NULL, n } 3586 + #define DBGBXVR(n) \ 3587 + { AA32(HI), Op1( 0), CRn( 1), CRm((n)), Op2( 1), \ 3588 + trap_dbg_wb_reg, NULL, n } 3476 3589 3477 3590 /* 3478 3591 * Trapped cp14 registers. We generally ignore most of the external
-75
arch/arm64/kvm/trace_handle_exit.h
··· 46 46 __entry->vcpu_pc, __entry->r0, __entry->imm) 47 47 ); 48 48 49 - TRACE_EVENT(kvm_arm_setup_debug, 50 - TP_PROTO(struct kvm_vcpu *vcpu, __u32 guest_debug), 51 - TP_ARGS(vcpu, guest_debug), 52 - 53 - TP_STRUCT__entry( 54 - __field(struct kvm_vcpu *, vcpu) 55 - __field(__u32, guest_debug) 56 - ), 57 - 58 - TP_fast_assign( 59 - __entry->vcpu = vcpu; 60 - __entry->guest_debug = guest_debug; 61 - ), 62 - 63 - TP_printk("vcpu: %p, flags: 0x%08x", __entry->vcpu, __entry->guest_debug) 64 - ); 65 - 66 - TRACE_EVENT(kvm_arm_clear_debug, 67 - TP_PROTO(__u32 guest_debug), 68 - TP_ARGS(guest_debug), 69 - 70 - TP_STRUCT__entry( 71 - __field(__u32, guest_debug) 72 - ), 73 - 74 - TP_fast_assign( 75 - __entry->guest_debug = guest_debug; 76 - ), 77 - 78 - TP_printk("flags: 0x%08x", __entry->guest_debug) 79 - ); 80 - 81 49 /* 82 50 * The dreg32 name is a leftover from a distant past. This will really 83 51 * output a 64bit value... ··· 65 97 ), 66 98 67 99 TP_printk("%s: 0x%llx", __entry->name, __entry->value) 68 - ); 69 - 70 - TRACE_DEFINE_SIZEOF(__u64); 71 - 72 - TRACE_EVENT(kvm_arm_set_regset, 73 - TP_PROTO(const char *type, int len, __u64 *control, __u64 *value), 74 - TP_ARGS(type, len, control, value), 75 - TP_STRUCT__entry( 76 - __field(const char *, name) 77 - __field(int, len) 78 - __array(u64, ctrls, 16) 79 - __array(u64, values, 16) 80 - ), 81 - TP_fast_assign( 82 - __entry->name = type; 83 - __entry->len = len; 84 - memcpy(__entry->ctrls, control, len << 3); 85 - memcpy(__entry->values, value, len << 3); 86 - ), 87 - TP_printk("%d %s CTRL:%s VALUE:%s", __entry->len, __entry->name, 88 - __print_array(__entry->ctrls, __entry->len, sizeof(__u64)), 89 - __print_array(__entry->values, __entry->len, sizeof(__u64))) 90 - ); 91 - 92 - TRACE_EVENT(trap_reg, 93 - TP_PROTO(const char *fn, int reg, bool is_write, u64 write_value), 94 - TP_ARGS(fn, reg, is_write, write_value), 95 - 96 - TP_STRUCT__entry( 97 - __field(const char *, fn) 98 - __field(int, reg) 99 - __field(bool, is_write) 100 - __field(u64, write_value) 101 - ), 102 - 103 - TP_fast_assign( 104 - __entry->fn = fn; 105 - __entry->reg = reg; 106 - __entry->is_write = is_write; 107 - __entry->write_value = write_value; 108 - ), 109 - 110 - TP_printk("%s %s reg %d (0x%016llx)", __entry->fn, __entry->is_write?"write to":"read from", __entry->reg, __entry->write_value) 111 100 ); 112 101 113 102 TRACE_EVENT(kvm_handle_sys_reg,