All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chao Wu <chaowu@linux.alibaba.com>
To: Thomas Gleixner <tglx@linutronix.de>,
	Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
	Richard Cochran <richardcochran@gmail.com>
Cc: x86@kernel.org, kvm@vger.kernel.org,
	Chao Wu <chaowu@linux.alibaba.com>,
	Jiang Liu <gerry@linux.alibaba.com>,
	Zha Bin <zhabin@linux.alibaba.com>
Subject: [PATCH 1/2] ptp_kvm: fix an infinite loop in ptp_kvm_get_time_fn when vm has more than 64 vcpus
Date: Tue, 25 May 2021 16:44:57 +0800	[thread overview]
Message-ID: <299220a82834b30257a710d2cff52fafa5f1fe1b.1621505277.git.chaowu@linux.alibaba.com> (raw)
In-Reply-To: <cover.1621505277.git.chaowu@linux.alibaba.com>

Commit 95a3d4454bb1 ("x86/kvmclock: Switch kvmclock data to a PER_CPU
variable") removes the static data array sized 64bytes * CONFIG_NR_CPUS
and uses a static page sized array to store pvclock data.
For the 64bytes * CONFIG_NR_CPUS size design, the address is consecutive
for all vcpus.
But for the static page sized array design, if page size is 4kB and
struct pvclock_vsyscall_time_info size is 64Byte (cache line aligned),
the maximum length of hv_clock_boot is 64.
For vcpus after 64, kernel will dynamically allocate pages for their
pvclock data in kvmclock_init_mem. So the address is not consecutive for
all vcpus.

Commit 95a3d4454bb1 ("x86/kvmclock: Switch kvmclock data to a PER_CPU
variable") uses per-cpu variable to store the pvclock_vsyscall_time_info
struct pointer to avoid the use of inconsecutive memory address. But
ptp_kvm_get_time_fn in ptp_kvm initiate hv_clock as the cpu0’s 
pvclock_vsyscall_time_info virtual address and uses &hv_clock[cpu].pvti 
to get specified cpu’s pvclock date. When the vcpu number is beyond 63,
&hv_clock[cpu].pvti will point to an incorrect virtual address and will 
cause infinite loop in the following do while code area.

Commit 95a3d4454bb1 ("x86/kvmclock: Switch kvmclock data to a PER_CPU
variable") has removed all &hv_clock[cpu].pvti usage with per-cpu in kvmclock
but the revelant code in ptp_kvm was ignored.

We use this_cpu_pvti() to get pvclock data in ptp_kvm and put per-cpu
related declaration in kvmclock.c to kvmclock.h for ptp_kvm to use.

Signed-off-by: Chao Wu <chaowu@linux.alibaba.com>
Signed-off-by: Jiang Liu <gerry@linux.alibaba.com>
Signed-off-by: Zha Bin <zhabin@linux.alibaba.com>
---
 arch/x86/include/asm/kvmclock.h | 16 ++++++++++++++++
 arch/x86/kernel/kvmclock.c      | 12 ++----------
 drivers/ptp/ptp_kvm.c           |  6 ++----
 3 files changed, 20 insertions(+), 14 deletions(-)

diff --git a/arch/x86/include/asm/kvmclock.h b/arch/x86/include/asm/kvmclock.h
index eceea9299097..69b09839e199 100644
--- a/arch/x86/include/asm/kvmclock.h
+++ b/arch/x86/include/asm/kvmclock.h
@@ -2,6 +2,22 @@
 #ifndef _ASM_X86_KVM_CLOCK_H
 #define _ASM_X86_KVM_CLOCK_H
 
+#include <asm/pvclock.h>
+
 extern struct clocksource kvm_clock;
 
+#ifdef CONFIG_KVM_GUEST
+DECLARE_PER_CPU(struct pvclock_vsyscall_time_info *, hv_clock_per_cpu);
+
+static inline struct pvclock_vcpu_time_info *this_cpu_pvti(void)
+{
+	return &this_cpu_read(hv_clock_per_cpu)->pvti;
+}
+
+static inline struct pvclock_vsyscall_time_info *this_cpu_hvclock(void)
+{
+	return this_cpu_read(hv_clock_per_cpu);
+}
+
+#endif /* CONFIG_KVM_GUEST */
 #endif /* _ASM_X86_KVM_CLOCK_H */
diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c
index 2ec202cb9dfd..006551cccdac 100644
--- a/arch/x86/kernel/kvmclock.c
+++ b/arch/x86/kernel/kvmclock.c
@@ -64,18 +64,10 @@ early_param("no-kvmclock-vsyscall", parse_no_kvmclock_vsyscall);
 static struct pvclock_vsyscall_time_info
 			hv_clock_boot[HVC_BOOT_ARRAY_SIZE] __bss_decrypted __aligned(PAGE_SIZE);
 static struct pvclock_wall_clock wall_clock __bss_decrypted;
-static DEFINE_PER_CPU(struct pvclock_vsyscall_time_info *, hv_clock_per_cpu);
 static struct pvclock_vsyscall_time_info *hvclock_mem;
 
-static inline struct pvclock_vcpu_time_info *this_cpu_pvti(void)
-{
-	return &this_cpu_read(hv_clock_per_cpu)->pvti;
-}
-
-static inline struct pvclock_vsyscall_time_info *this_cpu_hvclock(void)
-{
-	return this_cpu_read(hv_clock_per_cpu);
-}
+DEFINE_PER_CPU(struct pvclock_vsyscall_time_info *, hv_clock_per_cpu);
+EXPORT_PER_CPU_SYMBOL_GPL(hv_clock_per_cpu);
 
 /*
  * The wallclock is the time of day when we booted. Since then, some time may
diff --git a/drivers/ptp/ptp_kvm.c b/drivers/ptp/ptp_kvm.c
index c67dd11e08b1..985e3728016b 100644
--- a/drivers/ptp/ptp_kvm.c
+++ b/drivers/ptp/ptp_kvm.c
@@ -34,7 +34,6 @@ struct kvm_ptp_clock {
 
 DEFINE_SPINLOCK(kvm_ptp_lock);
 
-static struct pvclock_vsyscall_time_info *hv_clock;
 
 static struct kvm_clock_pairing clock_pair;
 static phys_addr_t clock_pair_gpa;
@@ -53,7 +52,7 @@ static int ptp_kvm_get_time_fn(ktime_t *device_time,
 
 	preempt_disable_notrace();
 	cpu = smp_processor_id();
-	src = &hv_clock[cpu].pvti;
+	src = this_cpu_pvti();
 
 	do {
 		/*
@@ -182,9 +181,8 @@ static int __init ptp_kvm_init(void)
 		return -ENODEV;
 
 	clock_pair_gpa = slow_virt_to_phys(&clock_pair);
-	hv_clock = pvclock_get_pvti_cpu0_va();
 
-	if (!hv_clock)
+	if (!this_cpu_pvti())
 		return -ENODEV;
 
 	ret = kvm_hypercall2(KVM_HC_CLOCK_PAIRING, clock_pair_gpa,
-- 
2.24.3 (Apple Git-128)


  reply	other threads:[~2021-05-25  8:45 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-25  8:44 [PATCH 0/2] Fix ptp_kvm_get_time_fn infinite loop and remove redundant EXPORT_SYMBOL_GPL Chao Wu
2021-05-25  8:44 ` Chao Wu [this message]
2021-05-25  8:44 ` [PATCH 2/2] pvclock: remove EXPORT_SYMBOL_GPL for pvclock_get_pvti_cpu0_va Chao Wu
2021-08-09 13:05 ` [PATCH 0/2] Fix ptp_kvm_get_time_fn infinite loop and remove redundant EXPORT_SYMBOL_GPL Chao Wu

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=299220a82834b30257a710d2cff52fafa5f1fe1b.1621505277.git.chaowu@linux.alibaba.com \
    --to=chaowu@linux.alibaba.com \
    --cc=bp@alien8.de \
    --cc=gerry@linux.alibaba.com \
    --cc=kvm@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=richardcochran@gmail.com \
    --cc=tglx@linutronix.de \
    --cc=x86@kernel.org \
    --cc=zhabin@linux.alibaba.com \
    /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.