Linux KVM/arm64 development list
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Fuad Tabba" <fuad.tabba@linux.dev>
Cc: "Oliver Upton" <oupton@kernel.org>,
	"Marc Zyngier" <maz@kernel.org>,
	kvmarm@lists.linux.dev
Subject: Re: [PATCH v4 12/18] KVM: arm64: Prevent host PC adjustments for protected vCPUs
Date: Thu, 01 Oct 2026 14:21:08 +0000	[thread overview]
Message-ID: <20261001142109.794CA1F000FF@smtp.kernel.org> (raw)
In-Reply-To: <20261001135711.1640520-13-fuad.tabba@linux.dev>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Critical] kvm: host DoS via KVM_SET_VCPU_EVENTS and uncleared INCREMENT_PC
- [High] kvm: silently dropped exception injections on non-trap exits for protected guests
--

commit 8bf814727f8778e45c8fb25a3c96ee3b58fc462e
Author: Fuad Tabba <fuad.tabba@linux.dev>

KVM: arm64: Prevent host PC adjustments for protected vCPUs

This commit modifies __kvm_adjust_pc() to leave PC_UPDATE_REQ (including
INCREMENT_PC and PENDING_EXCEPTION) on the host copy for protected VMs. It
introduces kvm_adjust_pc_get() which returns NULL for protected vCPUs,
bypassing the adjustment and leaving the flag clearing to entry/exit handlers.

