* Fix the pKVM stage-1 walker erronously using the stage-2 accessor * Correctly convert vcpu->kvm to a hyp pointer when generating an exception in a nVHE+MTE configuration * Check that KVM_CAP_DIRTY_LOG_* are valid before enabling them * Fix SMPRI_EL1/TPIDR2_EL0 trapping on VHE * Document the boot requirements for FGT when entering the kernel at EL1
Unified · Split
| @@ -340,6 +340,14 @@ Before jumping into the kernel, the following conditions must be met: · 339 unmodified lines | ||
| 340 | 340 | - SMCR_EL2.LEN must be initialised to the same value for all CPUs the |
| 341 | 341 | kernel will execute on. |
| 342 | 342 | |
| 343 | + - HWFGRTR_EL2.nTPIDR2_EL0 (bit 55) must be initialised to 0b01. | |
| 344 | + | |
| 345 | + - HWFGWTR_EL2.nTPIDR2_EL0 (bit 55) must be initialised to 0b01. | |
| 346 | + | |
| 347 | + - HWFGRTR_EL2.nSMPRI_EL1 (bit 54) must be initialised to 0b01. | |
| 348 | + | |
| 349 | + - HWFGWTR_EL2.nSMPRI_EL1 (bit 54) must be initialised to 0b01. | |
| 350 | + | |
| 343 | 351 | For CPUs with the Scalable Matrix Extension FA64 feature (FEAT_SME_FA64) |
| 344 | 352 | |
| 345 | 353 | - If EL3 is present: |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <hyp/adjust_pc.h> |
| 14 | 14 | #include <linux/kvm_host.h> |
| 15 | 15 | #include <asm/kvm_emulate.h> |
| 16 | +#include <asm/kvm_mmu.h> | |
| 16 | 17 | |
| 17 | 18 | #if !defined (__KVM_NVHE_HYPERVISOR__) && !defined (__KVM_VHE_HYPERVISOR__) |
| 18 | 19 | #error Hypervisor code only! |
| @@ -115,7 +116,7 @@ static void enter_exception64(struct kvm_vcpu *vcpu, unsigned long target_mode, · 96 unmodified lines | ||
| 115 | 116 | new |= (old & PSR_C_BIT); |
| 116 | 117 | new |= (old & PSR_V_BIT); |
| 117 | 118 | |
| 118 | − if (kvm_has_mte(vcpu->kvm)) | |
| 119 | + if (kvm_has_mte(kern_hyp_va(vcpu->kvm))) | |
| 119 | 120 | new |= PSR_TCO_BIT; |
| 120 | 121 | |
| 121 | 122 | new |= (old & PSR_DIT_BIT); |
| @@ -87,6 +87,17 @@ static inline void __activate_traps_common(struct kvm_vcpu *vcpu) · 86 unmodified lines | ||
| 87 | 87 | |
| 88 | 88 | vcpu->arch.mdcr_el2_host = read_sysreg(mdcr_el2); |
| 89 | 89 | write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2); |
| 90 | + | |
| 91 | + if (cpus_have_final_cap(ARM64_SME)) { | |
| 92 | + sysreg_clear_set_s(SYS_HFGRTR_EL2, | |
| 93 | + HFGxTR_EL2_nSMPRI_EL1_MASK | | |
| 94 | + HFGxTR_EL2_nTPIDR2_EL0_MASK, | |
| 95 | + 0); | |
| 96 | + sysreg_clear_set_s(SYS_HFGWTR_EL2, | |
| 97 | + HFGxTR_EL2_nSMPRI_EL1_MASK | | |
| 98 | + HFGxTR_EL2_nTPIDR2_EL0_MASK, | |
| 99 | + 0); | |
| 100 | + } | |
| 90 | 101 | } |
| 91 | 102 | |
| 92 | 103 | static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu) |
| @@ -96,6 +107,15 @@ static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu) · 3 unmodified lines | ||
| 96 | 107 | write_sysreg(0, hstr_el2); |
| 97 | 108 | if (kvm_arm_support_pmu_v3()) |
| 98 | 109 | write_sysreg(0, pmuserenr_el0); |
| 110 | + | |
| 111 | + if (cpus_have_final_cap(ARM64_SME)) { | |
| 112 | + sysreg_clear_set_s(SYS_HFGRTR_EL2, 0, | |
| 113 | + HFGxTR_EL2_nSMPRI_EL1_MASK | | |
| 114 | + HFGxTR_EL2_nTPIDR2_EL0_MASK); | |
| 115 | + sysreg_clear_set_s(SYS_HFGWTR_EL2, 0, | |
| 116 | + HFGxTR_EL2_nSMPRI_EL1_MASK | | |
| 117 | + HFGxTR_EL2_nTPIDR2_EL0_MASK); | |
| 118 | + } | |
| 99 | 119 | } |
| 100 | 120 | |
| 101 | 121 | static inline void ___activate_traps(struct kvm_vcpu *vcpu) |
| @@ -516,7 +516,7 @@ static enum pkvm_page_state hyp_get_page_state(kvm_pte_t pte) · 515 unmodified lines | ||
| 516 | 516 | if (!kvm_pte_valid(pte)) |
| 517 | 517 | return PKVM_NOPAGE; |
| 518 | 518 | |
| 519 | − return pkvm_getstate(kvm_pgtable_stage2_pte_prot(pte)); | |
| 519 | + return pkvm_getstate(kvm_pgtable_hyp_pte_prot(pte)); | |
| 520 | 520 | } |
| 521 | 521 | |
| 522 | 522 | static int __hyp_check_page_state_range(u64 addr, u64 size, |
| @@ -55,18 +55,6 @@ static void __activate_traps(struct kvm_vcpu *vcpu) · 54 unmodified lines | ||
| 55 | 55 | write_sysreg(val, cptr_el2); |
| 56 | 56 | write_sysreg(__this_cpu_read(kvm_hyp_vector), vbar_el2); |
| 57 | 57 | |
| 58 | − if (cpus_have_final_cap(ARM64_SME)) { | |
| 59 | − val = read_sysreg_s(SYS_HFGRTR_EL2); | |
| 60 | − val &= ~(HFGxTR_EL2_nTPIDR2_EL0_MASK | | |
| 61 | − HFGxTR_EL2_nSMPRI_EL1_MASK); | |
| 62 | − write_sysreg_s(val, SYS_HFGRTR_EL2); | |
| 63 | − | |
| 64 | − val = read_sysreg_s(SYS_HFGWTR_EL2); | |
| 65 | − val &= ~(HFGxTR_EL2_nTPIDR2_EL0_MASK | | |
| 66 | − HFGxTR_EL2_nSMPRI_EL1_MASK); | |
| 67 | − write_sysreg_s(val, SYS_HFGWTR_EL2); | |
| 68 | − } | |
| 69 | − | |
| 70 | 58 | if (cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT)) { |
| 71 | 59 | struct kvm_cpu_context *ctxt = &vcpu->arch.ctxt; |
| 72 | 60 | |
| @@ -110,20 +98,6 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu) · 37 unmodified lines | ||
| 110 | 98 | |
| 111 | 99 | write_sysreg(this_cpu_ptr(&kvm_init_params)->hcr_el2, hcr_el2); |
| 112 | 100 | |
| 113 | − if (cpus_have_final_cap(ARM64_SME)) { | |
| 114 | − u64 val; | |
| 115 | − | |
| 116 | − val = read_sysreg_s(SYS_HFGRTR_EL2); | |
| 117 | − val |= HFGxTR_EL2_nTPIDR2_EL0_MASK | | |
| 118 | − HFGxTR_EL2_nSMPRI_EL1_MASK; | |
| 119 | − write_sysreg_s(val, SYS_HFGRTR_EL2); | |
| 120 | − | |
| 121 | − val = read_sysreg_s(SYS_HFGWTR_EL2); | |
| 122 | − val |= HFGxTR_EL2_nTPIDR2_EL0_MASK | | |
| 123 | − HFGxTR_EL2_nSMPRI_EL1_MASK; | |
| 124 | − write_sysreg_s(val, SYS_HFGWTR_EL2); | |
| 125 | − } | |
| 126 | − | |
| 127 | 101 | cptr = CPTR_EL2_DEFAULT; |
| 128 | 102 | if (vcpu_has_sve(vcpu) && (vcpu->arch.fp_state == FP_STATE_GUEST_OWNED)) |
| 129 | 103 | cptr |= CPTR_EL2_TZ; |
| @@ -63,10 +63,6 @@ static void __activate_traps(struct kvm_vcpu *vcpu) · 62 unmodified lines | ||
| 63 | 63 | __activate_traps_fpsimd32(vcpu); |
| 64 | 64 | } |
| 65 | 65 | |
| 66 | − if (cpus_have_final_cap(ARM64_SME)) | |
| 67 | − write_sysreg(read_sysreg(sctlr_el2) & ~SCTLR_ELx_ENTP2, | |
| 68 | − sctlr_el2); | |
| 69 | − | |
| 70 | 66 | write_sysreg(val, cpacr_el1); |
| 71 | 67 | |
| 72 | 68 | write_sysreg(__this_cpu_read(kvm_hyp_vector), vbar_el1); |
| @@ -88,10 +84,6 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu) · 15 unmodified lines | ||
| 88 | 84 | */ |
| 89 | 85 | asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_SPECULATIVE_AT)); |
| 90 | 86 | |
| 91 | − if (cpus_have_final_cap(ARM64_SME)) | |
| 92 | − write_sysreg(read_sysreg(sctlr_el2) | SCTLR_ELx_ENTP2, | |
| 93 | − sctlr_el2); | |
| 94 | − | |
| 95 | 87 | write_sysreg(CPACR_EL1_DEFAULT, cpacr_el1); |
| 96 | 88 | |
| 97 | 89 | if (!arm64_kernel_unmapped_at_el0()) |
| @@ -4585,6 +4585,9 @@ static int kvm_vm_ioctl_enable_cap_generic(struct kvm *kvm, · 4584 unmodified lines | ||
| 4585 | 4585 | } |
| 4586 | 4586 | case KVM_CAP_DIRTY_LOG_RING: |
| 4587 | 4587 | case KVM_CAP_DIRTY_LOG_RING_ACQ_REL: |
| 4588 | + if (!kvm_vm_ioctl_check_extension_generic(kvm, cap->cap)) | |
| 4589 | + return -EINVAL; | |
| 4590 | + | |
| 4588 | 4591 | return kvm_vm_ioctl_enable_dirty_log_ring(kvm, cap->args[0]); |
| 4589 | 4592 | default: |
| 4590 | 4593 | return kvm_vm_ioctl_enable_cap(kvm, cap); |