On Fri, 4 Sept 2026 at 18:56, Dongli Zhang <[email protected]> wrote: > > KVM caches per-vCPU host task's run_delay in per-architecture struct > kvm_vcpu_arch at last_steal. > > Move the cache to struct kvm_vcpu and convert x86, arm64, riscv, and > loongarch to use the common field. > > Add HAVE_KVM_PV_STEAL_TIME so last_steal is used only for architectures > that implement KVM stealtime. > > Suggested-by: Marc Zyngier <[email protected]> > Signed-off-by: Dongli Zhang <[email protected]> > --- > Marc suggested reusing CONFIG_HAVE_PV_STEAL_CLOCK_GEN, but I introduced > HAVE_KVM_PV_STEAL_TIME instead.
FWIW, I think HAVE_KVM_PV_STEAL_TIME is the right choice here, since it's about what KVM itself supports. HAVE_PV_STEAL_CLOCK_GEN is the guest-side paravirt_steal_clock() config, so a KVM-side symbol fits the host field better. Reviewed-by: Fuad Tabba <[email protected]> Cheers, /fuad > As I have access to only x86 and arm64 KVM hosts, I created and validated > the selftest on those two architectures only. > > arch/arm64/include/asm/kvm_host.h | 1 - > arch/arm64/kvm/Kconfig | 1 + > arch/arm64/kvm/pvtime.c | 8 ++++---- > arch/loongarch/include/asm/kvm_host.h | 1 - > arch/loongarch/kvm/Kconfig | 1 + > arch/loongarch/kvm/exit.c | 2 +- > arch/loongarch/kvm/vcpu.c | 6 +++--- > arch/riscv/include/asm/kvm_host.h | 1 - > arch/riscv/kvm/Kconfig | 1 + > arch/riscv/kvm/vcpu_sbi_sta.c | 10 +++++----- > arch/x86/include/asm/kvm_host.h | 1 - > arch/x86/kvm/Kconfig | 1 + > arch/x86/kvm/x86.c | 5 ++--- > include/linux/kvm_host.h | 4 ++++ > virt/kvm/Kconfig | 3 +++ > 15 files changed, 26 insertions(+), 20 deletions(-) > > diff --git a/arch/arm64/include/asm/kvm_host.h > b/arch/arm64/include/asm/kvm_host.h > index 27fe0cd5b2d7..36cb7dee988c 100644 > --- a/arch/arm64/include/asm/kvm_host.h > +++ b/arch/arm64/include/asm/kvm_host.h > @@ -937,7 +937,6 @@ struct kvm_vcpu_arch { > > /* Guest PV state */ > struct { > - u64 last_steal; > gpa_t base; > } steal; > > diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig > index 449154f9a485..f5855bfc681c 100644 > --- a/arch/arm64/kvm/Kconfig > +++ b/arch/arm64/kvm/Kconfig > @@ -34,6 +34,7 @@ menuconfig KVM > select HAVE_KVM_IRQ_BYPASS > select HAVE_KVM_READONLY_MEM > select HAVE_KVM_VCPU_RUN_PID_CHANGE > + select HAVE_KVM_PV_STEAL_TIME > select SCHED_INFO > select GUEST_PERF_EVENTS if PERF_EVENTS > select KVM_GUEST_MEMFD > diff --git a/arch/arm64/kvm/pvtime.c b/arch/arm64/kvm/pvtime.c > index 4ceabaa4c30b..a67d93845d79 100644 > --- a/arch/arm64/kvm/pvtime.c > +++ b/arch/arm64/kvm/pvtime.c > @@ -14,7 +14,7 @@ void kvm_update_stolen_time(struct kvm_vcpu *vcpu) > { > struct kvm *kvm = vcpu->kvm; > u64 base = vcpu->arch.steal.base; > - u64 last_steal = vcpu->arch.steal.last_steal; > + u64 last_steal = vcpu->last_steal; > u64 offset = offsetof(struct pvclock_vcpu_stolen_time, stolen_time); > u64 steal = 0; > int idx; > @@ -25,8 +25,8 @@ void kvm_update_stolen_time(struct kvm_vcpu *vcpu) > idx = srcu_read_lock(&kvm->srcu); > if (!kvm_get_guest(kvm, base + offset, steal)) { > steal = le64_to_cpu(steal); > - vcpu->arch.steal.last_steal = > READ_ONCE(current->sched_info.run_delay); > - steal += vcpu->arch.steal.last_steal - last_steal; > + vcpu->last_steal = READ_ONCE(current->sched_info.run_delay); > + steal += vcpu->last_steal - last_steal; > kvm_put_guest(kvm, base + offset, cpu_to_le64(steal)); > } > srcu_read_unlock(&kvm->srcu, idx); > @@ -61,7 +61,7 @@ gpa_t kvm_init_stolen_time(struct kvm_vcpu *vcpu) > * Start counting stolen time from the time the guest requests > * the feature enabled. > */ > - vcpu->arch.steal.last_steal = current->sched_info.run_delay; > + vcpu->last_steal = current->sched_info.run_delay; > kvm_write_guest_lock(kvm, base, &init_values, sizeof(init_values)); > > return base; > diff --git a/arch/loongarch/include/asm/kvm_host.h > b/arch/loongarch/include/asm/kvm_host.h > index 23cfbecebbd7..14514a25b261 100644 > --- a/arch/loongarch/include/asm/kvm_host.h > +++ b/arch/loongarch/include/asm/kvm_host.h > @@ -253,7 +253,6 @@ struct kvm_vcpu_arch { > /* paravirt steal time */ > struct { > u64 guest_addr; > - u64 last_steal; > struct gfn_to_hva_cache cache; > u8 preempted; > } st; > diff --git a/arch/loongarch/kvm/Kconfig b/arch/loongarch/kvm/Kconfig > index 15da2d88c0c1..4996ec9c07f9 100644 > --- a/arch/loongarch/kvm/Kconfig > +++ b/arch/loongarch/kvm/Kconfig > @@ -26,6 +26,7 @@ config KVM > select HAVE_KVM_MSI > select HAVE_KVM_READONLY_MEM > select KVM_COMMON > + select HAVE_KVM_PV_STEAL_TIME > select KVM_GENERIC_DIRTYLOG_READ_PROTECT > select KVM_GENERIC_HARDWARE_ENABLING > select KVM_MMIO > diff --git a/arch/loongarch/kvm/exit.c b/arch/loongarch/kvm/exit.c > index 4f58e6e2cf86..56ae6b18f8c1 100644 > --- a/arch/loongarch/kvm/exit.c > +++ b/arch/loongarch/kvm/exit.c > @@ -773,7 +773,7 @@ static long kvm_save_notify(struct kvm_vcpu *vcpu) > if (!(data & KVM_STEAL_PHYS_VALID)) > return 0; > > - vcpu->arch.st.last_steal = current->sched_info.run_delay; > + vcpu->last_steal = current->sched_info.run_delay; > kvm_make_request(KVM_REQ_STEAL_UPDATE, vcpu); > return 0; > default: > diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c > index ed9e092c97ba..728d29eba8e0 100644 > --- a/arch/loongarch/kvm/vcpu.c > +++ b/arch/loongarch/kvm/vcpu.c > @@ -187,8 +187,8 @@ static void kvm_update_stolen_time(struct kvm_vcpu *vcpu) > smp_wmb(); > > unsafe_get_user(steal, &st->steal, out); > - steal += current->sched_info.run_delay - vcpu->arch.st.last_steal; > - vcpu->arch.st.last_steal = current->sched_info.run_delay; > + steal += current->sched_info.run_delay - vcpu->last_steal; > + vcpu->last_steal = current->sched_info.run_delay; > unsafe_put_user(steal, &st->steal, out); > > smp_wmb(); > @@ -1205,7 +1205,7 @@ static int kvm_loongarch_pvtime_set_attr(struct > kvm_vcpu *vcpu, > > if (!ret) { > vcpu->arch.st.guest_addr = gpa; > - vcpu->arch.st.last_steal = current->sched_info.run_delay; > + vcpu->last_steal = current->sched_info.run_delay; > kvm_make_request(KVM_REQ_STEAL_UPDATE, vcpu); > } > > diff --git a/arch/riscv/include/asm/kvm_host.h > b/arch/riscv/include/asm/kvm_host.h > index a30600579231..305875301c04 100644 > --- a/arch/riscv/include/asm/kvm_host.h > +++ b/arch/riscv/include/asm/kvm_host.h > @@ -273,7 +273,6 @@ struct kvm_vcpu_arch { > /* SBI steal-time accounting */ > struct { > gpa_t shmem; > - u64 last_steal; > } sta; > }; > > diff --git a/arch/riscv/kvm/Kconfig b/arch/riscv/kvm/Kconfig > index ec2cee0a39e0..1ff07a904a02 100644 > --- a/arch/riscv/kvm/Kconfig > +++ b/arch/riscv/kvm/Kconfig > @@ -26,6 +26,7 @@ config KVM > select HAVE_KVM_READONLY_MEM > select HAVE_KVM_DIRTY_RING_ACQ_REL > select KVM_COMMON > + select HAVE_KVM_PV_STEAL_TIME > select KVM_GENERIC_DIRTYLOG_READ_PROTECT > select KVM_GENERIC_HARDWARE_ENABLING > select KVM_MMIO > diff --git a/arch/riscv/kvm/vcpu_sbi_sta.c b/arch/riscv/kvm/vcpu_sbi_sta.c > index 60e50296a008..9a77d3bde7c7 100644 > --- a/arch/riscv/kvm/vcpu_sbi_sta.c > +++ b/arch/riscv/kvm/vcpu_sbi_sta.c > @@ -19,13 +19,13 @@ > static void kvm_riscv_vcpu_sbi_sta_reset(struct kvm_vcpu *vcpu) > { > vcpu->arch.sta.shmem = INVALID_GPA; > - vcpu->arch.sta.last_steal = 0; > + vcpu->last_steal = 0; > } > > void kvm_riscv_vcpu_record_steal_time(struct kvm_vcpu *vcpu) > { > gpa_t shmem = vcpu->arch.sta.shmem; > - u64 last_steal = vcpu->arch.sta.last_steal; > + u64 last_steal = vcpu->last_steal; > __le32 __user *sequence_ptr; > __le64 __user *steal_ptr; > __le32 sequence_le; > @@ -67,8 +67,8 @@ void kvm_riscv_vcpu_record_steal_time(struct kvm_vcpu *vcpu) > > if (!WARN_ON(get_user(steal_le, steal_ptr))) { > steal = le64_to_cpu(steal_le); > - vcpu->arch.sta.last_steal = > READ_ONCE(current->sched_info.run_delay); > - steal += vcpu->arch.sta.last_steal - last_steal; > + vcpu->last_steal = READ_ONCE(current->sched_info.run_delay); > + steal += vcpu->last_steal - last_steal; > WARN_ON(put_user(cpu_to_le64(steal), steal_ptr)); > } > > @@ -115,7 +115,7 @@ static int kvm_sbi_sta_steal_time_set_shmem(struct > kvm_vcpu *vcpu) > return SBI_ERR_INVALID_ADDRESS; > > vcpu->arch.sta.shmem = shmem; > - vcpu->arch.sta.last_steal = current->sched_info.run_delay; > + vcpu->last_steal = current->sched_info.run_delay; > > return 0; > } > diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h > index 683bb8bf43a9..ebdd8526ae12 100644 > --- a/arch/x86/include/asm/kvm_host.h > +++ b/arch/x86/include/asm/kvm_host.h > @@ -872,7 +872,6 @@ struct kvm_vcpu_arch { > struct { > u8 preempted; > u64 msr_val; > - u64 last_steal; > struct gfn_to_hva_cache cache; > } st; > > diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig > index 538ed1e80332..b2aea8058841 100644 > --- a/arch/x86/kvm/Kconfig > +++ b/arch/x86/kvm/Kconfig > @@ -40,6 +40,7 @@ config KVM_X86 > select HAVE_KVM_MSI > select HAVE_KVM_CPU_RELAX_INTERCEPT > select HAVE_KVM_NO_POLL > + select HAVE_KVM_PV_STEAL_TIME > select VIRT_XFER_TO_GUEST_WORK > select KVM_GENERIC_DIRTYLOG_READ_PROTECT > select KVM_VFIO > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c > index 79468ddfe473..927c8b1ed83d 100644 > --- a/arch/x86/kvm/x86.c > +++ b/arch/x86/kvm/x86.c > @@ -2129,9 +2129,8 @@ static void record_steal_time(struct kvm_vcpu *vcpu) > smp_wmb(); > > unsafe_get_user(steal, &st->steal, out); > - steal += current->sched_info.run_delay - > - vcpu->arch.st.last_steal; > - vcpu->arch.st.last_steal = current->sched_info.run_delay; > + steal += current->sched_info.run_delay - vcpu->last_steal; > + vcpu->last_steal = current->sched_info.run_delay; > unsafe_put_user(steal, &st->steal, out); > > version += 1; > diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h > index 03bfc92864b6..ff9d423b6a7c 100644 > --- a/include/linux/kvm_host.h > +++ b/include/linux/kvm_host.h > @@ -398,6 +398,10 @@ struct kvm_vcpu { > */ > struct kvm_memory_slot *last_used_slot; > u64 last_used_slot_gen; > + > +#ifdef CONFIG_HAVE_KVM_PV_STEAL_TIME > + u64 last_steal; > +#endif > }; > > /* > diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig > index c3c0ee253fc7..f42a3a0fc5ba 100644 > --- a/virt/kvm/Kconfig > +++ b/virt/kvm/Kconfig > @@ -82,6 +82,9 @@ config HAVE_KVM_IRQ_BYPASS > config HAVE_KVM_VCPU_RUN_PID_CHANGE > bool > > +config HAVE_KVM_PV_STEAL_TIME > + bool > + > config HAVE_KVM_NO_POLL > bool > > -- > 2.43.7 >
