[PATCH v2 1/4] KVM: Move last_steal to common struct kvm_vcpu
Dongli Zhang
dongli.zhang at oracle.com
Fri Sep 4 10:55:23 PDT 2026
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 <maz at kernel.org>
Signed-off-by: Dongli Zhang <dongli.zhang at oracle.com>
---
Marc suggested reusing CONFIG_HAVE_PV_STEAL_CLOCK_GEN, but I introduced
HAVE_KVM_PV_STEAL_TIME instead.
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
More information about the kvm-riscv
mailing list