Skip to content

Commit

Permalink
KVM: kvmclock: Fix vCPUs > 64 can't be online/hotpluged
Browse files Browse the repository at this point in the history
commit d7eb79c upstream.

# lscpu
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                88
On-line CPU(s) list:   0-63
Off-line CPU(s) list:  64-87

# cat /proc/cmdline
BOOT_IMAGE=/vmlinuz-5.10.0-rc3-tlinux2-0050+ root=/dev/mapper/cl-root ro
rd.lvm.lv=cl/root rhgb quiet console=ttyS0 LANG=en_US .UTF-8 no-kvmclock-vsyscall

# echo 1 > /sys/devices/system/cpu/cpu76/online
-bash: echo: write error: Cannot allocate memory

The per-cpu vsyscall pvclock data pointer assigns either an element of the
static array hv_clock_boot (#vCPU <= 64) or dynamically allocated memory
hvclock_mem (vCPU > 64), the dynamically memory will not be allocated if
kvmclock vsyscall is disabled, this can result in cpu hotpluged fails in
kvmclock_setup_percpu() which returns -ENOMEM. It's broken for no-vsyscall
and sometimes you end up with vsyscall disabled if the host does something
strange. This patch fixes it by allocating this dynamically memory
unconditionally even if vsyscall is disabled.

Fixes: 6a1cac5 ("x86/kvm: Use __bss_decrypted attribute in shared variables")
Reported-by: Zelin Deng <zelin.deng@linux.alibaba.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: stable@vger.kernel.org#v4.19-rc5+
Signed-off-by: Wanpeng Li <wanpengli@tencent.com>
Message-Id: <1614130683-24137-1-git-send-email-wanpengli@tencent.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Wanpeng Li authored and gregkh committed Mar 17, 2021
1 parent 4ab5d1b commit a688bf8
Showing 1 changed file with 9 additions and 10 deletions.
19 changes: 9 additions & 10 deletions arch/x86/kernel/kvmclock.c
Expand Up @@ -269,21 +269,20 @@ static void __init kvmclock_init_mem(void)

static int __init kvm_setup_vsyscall_timeinfo(void)
{
#ifdef CONFIG_X86_64
u8 flags;
kvmclock_init_mem();

if (!per_cpu(hv_clock_per_cpu, 0) || !kvmclock_vsyscall)
return 0;
#ifdef CONFIG_X86_64
if (per_cpu(hv_clock_per_cpu, 0) && kvmclock_vsyscall) {
u8 flags;

flags = pvclock_read_flags(&hv_clock_boot[0].pvti);
if (!(flags & PVCLOCK_TSC_STABLE_BIT))
return 0;
flags = pvclock_read_flags(&hv_clock_boot[0].pvti);
if (!(flags & PVCLOCK_TSC_STABLE_BIT))
return 0;

kvm_clock.vdso_clock_mode = VDSO_CLOCKMODE_PVCLOCK;
kvm_clock.vdso_clock_mode = VDSO_CLOCKMODE_PVCLOCK;
}
#endif

kvmclock_init_mem();

return 0;
}
early_initcall(kvm_setup_vsyscall_timeinfo);
Expand Down

0 comments on commit a688bf8

Please sign in to comment.