From: Alexandru Elisei <hidden> Date: 2025-12-16 10:31:27
v2 can be found at [1].
Similar to [2], when trying to run an unprotected VM on FVP with S1PIE enabled
and kvm-arm.mode=protected, writes to PIRE0_EL1 made by the guest in
__cpu_setup() are trapped by KVM and the BUG_ON(!r->access) is hit. That's
because HFGWTR_EL2.nPIRE0_EL1 is an inverse polarity trap and the FGT values for
the unprotected pKVM VCPU weren't being propagated from kvm_arch_vcpu_load().
Couldn't figure out how to run a protected pKVM VM, so that's untested.
Changelog v2->v3:
* Gathered Reviewed-by tags, thanks!
* In patch #2, KVM now calls bad_trap() instead of KVM_BUG(). Also changed patch
subject to match.
[1] https://lore.kernel.org/kvmarm/20251215114409.212512-1-alexandru.elisei@arm.com/
[2] https://lore.kernel.org/all/20251112102853.47759-1-alexandru.elisei@arm.com/
Alexandru Elisei (4):
KVM: arm64: Copy FGT traps to unprotected pKVM VCPU on VCPU load
KVM: arm64: Inject UNDEF for a register trap without accessor
KVM: arm64: Remove extra argument for __pvkm_host_{share,unshare}_hyp()
KVM: arm64: Remove unused parameter in synchronize_vcpu_pstate()
arch/arm64/kvm/hyp/include/hyp/switch.h | 2 +-
arch/arm64/kvm/hyp/nvhe/hyp-main.c | 3 +++
arch/arm64/kvm/hyp/nvhe/pkvm.c | 1 -
arch/arm64/kvm/hyp/nvhe/switch.c | 2 +-
arch/arm64/kvm/hyp/vhe/switch.c | 2 +-
arch/arm64/kvm/mmu.c | 4 ++--
arch/arm64/kvm/sys_regs.c | 5 ++++-
7 files changed, 12 insertions(+), 7 deletions(-)
base-commit: 8f0b4cce4481fb22653697cced8d0d04027cb1e8
--
2.52.0
From: Alexandru Elisei <hidden> Date: 2025-12-16 10:31:27
Commit fb10ddf35c1c ("KVM: arm64: Compute per-vCPU FGTs at vcpu_load()")
introduced per-VCPU FGT traps. For an unprotected pKVM VCPU, the untrusted
host FGT configuration is copied in pkvm_vcpu_init_traps(), which is called
from __pkvm_init_vcpu(). __pkvm_init_vcpu() is called once per VCPU (when
the VCPU is first run) which means that the uninitialized, zero, values for
the FGT registers end up being used for the entire lifetime of the VCPU.
This causes both unwanted traps (for the inverse polarity trap bits) and
the guest being allowed to access registers it shouldn't.
Fix it by copying the FGT traps for unprotected pKVM VCPUs when the
untrusted host loads the VCPU.
Fixes: fb10ddf35c1c ("KVM: arm64: Compute per-vCPU FGTs at vcpu_load()")
Acked-by: Will Deacon <will@kernel.org>
Tested-by: Fuad Tabba <redacted>
Reviewed-by: Fuad Tabba <redacted>
Signed-off-by: Alexandru Elisei <redacted>
---
arch/arm64/kvm/hyp/nvhe/hyp-main.c | 3 +++
arch/arm64/kvm/hyp/nvhe/pkvm.c | 1 -
2 files changed, 3 insertions(+), 1 deletion(-)
From: Alexandru Elisei <hidden> Date: 2025-12-16 10:31:30
__pvkm_host_share_hyp() and __pkvm_host_unshare_hyp() both have one
parameter, the pfn, not two. Even though correctness isn't impacted because
the SMCCC handlers pass the first argument and ignore the second one, let's
call the functions with the proper number of arguments.
Reviewed-by: Fuad Tabba <redacted>
Signed-off-by: Alexandru Elisei <redacted>
---
arch/arm64/kvm/mmu.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
From: Alexandru Elisei <hidden> Date: 2025-12-16 10:31:31
Configuring a register trap without specifying an accessor function is
abviously a bug. Instead of calling die() when that happens, let's be a
bit more helpful and print the register encoding. Also inject an
undefined instruction exception in the guest, similar to other unhandled
register accesses.
Signed-off-by: Alexandru Elisei <redacted>
---
arch/arm64/kvm/sys_regs.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
Hi Alexandru,
On Tue, 16 Dec 2025 at 10:31, Alexandru Elisei [off-list ref] wrote:
v2 can be found at [1].
Similar to [2], when trying to run an unprotected VM on FVP with S1PIE enabled
and kvm-arm.mode=protected, writes to PIRE0_EL1 made by the guest in
__cpu_setup() are trapped by KVM and the BUG_ON(!r->access) is hit. That's
because HFGWTR_EL2.nPIRE0_EL1 is an inverse polarity trap and the FGT values for
the unprotected pKVM VCPU weren't being propagated from kvm_arch_vcpu_load().
Couldn't figure out how to run a protected pKVM VM, so that's untested.
Hopefully this will change soon [1]!
I applied this to the pKVM/Android stack, and tested it with protected
VMs as well as non-protected VMs.
For the series:
Tested-by: Fuad Tabba <redacted>
Reviewed-by: Fuad Tabba <redacted>
Cheers,
/fuad
[1] https://lore.kernel.org/all/aTMPn0dBbSVUwwJ1@willie-the-truck/
Changelog v2->v3:
* Gathered Reviewed-by tags, thanks!
* In patch #2, KVM now calls bad_trap() instead of KVM_BUG(). Also changed patch
subject to match.
[1] https://lore.kernel.org/kvmarm/20251215114409.212512-1-alexandru.elisei@arm.com/
[2] https://lore.kernel.org/all/20251112102853.47759-1-alexandru.elisei@arm.com/
Alexandru Elisei (4):
KVM: arm64: Copy FGT traps to unprotected pKVM VCPU on VCPU load
KVM: arm64: Inject UNDEF for a register trap without accessor
KVM: arm64: Remove extra argument for __pvkm_host_{share,unshare}_hyp()
KVM: arm64: Remove unused parameter in synchronize_vcpu_pstate()
arch/arm64/kvm/hyp/include/hyp/switch.h | 2 +-
arch/arm64/kvm/hyp/nvhe/hyp-main.c | 3 +++
arch/arm64/kvm/hyp/nvhe/pkvm.c | 1 -
arch/arm64/kvm/hyp/nvhe/switch.c | 2 +-
arch/arm64/kvm/hyp/vhe/switch.c | 2 +-
arch/arm64/kvm/mmu.c | 4 ++--
arch/arm64/kvm/sys_regs.c | 5 ++++-
7 files changed, 12 insertions(+), 7 deletions(-)
base-commit: 8f0b4cce4481fb22653697cced8d0d04027cb1e8
--
2.52.0
From: Marc Zyngier <maz@kernel.org> Date: 2025-12-17 09:18:33
On Tue, 16 Dec 2025 10:30:49 +0000,
Alexandru Elisei [off-list ref] wrote:
v2 can be found at [1].
Similar to [2], when trying to run an unprotected VM on FVP with S1PIE enabled
and kvm-arm.mode=protected, writes to PIRE0_EL1 made by the guest in
__cpu_setup() are trapped by KVM and the BUG_ON(!r->access) is hit. That's
because HFGWTR_EL2.nPIRE0_EL1 is an inverse polarity trap and the FGT values for
the unprotected pKVM VCPU weren't being propagated from kvm_arch_vcpu_load().
Couldn't figure out how to run a protected pKVM VM, so that's untested.
Reviewed-by: Marc Zyngier <maz@kernel.org>
M.
--
Without deviation from the norm, progress is not possible.
From: Oliver Upton <oupton@kernel.org> Date: 2026-01-10 10:23:27
On Tue, 16 Dec 2025 10:30:49 +0000, Alexandru Elisei wrote:
v2 can be found at [1].
Similar to [2], when trying to run an unprotected VM on FVP with S1PIE enabled
and kvm-arm.mode=protected, writes to PIRE0_EL1 made by the guest in
__cpu_setup() are trapped by KVM and the BUG_ON(!r->access) is hit. That's
because HFGWTR_EL2.nPIRE0_EL1 is an inverse polarity trap and the FGT values for
the unprotected pKVM VCPU weren't being propagated from kvm_arch_vcpu_load().
[...]