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.

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


Reply via email to