* 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 | - SMCR_EL2.LEN must be initialised to the same value for all CPUs the | 340 | - SMCR_EL2.LEN must be initialised to the same value for all CPUs the |
| 341 | kernel will execute on. | 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 | For CPUs with the Scalable Matrix Extension FA64 feature (FEAT_SME_FA64) | 351 | For CPUs with the Scalable Matrix Extension FA64 feature (FEAT_SME_FA64) |
| 344 | 352 | ||
| 345 | - If EL3 is present: | 353 | - If EL3 is present: |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | |||
| 13 | #include <hyp/adjust_pc.h> | 13 | #include <hyp/adjust_pc.h> |
| 14 | #include <linux/kvm_host.h> | 14 | #include <linux/kvm_host.h> |
| 15 | #include <asm/kvm_emulate.h> | 15 | #include <asm/kvm_emulate.h> |
| 16 | #include <asm/kvm_mmu.h> | ||
| 16 | 17 | ||
| 17 | #if !defined (__KVM_NVHE_HYPERVISOR__) && !defined (__KVM_VHE_HYPERVISOR__) | 18 | #if !defined (__KVM_NVHE_HYPERVISOR__) && !defined (__KVM_VHE_HYPERVISOR__) |
| 18 | #error Hypervisor code only! | 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 | new |= (old & PSR_C_BIT); | 116 | new |= (old & PSR_C_BIT); |
| 116 | new |= (old & PSR_V_BIT); | 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 | new |= PSR_TCO_BIT; | 120 | new |= PSR_TCO_BIT; |
| 120 | 121 | ||
| 121 | new |= (old & PSR_DIT_BIT); | 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 | vcpu->arch.mdcr_el2_host = read_sysreg(mdcr_el2); | 88 | vcpu->arch.mdcr_el2_host = read_sysreg(mdcr_el2); |
| 89 | write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2); | 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 | static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu) | 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 | write_sysreg(0, hstr_el2); | 107 | write_sysreg(0, hstr_el2); |
| 97 | if (kvm_arm_support_pmu_v3()) | 108 | if (kvm_arm_support_pmu_v3()) |
| 98 | write_sysreg(0, pmuserenr_el0); | 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 | static inline void ___activate_traps(struct kvm_vcpu *vcpu) | 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 | if (!kvm_pte_valid(pte)) | 516 | if (!kvm_pte_valid(pte)) |
| 517 | return PKVM_NOPAGE; | 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 | static int __hyp_check_page_state_range(u64 addr, u64 size, | 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 | write_sysreg(val, cptr_el2); | 55 | write_sysreg(val, cptr_el2); |
| 56 | write_sysreg(__this_cpu_read(kvm_hyp_vector), vbar_el2); | 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 | if (cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT)) { | 58 | if (cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT)) { |
| 71 | struct kvm_cpu_context *ctxt = &vcpu->arch.ctxt; | 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 | write_sysreg(this_cpu_ptr(&kvm_init_params)->hcr_el2, hcr_el2); | 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 | cptr = CPTR_EL2_DEFAULT; | 101 | cptr = CPTR_EL2_DEFAULT; |
| 128 | if (vcpu_has_sve(vcpu) && (vcpu->arch.fp_state == FP_STATE_GUEST_OWNED)) | 102 | if (vcpu_has_sve(vcpu) && (vcpu->arch.fp_state == FP_STATE_GUEST_OWNED)) |
| 129 | cptr |= CPTR_EL2_TZ; | 103 | cptr |= CPTR_EL2_TZ; |
| @@ -63,10 +63,6 @@ static void __activate_traps(struct kvm_vcpu *vcpu) · 62 unmodified lines | |||
| 63 | __activate_traps_fpsimd32(vcpu); | 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 | write_sysreg(val, cpacr_el1); | 66 | write_sysreg(val, cpacr_el1); |
| 71 | 67 | ||
| 72 | write_sysreg(__this_cpu_read(kvm_hyp_vector), vbar_el1); | 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 | asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_SPECULATIVE_AT)); | 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 | write_sysreg(CPACR_EL1_DEFAULT, cpacr_el1); | 87 | write_sysreg(CPACR_EL1_DEFAULT, cpacr_el1); |
| 96 | 88 | ||
| 97 | if (!arm64_kernel_unmapped_at_el0()) | 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 | case KVM_CAP_DIRTY_LOG_RING: | 4586 | case KVM_CAP_DIRTY_LOG_RING: |
| 4587 | case KVM_CAP_DIRTY_LOG_RING_ACQ_REL: | 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 | return kvm_vm_ioctl_enable_dirty_log_ring(kvm, cap->args[0]); | 4591 | return kvm_vm_ioctl_enable_dirty_log_ring(kvm, cap->args[0]); |
| 4589 | default: | 4592 | default: |
| 4590 | return kvm_vm_ioctl_enable_cap(kvm, cap); | 4593 | return kvm_vm_ioctl_enable_cap(kvm, cap); |