[PATCH v1 0/4] KVM: arm64: Fix unguarded GICv5 CPU interface accesses
Sascha Bischoff
Sascha.Bischoff at arm.com
Fri Aug 7 03:07:16 PDT 2026
Hi Fuad,
On Thu, 2026-08-06 at 11:02 +0100, Fuad Tabba wrote:
> Hi folks,
>
> This series stops KVM reaching GICv5 CPU interface registers on
> hardware
> that does not implement them, in three places with no guard.
Thank you for fixing my mess!
I'd naively assumed that if we don't allow a vGICv5 to be initialised,
then we'd not be going down these paths. Obviously, that doesn't quite
fit with the pKVM model.
> Under pKVM the first two are reachable from an untrusted host. EL2
> copies vgic_model out of the host's struct kvm without validating it,
> and the nVHE world switch dispatches on that field with no cpucap
> guard, so a host writing KVM_DEV_TYPE_ARM_VGIC_V5 steers EL2 into
> ICC_ICSR_EL1 and the ICH_PPI_* registers. Separately,
> __vgic_v5_save_apr
> and __vgic_v5_restore_vmcr_apr sit in the hypercall band the
> de-privileged host may still call, and pKVM never registers a GICv5
> vgic, so neither has a valid caller in protected mode. Without
> FEAT_GCIE those registers are UNDEFINED at EL2, so either path panics
> the hypervisor. Both need a compromised host kernel rather than host
> userspace, so this is hardening and not a guest-reachable hole.
>
> I had said these paths were unreachable under pKVM because
> vgic_v5_probe() skips GICv5 registration in protected mode [1]. That
> was
> wrong. The skip is host-side only, and does not constrain what a
> malicious host can call.
Yeah, this is precisely what I'd gotten wrong in my mental model. I'll
try and bear this in mind going forward.
>
> The third one is not pKVM. can_access_vgic_from_kernel() excludes
> only
> the GICv3 system register interface, so on a native GICv5 system
> without FEAT_GCIE_LEGACY the kernel reaches EL2-only registers from
> EL1
> under nVHE, and the world switch does the same work at EL2 anyway.
>
> The last patch drops the VGICv3 reference from two nVHE world switch
> comments that cover GICv5 too. No functional change.
>
> Tested on QEMU. I also checked the first one with a local host patch
> that hands EL2 a GICv5 model: it panics at __vgic_v5_restore_state
> before the series and boots cleanly after.
>
> Based on Linux 7.2-rc6 (075b74841bd00). It also applies cleanly to
> kvmarm/next and kvmarm/fixes.
>
> I really should stop looking at the GIC, but I won't be able to
> anytime
> soon I'm afraid...
You and me both!
These three look good to me:
KVM: arm64: Reject the GICv5 CPU interface hypercalls under pKVM
KVM: arm64: vgic: Do not access the GICv5 CPU interface from EL1
KVM: arm64: Fix stale VGICv3 comments in the nVHE world switch
Hence, for those three:
Reviewed-by: Sascha Bischoff <sascha.bischoff at arm.com>
I've left a question on your first patch.
Thanks,
Sascha
>
> Cheers,
> /fuad
>
> [1]
> https://lore.kernel.org/all/CA%2BEHjTyGULmVCgyoya3bXG4gRj0OYFE1gnJLhNE6kvCrZFtXyQ@mail.gmail.com/
>
> Fuad Tabba (4):
> KVM: arm64: Validate the host-provided vgic model in pKVM
> KVM: arm64: Reject the GICv5 CPU interface hypercalls under pKVM
> KVM: arm64: vgic: Do not access the GICv5 CPU interface from EL1
> KVM: arm64: Fix stale VGICv3 comments in the nVHE world switch
>
> arch/arm64/kvm/hyp/nvhe/hyp-main.c | 6 ++++++
> arch/arm64/kvm/hyp/nvhe/pkvm.c | 16 ++++++++++++++--
> arch/arm64/kvm/hyp/nvhe/switch.c | 4 ++--
> arch/arm64/kvm/vgic/vgic.c | 12 ++++++++----
> 4 files changed, 30 insertions(+), 8 deletions(-)
>
>
> base-commit: 075b74841bd0065a3bda3440873c747938e69b68
More information about the linux-arm-kernel
mailing list