aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/kvm/hyp/exception.c
Commit message (Collapse)AuthorAgeFilesLines
* KVM: arm64: Simplify sysreg access on exception deliveryMarc Zyngier2025-08-281-12/+4
| | | | | | | | | | | | | Distinguishing between NV and VHE is slightly pointless, and only serves as an extra complication, or a way to introduce bugs, such as the way SPSR_EL1 gets written without checking for the state being resident. Get rid if this silly distinction, and fix the bug in one go. Signed-off-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Oliver Upton <[email protected]>
* KVM: arm64: Check for SYSREGS_ON_CPU before accessing the 32bit stateMarc Zyngier2025-08-281-2/+2
| | | | | | | | | | Just like c6e35dff58d3 ("KVM: arm64: Check for SYSREGS_ON_CPU before accessing the CPU state") fixed the 64bit state access, add a check for the 32bit state actually being on the CPU before writing it. Signed-off-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Oliver Upton <[email protected]>
* KVM: arm64: Check for SYSREGS_ON_CPU before accessing the CPU stateMarc Zyngier2025-07-211-2/+4
| | | | | | | | | | | | | | | | | | | | | | | Mark Brown reports that since we commit to making exceptions visible without the vcpu being loaded, the external abort selftest fails. Upon investigation, it turns out that the code that makes registers affected by an exception visible to the guest is completely broken on VHE, as we don't check whether the system registers are loaded on the CPU at this point. We managed to get away with this so far, but that's obviously as bad as it gets, Add the required checksm and document the absolute need to check for the SYSREGS_ON_CPU flag before calling into any of the __vcpu_write_sys_reg_to_cpu()__vcpu_read_sys_reg_from_cpu() helpers. Reported-by: Mark Brown <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/r/[email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Oliver Upton <[email protected]>
* KVM: arm64: Route SEAs to the SError vector when EASE is setOliver Upton2025-07-081-1/+5
| | | | | | | | | | | | | One of the finest additions of FEAT_DoubleFault2 is the ability for software to request *synchronous* external aborts be taken to the SError vector, which of coure are *asynchronous* in nature. Opinions be damned, implement the architecture and send SEAs to the SError vector if EASE is set for the target context. Reviewed-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Oliver Upton <[email protected]>
* KVM: arm64: nv: Honor SError exception routing / maskingOliver Upton2025-07-081-1/+5
| | | | | | | | | | | | | | | | | | | | | | | | To date KVM has used HCR_EL2.VSE to track the state of a pending SError for the guest. With this bit set, hardware respects the EL1 exception routing / masking rules and injects the vSError when appropriate. This isn't correct for NV guests as hardware is oblivious to vEL2's intentions for SErrors. Better yet, with FEAT_NV2 the guest can change the routing behind our back as HCR_EL2 is redirected to memory. Cope with this mess by: - Using a flag (instead of HCR_EL2.VSE) to track the pending SError state when SErrors are unconditionally masked for the current context - Resampling the routing / masking of a pending SError on every guest entry/exit - Emulating exception entry when SError routing implies a translation regime change Reviewed-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Oliver Upton <[email protected]>
* KVM: arm64: Add assignment-specific sysreg accessorMarc Zyngier2025-06-051-2/+2
| | | | | | | | | | | | | | | | | | | | Assigning a value to a system register doesn't do what it is supposed to be doing if that register is one that has RESx bits. The main problem is that we use __vcpu_sys_reg(), which can be used both as a lvalue and rvalue. When used as a lvalue, the bit masking occurs *before* the new value is assigned, meaning that we (1) do pointless work on the old cvalue, and (2) potentially assign an invalid value as we fail to apply the masks to it. Fix this by providing a new __vcpu_assign_sys_reg() that does what it says on the tin, and sanitises the *new* value instead of the old one. This comes with a significant amount of churn. Reviewed-by: Miguel Luis <[email protected]> Reviewed-by: Oliver Upton <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Marc Zyngier <[email protected]>
* KVM: arm64: nv: Support virtual EL2 exceptionsJintack Lim2023-02-111-12/+36
| | | | | | | | | | | | | | | | | Support injecting exceptions and performing exception returns to and from virtual EL2. This must be done entirely in software except when taking an exception from vEL0 to vEL2 when the virtual HCR_EL2.{E2H,TGE} == {1,1} (a VHE guest hypervisor). [maz: switch to common exception injection framework, illegal exeption return handling] Reviewed-by: Ganapatrao Kulkarni <[email protected]> Signed-off-by: Jintack Lim <[email protected]> Signed-off-by: Christoffer Dall <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Oliver Upton <[email protected]>
* KVM: arm64: Fix bad dereference on MTE-enabled systemsRyan Roberts2022-10-271-1/+2
| | | | | | | | | | | | | | | | | | | enter_exception64() performs an MTE check, which involves dereferencing vcpu->kvm. While vcpu has already been fixed up to be a HYP VA pointer, kvm is still a pointer in the kernel VA space. This only affects nVHE configurations with MTE enabled, as in other cases, the pointer is either valid (VHE) or not dereferenced (!MTE). Fix this by first converting kvm to a HYP VA pointer. Fixes: ea7fc1bb1cd1 ("KVM: arm64: Introduce MTE VM feature") Signed-off-by: Ryan Roberts <[email protected]> Reviewed-by: Steven Price <[email protected]> [maz: commit message tidy-up] Signed-off-by: Marc Zyngier <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/r/[email protected]
* KVM: arm64: Move vcpu PC/Exception flags to the input flag setMarc Zyngier2022-06-101-12/+11
| | | | | | | | | | | | | | | | | | | | | The PC update flags (which also deal with exception injection) is one of the most complicated use of the flag we have. Make it more fool prof by: - moving it over to the new accessors and assign it to the input flag set - turn the combination of generic ELx flags with another flag indicating the target EL itself into an explicit set of flags for each EL and vector combination - add a new accessor to pend the exception This is otherwise a pretty straightformward conversion. Reviewed-by: Fuad Tabba <[email protected]> Reviewed-by: Reiji Watanabe <[email protected]> Signed-off-by: Marc Zyngier <[email protected]>
* KVM: arm64: Use shadow SPSR_EL1 when injecting exceptions on !VHEMarc Zyngier2022-01-241-1/+4
| | | | | | | | | | | | | | | | | | | | | Injecting an exception into a guest with non-VHE is risky business. Instead of writing in the shadow register for the switch code to restore it, we override the CPU register instead. Which gets overriden a few instructions later by said restore code. The result is that although the guest correctly gets the exception, it will return to the original context in some random state, depending on what was there the first place... Boo. Fix the issue by writing to the shadow register. The original code is absolutely fine on VHE, as the state is already loaded, and writing to the shadow register in that case would actually be a bug. Fixes: bb666c472ca2 ("KVM: arm64: Inject AArch64 exceptions from HYP") Cc: [email protected] Signed-off-by: Marc Zyngier <[email protected]> Reviewed-by: Fuad Tabba <[email protected]> Link: https://lore.kernel.org/r/[email protected]
* KVM: arm64: Introduce MTE VM featureSteven Price2021-06-221-1/+2
| | | | | | | | | | | | | | | | | Add a new VM feature 'KVM_ARM_CAP_MTE' which enables memory tagging for a VM. This will expose the feature to the guest and automatically tag memory pages touched by the VM as PG_mte_tagged (and clear the tag storage) to ensure that the guest cannot see stale tags, and so that the tags are correctly saved/restored across swap. Actually exposing the new capability to user space happens in a later patch. Reviewed-by: Catalin Marinas <[email protected]> Signed-off-by: Steven Price <[email protected]> [maz: move VM_SHARED sampling into the critical section] Signed-off-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected]
* KVM: arm64: Commit pending PC adjustemnts before returning to userspaceMarc Zyngier2021-05-151-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | KVM currently updates PC (and the corresponding exception state) using a two phase approach: first by setting a set of flags, then by converting these flags into a state update when the vcpu is about to enter the guest. However, this creates a disconnect with userspace if the vcpu thread returns there with any exception/PC flag set. In this case, the exposed context is wrong, as userspace doesn't have access to these flags (they aren't architectural). It also means that these flags are preserved across a reset, which isn't expected. To solve this problem, force an explicit synchronisation of the exception state on vcpu exit to userspace. As an optimisation for nVHE systems, only perform this when there is something pending. Reported-by: Zenghui Yu <[email protected]> Reviewed-by: Alexandru Elisei <[email protected]> Reviewed-by: Zenghui Yu <[email protected]> Tested-by: Zenghui Yu <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Cc: [email protected] # 5.11
* KVM: arm64: Move __adjust_pc out of lineMarc Zyngier2021-05-151-1/+17
| | | | | | | | | | | | | | In order to make it easy to call __adjust_pc() from the EL1 code (in the case of nVHE), rename it to __kvm_adjust_pc() and move it out of line. No expected functional change. Reviewed-by: Alexandru Elisei <[email protected]> Reviewed-by: Zenghui Yu <[email protected]> Tested-by: Zenghui Yu <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Cc: [email protected] # 5.11
* KVM: arm64: Inject AArch32 exceptions from HYPMarc Zyngier2020-11-101-11/+189
| | | | | | | | | | | | | | | | Similarly to what has been done for AArch64, move the AArch32 exception injection to HYP. In order to not use the regmap selection code at EL2, simplify the code populating the target mode's LR register by useing the compatibility aliases for LR_abt and LR_und. We also introduce new accessors for SPSR_abt and SPSR_und, and move VBAR/SCTLR to using the AArch64 accessors (the use of the AArch32 names was an ARMv7 leftover). Acked-by: Mark Rutland <[email protected]> Signed-off-by: Marc Zyngier <[email protected]>
* KVM: arm64: Inject AArch64 exceptions from HYPMarc Zyngier2020-11-101-0/+136
| | | | | | | | | | Move the AArch64 exception injection code from EL1 to HYP, leaving only the ESR_EL1 updates to EL1. In order to come with the differences between VHE and nVHE, two set of system register accessors are provided. SPSR, ELR, PC and PSTATE are now completely handled in the hypervisor. Signed-off-by: Marc Zyngier <[email protected]>
* KVM: arm64: Add basic hooks for injecting exceptions from EL2Marc Zyngier2020-11-101-0/+17
Add the basic infrastructure to describe injection of exceptions into a guest. So far, nothing uses this code path. Signed-off-by: Marc Zyngier <[email protected]>