> diff --git a/arch/arm64/kvm/hyp/exception.c b/arch/arm64/kvm/hyp/exception.c
> index 6e60d890afa4a..93d68b1d38be8 100644
> --- a/arch/arm64/kvm/hyp/exception.c
> +++ b/arch/arm64/kvm/hyp/exception.c
> @@ -353,12 +353,19 @@ static void kvm_inject_exception(struct kvm_vcpu *vcpu)
>   */
>  void __kvm_adjust_pc(struct kvm_vcpu *vcpu)
>  {
> -	if (vcpu_get_flag(vcpu, PENDING_EXCEPTION)) {
> -		kvm_inject_exception(vcpu);
> -		vcpu_clear_flag(vcpu, PENDING_EXCEPTION);
> -		vcpu_clear_flag(vcpu, EXCEPT_MASK);
> -	} else if (vcpu_get_flag(vcpu, INCREMENT_PC)) {
> -		kvm_skip_instr(vcpu);
> -		vcpu_clear_flag(vcpu, INCREMENT_PC);
> +	struct kvm_vcpu *target = kvm_adjust_pc_get(vcpu);
> +
> +	if (!target)
> +		return;

[Severity: Critical]
Can this early return leave INCREMENT_PC uncleared, leading to a host panic?

When an unprivileged host userspace VMM manages a protected VM and sets
SCTLR2_EL1.NMEA=1, a guest MMIO exit causes kvm_handle_mmio_return() to set
INCREMENT_PC on the host vCPU copy.

If entry is then aborted due to a pending signal, we exit to userspace
with -EINTR. Because target is NULL for protected VMs, we return early here
without clearing INCREMENT_PC.

If userspace then calls KVM_SET_VCPU_EVENTS to inject an SError (with
serror_pending=1), serror_is_masked() returns false, which causes
pend_serror_exception() to call kvm_pend_exception(). This hits the assertion:

WARN_ON(vcpu_get_flag(v, INCREMENT_PC));

crashing the host if panic_on_warn is set. While Patch 14 attempts to fix this
by clearing PC_UPDATE_REQ on exit from EL2, INCREMENT_PC is set at EL1 on MMIO
return after the EL2 exit.

[ ... ]
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index 00038a162d09b..2fcd3f8cc8fc4 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -644,6 +644,38 @@ static void handle___pkvm_host_mkyoung_guest(struct kvm_cpu_context *host_ctxt)
>  	cpu_reg(host_ctxt, 1) =  ret;
>  }
>  
> +/*
> + * PKVM_HOST_STATE_DIRTY names the authoritative copy, the host's when set.
> + * A loaded protected vCPU takes the request at its next entry instead.
> + */
> +struct kvm_vcpu *kvm_adjust_pc_get(struct kvm_vcpu *vcpu)
> +{
> +	struct pkvm_hyp_vcpu *hyp_vcpu;
> +
> +	if (!is_protected_kvm_enabled())
> +		return vcpu;
> +
> +	hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
> +	if (!hyp_vcpu || vcpu == &hyp_vcpu->vcpu)
> +		return vcpu;
> +
> +	if (pkvm_hyp_vcpu_is_protected(hyp_vcpu))
> +		return NULL;

[Severity: High]
Does deferring exception injection to the entry path cause host-injected
exceptions to be silently dropped on non-trap exits?

If a protected guest exits due to an IRQ (ARM_EXCEPTION_IRQ) and userspace
calls KVM_SET_VCPU_EVENTS with serror_pending=1, PENDING_EXCEPTION is set on
the host vCPU. 

On KVM_RUN, flush_hyp_vcpu() evaluates the exit code and bypasses the
ec_handler for non-trap exits:

	case ARM_EXCEPTION_IRQ:
	case ARM_EXCEPTION_EL1_SERROR:
	case ARM_EXCEPTION_IL:
		break;

This ignores the PENDING_EXCEPTION flag during entry. When the guest exits
again, sync_hyp_vcpu() unconditionally clears PC_UPDATE_REQ (which includes
PENDING_EXCEPTION), permanently losing the injected exception.

[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261001135711.1640520-1-fuad.tabba@linux.dev?part=12

  reply	other threads:[~2026-10-01 14:21 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-01 13:56 [PATCH v4 00/18] KVM: arm64: Confine protected VM vCPU state to EL2 Fuad Tabba
2026-10-01 13:56 ` [PATCH v4 01/18] KVM: arm64: Sync HCR_EL2.VSE back to the host vCPU under pKVM Fuad Tabba
2026-10-01 13:56 ` [PATCH v4 02/18] KVM: arm64: Validate the host vCPU's VM before reading it " Fuad Tabba
2026-10-01 13:56 ` [PATCH v4 03/18] KVM: arm64: Pin the host vCPU before adjusting its PC " Fuad Tabba
2026-10-01 13:56 ` [PATCH v4 04/18] KVM: arm64: Disable steal time for protected VMs Fuad Tabba
2026-10-01 13:56 ` [PATCH v4 05/18] KVM: arm64: Introduce per-EC entry handlers for pKVM Fuad Tabba
2026-10-01 13:56 ` [PATCH v4 06/18] KVM: arm64: Skip fixed-feature state flush for protected vCPUs Fuad Tabba
2026-10-01 14:19   ` sashiko-bot
2026-10-01 15:06     ` Fuad Tabba
2026-10-01 13:57 ` [PATCH v4 07/18] KVM: arm64: Add {flush,sync}_hyp_timer_state() primitives Fuad Tabba
2026-10-01 13:57 ` [PATCH v4 08/18] KVM: arm64: Add system register reset framework for protected VMs Fuad Tabba
2026-10-01 13:57 ` [PATCH v4 09/18] KVM: arm64: Implement HVC handling for protected guests at EL2 Fuad Tabba
2026-10-01 13:57 ` [PATCH v4 10/18] KVM: arm64: Handle PSCI calls for protected VMs " Fuad Tabba
2026-10-01 13:57 ` [PATCH v4 11/18] KVM: arm64: Restrict KVM_ARM_VCPU_INIT and PSCI version for protected VMs Fuad Tabba
2026-10-01 13:57 ` [PATCH v4 12/18] KVM: arm64: Prevent host PC adjustments for protected vCPUs Fuad Tabba
2026-10-01 14:21   ` sashiko-bot [this message]
2026-10-01 15:08     ` Fuad Tabba
2026-10-01 13:57 ` [PATCH v4 13/18] KVM: arm64: Inject an UNDEF at EL2 for unhandled protected guest exits Fuad Tabba
2026-10-01 13:57 ` [PATCH v4 14/18] KVM: arm64: Add per-EC entry/exit state marshalling for protected guests Fuad Tabba
2026-10-01 13:57 ` [PATCH v4 15/18] KVM: arm64: Reject host access to protected VM private state Fuad Tabba
2026-10-01 13:57 ` [PATCH v4 16/18] KVM: arm64: Reject host power-on of a vCPU that EL2 holds powered off Fuad Tabba
2026-10-01 14:18   ` sashiko-bot
2026-10-01 15:10     ` Fuad Tabba
2026-10-01 13:57 ` [PATCH v4 17/18] KVM: arm64: Advertise the capabilities that protected VMs support Fuad Tabba
2026-10-01 13:57 ` [PATCH v4 18/18] KVM: arm64: Document the protected VM userspace API Fuad Tabba
2026-10-01 14:31 ` [PATCH v4 00/18] KVM: arm64: Confine protected VM vCPU state to EL2 Fuad Tabba
2026-10-02 15:55 ` Marc Zyngier
2026-10-03  6:57   ` Fuad Tabba
2026-10-03  8:38     ` Marc Zyngier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261001142109.794CA1F000FF@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=fuad.tabba@linux.dev \
    --cc=kvmarm@lists.linux.dev \
    --cc=maz@kernel.org \
    --cc=oupton@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox