[PATCH v2] RISC-V: KVM: Synchronize hrtimer callback during teardown

Anup Patel anup at brainfault.org
Thu Sep 10 01:44:34 PDT 2026


On Fri, Jul 31, 2026 at 10:05 PM Myeonghun Pak <mhun512 at gmail.com> wrote:
>
> The non-Sstc hrtimer callback clears next_set before its final uses of
> the enclosing vCPU.  If teardown observes next_set as false while the
> callback is still running, kvm_riscv_vcpu_timer_cancel() skips
> hrtimer_cancel() and kvm_destroy_vcpus() can free the vCPU before the
> callback enters kvm_riscv_vcpu_set_interrupt().
>
> A guest can arm the timer with SBI TIME and request shutdown with SBI
> legacy shutdown or SRST.  A VMM that honors KVM_EXIT_SYSTEM_EVENT and
> destroys the VM supplies the teardown side of the race; no post-launch
> host ioctl is needed to arm or request teardown.
>
> On upstream master 62cc90241548, generic KASAN reported:
>
>   BUG: KASAN: slab-use-after-free in do_raw_spin_lock
>   Write of size 4 at addr ff60000005e58898
>
>   kvm_riscv_vcpu_set_interrupt
>   kvm_riscv_vcpu_hrtimer_expired
>   __hrtimer_run_queues
>   hrtimer_interrupt
>
> The object was allocated by KVM_CREATE_VCPU and freed concurrently by:
>
>   kvm_destroy_vcpus
>   kvm_arch_destroy_vm
>   kvm_destroy_vm
>   __fput
>
> For deterministic validation, I added mdelay(1000) immediately after
> the existing next_set = false assignment.  This only widens the
> existing post-clear callback window.  A no-delay trace build naturally
> reached the callback-after-teardown-start/before-deinit ordering in 12
> of 200 runs, but 1,500 stock-kernel stress iterations did not produce a
> KASAN report, so natural reproduction is timing-sensitive.
>
> Always invoke hrtimer_cancel() for an initialized timer.  Preserve the
> existing -EINVAL result when the timer is no longer set, but only after
> synchronizing with a running callback.
>
> With this patch, hrtimer_cancel() blocked for the full widened callback
> window before vCPU destruction.  KASAN reported no error in 100
> fixed-and-widened runs or 200 fix-only timing-sweep runs.
>
> Fixes: 3a9f66cb25e1 ("RISC-V: KVM: Add timer functionality")
> Cc: stable at vger.kernel.org
> Assisted-by: OpenAI:GPT-5.6
> Signed-off-by: Myeonghun Pak <mhun512 at gmail.com>

LGTM.

Reviewed-by: Anup Patel <anup at brainfault.org>

Queued this patch as fix for Linux-7.3-rcX

Thanks,
Anup

> ---
> Changes in v2:
> - Add the required Assisted-by trailer.
> - Drop security at kernel.org from the recipients.
>
>  arch/riscv/kvm/vcpu_timer.c | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
>
> AI disclosure: I used AI assistance during the audit and am treating the
> issue as public as required by Documentation/process/security-bugs.rst.
> The reproducer and full KASAN trace have not been posted publicly and
> are available on request.
>
> diff --git a/arch/riscv/kvm/vcpu_timer.c b/arch/riscv/kvm/vcpu_timer.c
> index ae53133c7ab0..a2cd277a4059 100644
> --- a/arch/riscv/kvm/vcpu_timer.c
> +++ b/arch/riscv/kvm/vcpu_timer.c
> @@ -61,10 +61,13 @@ kvm_riscv_vcpu_hrtimer_expired(struct hrtimer *h)
>
>  static int kvm_riscv_vcpu_timer_cancel(struct kvm_vcpu_timer *t)
>  {
> -       if (!t->init_done || !t->next_set)
> +       if (!t->init_done)
>                 return -EINVAL;
>
>         hrtimer_cancel(&t->hrt);
> +
> +       if (!t->next_set)
> +               return -EINVAL;
>         t->next_set = false;
>
>         return 0;
> --
> 2.47.2



More information about the linux-riscv mailing list