All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.