* [PATCH 1/5] x86/vmware: Make vmware_select_hypercall() __init
2020-03-20 20:34 [PATCH 0/5] x86/vmware: Steal time accounting support Alexey Makhalov
@ 2020-03-20 20:34 ` Alexey Makhalov
2020-03-20 20:34 ` [PATCH 2/5] x86/vmware: Remove vmware_sched_clock_setup() Alexey Makhalov
` (4 subsequent siblings)
5 siblings, 0 replies; 15+ messages in thread
From: Alexey Makhalov @ 2020-03-20 20:34 UTC (permalink / raw)
To: linux-x86_64
Cc: linux-kernel, Jonathan Corbet, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, H . Peter Anvin, Mauro Carvalho Chehab,
Josh Poimboeuf, Greg Kroah-Hartman, Pawan Gupta, Juergen Gross,
Alexey Makhalov
vmware_select_hypercall() is used only by the __init
functions, and should be annotated with __init as well.
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
---
arch/x86/kernel/cpu/vmware.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c
index 46d732696c1c..d280560fd75e 100644
--- a/arch/x86/kernel/cpu/vmware.c
+++ b/arch/x86/kernel/cpu/vmware.c
@@ -213,7 +213,7 @@ static void __init vmware_platform_setup(void)
vmware_set_capabilities();
}
-static u8 vmware_select_hypercall(void)
+static u8 __init vmware_select_hypercall(void)
{
int eax, ebx, ecx, edx;
--
2.14.2
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 2/5] x86/vmware: Remove vmware_sched_clock_setup()
2020-03-20 20:34 [PATCH 0/5] x86/vmware: Steal time accounting support Alexey Makhalov
2020-03-20 20:34 ` [PATCH 1/5] x86/vmware: Make vmware_select_hypercall() __init Alexey Makhalov
@ 2020-03-20 20:34 ` Alexey Makhalov
2020-03-20 20:34 ` [PATCH 3/5] x86/vmware: Steal time clock for VMware guest Alexey Makhalov
` (3 subsequent siblings)
5 siblings, 0 replies; 15+ messages in thread
From: Alexey Makhalov @ 2020-03-20 20:34 UTC (permalink / raw)
To: linux-x86_64
Cc: linux-kernel, Jonathan Corbet, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, H . Peter Anvin, Mauro Carvalho Chehab,
Josh Poimboeuf, Greg Kroah-Hartman, Pawan Gupta, Juergen Gross,
Alexey Makhalov
Move cyc2ns setup logic to separate function.
This separation will allow to use cyc2ns mult/shift pair
not only for the sched_clock but also for other clocks
such as steal_clock.
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
---
arch/x86/kernel/cpu/vmware.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c
index d280560fd75e..efb22fa76ba4 100644
--- a/arch/x86/kernel/cpu/vmware.c
+++ b/arch/x86/kernel/cpu/vmware.c
@@ -122,7 +122,7 @@ static unsigned long long notrace vmware_sched_clock(void)
return ns;
}
-static void __init vmware_sched_clock_setup(void)
+static void __init vmware_cyc2ns_setup(void)
{
struct cyc2ns_data *d = &vmware_cyc2ns;
unsigned long long tsc_now = rdtsc();
@@ -132,8 +132,7 @@ static void __init vmware_sched_clock_setup(void)
d->cyc2ns_offset = mul_u64_u32_shr(tsc_now, d->cyc2ns_mul,
d->cyc2ns_shift);
- pv_ops.time.sched_clock = vmware_sched_clock;
- pr_info("using sched offset of %llu ns\n", d->cyc2ns_offset);
+ pr_info("using clock offset of %llu ns\n", d->cyc2ns_offset);
}
static void __init vmware_paravirt_ops_setup(void)
@@ -141,8 +140,14 @@ static void __init vmware_paravirt_ops_setup(void)
pv_info.name = "VMware hypervisor";
pv_ops.cpu.io_delay = paravirt_nop;
- if (vmware_tsc_khz && vmw_sched_clock)
- vmware_sched_clock_setup();
+ if (vmware_tsc_khz == 0)
+ return;
+
+ vmware_cyc2ns_setup();
+
+ if (vmw_sched_clock)
+ pv_ops.time.sched_clock = vmware_sched_clock;
+
}
#else
#define vmware_paravirt_ops_setup() do {} while (0)
--
2.14.2
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 3/5] x86/vmware: Steal time clock for VMware guest
2020-03-20 20:34 [PATCH 0/5] x86/vmware: Steal time accounting support Alexey Makhalov
2020-03-20 20:34 ` [PATCH 1/5] x86/vmware: Make vmware_select_hypercall() __init Alexey Makhalov
2020-03-20 20:34 ` [PATCH 2/5] x86/vmware: Remove vmware_sched_clock_setup() Alexey Makhalov
@ 2020-03-20 20:34 ` Alexey Makhalov
2020-03-21 6:19 ` kbuild test robot
2020-03-21 10:04 ` kbuild test robot
2020-03-20 20:34 ` [PATCH 4/5] x86/vmware: Enable steal time accounting Alexey Makhalov
` (2 subsequent siblings)
5 siblings, 2 replies; 15+ messages in thread
From: Alexey Makhalov @ 2020-03-20 20:34 UTC (permalink / raw)
To: linux-x86_64
Cc: linux-kernel, Jonathan Corbet, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, H . Peter Anvin, Mauro Carvalho Chehab,
Josh Poimboeuf, Greg Kroah-Hartman, Pawan Gupta, Juergen Gross,
Alexey Makhalov, Tomer Zeltzer
Steal time is the amount of CPU time needed by a guest
virtual machine that is not provided by the host. Steal
time occurs when the host allocates this CPU time
elsewhere: for example, to another guest.
Steal time can be enabled by adding VM configuration option
stealclock.enable = "TRUE". It is supported by VMs that run
hardware version 13 or newer.
This change introduces the VMware steal time infrastructure.
The high level code (such as enabling, disabling and
hot-plug routines) was derived from KVM one.
[Tomer: use READ_ONCE macros and 32bit guests support]
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
Co-developed-by: Tomer Zeltzer <tomerr90@gmail.com>
Signed-off-by: Tomer Zeltzer <tomerr90@gmail.com>
Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
---
arch/x86/kernel/cpu/vmware.c | 197 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 197 insertions(+)
diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c
index efb22fa76ba4..59459992ad47 100644
--- a/arch/x86/kernel/cpu/vmware.c
+++ b/arch/x86/kernel/cpu/vmware.c
@@ -25,6 +25,8 @@
#include <linux/init.h>
#include <linux/export.h>
#include <linux/clocksource.h>
+#include <linux/cpu.h>
+#include <linux/reboot.h>
#include <asm/div64.h>
#include <asm/x86_init.h>
#include <asm/hypervisor.h>
@@ -47,6 +49,11 @@
#define VMWARE_CMD_GETVCPU_INFO 68
#define VMWARE_CMD_LEGACY_X2APIC 3
#define VMWARE_CMD_VCPU_RESERVED 31
+#define VMWARE_CMD_STEALCLOCK 91
+
+#define STEALCLOCK_NOT_AVAILABLE (-1)
+#define STEALCLOCK_DISABLED 0
+#define STEALCLOCK_ENABLED 1
#define VMWARE_PORT(cmd, eax, ebx, ecx, edx) \
__asm__("inl (%%dx), %%eax" : \
@@ -86,6 +93,18 @@
} \
} while (0)
+struct vmware_steal_time {
+ union {
+ uint64_t clock; /* stolen time counter in units of vtsc */
+ struct {
+ /* only for little-endian */
+ uint32_t clock_low;
+ uint32_t clock_high;
+ };
+ };
+ uint64_t reserved[7];
+};
+
static unsigned long vmware_tsc_khz __ro_after_init;
static u8 vmware_hypercall_mode __ro_after_init;
@@ -104,6 +123,8 @@ static unsigned long vmware_get_tsc_khz(void)
#ifdef CONFIG_PARAVIRT
static struct cyc2ns_data vmware_cyc2ns __ro_after_init;
static int vmw_sched_clock __initdata = 1;
+static DEFINE_PER_CPU_DECRYPTED(struct vmware_steal_time, steal_time) __aligned(64);
+static bool has_steal_clock;
static __init int setup_vmw_sched_clock(char *s)
{
@@ -135,6 +156,163 @@ static void __init vmware_cyc2ns_setup(void)
pr_info("using clock offset of %llu ns\n", d->cyc2ns_offset);
}
+static int vmware_cmd_stealclock(uint32_t arg1, uint32_t arg2)
+{
+ uint32_t result, info;
+
+ asm volatile (VMWARE_HYPERCALL :
+ "=a"(result),
+ "=c"(info) :
+ "a"(VMWARE_HYPERVISOR_MAGIC),
+ "b"(0),
+ "c"(VMWARE_CMD_STEALCLOCK),
+ "d"(0),
+ "S"(arg1),
+ "D"(arg2) :
+ "memory");
+ return result;
+}
+
+static bool stealclock_enable(phys_addr_t pa)
+{
+ return vmware_cmd_stealclock(upper_32_bits(pa),
+ lower_32_bits(pa)) == STEALCLOCK_ENABLED;
+}
+
+static int __stealclock_disable(void)
+{
+ return vmware_cmd_stealclock(0, 1);
+}
+
+static void stealclock_disable(void)
+{
+ __stealclock_disable();
+}
+
+static bool vmware_is_stealclock_available(void)
+{
+ return __stealclock_disable() != STEALCLOCK_NOT_AVAILABLE;
+}
+
+/**
+ * vmware_steal_clock() - read the per-cpu steal clock
+ * @cpu: the cpu number whose steal clock we want to read
+ *
+ * The function reads the steal clock if we are on a 64-bit system, otherwise
+ * reads it in parts, checking that the high part didn't change in the
+ * meantime.
+ *
+ * Return:
+ * The steal clock reading in ns.
+ */
+static uint64_t vmware_steal_clock(int cpu)
+{
+ struct vmware_steal_time *steal = &per_cpu(steal_time, cpu);
+ uint64_t clock;
+
+ if (IS_ENABLED(CONFIG_64BIT))
+ clock = READ_ONCE(steal->clock);
+ else {
+ uint32_t initial_high, low, high;
+
+ do {
+ initial_high = READ_ONCE(steal->clock_high);
+ /* Do not reorder initial_high and high readings */
+ virt_rmb();
+ low = READ_ONCE(steal->clock_low);
+ /* Keep low reading in between */
+ virt_rmb();
+ high = READ_ONCE(steal->clock_high);
+ } while (initial_high != high);
+
+ clock = ((uint64_t)high << 32) | low;
+ }
+
+ return mul_u64_u32_shr(clock, vmware_cyc2ns.cyc2ns_mul,
+ vmware_cyc2ns.cyc2ns_shift);
+}
+
+static void vmware_register_steal_time(void)
+{
+ int cpu = smp_processor_id();
+ struct vmware_steal_time *st = &per_cpu(steal_time, cpu);
+
+ if (!has_steal_clock)
+ return;
+
+ if (!stealclock_enable(slow_virt_to_phys(st))) {
+ has_steal_clock = false;
+ return;
+ }
+
+ pr_info("vmware-stealtime: cpu %d, pa %llx\n",
+ cpu, (unsigned long long) slow_virt_to_phys(st));
+}
+
+static void vmware_disable_steal_time(void)
+{
+ if (!has_steal_clock)
+ return;
+
+ stealclock_disable();
+}
+
+static void vmware_guest_cpu_init(void)
+{
+ if (has_steal_clock)
+ vmware_register_steal_time();
+}
+
+static void vmware_pv_guest_cpu_reboot(void *unused)
+{
+ vmware_disable_steal_time();
+}
+
+static int vmware_pv_reboot_notify(struct notifier_block *nb,
+ unsigned long code, void *unused)
+{
+ if (code == SYS_RESTART)
+ on_each_cpu(vmware_pv_guest_cpu_reboot, NULL, 1);
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block vmware_pv_reboot_nb = {
+ .notifier_call = vmware_pv_reboot_notify,
+};
+
+#ifdef CONFIG_SMP
+static void __init vmware_smp_prepare_boot_cpu(void)
+{
+ vmware_guest_cpu_init();
+ native_smp_prepare_boot_cpu();
+}
+
+static int vmware_cpu_online(unsigned int cpu)
+{
+ local_irq_disable();
+ vmware_guest_cpu_init();
+ local_irq_enable();
+ return 0;
+}
+
+static int vmware_cpu_down_prepare(unsigned int cpu)
+{
+ local_irq_disable();
+ vmware_disable_steal_time();
+ local_irq_enable();
+ return 0;
+}
+#endif
+
+static __init int activate_jump_labels(void)
+{
+ if (has_steal_clock)
+ static_key_slow_inc(¶virt_steal_enabled);
+
+ return 0;
+}
+arch_initcall(activate_jump_labels);
+
static void __init vmware_paravirt_ops_setup(void)
{
pv_info.name = "VMware hypervisor";
@@ -148,6 +326,25 @@ static void __init vmware_paravirt_ops_setup(void)
if (vmw_sched_clock)
pv_ops.time.sched_clock = vmware_sched_clock;
+ if (vmware_is_stealclock_available()) {
+ has_steal_clock = true;
+ pv_ops.time.steal_clock = vmware_steal_clock;
+
+ /* We use reboot notifier only to disable steal clock */
+ register_reboot_notifier(&vmware_pv_reboot_nb);
+
+#ifdef CONFIG_SMP
+ smp_ops.smp_prepare_boot_cpu =
+ vmware_smp_prepare_boot_cpu;
+ if (cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
+ "x86/vmware:online",
+ vmware_cpu_online,
+ vmware_cpu_down_prepare) < 0)
+ pr_err("vmware_guest: Failed to install cpu hotplug callbacks\n");
+#else
+ vmware_guest_cpu_init();
+#endif
+ }
}
#else
#define vmware_paravirt_ops_setup() do {} while (0)
--
2.14.2
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH 3/5] x86/vmware: Steal time clock for VMware guest
2020-03-20 20:34 ` [PATCH 3/5] x86/vmware: Steal time clock for VMware guest Alexey Makhalov
@ 2020-03-21 6:19 ` kbuild test robot
2020-03-21 10:04 ` kbuild test robot
1 sibling, 0 replies; 15+ messages in thread
From: kbuild test robot @ 2020-03-21 6:19 UTC (permalink / raw)
To: Alexey Makhalov
Cc: kbuild-all, linux-x86_64, linux-kernel@vger.kernel.org,
Jonathan Corbet, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
H . Peter Anvin, Mauro Carvalho Chehab, Josh Poimboeuf,
Greg Kroah-Hartman, Pawan Gupta, Juergen Gross, Alexey Makhalov,
Tomer Zeltzer, linux-media
[-- Attachment #1: Type: text/plain, Size: 1312 bytes --]
Hi Alexey,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on tip/x86/core]
[also build test ERROR on tip/auto-latest linux/master linus/master v5.6-rc6 next-20200320]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]
url: https://github.com/0day-ci/linux/commits/Alexey-Makhalov/x86-vmware-Steal-time-accounting-support/20200321-050449
base: https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git 248ed51048c40d36728e70914e38bffd7821da57
config: x86_64-randconfig-s1-20200321 (attached as .config)
compiler: gcc-5 (Ubuntu 5.5.0-12ubuntu1) 5.5.0 20171010
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
>> ld: arch/x86/kernel/kvm.o:arch/x86/kernel/kvm.c:58: multiple definition of `__pcpu_unique_steal_time'; arch/x86/kernel/cpu/vmware.o:arch/x86/kernel/cpu/vmware.c:126: first defined here
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 32158 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 3/5] x86/vmware: Steal time clock for VMware guest
2020-03-20 20:34 ` [PATCH 3/5] x86/vmware: Steal time clock for VMware guest Alexey Makhalov
@ 2020-03-21 10:04 ` kbuild test robot
2020-03-21 10:04 ` kbuild test robot
1 sibling, 0 replies; 15+ messages in thread
From: kbuild test robot @ 2020-03-21 10:04 UTC (permalink / raw)
To: Alexey Makhalov
Cc: kbuild-all, linux-x86_64, linux-kernel@vger.kernel.org,
Jonathan Corbet, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
H . Peter Anvin, Mauro Carvalho Chehab, Josh Poimboeuf,
Greg Kroah-Hartman, Pawan Gupta, Juergen Gross, Alexey Makhalov,
Tomer Zeltzer, linux-media
[-- Attachment #1: Type: text/plain, Size: 1269 bytes --]
Hi Alexey,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on tip/x86/core]
[also build test ERROR on tip/auto-latest linux/master linus/master v5.6-rc6 next-20200320]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]
url: https://github.com/0day-ci/linux/commits/Alexey-Makhalov/x86-vmware-Steal-time-accounting-support/20200321-050449
base: https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git 248ed51048c40d36728e70914e38bffd7821da57
config: x86_64-randconfig-g002-20200320 (attached as .config)
compiler: gcc-7 (Debian 7.5.0-5) 7.5.0
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
>> ld: arch/x86/kernel/kvm.o:(.discard+0x2): multiple definition of `__pcpu_unique_steal_time'; arch/x86/kernel/cpu/vmware.o:(.discard+0x0): first defined here
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 35650 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 4/5] x86/vmware: Enable steal time accounting
2020-03-20 20:34 [PATCH 0/5] x86/vmware: Steal time accounting support Alexey Makhalov
` (2 preceding siblings ...)
2020-03-20 20:34 ` [PATCH 3/5] x86/vmware: Steal time clock for VMware guest Alexey Makhalov
@ 2020-03-20 20:34 ` Alexey Makhalov
2020-03-20 20:34 ` [PATCH 5/5] x86/vmware: Use bool type for vmw_sched_clock Alexey Makhalov
2020-03-20 20:59 ` [PATCH 0/5] x86/vmware: Steal time accounting support Borislav Petkov
5 siblings, 0 replies; 15+ messages in thread
From: Alexey Makhalov @ 2020-03-20 20:34 UTC (permalink / raw)
To: linux-x86_64
Cc: linux-kernel, Jonathan Corbet, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, H . Peter Anvin, Mauro Carvalho Chehab,
Josh Poimboeuf, Greg Kroah-Hartman, Pawan Gupta, Juergen Gross,
Alexey Makhalov
Set paravirt_steal_rq_enabled if steal clock present.
paravirt_steal_rq_enabled is used in sched/core.c to
adjust task progress by offsetting stolen time.
Use 'no-steal-acc' off switch (share same name with KVM)
to disable steal time accounting.
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
---
Documentation/admin-guide/kernel-parameters.txt | 2 +-
arch/x86/kernel/cpu/vmware.c | 13 ++++++++++++-
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 87176a90e61a..07fbdccdd77c 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -3152,7 +3152,7 @@
[X86,PV_OPS] Disable paravirtualized VMware scheduler
clock and use the default one.
- no-steal-acc [X86,KVM,ARM64] Disable paravirtualized steal time
+ no-steal-acc [X86,PV_OPS,ARM64] Disable paravirtualized steal time
accounting. steal time is computed, but won't
influence scheduler behaviour
diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c
index 59459992ad47..0c65d661d88b 100644
--- a/arch/x86/kernel/cpu/vmware.c
+++ b/arch/x86/kernel/cpu/vmware.c
@@ -125,6 +125,7 @@ static struct cyc2ns_data vmware_cyc2ns __ro_after_init;
static int vmw_sched_clock __initdata = 1;
static DEFINE_PER_CPU_DECRYPTED(struct vmware_steal_time, steal_time) __aligned(64);
static bool has_steal_clock;
+static bool steal_acc __initdata = true; /* steal time accounting */
static __init int setup_vmw_sched_clock(char *s)
{
@@ -133,6 +134,13 @@ static __init int setup_vmw_sched_clock(char *s)
}
early_param("no-vmw-sched-clock", setup_vmw_sched_clock);
+static __init int parse_no_stealacc(char *arg)
+{
+ steal_acc = false;
+ return 0;
+}
+early_param("no-steal-acc", parse_no_stealacc);
+
static unsigned long long notrace vmware_sched_clock(void)
{
unsigned long long ns;
@@ -306,8 +314,11 @@ static int vmware_cpu_down_prepare(unsigned int cpu)
static __init int activate_jump_labels(void)
{
- if (has_steal_clock)
+ if (has_steal_clock) {
static_key_slow_inc(¶virt_steal_enabled);
+ if (steal_acc)
+ static_key_slow_inc(¶virt_steal_rq_enabled);
+ }
return 0;
}
--
2.14.2
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 5/5] x86/vmware: Use bool type for vmw_sched_clock
2020-03-20 20:34 [PATCH 0/5] x86/vmware: Steal time accounting support Alexey Makhalov
` (3 preceding siblings ...)
2020-03-20 20:34 ` [PATCH 4/5] x86/vmware: Enable steal time accounting Alexey Makhalov
@ 2020-03-20 20:34 ` Alexey Makhalov
2020-03-20 20:59 ` [PATCH 0/5] x86/vmware: Steal time accounting support Borislav Petkov
5 siblings, 0 replies; 15+ messages in thread
From: Alexey Makhalov @ 2020-03-20 20:34 UTC (permalink / raw)
To: linux-x86_64
Cc: linux-kernel, Jonathan Corbet, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, H . Peter Anvin, Mauro Carvalho Chehab,
Josh Poimboeuf, Greg Kroah-Hartman, Pawan Gupta, Juergen Gross,
Alexey Makhalov
To be aligned with other bool variables.
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
---
arch/x86/kernel/cpu/vmware.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c
index 0c65d661d88b..54e57931051d 100644
--- a/arch/x86/kernel/cpu/vmware.c
+++ b/arch/x86/kernel/cpu/vmware.c
@@ -122,14 +122,14 @@ static unsigned long vmware_get_tsc_khz(void)
#ifdef CONFIG_PARAVIRT
static struct cyc2ns_data vmware_cyc2ns __ro_after_init;
-static int vmw_sched_clock __initdata = 1;
+static bool vmw_sched_clock __initdata = true;
static DEFINE_PER_CPU_DECRYPTED(struct vmware_steal_time, steal_time) __aligned(64);
static bool has_steal_clock;
static bool steal_acc __initdata = true; /* steal time accounting */
static __init int setup_vmw_sched_clock(char *s)
{
- vmw_sched_clock = 0;
+ vmw_sched_clock = false;
return 0;
}
early_param("no-vmw-sched-clock", setup_vmw_sched_clock);
--
2.14.2
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH 0/5] x86/vmware: Steal time accounting support
2020-03-20 20:34 [PATCH 0/5] x86/vmware: Steal time accounting support Alexey Makhalov
` (4 preceding siblings ...)
2020-03-20 20:34 ` [PATCH 5/5] x86/vmware: Use bool type for vmw_sched_clock Alexey Makhalov
@ 2020-03-20 20:59 ` Borislav Petkov
2020-03-20 21:06 ` Alexey Makhalov
5 siblings, 1 reply; 15+ messages in thread
From: Borislav Petkov @ 2020-03-20 20:59 UTC (permalink / raw)
To: Alexey Makhalov
Cc: linux-x86_64, linux-kernel, Jonathan Corbet, Thomas Gleixner,
Ingo Molnar, H . Peter Anvin, Mauro Carvalho Chehab,
Josh Poimboeuf, Greg Kroah-Hartman, Pawan Gupta, Juergen Gross
On Fri, Mar 20, 2020 at 08:34:38PM +0000, Alexey Makhalov wrote:
> Hello,
>
> This patchset introduces steal time accounting support for
> the VMware guest. The idea and implementation of guest
> steal time support is similar to KVM ones and it is based
> on steal clock. The steal clock is a per CPU structure in
> a shared memory between hypervisor and guest, initialized
> by each CPU through hypercall. Steal clock is got updated
> by the hypervisor and read by the guest.
...
> Documentation/admin-guide/kernel-parameters.txt | 2 +-
> arch/x86/kernel/cpu/vmware.c | 227 +++++++++++++++++++++++-
> 2 files changed, 220 insertions(+), 9 deletions(-)
Did you not see my reply to you the last time?
https://marc.info/?l=linux-virtualization&m=158410546921328
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 0/5] x86/vmware: Steal time accounting support
2020-03-20 20:59 ` [PATCH 0/5] x86/vmware: Steal time accounting support Borislav Petkov
@ 2020-03-20 21:06 ` Alexey Makhalov
2020-03-20 21:16 ` Borislav Petkov
0 siblings, 1 reply; 15+ messages in thread
From: Alexey Makhalov @ 2020-03-20 21:06 UTC (permalink / raw)
To: Borislav Petkov
Cc: linux-x86_64, linux-kernel, Jonathan Corbet, Thomas Gleixner,
Ingo Molnar, H . Peter Anvin, Mauro Carvalho Chehab,
Josh Poimboeuf, Greg Kroah-Hartman, Pawan Gupta, Juergen Gross
Hi Borislav,
I didn't receive any response first time. I'm not on the list.
Thanks for reporting i386 issue. I'll address it in v2.
Regards,
--Alexey
On 3/20/20, 1:59 PM, "Borislav Petkov" <bp@alien8.de> wrote:
On Fri, Mar 20, 2020 at 08:34:38PM +0000, Alexey Makhalov wrote:
> Hello,
>
> This patchset introduces steal time accounting support for
> the VMware guest. The idea and implementation of guest
> steal time support is similar to KVM ones and it is based
> on steal clock. The steal clock is a per CPU structure in
> a shared memory between hypervisor and guest, initialized
> by each CPU through hypercall. Steal clock is got updated
> by the hypervisor and read by the guest.
...
> Documentation/admin-guide/kernel-parameters.txt | 2 +-
> arch/x86/kernel/cpu/vmware.c | 227 +++++++++++++++++++++++-
> 2 files changed, 220 insertions(+), 9 deletions(-)
Did you not see my reply to you the last time?
https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmarc.info%2F%3Fl%3Dlinux-virtualization%26m%3D158410546921328&data=02%7C01%7Camakhalov%40vmware.com%7Cf91e8ea6a80f43f4867408d7cd1192d3%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C0%7C0%7C637203347695264396&sdata=DjWJo0H%2Bu6tIerl%2B0P%2Frt5uQTrIV67wsf3LbrIKS3fI%3D&reserved=0
--
Regards/Gruss,
Boris.
https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpeople.kernel.org%2Ftglx%2Fnotes-about-netiquette&data=02%7C01%7Camakhalov%40vmware.com%7Cf91e8ea6a80f43f4867408d7cd1192d3%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C0%7C0%7C637203347695264396&sdata=eZ6oXYdeB3FhpQ30IvBmjHhED0F1RHbUy0%2BgLFvvqt4%3D&reserved=0
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 0/5] x86/vmware: Steal time accounting support
2020-03-20 21:06 ` Alexey Makhalov
@ 2020-03-20 21:16 ` Borislav Petkov
2020-03-20 21:26 ` Alexey Makhalov
0 siblings, 1 reply; 15+ messages in thread
From: Borislav Petkov @ 2020-03-20 21:16 UTC (permalink / raw)
To: Alexey Makhalov
Cc: linux-x86_64, linux-kernel, Jonathan Corbet, Thomas Gleixner,
Ingo Molnar, H . Peter Anvin, Mauro Carvalho Chehab,
Josh Poimboeuf, Greg Kroah-Hartman, Pawan Gupta, Juergen Gross
On Fri, Mar 20, 2020 at 09:06:57PM +0000, Alexey Makhalov wrote:
> I didn't receive any response first time. I'm not on the list.
The mail was sent to you directly:
Date: Fri, 13 Mar 2020 14:17:42 +0100
From: Borislav Petkov <bp@alien8.de>
To: Alexey Makhalov <amakhalov@vmware.com>
....
Perhaps in your spam folder.
Did you, per chance, receive this reply:
https://marc.info/?l=linux-virtualization&m=158403993331603&w=2
?
> Thanks for reporting i386 issue. I'll address it in v2.
Thx.
Btw, please do not top-post.
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 0/5] x86/vmware: Steal time accounting support
2020-03-20 21:16 ` Borislav Petkov
@ 2020-03-20 21:26 ` Alexey Makhalov
0 siblings, 0 replies; 15+ messages in thread
From: Alexey Makhalov @ 2020-03-20 21:26 UTC (permalink / raw)
To: Borislav Petkov
Cc: linux-x86_64, linux-kernel, Jonathan Corbet, Thomas Gleixner,
Ingo Molnar, H . Peter Anvin, Mauro Carvalho Chehab,
Josh Poimboeuf, Greg Kroah-Hartman, Pawan Gupta, Juergen Gross
[-- Attachment #1: Type: text/plain, Size: 623 bytes --]
> Perhaps in your spam folder.
Not in spam/junk folder
> Did you, per chance, receive this reply:
>
> https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmarc.info%2F%3Fl%3Dlinux-virtualization%26m%3D158403993331603%26w%3D2&data=02%7C01%7Camakhalov%40vmware.com%7Cd6008c5deddf4d17315b08d7cd13f322%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C0%7C0%7C637203357928546249&sdata=CrOJhbOoIutstB9FYIvZ9Orrl3Xp3JmZSk%2BM6xODGOk%3D&reserved=0
>
> ?
Got it from marc.info web page you pointed out. I will address is as well.
> Btw, please do not top-post.
>
Thanks for the hint.
—Alexey
[-- Attachment #2: Message signed with OpenPGP --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 3/5] x86/vmware: Steal time clock for VMware guest
2020-02-12 20:03 Alexey Makhalov via Virtualization
@ 2020-02-12 20:03 ` Alexey Makhalov via Virtualization
0 siblings, 0 replies; 15+ messages in thread
From: Alexey Makhalov via Virtualization @ 2020-02-12 20:03 UTC (permalink / raw)
To: x86
Cc: Juergen Gross, Alexey Makhalov, Jonathan Corbet, VMware, Inc.,
Greg Kroah-Hartman, Josh Poimboeuf, virtualization, Ingo Molnar,
Borislav Petkov, H . Peter Anvin, Mauro Carvalho Chehab,
Pawan Gupta, Thomas Gleixner, Tomer Zeltzer
Steal time is the amount of CPU time needed by a guest
virtual machine that is not provided by the host. Steal
time occurs when the host allocates this CPU time
elsewhere: for example, to another guest.
Steal time can be enabled by adding VM configuration option
stealclock.enable = "TRUE". It is supported by VMs that run
hardware version 13 or newer.
This change introduces the VMware steal time infrastructure.
The high level code (such as enabling, disabling and
hot-plug routines) was derived from KVM one.
[Tomer: use READ_ONCE macros and 32bit guests support]
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
Co-developed-by: Tomer Zeltzer <tomerr90@gmail.com>
Signed-off-by: Tomer Zeltzer <tomerr90@gmail.com>
Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
---
arch/x86/kernel/cpu/vmware.c | 197 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 197 insertions(+)
diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c
index efb22fa76ba4..59459992ad47 100644
--- a/arch/x86/kernel/cpu/vmware.c
+++ b/arch/x86/kernel/cpu/vmware.c
@@ -25,6 +25,8 @@
#include <linux/init.h>
#include <linux/export.h>
#include <linux/clocksource.h>
+#include <linux/cpu.h>
+#include <linux/reboot.h>
#include <asm/div64.h>
#include <asm/x86_init.h>
#include <asm/hypervisor.h>
@@ -47,6 +49,11 @@
#define VMWARE_CMD_GETVCPU_INFO 68
#define VMWARE_CMD_LEGACY_X2APIC 3
#define VMWARE_CMD_VCPU_RESERVED 31
+#define VMWARE_CMD_STEALCLOCK 91
+
+#define STEALCLOCK_NOT_AVAILABLE (-1)
+#define STEALCLOCK_DISABLED 0
+#define STEALCLOCK_ENABLED 1
#define VMWARE_PORT(cmd, eax, ebx, ecx, edx) \
__asm__("inl (%%dx), %%eax" : \
@@ -86,6 +93,18 @@
} \
} while (0)
+struct vmware_steal_time {
+ union {
+ uint64_t clock; /* stolen time counter in units of vtsc */
+ struct {
+ /* only for little-endian */
+ uint32_t clock_low;
+ uint32_t clock_high;
+ };
+ };
+ uint64_t reserved[7];
+};
+
static unsigned long vmware_tsc_khz __ro_after_init;
static u8 vmware_hypercall_mode __ro_after_init;
@@ -104,6 +123,8 @@ static unsigned long vmware_get_tsc_khz(void)
#ifdef CONFIG_PARAVIRT
static struct cyc2ns_data vmware_cyc2ns __ro_after_init;
static int vmw_sched_clock __initdata = 1;
+static DEFINE_PER_CPU_DECRYPTED(struct vmware_steal_time, steal_time) __aligned(64);
+static bool has_steal_clock;
static __init int setup_vmw_sched_clock(char *s)
{
@@ -135,6 +156,163 @@ static void __init vmware_cyc2ns_setup(void)
pr_info("using clock offset of %llu ns\n", d->cyc2ns_offset);
}
+static int vmware_cmd_stealclock(uint32_t arg1, uint32_t arg2)
+{
+ uint32_t result, info;
+
+ asm volatile (VMWARE_HYPERCALL :
+ "=a"(result),
+ "=c"(info) :
+ "a"(VMWARE_HYPERVISOR_MAGIC),
+ "b"(0),
+ "c"(VMWARE_CMD_STEALCLOCK),
+ "d"(0),
+ "S"(arg1),
+ "D"(arg2) :
+ "memory");
+ return result;
+}
+
+static bool stealclock_enable(phys_addr_t pa)
+{
+ return vmware_cmd_stealclock(upper_32_bits(pa),
+ lower_32_bits(pa)) == STEALCLOCK_ENABLED;
+}
+
+static int __stealclock_disable(void)
+{
+ return vmware_cmd_stealclock(0, 1);
+}
+
+static void stealclock_disable(void)
+{
+ __stealclock_disable();
+}
+
+static bool vmware_is_stealclock_available(void)
+{
+ return __stealclock_disable() != STEALCLOCK_NOT_AVAILABLE;
+}
+
+/**
+ * vmware_steal_clock() - read the per-cpu steal clock
+ * @cpu: the cpu number whose steal clock we want to read
+ *
+ * The function reads the steal clock if we are on a 64-bit system, otherwise
+ * reads it in parts, checking that the high part didn't change in the
+ * meantime.
+ *
+ * Return:
+ * The steal clock reading in ns.
+ */
+static uint64_t vmware_steal_clock(int cpu)
+{
+ struct vmware_steal_time *steal = &per_cpu(steal_time, cpu);
+ uint64_t clock;
+
+ if (IS_ENABLED(CONFIG_64BIT))
+ clock = READ_ONCE(steal->clock);
+ else {
+ uint32_t initial_high, low, high;
+
+ do {
+ initial_high = READ_ONCE(steal->clock_high);
+ /* Do not reorder initial_high and high readings */
+ virt_rmb();
+ low = READ_ONCE(steal->clock_low);
+ /* Keep low reading in between */
+ virt_rmb();
+ high = READ_ONCE(steal->clock_high);
+ } while (initial_high != high);
+
+ clock = ((uint64_t)high << 32) | low;
+ }
+
+ return mul_u64_u32_shr(clock, vmware_cyc2ns.cyc2ns_mul,
+ vmware_cyc2ns.cyc2ns_shift);
+}
+
+static void vmware_register_steal_time(void)
+{
+ int cpu = smp_processor_id();
+ struct vmware_steal_time *st = &per_cpu(steal_time, cpu);
+
+ if (!has_steal_clock)
+ return;
+
+ if (!stealclock_enable(slow_virt_to_phys(st))) {
+ has_steal_clock = false;
+ return;
+ }
+
+ pr_info("vmware-stealtime: cpu %d, pa %llx\n",
+ cpu, (unsigned long long) slow_virt_to_phys(st));
+}
+
+static void vmware_disable_steal_time(void)
+{
+ if (!has_steal_clock)
+ return;
+
+ stealclock_disable();
+}
+
+static void vmware_guest_cpu_init(void)
+{
+ if (has_steal_clock)
+ vmware_register_steal_time();
+}
+
+static void vmware_pv_guest_cpu_reboot(void *unused)
+{
+ vmware_disable_steal_time();
+}
+
+static int vmware_pv_reboot_notify(struct notifier_block *nb,
+ unsigned long code, void *unused)
+{
+ if (code == SYS_RESTART)
+ on_each_cpu(vmware_pv_guest_cpu_reboot, NULL, 1);
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block vmware_pv_reboot_nb = {
+ .notifier_call = vmware_pv_reboot_notify,
+};
+
+#ifdef CONFIG_SMP
+static void __init vmware_smp_prepare_boot_cpu(void)
+{
+ vmware_guest_cpu_init();
+ native_smp_prepare_boot_cpu();
+}
+
+static int vmware_cpu_online(unsigned int cpu)
+{
+ local_irq_disable();
+ vmware_guest_cpu_init();
+ local_irq_enable();
+ return 0;
+}
+
+static int vmware_cpu_down_prepare(unsigned int cpu)
+{
+ local_irq_disable();
+ vmware_disable_steal_time();
+ local_irq_enable();
+ return 0;
+}
+#endif
+
+static __init int activate_jump_labels(void)
+{
+ if (has_steal_clock)
+ static_key_slow_inc(¶virt_steal_enabled);
+
+ return 0;
+}
+arch_initcall(activate_jump_labels);
+
static void __init vmware_paravirt_ops_setup(void)
{
pv_info.name = "VMware hypervisor";
@@ -148,6 +326,25 @@ static void __init vmware_paravirt_ops_setup(void)
if (vmw_sched_clock)
pv_ops.time.sched_clock = vmware_sched_clock;
+ if (vmware_is_stealclock_available()) {
+ has_steal_clock = true;
+ pv_ops.time.steal_clock = vmware_steal_clock;
+
+ /* We use reboot notifier only to disable steal clock */
+ register_reboot_notifier(&vmware_pv_reboot_nb);
+
+#ifdef CONFIG_SMP
+ smp_ops.smp_prepare_boot_cpu =
+ vmware_smp_prepare_boot_cpu;
+ if (cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
+ "x86/vmware:online",
+ vmware_cpu_online,
+ vmware_cpu_down_prepare) < 0)
+ pr_err("vmware_guest: Failed to install cpu hotplug callbacks\n");
+#else
+ vmware_guest_cpu_init();
+#endif
+ }
}
#else
#define vmware_paravirt_ops_setup() do {} while (0)
--
2.14.2
^ permalink raw reply related [flat|nested] 15+ messages in thread