All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Qiang Ma" <maqianga@uniontech.com>
Cc: kvm@vger.kernel.org
Subject: Re: [PATCH] RISC-V: KVM: Fix timer state restore
Date: Tue, 26 May 2026 08:23:36 +0000	[thread overview]
Message-ID: <20260526082339.101271F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260526075544.796396-1-maqianga@uniontech.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

New issues:
- [High] The patch introduces a strict UAPI register restoration ordering dependency, causing the timer to permanently stall if `state` is restored before `compare`.

Pre-existing issues:
- [Critical] Timer teardown uses a state flag for synchronization instead of unconditionally canceling the hrtimer, leading to a use-after-free on VCPU destruction.
- [High] Restoring the timer state to OFF fails with `-EINVAL` if the timer is already OFF, aborting live migration. This is exacerbated by SSTC incorrectly reporting its state.
--

commit 12ffaa755d54118c3c86ae260e5df5a3b6b59454
Author: Qiang Ma <maqianga@uniontech.com>

RISC-V: KVM: Fix timer state restore

This commit changes the timer state restoration logic in the one-reg interface
to re-arm the timer using the restored compare value (t->next_cycles) instead
of using the state value itself.

> diff --git a/arch/riscv/kvm/vcpu_timer.c b/arch/riscv/kvm/vcpu_timer.c
> --- a/arch/riscv/kvm/vcpu_timer.c
> +++ b/arch/riscv/kvm/vcpu_timer.c
> @@ -229,7 +229,7 @@ int kvm_riscv_vcpu_set_reg_timer(struct kvm_vcpu *vcpu,
>  		break;
>  	case KVM_REG_RISCV_TIMER_REG(state):
>  		if (reg_val == KVM_RISCV_TIMER_STATE_ON)
> -			ret = kvm_riscv_vcpu_timer_next_event(vcpu, reg_val);
> +			ret = kvm_riscv_vcpu_timer_next_event(vcpu, t->next_cycles);

[Severity: High]
Does this change introduce a strict ordering dependency for userspace register
restoration?

If a VMM restores the state register to ON before restoring the compare
register, it appears this will arm the timer using an uninitialized or stale
t->next_cycles value.

If the compare register is restored later via KVM_SET_ONE_REG:

	case KVM_REG_RISCV_TIMER_REG(compare):
		t->next_cycles = reg_val;
		break;

This only updates memory and doesn't seem to re-arm the running hrtimer. Will
this cause the virtual timer to stall indefinitely?

Before this patch, using 1 armed the timer for immediate expiration, and the
subsequent callback would asynchronously pick up the restored compare value.

>  		else
>  			ret = kvm_riscv_vcpu_timer_cancel(t);

[Severity: High]
This isn't a bug introduced by this patch, but does restoring the timer state
to OFF fail and abort live migration if the timer is already OFF?

If kvm_riscv_vcpu_timer_cancel() is called when restoring an OFF state:

static int kvm_riscv_vcpu_timer_cancel(struct kvm_vcpu_timer *t)
{
	if (!t->init_done || !t->next_set)
		return -EINVAL;
        ...
}

On the migration destination, a newly created VCPU has t->next_set == false, so
restoring an OFF state returns -EINVAL.

Additionally, when the SSTC extension is enabled, the timer is programmed
directly via CSRs and t->next_set is not set to true for a running timer. Will
this cause KVM_GET_ONE_REG to incorrectly report the state as OFF for active
VMs, which then fails during restoration on the destination?

[Severity: Critical]
This is a pre-existing issue, but does using the t->next_set flag for
synchronization during teardown lead to a use-after-free?

Looking at kvm_riscv_vcpu_timer_cancel(), it skips canceling the hrtimer if
the flag is false:

static int kvm_riscv_vcpu_timer_cancel(struct kvm_vcpu_timer *t)
{
	if (!t->init_done || !t->next_set)
		return -EINVAL;

	hrtimer_cancel(&t->hrt);
	t->next_set = false;
...

If the hrtimer callback clears t->next_set before it finishes executing, and
the VCPU is destroyed concurrently, the teardown path will see
t->next_set == false and skip hrtimer_cancel().

Will the still-executing callback then dereference the freed VCPU memory?

>  		break;

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260526075544.796396-1-maqianga@uniontech.com?part=1

  reply	other threads:[~2026-05-26  8:23 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-26  7:55 [PATCH] RISC-V: KVM: Fix timer state restore Qiang Ma
2026-05-26  7:55 ` Qiang Ma
2026-05-26  7:55 ` Qiang Ma
2026-05-26  8:23 ` sashiko-bot [this message]
2026-05-26 13:31   ` Qiang Ma
2026-06-04  7:52 ` Anup Patel
2026-06-04  7:52   ` Anup Patel
2026-06-04  7:52   ` Anup Patel
2026-06-26  8:21 ` patchwork-bot+linux-riscv
2026-06-26  8:21   ` patchwork-bot+linux-riscv
2026-06-26  8:21   ` patchwork-bot+linux-riscv

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=20260526082339.101271F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=kvm@vger.kernel.org \
    --cc=maqianga@uniontech.com \
    --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.