Re: [PATCH 4/4] KVM: arm64: Add SMC hook for SME dvmsync erratum
From: Will Deacon <will@kernel.org>
Date: 2026-03-05 14:33:10
Also in:
kvmarm
On Mon, Mar 02, 2026 at 04:57:57PM +0000, Catalin Marinas wrote:
quoted hunk ↗ jump to hunk
From: James Morse <james.morse@arm.com> C1-Pro cores with SME have an erratum where TLBI+DSB does not complete all outstanding SME accesses. Instead a DSB needs to be executed on the affecteed CPUs. The implication is pages cannot be unmapped from the host stage2 then provided to the guest. Host SME accesses may occur after this point. This erratum breaks pKVM's guarantees, and the workaround is hard to implement as EL2 and EL1 share a security state meaning EL1 can mask IPI sent by EL2, leading to interrupt blackouts. Instead, do this in EL3. This has the advantage of a separate security state, meaning lower EL cannot mask the IPI. It is also simpler for EL3 to know about CPUs that are off or in PSCI's CPU_SUSPEND. Add the needed hook. Signed-off-by: James Morse <james.morse@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> Cc: Marc Zyngier <maz@kernel.org> Cc: Oliver Upton <oupton@kernel.org> Cc: Will Deacon <will@kernel.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Lorenzo Pieralisi <lpieralisi@kernel.org> Cc: Sudeep Holla <sudeep.holla@kernel.org> --- arch/arm64/kvm/hyp/nvhe/mem_protect.c | 17 +++++++++++++++++ include/linux/arm-smccc.h | 5 +++++ 2 files changed, 22 insertions(+)diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c index 38f66a56a766..ab7f9273fddf 100644 --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c@@ -5,6 +5,8 @@ */ #include <linux/kvm_host.h> +#include <linux/arm-smccc.h> + #include <asm/kvm_emulate.h> #include <asm/kvm_hyp.h> #include <asm/kvm_mmu.h>@@ -28,6 +30,15 @@ static struct hyp_pool host_s2_pool; static DEFINE_PER_CPU(struct pkvm_hyp_vm *, __current_vm); #define current_vm (*this_cpu_ptr(&__current_vm)) +static void pkvm_sme_dvmsync_fw_call(void) +{ + if (cpus_have_final_cap(ARM64_WORKAROUND_SME_DVMSYNC)) { + struct arm_smccc_res res; + + arm_smccc_1_1_smc(ARM_SMCCC_CPU_SME_DVMSYNC_WORKAROUND, &res); + } +} + static void guest_lock_component(struct pkvm_hyp_vm *vm) { hyp_spin_lock(&vm->lock);@@ -553,6 +564,12 @@ int host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_id) if (ret) return ret; + /* + * After stage2 maintenance has happened, but before the page owner has + * changed. + */ + pkvm_sme_dvmsync_fw_call();
Please note that this will conflict with my patch series adding support for protected memory with pkvm. I _think_ the right answer is to move this call into host_stage2_set_owner_metadata_locked(). Will