Change-Id: I48a17bcb876d1494d0bfed6969ad9cb0ce41ed8a
Extras:
linux: do not panic on `modprobe tcrypt` in fips mode
linux-esx: add vclock capatability to clocksource_vmware
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/3451
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: Sharath George
| ... | ... |
@@ -1,361 +1,36 @@ |
| 1 |
-From 6021a95a6b7ffb8df8823337d4ca05807c2eb6e5 Mon Sep 17 00:00:00 2001 |
|
| 1 |
+From c6c12d88ab31ac78bcb779ad09204bde05b68f3e Mon Sep 17 00:00:00 2001 |
|
| 2 | 2 |
From: Alexey Makhalov <amakhalov@vmware.com> |
| 3 |
-Date: Wed, 30 Sep 2015 23:00:00 +0000 |
|
| 4 |
-Subject: [PATCH 01/15] Measure correct boot time. |
|
| 3 |
+Date: Tue, 8 Aug 2017 19:32:45 +0000 |
|
| 4 |
+Subject: [PATCH] PV-ops support for VMware guest |
|
| 5 | 5 |
|
| 6 | 6 |
--- |
| 7 |
- arch/x86/Kconfig | 8 ++++++++ |
|
| 8 |
- arch/x86/kernel/head_64.S | 16 ++++++++++++++++ |
|
| 9 |
- init/main.c | 11 +++++++++++ |
|
| 10 |
- 3 files changed, 35 insertions(+) |
|
| 7 |
+ arch/x86/Kconfig | 18 ++ |
|
| 8 |
+ arch/x86/include/asm/paravirt.h | 5 + |
|
| 9 |
+ arch/x86/include/asm/paravirt_types.h | 5 + |
|
| 10 |
+ arch/x86/kernel/cpu/common.c | 2 + |
|
| 11 |
+ arch/x86/kernel/cpu/rdrand.c | 2 + |
|
| 12 |
+ arch/x86/kernel/cpu/vmware.c | 414 +++++++++++++++++++++++++++++++++- |
|
| 13 |
+ arch/x86/kernel/head_64.S | 10 + |
|
| 14 |
+ arch/x86/kernel/paravirt.c | 7 + |
|
| 15 |
+ arch/x86/kernel/setup.c | 9 + |
|
| 16 |
+ arch/x86/kernel/smpboot.c | 2 +- |
|
| 17 |
+ kernel/sched/clock.c | 7 + |
|
| 18 |
+ 11 files changed, 475 insertions(+), 6 deletions(-) |
|
| 11 | 19 |
|
| 12 | 20 |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig |
| 13 |
-index db3622f22b61..3f6337e0ac32 100644 |
|
| 21 |
+index 436639a..4ad7f49 100644 |
|
| 14 | 22 |
--- a/arch/x86/Kconfig |
| 15 | 23 |
+++ b/arch/x86/Kconfig |
| 16 |
-@@ -710,6 +710,14 @@ config KVM_DEBUG_FS |
|
| 24 |
+@@ -710,6 +710,24 @@ config KVM_DEBUG_FS |
|
| 17 | 25 |
Statistics are displayed in debugfs filesystem. Enabling this option |
| 18 | 26 |
may incur significant overhead. |
| 19 | 27 |
|
| 20 | 28 |
+config VMWARE |
| 21 |
-+ bool "VMware Guest support" |
|
| 29 |
++ bool "VMware guest support" |
|
| 22 | 30 |
+ depends on PARAVIRT |
| 23 | 31 |
+ default y |
| 24 | 32 |
+ ---help--- |
| 25 | 33 |
+ This option enables various optimizations for running under the |
| 26 |
-+ VMware hypervisor. It includes a correct boot time measurement. |
|
| 27 |
-+ |
|
| 28 |
- source "arch/x86/lguest/Kconfig" |
|
| 29 |
- |
|
| 30 |
- config PARAVIRT_TIME_ACCOUNTING |
|
| 31 |
-diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S |
|
| 32 |
-index ffdc0e860390..0f5460806688 100644 |
|
| 33 |
-+++ b/arch/x86/kernel/head_64.S |
|
| 34 |
-@@ -65,6 +65,16 @@ startup_64: |
|
| 35 |
- * tables and then reload them. |
|
| 36 |
- */ |
|
| 37 |
- |
|
| 38 |
-+#ifdef CONFIG_VMWARE |
|
| 39 |
-+ /* |
|
| 40 |
-+ * Read a TSC value first |
|
| 41 |
-+ */ |
|
| 42 |
-+ rdtsc |
|
| 43 |
-+ shl $0x20, %rdx |
|
| 44 |
-+ or %rax, %rdx |
|
| 45 |
-+ mov %rdx, tsc_at_head(%rip) |
|
| 46 |
-+#endif |
|
| 47 |
-+ |
|
| 48 |
- /* Sanitize CPU configuration */ |
|
| 49 |
- call verify_cpu |
|
| 50 |
- |
|
| 51 |
-@@ -520,6 +530,12 @@ early_gdt_descr: |
|
| 52 |
- early_gdt_descr_base: |
|
| 53 |
- .quad INIT_PER_CPU_VAR(gdt_page) |
|
| 54 |
- |
|
| 55 |
-+#ifdef CONFIG_VMWARE |
|
| 56 |
-+ .globl tsc_at_head |
|
| 57 |
-+tsc_at_head: |
|
| 58 |
-+ .quad 0 |
|
| 59 |
-+#endif |
|
| 60 |
-+ |
|
| 61 |
- ENTRY(phys_base) |
|
| 62 |
- /* This must match the first entry in level2_kernel_pgt */ |
|
| 63 |
- .quad 0x0000000000000000 |
|
| 64 |
-diff --git a/init/main.c b/init/main.c |
|
| 65 |
-index 9e64d7097f1a..ccc9a221dae3 100644 |
|
| 66 |
-+++ b/init/main.c |
|
| 67 |
-@@ -928,6 +928,9 @@ static int try_to_run_init_process(const char *init_filename) |
|
| 68 |
- } |
|
| 69 |
- |
|
| 70 |
- static noinline void __init kernel_init_freeable(void); |
|
| 71 |
-+#ifdef CONFIG_VMWARE |
|
| 72 |
-+extern unsigned long long tsc_at_head; |
|
| 73 |
-+#endif |
|
| 74 |
- |
|
| 75 |
- static int __ref kernel_init(void *unused) |
|
| 76 |
- {
|
|
| 77 |
-@@ -943,6 +946,14 @@ static int __ref kernel_init(void *unused) |
|
| 78 |
- |
|
| 79 |
- flush_delayed_fput(); |
|
| 80 |
- |
|
| 81 |
-+#ifdef CONFIG_VMWARE |
|
| 82 |
-+ printk(KERN_INFO "Pre-Kernel time: %5dms\n", |
|
| 83 |
-+ (unsigned int) (tsc_at_head / tsc_khz)); |
|
| 84 |
-+ printk(KERN_INFO "Kernel boot time:%5dms\n", |
|
| 85 |
-+ (unsigned int) ((__native_read_tsc() - tsc_at_head) / |
|
| 86 |
-+ tsc_khz)); |
|
| 87 |
-+#endif |
|
| 88 |
-+ |
|
| 89 |
- if (ramdisk_execute_command) {
|
|
| 90 |
- ret = run_init_process(ramdisk_execute_command); |
|
| 91 |
- if (!ret) |
|
| 92 |
-2.11.0 |
|
| 93 |
- |
|
| 94 |
- |
|
| 95 |
-From 1dc2e9f9a9d8d8065fa096b5551ca646086a72ed Mon Sep 17 00:00:00 2001 |
|
| 96 |
-From: Alexey Makhalov <amakhalov@vmware.com> |
|
| 97 |
-Date: Fri, 2 Oct 2015 20:00:06 +0000 |
|
| 98 |
-Subject: [PATCH 02/15] PV io_delay for VMware guest. |
|
| 99 |
- |
|
| 100 |
- arch/x86/kernel/cpu/vmware.c | 13 +++++++++++++ |
|
| 101 |
- 1 file changed, 13 insertions(+) |
|
| 102 |
- |
|
| 103 |
-diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c |
|
| 104 |
-index 628a059a9a06..8fdd0315f218 100644 |
|
| 105 |
-+++ b/arch/x86/kernel/cpu/vmware.c |
|
| 106 |
-@@ -26,6 +26,7 @@ |
|
| 107 |
- #include <asm/div64.h> |
|
| 108 |
- #include <asm/x86_init.h> |
|
| 109 |
- #include <asm/hypervisor.h> |
|
| 110 |
-+#include <asm/timer.h> |
|
| 111 |
- |
|
| 112 |
- #define CPUID_VMWARE_INFO_LEAF 0x40000000 |
|
| 113 |
- #define VMWARE_HYPERVISOR_MAGIC 0x564D5868 |
|
| 114 |
-@@ -75,6 +76,16 @@ static unsigned long vmware_get_tsc_khz(void) |
|
| 115 |
- return tsc_hz; |
|
| 116 |
- } |
|
| 117 |
- |
|
| 118 |
-+static void __init paravirt_ops_setup(void) |
|
| 119 |
-+{
|
|
| 120 |
-+ pv_info.name = "VMware"; |
|
| 121 |
-+ pv_cpu_ops.io_delay = paravirt_nop, |
|
| 122 |
-+ |
|
| 123 |
-+#ifdef CONFIG_X86_IO_APIC |
|
| 124 |
-+ no_timer_check = 1; |
|
| 125 |
-+#endif |
|
| 126 |
-+} |
|
| 127 |
-+ |
|
| 128 |
- static void __init vmware_platform_setup(void) |
|
| 129 |
- {
|
|
| 130 |
- uint32_t eax, ebx, ecx, edx; |
|
| 131 |
-@@ -86,6 +97,8 @@ static void __init vmware_platform_setup(void) |
|
| 132 |
- else |
|
| 133 |
- printk(KERN_WARNING |
|
| 134 |
- "Failed to get TSC freq from the hypervisor\n"); |
|
| 135 |
-+ |
|
| 136 |
-+ paravirt_ops_setup(); |
|
| 137 |
- } |
|
| 138 |
- |
|
| 139 |
- /* |
|
| 140 |
-2.11.0 |
|
| 141 |
- |
|
| 142 |
- |
|
| 143 |
-From faf39d20732abb865f003b46a567ea42d0841e92 Mon Sep 17 00:00:00 2001 |
|
| 144 |
-From: Alexey Makhalov <amakhalov@vmware.com> |
|
| 145 |
-Date: Wed, 7 Oct 2015 22:53:18 +0000 |
|
| 146 |
-Subject: [PATCH 03/15] Improved tsc based sched_clock & clocksource. |
|
| 147 |
- |
|
| 148 |
- arch/x86/Kconfig | 1 + |
|
| 149 |
- arch/x86/kernel/cpu/vmware.c | 66 ++++++++++++++++++++++++++++++++++++++++++++ |
|
| 150 |
- init/main.c | 11 -------- |
|
| 151 |
- kernel/sched/clock.c | 2 ++ |
|
| 152 |
- 4 files changed, 69 insertions(+), 11 deletions(-) |
|
| 153 |
- |
|
| 154 |
-diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig |
|
| 155 |
-index 3f6337e0ac32..8182ad6d8509 100644 |
|
| 156 |
-+++ b/arch/x86/Kconfig |
|
| 157 |
-@@ -713,6 +713,7 @@ config KVM_DEBUG_FS |
|
| 158 |
- config VMWARE |
|
| 159 |
- bool "VMware Guest support" |
|
| 160 |
- depends on PARAVIRT |
|
| 161 |
-+ select PARAVIRT_CLOCK |
|
| 162 |
- default y |
|
| 163 |
- ---help--- |
|
| 164 |
- This option enables various optimizations for running under the |
|
| 165 |
-diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c |
|
| 166 |
-index 8fdd0315f218..004825edfa6f 100644 |
|
| 167 |
-+++ b/arch/x86/kernel/cpu/vmware.c |
|
| 168 |
-@@ -27,6 +27,7 @@ |
|
| 169 |
- #include <asm/x86_init.h> |
|
| 170 |
- #include <asm/hypervisor.h> |
|
| 171 |
- #include <asm/timer.h> |
|
| 172 |
-+#include <linux/sched.h> |
|
| 173 |
- |
|
| 174 |
- #define CPUID_VMWARE_INFO_LEAF 0x40000000 |
|
| 175 |
- #define VMWARE_HYPERVISOR_MAGIC 0x564D5868 |
|
| 176 |
-@@ -76,10 +77,43 @@ static unsigned long vmware_get_tsc_khz(void) |
|
| 177 |
- return tsc_hz; |
|
| 178 |
- } |
|
| 179 |
- |
|
| 180 |
-+static struct cyc2ns_data vmware_cyc2ns; |
|
| 181 |
-+extern unsigned long long tsc_at_head; |
|
| 182 |
-+static cycle_t vmware_clock_get_cycles(struct clocksource *cs) |
|
| 183 |
-+{
|
|
| 184 |
-+ return __native_read_tsc(); |
|
| 185 |
-+} |
|
| 186 |
-+ |
|
| 187 |
-+static struct clocksource clocksource_vmware = {
|
|
| 188 |
-+ .name = "vmware-clock", |
|
| 189 |
-+ .read = vmware_clock_get_cycles, |
|
| 190 |
-+ .rating = 400, |
|
| 191 |
-+ .mask = CLOCKSOURCE_MASK(64), |
|
| 192 |
-+ .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
|
| 193 |
-+}; |
|
| 194 |
-+ |
|
| 195 |
-+struct clocksource * __init clocksource_default_clock(void) |
|
| 196 |
-+{
|
|
| 197 |
-+ return &clocksource_vmware; |
|
| 198 |
-+} |
|
| 199 |
-+ |
|
| 200 |
-+#define CYC2NS_SCALE_FACTOR 8 |
|
| 201 |
-+ |
|
| 202 |
-+static u64 vmware_sched_clock(void) |
|
| 203 |
-+{
|
|
| 204 |
-+ u64 ret; |
|
| 205 |
-+ |
|
| 206 |
-+ ret = __native_read_tsc() - vmware_cyc2ns.cyc2ns_offset; |
|
| 207 |
-+ ret = mul_u64_u32_shr(ret, vmware_cyc2ns.cyc2ns_mul, CYC2NS_SCALE_FACTOR); |
|
| 208 |
-+ return ret; |
|
| 209 |
-+} |
|
| 210 |
-+ |
|
| 211 |
-+extern __read_mostly int sched_clock_running; |
|
| 212 |
- static void __init paravirt_ops_setup(void) |
|
| 213 |
- {
|
|
| 214 |
- pv_info.name = "VMware"; |
|
| 215 |
- pv_cpu_ops.io_delay = paravirt_nop, |
|
| 216 |
-+ pv_time_ops.sched_clock = vmware_sched_clock; |
|
| 217 |
- |
|
| 218 |
- #ifdef CONFIG_X86_IO_APIC |
|
| 219 |
- no_timer_check = 1; |
|
| 220 |
-@@ -88,6 +122,7 @@ static void __init paravirt_ops_setup(void) |
|
| 221 |
- |
|
| 222 |
- static void __init vmware_platform_setup(void) |
|
| 223 |
- {
|
|
| 224 |
-+ uint64_t cpu_khz; |
|
| 225 |
- uint32_t eax, ebx, ecx, edx; |
|
| 226 |
- |
|
| 227 |
- VMWARE_PORT(GETHZ, eax, ebx, ecx, edx); |
|
| 228 |
-@@ -98,6 +133,19 @@ static void __init vmware_platform_setup(void) |
|
| 229 |
- printk(KERN_WARNING |
|
| 230 |
- "Failed to get TSC freq from the hypervisor\n"); |
|
| 231 |
- |
|
| 232 |
-+ cpu_khz = eax | (((uint64_t)ebx) << 32); |
|
| 233 |
-+ do_div(cpu_khz, 1000); |
|
| 234 |
-+ printk(KERN_INFO "Pre Kernel boot time: %dms\n", |
|
| 235 |
-+ (unsigned int) (tsc_at_head / cpu_khz)); |
|
| 236 |
-+ |
|
| 237 |
-+ vmware_cyc2ns.cyc2ns_mul = |
|
| 238 |
-+ DIV_ROUND_CLOSEST(NSEC_PER_MSEC << CYC2NS_SCALE_FACTOR, |
|
| 239 |
-+ cpu_khz); |
|
| 240 |
-+ vmware_cyc2ns.cyc2ns_shift = CYC2NS_SCALE_FACTOR; |
|
| 241 |
-+ vmware_cyc2ns.cyc2ns_offset = tsc_at_head; |
|
| 242 |
-+ |
|
| 243 |
-+ clocksource_register_khz(&clocksource_vmware, cpu_khz); |
|
| 244 |
-+ |
|
| 245 |
- paravirt_ops_setup(); |
|
| 246 |
- } |
|
| 247 |
- |
|
| 248 |
-@@ -158,3 +206,21 @@ const __refconst struct hypervisor_x86 x86_hyper_vmware = {
|
|
| 249 |
- .x2apic_available = vmware_legacy_x2apic_available, |
|
| 250 |
- }; |
|
| 251 |
- EXPORT_SYMBOL(x86_hyper_vmware); |
|
| 252 |
-+ |
|
| 253 |
-+void read_boot_clock64(struct timespec64 *ts) |
|
| 254 |
-+{
|
|
| 255 |
-+ struct timespec64 now; |
|
| 256 |
-+ u64 delta, delta_nsec; |
|
| 257 |
-+ u32 rem; |
|
| 258 |
-+ |
|
| 259 |
-+ read_persistent_clock64(&now); |
|
| 260 |
-+ delta = __native_read_tsc() - vmware_cyc2ns.cyc2ns_offset; |
|
| 261 |
-+ delta_nsec = mul_u64_u32_shr(delta, vmware_cyc2ns.cyc2ns_mul, |
|
| 262 |
-+ CYC2NS_SCALE_FACTOR); |
|
| 263 |
-+ ts->tv_sec = now.tv_sec - div_s64_rem(delta_nsec, NSEC_PER_SEC, &rem); |
|
| 264 |
-+ ts->tv_nsec = now.tv_nsec - rem; |
|
| 265 |
-+ while (unlikely(ts->tv_nsec < 0)) {
|
|
| 266 |
-+ ts->tv_sec--; |
|
| 267 |
-+ ts->tv_nsec += NSEC_PER_SEC; |
|
| 268 |
-+ } |
|
| 269 |
-+} |
|
| 270 |
-diff --git a/init/main.c b/init/main.c |
|
| 271 |
-index ccc9a221dae3..9e64d7097f1a 100644 |
|
| 272 |
-+++ b/init/main.c |
|
| 273 |
-@@ -928,9 +928,6 @@ static int try_to_run_init_process(const char *init_filename) |
|
| 274 |
- } |
|
| 275 |
- |
|
| 276 |
- static noinline void __init kernel_init_freeable(void); |
|
| 277 |
--#ifdef CONFIG_VMWARE |
|
| 278 |
--extern unsigned long long tsc_at_head; |
|
| 279 |
--#endif |
|
| 280 |
- |
|
| 281 |
- static int __ref kernel_init(void *unused) |
|
| 282 |
- {
|
|
| 283 |
-@@ -946,14 +943,6 @@ static int __ref kernel_init(void *unused) |
|
| 284 |
- |
|
| 285 |
- flush_delayed_fput(); |
|
| 286 |
- |
|
| 287 |
--#ifdef CONFIG_VMWARE |
|
| 288 |
-- printk(KERN_INFO "Pre-Kernel time: %5dms\n", |
|
| 289 |
-- (unsigned int) (tsc_at_head / tsc_khz)); |
|
| 290 |
-- printk(KERN_INFO "Kernel boot time:%5dms\n", |
|
| 291 |
-- (unsigned int) ((__native_read_tsc() - tsc_at_head) / |
|
| 292 |
-- tsc_khz)); |
|
| 293 |
--#endif |
|
| 294 |
-- |
|
| 295 |
- if (ramdisk_execute_command) {
|
|
| 296 |
- ret = run_init_process(ramdisk_execute_command); |
|
| 297 |
- if (!ret) |
|
| 298 |
-diff --git a/kernel/sched/clock.c b/kernel/sched/clock.c |
|
| 299 |
-index caf4041f5b0a..86d8a78efc27 100644 |
|
| 300 |
-+++ b/kernel/sched/clock.c |
|
| 301 |
-@@ -385,8 +385,10 @@ u64 cpu_clock(int cpu) |
|
| 302 |
- */ |
|
| 303 |
- u64 local_clock(void) |
|
| 304 |
- {
|
|
| 305 |
-+#ifndef CONFIG_VMWARE |
|
| 306 |
- if (!sched_clock_stable()) |
|
| 307 |
- return sched_clock_cpu(raw_smp_processor_id()); |
|
| 308 |
-+#endif |
|
| 309 |
- |
|
| 310 |
- return sched_clock(); |
|
| 311 |
- } |
|
| 312 |
-2.11.0 |
|
| 313 |
- |
|
| 314 |
- |
|
| 315 |
-From 543bcc0aa46846859c92be5effde0d900a456c2a Mon Sep 17 00:00:00 2001 |
|
| 316 |
-From: Alexey Makhalov <amakhalov@vmware.com> |
|
| 317 |
-Date: Mon, 12 Oct 2015 22:43:38 +0000 |
|
| 318 |
-Subject: [PATCH 04/15] Move read_boot_clock64 into pv_time_ops. |
|
| 319 |
- |
|
| 320 |
- arch/x86/Kconfig | 14 ++++++-- |
|
| 321 |
- arch/x86/include/asm/paravirt.h | 5 +++ |
|
| 322 |
- arch/x86/include/asm/paravirt_types.h | 5 +++ |
|
| 323 |
- arch/x86/kernel/cpu/vmware.c | 66 ++++++++++++++++++++--------------- |
|
| 324 |
- arch/x86/kernel/head_64.S | 8 +---- |
|
| 325 |
- arch/x86/kernel/paravirt.c | 7 ++++ |
|
| 326 |
- arch/x86/kernel/setup.c | 9 +++++ |
|
| 327 |
- kernel/sched/clock.c | 7 +++- |
|
| 328 |
- 8 files changed, 83 insertions(+), 38 deletions(-) |
|
| 329 |
- |
|
| 330 |
-diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig |
|
| 331 |
-index 8182ad6d8509..4c3d10a0ae3a 100644 |
|
| 332 |
-+++ b/arch/x86/Kconfig |
|
| 333 |
-@@ -711,13 +711,23 @@ config KVM_DEBUG_FS |
|
| 334 |
- may incur significant overhead. |
|
| 335 |
- |
|
| 336 |
- config VMWARE |
|
| 337 |
-- bool "VMware Guest support" |
|
| 338 |
-+ bool "VMware guest support" |
|
| 339 |
- depends on PARAVIRT |
|
| 340 |
- select PARAVIRT_CLOCK |
|
| 341 |
- default y |
|
| 342 |
- ---help--- |
|
| 343 |
- This option enables various optimizations for running under the |
|
| 344 |
-- VMware hypervisor. It includes a correct boot time measurement. |
|
| 345 | 34 |
+ VMware hypervisor. It includes vmware-clock clocksource and some |
| 346 | 35 |
+ pv-ops implementations. |
| 347 | 36 |
+ |
| ... | ... |
@@ -367,11 +42,12 @@ index 8182ad6d8509..4c3d10a0ae3a 100644 |
| 367 | 367 |
+ This option enables VMware guest specific optimizations. If you say |
| 368 | 368 |
+ yes here, the kernel will probably work only under VMware hypervisor. |
| 369 | 369 |
+ |
| 370 |
- |
|
| 370 |
++ |
|
| 371 | 371 |
source "arch/x86/lguest/Kconfig" |
| 372 | 372 |
|
| 373 |
+ config PARAVIRT_TIME_ACCOUNTING |
|
| 373 | 374 |
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h |
| 374 |
-index c759b3cca663..5ee337859ace 100644 |
|
| 375 |
+index c759b3c..5ee3378 100644 |
|
| 375 | 376 |
--- a/arch/x86/include/asm/paravirt.h |
| 376 | 377 |
+++ b/arch/x86/include/asm/paravirt.h |
| 377 | 378 |
@@ -198,6 +198,11 @@ static inline u64 paravirt_steal_clock(int cpu) |
| ... | ... |
@@ -387,7 +63,7 @@ index c759b3cca663..5ee337859ace 100644 |
| 387 | 387 |
{
|
| 388 | 388 |
return PVOP_CALL1(u64, pv_cpu_ops.read_pmc, counter); |
| 389 | 389 |
diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h |
| 390 |
-index 3d44191185f8..2e76e4ad21a7 100644 |
|
| 390 |
+index 3d44191..2e76e4a 100644 |
|
| 391 | 391 |
--- a/arch/x86/include/asm/paravirt_types.h |
| 392 | 392 |
+++ b/arch/x86/include/asm/paravirt_types.h |
| 393 | 393 |
@@ -51,6 +51,10 @@ struct mm_struct; |
| ... | ... |
@@ -409,432 +85,11 @@ index 3d44191185f8..2e76e4ad21a7 100644 |
| 409 | 409 |
}; |
| 410 | 410 |
|
| 411 | 411 |
struct pv_cpu_ops {
|
| 412 |
-diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c |
|
| 413 |
-index 004825edfa6f..1bf1fe3d7886 100644 |
|
| 414 |
-+++ b/arch/x86/kernel/cpu/vmware.c |
|
| 415 |
-@@ -77,8 +77,10 @@ static unsigned long vmware_get_tsc_khz(void) |
|
| 416 |
- return tsc_hz; |
|
| 417 |
- } |
|
| 418 |
- |
|
| 419 |
-+#define CYC2NS_SCALE_FACTOR 8 |
|
| 420 |
- static struct cyc2ns_data vmware_cyc2ns; |
|
| 421 |
--extern unsigned long long tsc_at_head; |
|
| 422 |
-+u64 __initdata tsc_at_head; |
|
| 423 |
-+ |
|
| 424 |
- static cycle_t vmware_clock_get_cycles(struct clocksource *cs) |
|
| 425 |
- {
|
|
| 426 |
- return __native_read_tsc(); |
|
| 427 |
-@@ -92,12 +94,14 @@ static struct clocksource clocksource_vmware = {
|
|
| 428 |
- .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
|
| 429 |
- }; |
|
| 430 |
- |
|
| 431 |
-+#ifdef CONFIG_VMWARE_ONLY |
|
| 432 |
-+/* We want to use clocksource_vmware from the beginning to avoid drifting in |
|
| 433 |
-+ monotonic clock */ |
|
| 434 |
- struct clocksource * __init clocksource_default_clock(void) |
|
| 435 |
- {
|
|
| 436 |
- return &clocksource_vmware; |
|
| 437 |
- } |
|
| 438 |
-- |
|
| 439 |
--#define CYC2NS_SCALE_FACTOR 8 |
|
| 440 |
-+#endif |
|
| 441 |
- |
|
| 442 |
- static u64 vmware_sched_clock(void) |
|
| 443 |
- {
|
|
| 444 |
-@@ -108,12 +112,33 @@ static u64 vmware_sched_clock(void) |
|
| 445 |
- return ret; |
|
| 446 |
- } |
|
| 447 |
- |
|
| 448 |
--extern __read_mostly int sched_clock_running; |
|
| 449 |
-+ |
|
| 450 |
-+/* Function to read the exact time the system has been started. It will be |
|
| 451 |
-+ used as zero time for monotonic clock */ |
|
| 452 |
-+static void vmware_read_boot_clock64(struct timespec64 *ts) |
|
| 453 |
-+{
|
|
| 454 |
-+ struct timespec64 now; |
|
| 455 |
-+ u64 delta, delta_nsec; |
|
| 456 |
-+ u32 rem; |
|
| 457 |
-+ |
|
| 458 |
-+ read_persistent_clock64(&now); |
|
| 459 |
-+ delta = __native_read_tsc() - vmware_cyc2ns.cyc2ns_offset; |
|
| 460 |
-+ delta_nsec = mul_u64_u32_shr(delta, vmware_cyc2ns.cyc2ns_mul, |
|
| 461 |
-+ CYC2NS_SCALE_FACTOR); |
|
| 462 |
-+ ts->tv_sec = now.tv_sec - div_s64_rem(delta_nsec, NSEC_PER_SEC, &rem); |
|
| 463 |
-+ ts->tv_nsec = now.tv_nsec - rem; |
|
| 464 |
-+ while (unlikely(ts->tv_nsec < 0)) {
|
|
| 465 |
-+ ts->tv_sec--; |
|
| 466 |
-+ ts->tv_nsec += NSEC_PER_SEC; |
|
| 467 |
-+ } |
|
| 468 |
-+} |
|
| 469 |
-+ |
|
| 470 |
- static void __init paravirt_ops_setup(void) |
|
| 471 |
- {
|
|
| 472 |
- pv_info.name = "VMware"; |
|
| 473 |
- pv_cpu_ops.io_delay = paravirt_nop, |
|
| 474 |
- pv_time_ops.sched_clock = vmware_sched_clock; |
|
| 475 |
-+ pv_time_ops.read_boot_clock64 = vmware_read_boot_clock64; |
|
| 476 |
- |
|
| 477 |
- #ifdef CONFIG_X86_IO_APIC |
|
| 478 |
- no_timer_check = 1; |
|
| 479 |
-@@ -122,7 +147,7 @@ static void __init paravirt_ops_setup(void) |
|
| 480 |
- |
|
| 481 |
- static void __init vmware_platform_setup(void) |
|
| 482 |
- {
|
|
| 483 |
-- uint64_t cpu_khz; |
|
| 484 |
-+ uint64_t vtsc_khz; |
|
| 485 |
- uint32_t eax, ebx, ecx, edx; |
|
| 486 |
- |
|
| 487 |
- VMWARE_PORT(GETHZ, eax, ebx, ecx, edx); |
|
| 488 |
-@@ -133,18 +158,18 @@ static void __init vmware_platform_setup(void) |
|
| 489 |
- printk(KERN_WARNING |
|
| 490 |
- "Failed to get TSC freq from the hypervisor\n"); |
|
| 491 |
- |
|
| 492 |
-- cpu_khz = eax | (((uint64_t)ebx) << 32); |
|
| 493 |
-- do_div(cpu_khz, 1000); |
|
| 494 |
-+ vtsc_khz = eax | (((uint64_t)ebx) << 32); |
|
| 495 |
-+ do_div(vtsc_khz, 1000); |
|
| 496 |
- printk(KERN_INFO "Pre Kernel boot time: %dms\n", |
|
| 497 |
-- (unsigned int) (tsc_at_head / cpu_khz)); |
|
| 498 |
-+ (unsigned int) (tsc_at_head / vtsc_khz)); |
|
| 499 |
- |
|
| 500 |
- vmware_cyc2ns.cyc2ns_mul = |
|
| 501 |
- DIV_ROUND_CLOSEST(NSEC_PER_MSEC << CYC2NS_SCALE_FACTOR, |
|
| 502 |
-- cpu_khz); |
|
| 503 |
-+ vtsc_khz); |
|
| 504 |
- vmware_cyc2ns.cyc2ns_shift = CYC2NS_SCALE_FACTOR; |
|
| 505 |
- vmware_cyc2ns.cyc2ns_offset = tsc_at_head; |
|
| 506 |
- |
|
| 507 |
-- clocksource_register_khz(&clocksource_vmware, cpu_khz); |
|
| 508 |
-+ clocksource_register_khz(&clocksource_vmware, vtsc_khz); |
|
| 509 |
- |
|
| 510 |
- paravirt_ops_setup(); |
|
| 511 |
- } |
|
| 512 |
-@@ -156,6 +181,9 @@ static void __init vmware_platform_setup(void) |
|
| 513 |
- */ |
|
| 514 |
- static uint32_t __init vmware_platform(void) |
|
| 515 |
- {
|
|
| 516 |
-+#ifndef CONFIG_VMWARE_ONLY |
|
| 517 |
-+ tsc_at_head = __native_read_tsc(); |
|
| 518 |
-+#endif |
|
| 519 |
- if (cpu_has_hypervisor) {
|
|
| 520 |
- unsigned int eax; |
|
| 521 |
- unsigned int hyper_vendor_id[3]; |
|
| 522 |
-@@ -206,21 +234,3 @@ const __refconst struct hypervisor_x86 x86_hyper_vmware = {
|
|
| 523 |
- .x2apic_available = vmware_legacy_x2apic_available, |
|
| 524 |
- }; |
|
| 525 |
- EXPORT_SYMBOL(x86_hyper_vmware); |
|
| 526 |
-- |
|
| 527 |
--void read_boot_clock64(struct timespec64 *ts) |
|
| 528 |
--{
|
|
| 529 |
-- struct timespec64 now; |
|
| 530 |
-- u64 delta, delta_nsec; |
|
| 531 |
-- u32 rem; |
|
| 532 |
-- |
|
| 533 |
-- read_persistent_clock64(&now); |
|
| 534 |
-- delta = __native_read_tsc() - vmware_cyc2ns.cyc2ns_offset; |
|
| 535 |
-- delta_nsec = mul_u64_u32_shr(delta, vmware_cyc2ns.cyc2ns_mul, |
|
| 536 |
-- CYC2NS_SCALE_FACTOR); |
|
| 537 |
-- ts->tv_sec = now.tv_sec - div_s64_rem(delta_nsec, NSEC_PER_SEC, &rem); |
|
| 538 |
-- ts->tv_nsec = now.tv_nsec - rem; |
|
| 539 |
-- while (unlikely(ts->tv_nsec < 0)) {
|
|
| 540 |
-- ts->tv_sec--; |
|
| 541 |
-- ts->tv_nsec += NSEC_PER_SEC; |
|
| 542 |
-- } |
|
| 543 |
--} |
|
| 544 |
-diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S |
|
| 545 |
-index 0f5460806688..1bc014083afb 100644 |
|
| 546 |
-+++ b/arch/x86/kernel/head_64.S |
|
| 547 |
-@@ -65,7 +65,7 @@ startup_64: |
|
| 548 |
- * tables and then reload them. |
|
| 549 |
- */ |
|
| 550 |
- |
|
| 551 |
--#ifdef CONFIG_VMWARE |
|
| 552 |
-+#ifdef CONFIG_VMWARE_ONLY |
|
| 553 |
- /* |
|
| 554 |
- * Read a TSC value first |
|
| 555 |
- */ |
|
| 556 |
-@@ -530,12 +530,6 @@ early_gdt_descr: |
|
| 557 |
- early_gdt_descr_base: |
|
| 558 |
- .quad INIT_PER_CPU_VAR(gdt_page) |
|
| 559 |
- |
|
| 560 |
--#ifdef CONFIG_VMWARE |
|
| 561 |
-- .globl tsc_at_head |
|
| 562 |
--tsc_at_head: |
|
| 563 |
-- .quad 0 |
|
| 564 |
--#endif |
|
| 565 |
-- |
|
| 566 |
- ENTRY(phys_base) |
|
| 567 |
- /* This must match the first entry in level2_kernel_pgt */ |
|
| 568 |
- .quad 0x0000000000000000 |
|
| 569 |
-diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c |
|
| 570 |
-index c2130aef3f9d..0bb48cb3386a 100644 |
|
| 571 |
-+++ b/arch/x86/kernel/paravirt.c |
|
| 572 |
-@@ -218,6 +218,12 @@ static u64 native_steal_clock(int cpu) |
|
| 573 |
- return 0; |
|
| 574 |
- } |
|
| 575 |
- |
|
| 576 |
-+static void native_read_boot_clock64(struct timespec64 *ts) |
|
| 577 |
-+{
|
|
| 578 |
-+ ts->tv_sec = 0; |
|
| 579 |
-+ ts->tv_nsec = 0; |
|
| 580 |
-+} |
|
| 581 |
-+ |
|
| 582 |
- /* These are in entry.S */ |
|
| 583 |
- extern void native_iret(void); |
|
| 584 |
- extern void native_irq_enable_sysexit(void); |
|
| 585 |
-@@ -328,6 +334,7 @@ struct pv_init_ops pv_init_ops = {
|
|
| 586 |
- struct pv_time_ops pv_time_ops = {
|
|
| 587 |
- .sched_clock = native_sched_clock, |
|
| 588 |
- .steal_clock = native_steal_clock, |
|
| 589 |
-+ .read_boot_clock64 = native_read_boot_clock64, |
|
| 590 |
- }; |
|
| 591 |
- |
|
| 592 |
- __visible struct pv_irq_ops pv_irq_ops = {
|
|
| 593 |
-diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c |
|
| 594 |
-index d2bbe343fda7..00032034d2e2 100644 |
|
| 595 |
-+++ b/arch/x86/kernel/setup.c |
|
| 596 |
-@@ -1280,3 +1280,12 @@ static int __init register_kernel_offset_dumper(void) |
|
| 597 |
- return 0; |
|
| 598 |
- } |
|
| 599 |
- __initcall(register_kernel_offset_dumper); |
|
| 600 |
-+ |
|
| 601 |
-+/* We need to define a real function for read_boot_clock64, to override the |
|
| 602 |
-+ weak default version */ |
|
| 603 |
-+#ifdef CONFIG_PARAVIRT |
|
| 604 |
-+void read_boot_clock64(struct timespec64 *ts) |
|
| 605 |
-+{
|
|
| 606 |
-+ paravirt_read_boot_clock64(ts); |
|
| 607 |
-+} |
|
| 608 |
-+#endif |
|
| 609 |
-diff --git a/kernel/sched/clock.c b/kernel/sched/clock.c |
|
| 610 |
-index 86d8a78efc27..377ab5aee627 100644 |
|
| 611 |
-+++ b/kernel/sched/clock.c |
|
| 612 |
-@@ -385,7 +385,12 @@ u64 cpu_clock(int cpu) |
|
| 613 |
- */ |
|
| 614 |
- u64 local_clock(void) |
|
| 615 |
- {
|
|
| 616 |
--#ifndef CONFIG_VMWARE |
|
| 617 |
-+ /* |
|
| 618 |
-+ * sched_clock is stable and running for VMware guest. |
|
| 619 |
-+ * Let's disable this checking. It will allow us to have |
|
| 620 |
-+ * printk timestamps from the beginning |
|
| 621 |
-+ */ |
|
| 622 |
-+#if !defined(CONFIG_VMWARE_ONLY) || !defined(CONFIG_PRINTK_TIME) |
|
| 623 |
- if (!sched_clock_stable()) |
|
| 624 |
- return sched_clock_cpu(raw_smp_processor_id()); |
|
| 625 |
- #endif |
|
| 626 |
-2.11.0 |
|
| 627 |
- |
|
| 628 |
- |
|
| 629 |
-From f832fc949c5e97799fc977a317025a721d87bb68 Mon Sep 17 00:00:00 2001 |
|
| 630 |
-From: Alexey Makhalov <amakhalov@vmware.com> |
|
| 631 |
-Date: Thu, 5 Nov 2015 21:02:52 +0000 |
|
| 632 |
-Subject: [PATCH 05/15] Fix clocksource_vmware issue in VM version <= 10 |
|
| 633 |
- |
|
| 634 |
- arch/x86/kernel/cpu/vmware.c | 48 +++++++++++++++++++++++++++++++++++++++++--- |
|
| 635 |
- 1 file changed, 45 insertions(+), 3 deletions(-) |
|
| 636 |
- |
|
| 637 |
-diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c |
|
| 638 |
-index 1bf1fe3d7886..0b89bb976a35 100644 |
|
| 639 |
-+++ b/arch/x86/kernel/cpu/vmware.c |
|
| 640 |
-@@ -79,7 +79,8 @@ static unsigned long vmware_get_tsc_khz(void) |
|
| 641 |
- |
|
| 642 |
- #define CYC2NS_SCALE_FACTOR 8 |
|
| 643 |
- static struct cyc2ns_data vmware_cyc2ns; |
|
| 644 |
--u64 __initdata tsc_at_head; |
|
| 645 |
-+uint64_t __initdata tsc_at_head; |
|
| 646 |
-+uint64_t __initdata vtsc_khz; |
|
| 647 |
- |
|
| 648 |
- static cycle_t vmware_clock_get_cycles(struct clocksource *cs) |
|
| 649 |
- {
|
|
| 650 |
-@@ -95,11 +96,45 @@ static struct clocksource clocksource_vmware = {
|
|
| 651 |
- }; |
|
| 652 |
- |
|
| 653 |
- #ifdef CONFIG_VMWARE_ONLY |
|
| 654 |
-+/* |
|
| 655 |
-+ * clocksource_vmware_periodic - is a temporary clocksource only for |
|
| 656 |
-+ * early boot initialization. |
|
| 657 |
-+ * Hack to avoid infinite looping in calibrate_APIC_clock() when |
|
| 658 |
-+ * tsc_deadline_timer is not supported by hypervisor (VM version <= 10) |
|
| 659 |
-+ * calibrate_APIC_clock() relies on _periodic_ timer! |
|
| 660 |
-+ * In that case we do not need to use clocksource that is valid for |
|
| 661 |
-+ * hres/oneshot timer. |
|
| 662 |
-+ */ |
|
| 663 |
-+static struct clocksource __initdata clocksource_vmware_periodic = {
|
|
| 664 |
-+ .name = "vmware-clock-periodic", |
|
| 665 |
-+ .read = vmware_clock_get_cycles, |
|
| 666 |
-+ .rating = 100, |
|
| 667 |
-+ .mask = CLOCKSOURCE_MASK(64), |
|
| 668 |
-+}; |
|
| 669 |
-+ |
|
| 670 |
-+static struct clocksource __initdata * initial_clocksource; |
|
| 671 |
-+ |
|
| 672 |
-+/* |
|
| 673 |
-+ * clocksource_vmware_register |
|
| 674 |
-+ * |
|
| 675 |
-+ * Time to register real clocksource. It will be activated in |
|
| 676 |
-+ * clocksource_done_booting(). |
|
| 677 |
-+ */ |
|
| 678 |
-+static int __init clocksource_vmware_register(void) |
|
| 679 |
-+{
|
|
| 680 |
-+ if (!boot_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER)) {
|
|
| 681 |
-+ clocksource_register_khz(&clocksource_vmware, vtsc_khz); |
|
| 682 |
-+ clocksource_unregister(&clocksource_vmware_periodic); |
|
| 683 |
-+ } |
|
| 684 |
-+ return 0; |
|
| 685 |
-+} |
|
| 686 |
-+subsys_initcall(clocksource_vmware_register); |
|
| 687 |
-+ |
|
| 688 |
- /* We want to use clocksource_vmware from the beginning to avoid drifting in |
|
| 689 |
- monotonic clock */ |
|
| 690 |
- struct clocksource * __init clocksource_default_clock(void) |
|
| 691 |
- {
|
|
| 692 |
-- return &clocksource_vmware; |
|
| 693 |
-+ return initial_clocksource; |
|
| 694 |
- } |
|
| 695 |
- #endif |
|
| 696 |
- |
|
| 697 |
-@@ -147,7 +182,6 @@ static void __init paravirt_ops_setup(void) |
|
| 698 |
- |
|
| 699 |
- static void __init vmware_platform_setup(void) |
|
| 700 |
- {
|
|
| 701 |
-- uint64_t vtsc_khz; |
|
| 702 |
- uint32_t eax, ebx, ecx, edx; |
|
| 703 |
- |
|
| 704 |
- VMWARE_PORT(GETHZ, eax, ebx, ecx, edx); |
|
| 705 |
-@@ -169,7 +203,15 @@ static void __init vmware_platform_setup(void) |
|
| 706 |
- vmware_cyc2ns.cyc2ns_shift = CYC2NS_SCALE_FACTOR; |
|
| 707 |
- vmware_cyc2ns.cyc2ns_offset = tsc_at_head; |
|
| 708 |
- |
|
| 709 |
-+#ifdef CONFIG_VMWARE_ONLY |
|
| 710 |
-+ if (!boot_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER)) |
|
| 711 |
-+ initial_clocksource = &clocksource_vmware_periodic; |
|
| 712 |
-+ else |
|
| 713 |
-+ initial_clocksource = &clocksource_vmware; |
|
| 714 |
-+ clocksource_register_khz(initial_clocksource, vtsc_khz); |
|
| 715 |
-+#else |
|
| 716 |
- clocksource_register_khz(&clocksource_vmware, vtsc_khz); |
|
| 717 |
-+#endif |
|
| 718 |
- |
|
| 719 |
- paravirt_ops_setup(); |
|
| 720 |
- } |
|
| 721 |
-2.11.0 |
|
| 722 |
- |
|
| 723 |
- |
|
| 724 |
-From 15e6d2cc5239e58ab805f882650ad7de9b163228 Mon Sep 17 00:00:00 2001 |
|
| 725 |
-From: Alexey Makhalov <amakhalov@vmware.com> |
|
| 726 |
-Date: Tue, 10 Nov 2015 11:46:57 +0000 |
|
| 727 |
-Subject: [PATCH 06/15] Get lapic timer frequency from HV, skip calibration |
|
| 728 |
- |
|
| 729 |
- arch/x86/kernel/cpu/vmware.c | 48 +++++--------------------------------------- |
|
| 730 |
- 1 file changed, 5 insertions(+), 43 deletions(-) |
|
| 731 |
- |
|
| 732 |
-diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c |
|
| 733 |
-index 0b89bb976a35..b16618b5f880 100644 |
|
| 734 |
-+++ b/arch/x86/kernel/cpu/vmware.c |
|
| 735 |
-@@ -96,45 +96,11 @@ static struct clocksource clocksource_vmware = {
|
|
| 736 |
- }; |
|
| 737 |
- |
|
| 738 |
- #ifdef CONFIG_VMWARE_ONLY |
|
| 739 |
--/* |
|
| 740 |
-- * clocksource_vmware_periodic - is a temporary clocksource only for |
|
| 741 |
-- * early boot initialization. |
|
| 742 |
-- * Hack to avoid infinite looping in calibrate_APIC_clock() when |
|
| 743 |
-- * tsc_deadline_timer is not supported by hypervisor (VM version <= 10) |
|
| 744 |
-- * calibrate_APIC_clock() relies on _periodic_ timer! |
|
| 745 |
-- * In that case we do not need to use clocksource that is valid for |
|
| 746 |
-- * hres/oneshot timer. |
|
| 747 |
-- */ |
|
| 748 |
--static struct clocksource __initdata clocksource_vmware_periodic = {
|
|
| 749 |
-- .name = "vmware-clock-periodic", |
|
| 750 |
-- .read = vmware_clock_get_cycles, |
|
| 751 |
-- .rating = 100, |
|
| 752 |
-- .mask = CLOCKSOURCE_MASK(64), |
|
| 753 |
--}; |
|
| 754 |
-- |
|
| 755 |
--static struct clocksource __initdata * initial_clocksource; |
|
| 756 |
-- |
|
| 757 |
--/* |
|
| 758 |
-- * clocksource_vmware_register |
|
| 759 |
-- * |
|
| 760 |
-- * Time to register real clocksource. It will be activated in |
|
| 761 |
-- * clocksource_done_booting(). |
|
| 762 |
-- */ |
|
| 763 |
--static int __init clocksource_vmware_register(void) |
|
| 764 |
--{
|
|
| 765 |
-- if (!boot_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER)) {
|
|
| 766 |
-- clocksource_register_khz(&clocksource_vmware, vtsc_khz); |
|
| 767 |
-- clocksource_unregister(&clocksource_vmware_periodic); |
|
| 768 |
-- } |
|
| 769 |
-- return 0; |
|
| 770 |
--} |
|
| 771 |
--subsys_initcall(clocksource_vmware_register); |
|
| 772 |
-- |
|
| 773 |
- /* We want to use clocksource_vmware from the beginning to avoid drifting in |
|
| 774 |
- monotonic clock */ |
|
| 775 |
- struct clocksource * __init clocksource_default_clock(void) |
|
| 776 |
- {
|
|
| 777 |
-- return initial_clocksource; |
|
| 778 |
-+ return &clocksource_vmware; |
|
| 779 |
- } |
|
| 780 |
- #endif |
|
| 781 |
- |
|
| 782 |
-@@ -197,21 +163,17 @@ static void __init vmware_platform_setup(void) |
|
| 783 |
- printk(KERN_INFO "Pre Kernel boot time: %dms\n", |
|
| 784 |
- (unsigned int) (tsc_at_head / vtsc_khz)); |
|
| 785 |
- |
|
| 786 |
-+#ifdef CONFIG_X86_LOCAL_APIC |
|
| 787 |
-+ /* Skip lapic calibration since we know bus frequency. */ |
|
| 788 |
-+ lapic_timer_frequency = ecx; |
|
| 789 |
-+#endif |
|
| 790 |
- vmware_cyc2ns.cyc2ns_mul = |
|
| 791 |
- DIV_ROUND_CLOSEST(NSEC_PER_MSEC << CYC2NS_SCALE_FACTOR, |
|
| 792 |
- vtsc_khz); |
|
| 793 |
- vmware_cyc2ns.cyc2ns_shift = CYC2NS_SCALE_FACTOR; |
|
| 794 |
- vmware_cyc2ns.cyc2ns_offset = tsc_at_head; |
|
| 795 |
- |
|
| 796 |
--#ifdef CONFIG_VMWARE_ONLY |
|
| 797 |
-- if (!boot_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER)) |
|
| 798 |
-- initial_clocksource = &clocksource_vmware_periodic; |
|
| 799 |
-- else |
|
| 800 |
-- initial_clocksource = &clocksource_vmware; |
|
| 801 |
-- clocksource_register_khz(initial_clocksource, vtsc_khz); |
|
| 802 |
--#else |
|
| 803 |
- clocksource_register_khz(&clocksource_vmware, vtsc_khz); |
|
| 804 |
--#endif |
|
| 805 |
- |
|
| 806 |
- paravirt_ops_setup(); |
|
| 807 |
- } |
|
| 808 |
-2.11.0 |
|
| 809 |
- |
|
| 810 |
- |
|
| 811 |
-From 10ebf94df7ed241429a04b2cc3c2d590dd97d7dd Mon Sep 17 00:00:00 2001 |
|
| 812 |
-From: Alexey Makhalov <amakhalov@vmware.com> |
|
| 813 |
-Date: Tue, 15 Dec 2015 21:31:18 +0000 |
|
| 814 |
-Subject: [PATCH 07/15] Skip rdrand reseed |
|
| 815 |
- |
|
| 816 |
- arch/x86/kernel/cpu/common.c | 2 ++ |
|
| 817 |
- arch/x86/kernel/cpu/rdrand.c | 2 ++ |
|
| 818 |
- 2 files changed, 4 insertions(+) |
|
| 819 |
- |
|
| 820 | 412 |
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c |
| 821 |
-index c2b7522cbf35..45a37dac1388 100644 |
|
| 413 |
+index 637ca41..2635ce9 100644 |
|
| 822 | 414 |
--- a/arch/x86/kernel/cpu/common.c |
| 823 | 415 |
+++ b/arch/x86/kernel/cpu/common.c |
| 824 |
-@@ -944,7 +944,9 @@ static void identify_cpu(struct cpuinfo_x86 *c) |
|
| 416 |
+@@ -943,7 +943,9 @@ static void identify_cpu(struct cpuinfo_x86 *c) |
|
| 825 | 417 |
#endif |
| 826 | 418 |
|
| 827 | 419 |
init_hypervisor(c); |
| ... | ... |
@@ -845,7 +100,7 @@ index c2b7522cbf35..45a37dac1388 100644 |
| 845 | 845 |
|
| 846 | 846 |
/* |
| 847 | 847 |
diff --git a/arch/x86/kernel/cpu/rdrand.c b/arch/x86/kernel/cpu/rdrand.c |
| 848 |
-index 136ac74dee82..06858910dfca 100644 |
|
| 848 |
+index 136ac74..0685891 100644 |
|
| 849 | 849 |
--- a/arch/x86/kernel/cpu/rdrand.c |
| 850 | 850 |
+++ b/arch/x86/kernel/cpu/rdrand.c |
| 851 | 851 |
@@ -32,6 +32,7 @@ static int __init x86_rdrand_setup(char *s) |
| ... | ... |
@@ -861,55 +116,60 @@ index 136ac74dee82..06858910dfca 100644 |
| 861 | 861 |
#endif |
| 862 | 862 |
} |
| 863 | 863 |
+#endif |
| 864 |
-2.11.0 |
|
| 865 |
- |
|
| 866 |
- |
|
| 867 |
-From 237e42455bd98cf6e0e0725d35bba1b6d0d04822 Mon Sep 17 00:00:00 2001 |
|
| 868 |
-From: Alexey Makhalov <amakhalov@vmware.com> |
|
| 869 |
-Date: Thu, 3 Dec 2015 00:46:46 +0000 |
|
| 870 |
-Subject: [PATCH 08/15] STA implementation. first version. |
|
| 871 |
- |
|
| 872 |
- arch/x86/kernel/cpu/vmware.c | 163 +++++++++++++++++++++++++++++++++++++++++++ |
|
| 873 |
- 1 file changed, 163 insertions(+) |
|
| 874 |
- |
|
| 875 | 864 |
diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c |
| 876 |
-index b16618b5f880..cf1fb6476af8 100644 |
|
| 865 |
+index 628a059..43aae4e 100644 |
|
| 877 | 866 |
--- a/arch/x86/kernel/cpu/vmware.c |
| 878 | 867 |
+++ b/arch/x86/kernel/cpu/vmware.c |
| 879 |
-@@ -28,6 +28,8 @@ |
|
| 868 |
+@@ -26,25 +26,73 @@ |
|
| 869 |
+ #include <asm/div64.h> |
|
| 870 |
+ #include <asm/x86_init.h> |
|
| 880 | 871 |
#include <asm/hypervisor.h> |
| 881 |
- #include <asm/timer.h> |
|
| 882 |
- #include <linux/sched.h> |
|
| 872 |
++#include <asm/timer.h> |
|
| 873 |
++#include <linux/sched.h> |
|
| 883 | 874 |
+#include <linux/cpu.h> |
| 884 | 875 |
+#include <asm/pci_x86.h> |
| 876 |
++#include <linux/kmsg_dump.h> |
|
| 885 | 877 |
|
| 886 |
- #define CPUID_VMWARE_INFO_LEAF 0x40000000 |
|
| 887 |
- #define VMWARE_HYPERVISOR_MAGIC 0x564D5868 |
|
| 888 |
-@@ -38,6 +40,10 @@ |
|
| 878 |
+-#define CPUID_VMWARE_INFO_LEAF 0x40000000 |
|
| 879 |
+-#define VMWARE_HYPERVISOR_MAGIC 0x564D5868 |
|
| 880 |
+-#define VMWARE_HYPERVISOR_PORT 0x5658 |
|
| 881 |
++#define CPUID_VMWARE_INFO_LEAF 0x40000000 |
|
| 882 |
++#define VMWARE_HYPERVISOR_MAGIC 0x564D5868 |
|
| 883 |
++#define VMWARE_HYPERVISOR_PORT 0x5658 |
|
| 884 |
++#define VMWARE_HYPERVISOR_HB_PORT 0x5659 |
|
| 885 |
+ |
|
| 886 |
+ #define VMWARE_PORT_CMD_GETVERSION 10 |
|
| 887 |
+ #define VMWARE_PORT_CMD_GETHZ 45 |
|
| 889 | 888 |
#define VMWARE_PORT_CMD_GETVCPU_INFO 68 |
| 890 | 889 |
#define VMWARE_PORT_CMD_LEGACY_X2APIC 3 |
| 891 | 890 |
#define VMWARE_PORT_CMD_VCPU_RESERVED 31 |
| 892 | 891 |
+#define VMWARE_PORT_CMD_STEALCLOCK 91 |
| 893 |
-+# define CMD_STEALCLOCK_ENABLE 0 |
|
| 894 |
-+# define CMD_STEALCLOCK_DISABLE 1 |
|
| 895 |
-+ |
|
| 892 |
++# define STEALCLOCK_IS_NOT_AVALIABLE -1 |
|
| 893 |
++# define STEALCLOCK_IS_DISABLED 0 |
|
| 894 |
++# define STEALCLOCK_IS_ENABLED 1 |
|
| 895 |
++#define VMWARE_PORT_CMD_MESSAGE 30 |
|
| 896 |
++#define VMWARE_HB_PORT_CMD_MESSAGE 0 |
|
| 896 | 897 |
|
| 897 | 898 |
#define VMWARE_PORT(cmd, eax, ebx, ecx, edx) \ |
| 899 |
++ VMWARE_PORT2(cmd, eax, ebx, ecx, edx, UINT_MAX) |
|
| 900 |
++ |
|
| 901 |
++#define VMWARE_PORT2(cmd, eax, ebx, ecx, edx, arg) \ |
|
| 898 | 902 |
__asm__("inl (%%dx)" : \
|
| 899 |
-@@ -47,6 +53,34 @@ |
|
| 900 |
- "2"(VMWARE_HYPERVISOR_PORT), "3"(UINT_MAX) : \ |
|
| 903 |
+ "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) : \ |
|
| 904 |
+ "0"(VMWARE_HYPERVISOR_MAGIC), \ |
|
| 905 |
+ "1"(VMWARE_PORT_CMD_##cmd), \ |
|
| 906 |
+- "2"(VMWARE_HYPERVISOR_PORT), "3"(UINT_MAX) : \ |
|
| 907 |
++ "2"(VMWARE_HYPERVISOR_PORT), "3"(arg) : \ |
|
| 901 | 908 |
"memory"); |
| 902 | 909 |
|
| 903 | 910 |
+struct vmware_steal_time {
|
| 904 | 911 |
+ uint64_t clock; /* stolen time counter in units of vtsc */ |
| 905 |
-+ uint64_t reserved; |
|
| 912 |
++ uint64_t reserved[7]; |
|
| 906 | 913 |
+}; |
| 907 | 914 |
+static DEFINE_PER_CPU(struct vmware_steal_time, steal_time) __aligned(64); |
| 908 | 915 |
+static int has_steal_clock = 0; |
| 909 | 916 |
+ |
| 910 |
-+static int vmware_cmd_stealclock(int subcmd, uint32_t arg1, uint32_t arg2) |
|
| 917 |
++static int vmware_cmd_stealclock(uint32_t arg1, uint32_t arg2) |
|
| 911 | 918 |
+{
|
| 912 | 919 |
+ uint32_t result, info; |
| 913 | 920 |
+ __asm__ __volatile__ ("inl (%%dx)"
|
| ... | ... |
@@ -918,25 +178,88 @@ index b16618b5f880..cf1fb6476af8 100644 |
| 918 | 918 |
+ : "a" (VMWARE_HYPERVISOR_MAGIC), |
| 919 | 919 |
+ "c" (VMWARE_PORT_CMD_STEALCLOCK), |
| 920 | 920 |
+ "d" (VMWARE_HYPERVISOR_PORT), |
| 921 |
-+ "b" (subcmd), |
|
| 921 |
++ "b" (0), |
|
| 922 | 922 |
+ "S" (arg1), |
| 923 | 923 |
+ "D" (arg2)); |
| 924 | 924 |
+ return result; |
| 925 | 925 |
+} |
| 926 | 926 |
+#define STEALCLOCK_ENABLE(pa) \ |
| 927 |
-+ vmware_cmd_stealclock(CMD_STEALCLOCK_ENABLE, \ |
|
| 928 |
-+ (pa) >> 32, (pa) & 0xffffffff) |
|
| 927 |
++ (vmware_cmd_stealclock((pa) >> 32, (pa) & 0xffffffff) \ |
|
| 928 |
++ == STEALCLOCK_IS_ENABLED) |
|
| 929 | 929 |
+ |
| 930 | 930 |
+#define STEALCLOCK_DISABLE() \ |
| 931 |
-+ vmware_cmd_stealclock(CMD_STEALCLOCK_DISABLE, 0, 0) |
|
| 931 |
++ vmware_cmd_stealclock(0, 1) |
|
| 932 |
++ |
|
| 933 |
++static int vmware_is_stealclock_available(void) |
|
| 934 |
++{
|
|
| 935 |
++ return STEALCLOCK_DISABLE() != STEALCLOCK_IS_NOT_AVALIABLE; |
|
| 936 |
++} |
|
| 932 | 937 |
+ |
| 933 | 938 |
static inline int __vmware_platform(void) |
| 934 | 939 |
{
|
| 935 | 940 |
uint32_t eax, ebx, ecx, edx; |
| 936 |
-@@ -134,6 +168,114 @@ static void vmware_read_boot_clock64(struct timespec64 *ts) |
|
| 937 |
- } |
|
| 941 |
+@@ -75,17 +123,246 @@ static unsigned long vmware_get_tsc_khz(void) |
|
| 942 |
+ return tsc_hz; |
|
| 938 | 943 |
} |
| 939 | 944 |
|
| 945 |
++#define CYC2NS_SCALE_FACTOR 8 |
|
| 946 |
++static struct cyc2ns_data vmware_cyc2ns; |
|
| 947 |
++uint64_t __initdata tsc_at_head; |
|
| 948 |
++uint64_t __initdata vtsc_khz; |
|
| 949 |
++ |
|
| 950 |
++static cycle_t vmware_clock_get_cycles(struct clocksource *cs) |
|
| 951 |
++{
|
|
| 952 |
++ return (cycle_t)rdtsc_ordered(); |
|
| 953 |
++} |
|
| 954 |
++ |
|
| 955 |
++static struct clocksource clocksource_vmware = {
|
|
| 956 |
++ .name = "vmware-clock", |
|
| 957 |
++ .read = vmware_clock_get_cycles, |
|
| 958 |
++ .rating = 400, |
|
| 959 |
++ .mask = CLOCKSOURCE_MASK(64), |
|
| 960 |
++ .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
|
| 961 |
++ .archdata = { .vclock_mode = VCLOCK_TSC },
|
|
| 962 |
++}; |
|
| 963 |
++ |
|
| 964 |
++#ifdef CONFIG_VMWARE_ONLY |
|
| 965 |
++/* We want to use clocksource_vmware from the beginning to avoid drifting in |
|
| 966 |
++ monotonic clock */ |
|
| 967 |
++struct clocksource * __init clocksource_default_clock(void) |
|
| 968 |
++{
|
|
| 969 |
++ return &clocksource_vmware; |
|
| 970 |
++} |
|
| 971 |
++#endif |
|
| 972 |
++ |
|
| 973 |
++static u64 vmware_sched_clock(void) |
|
| 974 |
++{
|
|
| 975 |
++ u64 ret; |
|
| 976 |
++ |
|
| 977 |
++ ret = rdtsc() - vmware_cyc2ns.cyc2ns_offset; |
|
| 978 |
++ ret = mul_u64_u32_shr(ret, vmware_cyc2ns.cyc2ns_mul, CYC2NS_SCALE_FACTOR); |
|
| 979 |
++ return ret; |
|
| 980 |
++} |
|
| 981 |
++ |
|
| 982 |
++ |
|
| 983 |
++/* Function to read the exact time the system has been started. It will be |
|
| 984 |
++ used as zero time for monotonic clock */ |
|
| 985 |
++static void vmware_read_boot_clock64(struct timespec64 *ts) |
|
| 986 |
++{
|
|
| 987 |
++ struct timespec64 now; |
|
| 988 |
++ u64 delta, delta_nsec; |
|
| 989 |
++ u32 rem; |
|
| 990 |
++ |
|
| 991 |
++ read_persistent_clock64(&now); |
|
| 992 |
++ delta = rdtsc() - vmware_cyc2ns.cyc2ns_offset; |
|
| 993 |
++ delta_nsec = mul_u64_u32_shr(delta, vmware_cyc2ns.cyc2ns_mul, |
|
| 994 |
++ CYC2NS_SCALE_FACTOR); |
|
| 995 |
++ ts->tv_sec = now.tv_sec - div_s64_rem(delta_nsec, NSEC_PER_SEC, &rem); |
|
| 996 |
++ ts->tv_nsec = now.tv_nsec - rem; |
|
| 997 |
++ while (unlikely(ts->tv_nsec < 0)) {
|
|
| 998 |
++ ts->tv_sec--; |
|
| 999 |
++ ts->tv_nsec += NSEC_PER_SEC; |
|
| 1000 |
++ } |
|
| 1001 |
++} |
|
| 1002 |
++ |
|
| 940 | 1003 |
+static uint64_t vmware_steal_clock(int cpu) |
| 941 | 1004 |
+{
|
| 942 | 1005 |
+ struct vmware_steal_time *steal; |
| ... | ... |
@@ -956,7 +279,7 @@ index b16618b5f880..cf1fb6476af8 100644 |
| 956 | 956 |
+ |
| 957 | 957 |
+ memset(st, 0, sizeof(*st)); |
| 958 | 958 |
+ |
| 959 |
-+ if (STEALCLOCK_ENABLE(slow_virt_to_phys(st)) != 0) {
|
|
| 959 |
++ if (!STEALCLOCK_ENABLE(slow_virt_to_phys(st))) {
|
|
| 960 | 960 |
+ has_steal_clock = 0; |
| 961 | 961 |
+ return; |
| 962 | 962 |
+ } |
| ... | ... |
@@ -1045,300 +368,24 @@ index b16618b5f880..cf1fb6476af8 100644 |
| 1045 | 1045 |
+arch_initcall(activate_jump_labels); |
| 1046 | 1046 |
+ |
| 1047 | 1047 |
+ |
| 1048 |
- static void __init paravirt_ops_setup(void) |
|
| 1049 |
- {
|
|
| 1050 |
- pv_info.name = "VMware"; |
|
| 1051 |
-@@ -141,9 +283,18 @@ static void __init paravirt_ops_setup(void) |
|
| 1052 |
- pv_time_ops.sched_clock = vmware_sched_clock; |
|
| 1053 |
- pv_time_ops.read_boot_clock64 = vmware_read_boot_clock64; |
|
| 1054 |
- |
|
| 1055 |
-+ /* |
|
| 1056 |
-+ * TODO: check for STEAL_TIME support |
|
| 1057 |
-+ */ |
|
| 1058 |
-+ if (1) {
|
|
| 1048 |
++static void __init paravirt_ops_setup(void) |
|
| 1049 |
++{
|
|
| 1050 |
++ pv_info.name = "VMware"; |
|
| 1051 |
++ pv_cpu_ops.io_delay = paravirt_nop; |
|
| 1052 |
++ pv_time_ops.sched_clock = vmware_sched_clock; |
|
| 1053 |
++ pv_time_ops.read_boot_clock64 = vmware_read_boot_clock64; |
|
| 1054 |
++ |
|
| 1055 |
++ if (vmware_is_stealclock_available()) {
|
|
| 1059 | 1056 |
+ has_steal_clock = 1; |
| 1060 | 1057 |
+ pv_time_ops.steal_clock = vmware_steal_clock; |
| 1061 | 1058 |
+ } |
| 1062 | 1059 |
+ |
| 1063 |
- #ifdef CONFIG_X86_IO_APIC |
|
| 1064 |
- no_timer_check = 1; |
|
| 1065 |
- #endif |
|
| 1066 |
-+ |
|
| 1067 |
- } |
|
| 1068 |
- |
|
| 1069 |
- static void __init vmware_platform_setup(void) |
|
| 1070 |
-@@ -176,6 +327,18 @@ static void __init vmware_platform_setup(void) |
|
| 1071 |
- clocksource_register_khz(&clocksource_vmware, vtsc_khz); |
|
| 1072 |
- |
|
| 1073 |
- paravirt_ops_setup(); |
|
| 1074 |
-+ |
|
| 1075 |
-+#ifdef CONFIG_SMP |
|
| 1076 |
-+ smp_ops.smp_prepare_boot_cpu = vmware_smp_prepare_boot_cpu; |
|
| 1077 |
-+ register_cpu_notifier(&vmware_cpu_notifier); |
|
| 1078 |
-+#else |
|
| 1079 |
-+ vmware_guest_cpu_init(); |
|
| 1080 |
-+#endif |
|
| 1081 |
-+ |
|
| 1082 |
-+#ifdef CONFIG_PCI |
|
| 1083 |
-+ /* PCI BIOS service won't work from a PV guest. */ |
|
| 1084 |
-+ pci_probe &= ~PCI_PROBE_BIOS; |
|
| 1060 |
++#ifdef CONFIG_X86_IO_APIC |
|
| 1061 |
++ no_timer_check = 1; |
|
| 1085 | 1062 |
+#endif |
| 1086 |
- } |
|
| 1087 |
- |
|
| 1088 |
- /* |
|
| 1089 |
-2.11.0 |
|
| 1090 |
- |
|
| 1091 |
- |
|
| 1092 |
-From 21249118757b7232948c8401ba5d0b039cd0fa35 Mon Sep 17 00:00:00 2001 |
|
| 1093 |
-From: Alexey Makhalov <amakhalov@vmware.com> |
|
| 1094 |
-Date: Wed, 13 Jan 2016 22:54:04 +0000 |
|
| 1095 |
-Subject: [PATCH 09/15] STA. updated version |
|
| 1096 |
- |
|
| 1097 |
- arch/x86/kernel/cpu/vmware.c | 34 ++++++++++++++++++++++++---------- |
|
| 1098 |
- 1 file changed, 24 insertions(+), 10 deletions(-) |
|
| 1099 |
- |
|
| 1100 |
-diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c |
|
| 1101 |
-index cf1fb6476af8..196703c7ec49 100644 |
|
| 1102 |
-+++ b/arch/x86/kernel/cpu/vmware.c |
|
| 1103 |
-@@ -41,16 +41,23 @@ |
|
| 1104 |
- #define VMWARE_PORT_CMD_LEGACY_X2APIC 3 |
|
| 1105 |
- #define VMWARE_PORT_CMD_VCPU_RESERVED 31 |
|
| 1106 |
- #define VMWARE_PORT_CMD_STEALCLOCK 91 |
|
| 1107 |
--# define CMD_STEALCLOCK_ENABLE 0 |
|
| 1108 |
--# define CMD_STEALCLOCK_DISABLE 1 |
|
| 1109 |
-+# define CMD_STEALCLOCK_STATUS 0 |
|
| 1110 |
-+# define STEALCLOCK_IS_NOT_AVALIABLE 0 |
|
| 1111 |
-+# define STEALCLOCK_IS_ENABLED 1 |
|
| 1112 |
-+# define STEALCLOCK_IS_DISABLED 2 |
|
| 1113 |
-+# define CMD_STEALCLOCK_ENABLE 1 |
|
| 1114 |
-+# define CMD_STEALCLOCK_DISABLE 2 |
|
| 1115 |
- |
|
| 1116 |
- |
|
| 1117 |
- #define VMWARE_PORT(cmd, eax, ebx, ecx, edx) \ |
|
| 1118 |
-+ VMWARE_PORT2(cmd, eax, ebx, ecx, edx, UINT_MAX) |
|
| 1119 | 1063 |
+ |
| 1120 |
-+#define VMWARE_PORT2(cmd, eax, ebx, ecx, edx, arg) \ |
|
| 1121 |
- __asm__("inl (%%dx)" : \
|
|
| 1122 |
- "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) : \ |
|
| 1123 |
- "0"(VMWARE_HYPERVISOR_MAGIC), \ |
|
| 1124 |
- "1"(VMWARE_PORT_CMD_##cmd), \ |
|
| 1125 |
-- "2"(VMWARE_HYPERVISOR_PORT), "3"(UINT_MAX) : \ |
|
| 1126 |
-+ "2"(VMWARE_HYPERVISOR_PORT), "3"(arg) : \ |
|
| 1127 |
- "memory"); |
|
| 1128 |
- |
|
| 1129 |
- struct vmware_steal_time {
|
|
| 1130 |
-@@ -60,6 +67,13 @@ struct vmware_steal_time {
|
|
| 1131 |
- static DEFINE_PER_CPU(struct vmware_steal_time, steal_time) __aligned(64); |
|
| 1132 |
- static int has_steal_clock = 0; |
|
| 1133 |
- |
|
| 1134 |
-+static int vmware_is_stealclock_available(void) |
|
| 1135 |
-+{
|
|
| 1136 |
-+ uint32_t eax, ebx, ecx, edx; |
|
| 1137 |
-+ VMWARE_PORT2(STEALCLOCK, eax, ebx, ecx, edx, CMD_STEALCLOCK_STATUS); |
|
| 1138 |
-+ printk("%s:%d %d %d\n", __FUNCTION__, __LINE__, eax, ebx);
|
|
| 1139 |
-+ return eax == 0 && ebx != STEALCLOCK_IS_NOT_AVALIABLE; |
|
| 1140 | 1064 |
+} |
| 1141 |
- static int vmware_cmd_stealclock(int subcmd, uint32_t arg1, uint32_t arg2) |
|
| 1142 |
- {
|
|
| 1143 |
- uint32_t result, info; |
|
| 1144 |
-@@ -283,10 +297,7 @@ static void __init paravirt_ops_setup(void) |
|
| 1145 |
- pv_time_ops.sched_clock = vmware_sched_clock; |
|
| 1146 |
- pv_time_ops.read_boot_clock64 = vmware_read_boot_clock64; |
|
| 1147 |
- |
|
| 1148 |
-- /* |
|
| 1149 |
-- * TODO: check for STEAL_TIME support |
|
| 1150 |
-- */ |
|
| 1151 |
-- if (1) {
|
|
| 1152 |
-+ if (vmware_is_stealclock_available()) {
|
|
| 1153 |
- has_steal_clock = 1; |
|
| 1154 |
- pv_time_ops.steal_clock = vmware_steal_clock; |
|
| 1155 |
- } |
|
| 1156 |
-@@ -328,12 +339,15 @@ static void __init vmware_platform_setup(void) |
|
| 1157 |
- |
|
| 1158 |
- paravirt_ops_setup(); |
|
| 1159 |
- |
|
| 1160 |
-+ /* vmware_cpu_notifier is used only by STA */ |
|
| 1161 |
-+ if (has_steal_clock) {
|
|
| 1162 |
- #ifdef CONFIG_SMP |
|
| 1163 |
-- smp_ops.smp_prepare_boot_cpu = vmware_smp_prepare_boot_cpu; |
|
| 1164 |
-- register_cpu_notifier(&vmware_cpu_notifier); |
|
| 1165 |
-+ smp_ops.smp_prepare_boot_cpu = vmware_smp_prepare_boot_cpu; |
|
| 1166 |
-+ register_cpu_notifier(&vmware_cpu_notifier); |
|
| 1167 |
- #else |
|
| 1168 |
-- vmware_guest_cpu_init(); |
|
| 1169 |
-+ vmware_guest_cpu_init(); |
|
| 1170 |
- #endif |
|
| 1171 |
-+ } |
|
| 1172 |
- |
|
| 1173 |
- #ifdef CONFIG_PCI |
|
| 1174 |
- /* PCI BIOS service won't work from a PV guest. */ |
|
| 1175 |
-2.11.0 |
|
| 1176 |
- |
|
| 1177 |
- |
|
| 1178 |
-From 7061430a3c8906e67978da76a73967b0b26aece7 Mon Sep 17 00:00:00 2001 |
|
| 1179 |
-From: Alexey Makhalov <amakhalov@vmware.com> |
|
| 1180 |
-Date: Tue, 15 Mar 2016 22:29:23 +0000 |
|
| 1181 |
-Subject: [PATCH 10/15] STA: version with a single backdoor command. |
|
| 1182 |
- |
|
| 1183 |
- arch/x86/kernel/cpu/vmware.c | 35 +++++++++++++++-------------------- |
|
| 1184 |
- 1 file changed, 15 insertions(+), 20 deletions(-) |
|
| 1185 |
- |
|
| 1186 |
-diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c |
|
| 1187 |
-index 196703c7ec49..743b8ad32119 100644 |
|
| 1188 |
-+++ b/arch/x86/kernel/cpu/vmware.c |
|
| 1189 |
-@@ -41,12 +41,9 @@ |
|
| 1190 |
- #define VMWARE_PORT_CMD_LEGACY_X2APIC 3 |
|
| 1191 |
- #define VMWARE_PORT_CMD_VCPU_RESERVED 31 |
|
| 1192 |
- #define VMWARE_PORT_CMD_STEALCLOCK 91 |
|
| 1193 |
--# define CMD_STEALCLOCK_STATUS 0 |
|
| 1194 |
--# define STEALCLOCK_IS_NOT_AVALIABLE 0 |
|
| 1195 |
--# define STEALCLOCK_IS_ENABLED 1 |
|
| 1196 |
--# define STEALCLOCK_IS_DISABLED 2 |
|
| 1197 |
--# define CMD_STEALCLOCK_ENABLE 1 |
|
| 1198 |
--# define CMD_STEALCLOCK_DISABLE 2 |
|
| 1199 |
-+# define STEALCLOCK_IS_NOT_AVALIABLE -1 |
|
| 1200 |
-+# define STEALCLOCK_IS_DISABLED 0 |
|
| 1201 |
-+# define STEALCLOCK_IS_ENABLED 1 |
|
| 1202 |
- |
|
| 1203 |
- |
|
| 1204 |
- #define VMWARE_PORT(cmd, eax, ebx, ecx, edx) \ |
|
| 1205 |
-@@ -62,19 +59,12 @@ |
|
| 1206 |
- |
|
| 1207 |
- struct vmware_steal_time {
|
|
| 1208 |
- uint64_t clock; /* stolen time counter in units of vtsc */ |
|
| 1209 |
-- uint64_t reserved; |
|
| 1210 |
-+ uint64_t reserved[7]; |
|
| 1211 |
- }; |
|
| 1212 |
- static DEFINE_PER_CPU(struct vmware_steal_time, steal_time) __aligned(64); |
|
| 1213 |
- static int has_steal_clock = 0; |
|
| 1214 |
- |
|
| 1215 |
--static int vmware_is_stealclock_available(void) |
|
| 1216 |
--{
|
|
| 1217 |
-- uint32_t eax, ebx, ecx, edx; |
|
| 1218 |
-- VMWARE_PORT2(STEALCLOCK, eax, ebx, ecx, edx, CMD_STEALCLOCK_STATUS); |
|
| 1219 |
-- printk("%s:%d %d %d\n", __FUNCTION__, __LINE__, eax, ebx);
|
|
| 1220 |
-- return eax == 0 && ebx != STEALCLOCK_IS_NOT_AVALIABLE; |
|
| 1221 |
--} |
|
| 1222 |
--static int vmware_cmd_stealclock(int subcmd, uint32_t arg1, uint32_t arg2) |
|
| 1223 |
-+static int vmware_cmd_stealclock(uint32_t arg1, uint32_t arg2) |
|
| 1224 |
- {
|
|
| 1225 |
- uint32_t result, info; |
|
| 1226 |
- __asm__ __volatile__ ("inl (%%dx)"
|
|
| 1227 |
-@@ -83,17 +73,22 @@ static int vmware_cmd_stealclock(int subcmd, uint32_t arg1, uint32_t arg2) |
|
| 1228 |
- : "a" (VMWARE_HYPERVISOR_MAGIC), |
|
| 1229 |
- "c" (VMWARE_PORT_CMD_STEALCLOCK), |
|
| 1230 |
- "d" (VMWARE_HYPERVISOR_PORT), |
|
| 1231 |
-- "b" (subcmd), |
|
| 1232 |
-+ "b" (0), |
|
| 1233 |
- "S" (arg1), |
|
| 1234 |
- "D" (arg2)); |
|
| 1235 |
- return result; |
|
| 1236 |
- } |
|
| 1237 |
- #define STEALCLOCK_ENABLE(pa) \ |
|
| 1238 |
-- vmware_cmd_stealclock(CMD_STEALCLOCK_ENABLE, \ |
|
| 1239 |
-- (pa) >> 32, (pa) & 0xffffffff) |
|
| 1240 |
-+ (vmware_cmd_stealclock((pa) >> 32, (pa) & 0xffffffff) \ |
|
| 1241 |
-+ == STEALCLOCK_IS_ENABLED) |
|
| 1242 |
- |
|
| 1243 |
- #define STEALCLOCK_DISABLE() \ |
|
| 1244 |
-- vmware_cmd_stealclock(CMD_STEALCLOCK_DISABLE, 0, 0) |
|
| 1245 |
-+ vmware_cmd_stealclock(0, 1) |
|
| 1246 | 1065 |
+ |
| 1247 |
-+static int vmware_is_stealclock_available(void) |
|
| 1248 |
-+{
|
|
| 1249 |
-+ return STEALCLOCK_DISABLE() != STEALCLOCK_IS_NOT_AVALIABLE; |
|
| 1250 |
-+} |
|
| 1251 |
- |
|
| 1252 |
- static inline int __vmware_platform(void) |
|
| 1253 |
- {
|
|
| 1254 |
-@@ -201,7 +196,7 @@ static void vmware_register_steal_time(void) |
|
| 1255 |
- |
|
| 1256 |
- memset(st, 0, sizeof(*st)); |
|
| 1257 |
- |
|
| 1258 |
-- if (STEALCLOCK_ENABLE(slow_virt_to_phys(st)) != 0) {
|
|
| 1259 |
-+ if (!STEALCLOCK_ENABLE(slow_virt_to_phys(st))) {
|
|
| 1260 |
- has_steal_clock = 0; |
|
| 1261 |
- return; |
|
| 1262 |
- } |
|
| 1263 |
-2.11.0 |
|
| 1264 |
- |
|
| 1265 |
- |
|
| 1266 |
-From ee3ab56a4bdca7e514b4d07b6a70f724cde7f0f5 Mon Sep 17 00:00:00 2001 |
|
| 1267 |
-From: Alexey Makhalov <amakhalov@vmware.com> |
|
| 1268 |
-Date: Fri, 25 Mar 2016 01:14:17 +0000 |
|
| 1269 |
-Subject: [PATCH 11/15] Remove delays for smpboot |
|
| 1270 |
- |
|
| 1271 |
- arch/x86/kernel/smpboot.c | 2 +- |
|
| 1272 |
- 1 file changed, 1 insertion(+), 1 deletion(-) |
|
| 1273 |
- |
|
| 1274 |
-diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c |
|
| 1275 |
-index fbabe4fcc7fb..5a18dd6dcf07 100644 |
|
| 1276 |
-+++ b/arch/x86/kernel/smpboot.c |
|
| 1277 |
-@@ -557,7 +557,7 @@ wakeup_secondary_cpu_via_nmi(int apicid, unsigned long start_eip) |
|
| 1278 |
- /* |
|
| 1279 |
- * Give the other CPU some time to accept the IPI. |
|
| 1280 |
- */ |
|
| 1281 |
-- udelay(200); |
|
| 1282 |
-+// udelay(200); |
|
| 1283 |
- if (APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
|
|
| 1284 |
- maxlvt = lapic_get_maxlvt(); |
|
| 1285 |
- if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */ |
|
| 1286 |
-2.11.0 |
|
| 1287 |
- |
|
| 1288 |
- |
|
| 1289 |
-From c6ade3b8c3db962d24e07ff9a483d26e46a41bb0 Mon Sep 17 00:00:00 2001 |
|
| 1290 |
-From: Alexey Makhalov <amakhalov@vmware.com> |
|
| 1291 |
-Date: Tue, 29 Mar 2016 21:14:46 +0000 |
|
| 1292 |
-Subject: [PATCH 12/15] kmsg_dumper to vmware.log |
|
| 1293 |
- |
|
| 1294 |
- arch/x86/kernel/cpu/vmware.c | 143 +++++++++++++++++++++++++++++++++++++++++-- |
|
| 1295 |
- 1 file changed, 139 insertions(+), 4 deletions(-) |
|
| 1296 |
- |
|
| 1297 |
-diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c |
|
| 1298 |
-index 743b8ad32119..e9f7d520d33c 100644 |
|
| 1299 |
-+++ b/arch/x86/kernel/cpu/vmware.c |
|
| 1300 |
-@@ -30,10 +30,12 @@ |
|
| 1301 |
- #include <linux/sched.h> |
|
| 1302 |
- #include <linux/cpu.h> |
|
| 1303 |
- #include <asm/pci_x86.h> |
|
| 1304 |
-+#include <linux/kmsg_dump.h> |
|
| 1305 |
- |
|
| 1306 |
--#define CPUID_VMWARE_INFO_LEAF 0x40000000 |
|
| 1307 |
--#define VMWARE_HYPERVISOR_MAGIC 0x564D5868 |
|
| 1308 |
--#define VMWARE_HYPERVISOR_PORT 0x5658 |
|
| 1309 |
-+#define CPUID_VMWARE_INFO_LEAF 0x40000000 |
|
| 1310 |
-+#define VMWARE_HYPERVISOR_MAGIC 0x564D5868 |
|
| 1311 |
-+#define VMWARE_HYPERVISOR_PORT 0x5658 |
|
| 1312 |
-+#define VMWARE_HYPERVISOR_HB_PORT 0x5659 |
|
| 1313 |
- |
|
| 1314 |
- #define VMWARE_PORT_CMD_GETVERSION 10 |
|
| 1315 |
- #define VMWARE_PORT_CMD_GETHZ 45 |
|
| 1316 |
-@@ -44,7 +46,8 @@ |
|
| 1317 |
- # define STEALCLOCK_IS_NOT_AVALIABLE -1 |
|
| 1318 |
- # define STEALCLOCK_IS_DISABLED 0 |
|
| 1319 |
- # define STEALCLOCK_IS_ENABLED 1 |
|
| 1320 |
-- |
|
| 1321 |
-+#define VMWARE_PORT_CMD_MESSAGE 30 |
|
| 1322 |
-+#define VMWARE_HB_PORT_CMD_MESSAGE 0 |
|
| 1323 |
- |
|
| 1324 |
- #define VMWARE_PORT(cmd, eax, ebx, ecx, edx) \ |
|
| 1325 |
- VMWARE_PORT2(cmd, eax, ebx, ecx, edx, UINT_MAX) |
|
| 1326 |
-@@ -303,6 +306,13 @@ static void __init paravirt_ops_setup(void) |
|
| 1327 |
- |
|
| 1328 |
- } |
|
| 1329 |
- |
|
| 1330 | 1066 |
+static void kmsg_dumper_vmware_log(struct kmsg_dumper *dumper, |
| 1331 | 1067 |
+ enum kmsg_dump_reason reason); |
| 1332 | 1068 |
+ |
| ... | ... |
@@ -1349,15 +396,67 @@ index 743b8ad32119..e9f7d520d33c 100644 |
| 1349 | 1349 |
static void __init vmware_platform_setup(void) |
| 1350 | 1350 |
{
|
| 1351 | 1351 |
uint32_t eax, ebx, ecx, edx; |
| 1352 |
-@@ -348,6 +358,7 @@ static void __init vmware_platform_setup(void) |
|
| 1353 |
- /* PCI BIOS service won't work from a PV guest. */ |
|
| 1354 |
- pci_probe &= ~PCI_PROBE_BIOS; |
|
| 1355 |
- #endif |
|
| 1352 |
+ |
|
| 1353 |
+ VMWARE_PORT(GETHZ, eax, ebx, ecx, edx); |
|
| 1354 |
+ |
|
| 1355 |
+- if (ebx != UINT_MAX) |
|
| 1356 |
++ if (ebx != UINT_MAX) {
|
|
| 1357 |
+ x86_platform.calibrate_tsc = vmware_get_tsc_khz; |
|
| 1358 |
++#ifdef CONFIG_X86_LOCAL_APIC |
|
| 1359 |
++ /* Skip lapic calibration since we know the bus frequency. */ |
|
| 1360 |
++ lapic_timer_frequency = ecx / HZ; |
|
| 1361 |
++ pr_info("Host bus clock speed read from hypervisor : %u Hz\n",
|
|
| 1362 |
++ ecx); |
|
| 1363 |
++#endif |
|
| 1364 |
++ } |
|
| 1365 |
+ else |
|
| 1366 |
+ printk(KERN_WARNING |
|
| 1367 |
+ "Failed to get TSC freq from the hypervisor\n"); |
|
| 1368 |
++ |
|
| 1369 |
++ vtsc_khz = eax | (((uint64_t)ebx) << 32); |
|
| 1370 |
++ do_div(vtsc_khz, 1000); |
|
| 1371 |
++ printk(KERN_INFO "Pre Kernel boot time: %dms\n", |
|
| 1372 |
++ (unsigned int) (tsc_at_head / vtsc_khz)); |
|
| 1373 |
++ |
|
| 1374 |
++ vmware_cyc2ns.cyc2ns_mul = |
|
| 1375 |
++ DIV_ROUND_CLOSEST(NSEC_PER_MSEC << CYC2NS_SCALE_FACTOR, |
|
| 1376 |
++ vtsc_khz); |
|
| 1377 |
++ vmware_cyc2ns.cyc2ns_shift = CYC2NS_SCALE_FACTOR; |
|
| 1378 |
++ vmware_cyc2ns.cyc2ns_offset = tsc_at_head; |
|
| 1379 |
++ |
|
| 1380 |
++ clocksource_register_khz(&clocksource_vmware, vtsc_khz); |
|
| 1381 |
++ |
|
| 1382 |
++ paravirt_ops_setup(); |
|
| 1383 |
++ |
|
| 1384 |
++ /* vmware_cpu_notifier is used only by STA */ |
|
| 1385 |
++ if (has_steal_clock) {
|
|
| 1386 |
++#ifdef CONFIG_SMP |
|
| 1387 |
++ smp_ops.smp_prepare_boot_cpu = vmware_smp_prepare_boot_cpu; |
|
| 1388 |
++ register_cpu_notifier(&vmware_cpu_notifier); |
|
| 1389 |
++#else |
|
| 1390 |
++ vmware_guest_cpu_init(); |
|
| 1391 |
++#endif |
|
| 1392 |
++ } |
|
| 1393 |
++ |
|
| 1394 |
++#ifdef CONFIG_PCI |
|
| 1395 |
++ /* PCI BIOS service won't work from a PV guest. */ |
|
| 1396 |
++ pci_probe &= ~PCI_PROBE_BIOS; |
|
| 1397 |
++#endif |
|
| 1356 | 1398 |
+ kmsg_dump_register(&kmsg_dumper); |
| 1357 | 1399 |
} |
| 1358 | 1400 |
|
| 1359 | 1401 |
/* |
| 1360 |
-@@ -410,3 +421,127 @@ const __refconst struct hypervisor_x86 x86_hyper_vmware = {
|
|
| 1402 |
+@@ -95,6 +372,9 @@ static void __init vmware_platform_setup(void) |
|
| 1403 |
+ */ |
|
| 1404 |
+ static uint32_t __init vmware_platform(void) |
|
| 1405 |
+ {
|
|
| 1406 |
++#ifndef CONFIG_VMWARE_ONLY |
|
| 1407 |
++ tsc_at_head = rdtsc(); |
|
| 1408 |
++#endif |
|
| 1409 |
+ if (cpu_has_hypervisor) {
|
|
| 1410 |
+ unsigned int eax; |
|
| 1411 |
+ unsigned int hyper_vendor_id[3]; |
|
| 1412 |
+@@ -145,3 +425,127 @@ const __refconst struct hypervisor_x86 x86_hyper_vmware = {
|
|
| 1361 | 1413 |
.x2apic_available = vmware_legacy_x2apic_available, |
| 1362 | 1414 |
}; |
| 1363 | 1415 |
EXPORT_SYMBOL(x86_hyper_vmware); |
| ... | ... |
@@ -1485,141 +584,102 @@ index 743b8ad32119..e9f7d520d33c 100644 |
| 1485 | 1485 |
+ break; |
| 1486 | 1486 |
+ } |
| 1487 | 1487 |
+} |
| 1488 |
-2.11.0 |
|
| 1489 |
- |
|
| 1490 |
- |
|
| 1491 |
-From 9edf1bf3a56c8c8048d2958d13283df5a283acd1 Mon Sep 17 00:00:00 2001 |
|
| 1492 |
-From: Alexey Makhalov <amakhalov@vmware.com> |
|
| 1493 |
-Date: Mon, 9 May 2016 04:14:03 -0700 |
|
| 1494 |
-Subject: [PATCH 13/15] __native_read_tsc() -> rdtsc() |
|
| 1495 |
- |
|
| 1496 |
- arch/x86/kernel/cpu/vmware.c | 8 ++++---- |
|
| 1497 |
- 1 file changed, 4 insertions(+), 4 deletions(-) |
|
| 1498 |
- |
|
| 1499 |
-diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c |
|
| 1500 |
-index e9f7d520d33c..57cef56c8ccb 100644 |
|
| 1501 |
-+++ b/arch/x86/kernel/cpu/vmware.c |
|
| 1502 |
-@@ -130,7 +130,7 @@ uint64_t __initdata vtsc_khz; |
|
| 1488 |
+diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S |
|
| 1489 |
+index ffdc0e8..1bc0140 100644 |
|
| 1490 |
+--- a/arch/x86/kernel/head_64.S |
|
| 1491 |
+@@ -65,6 +65,16 @@ startup_64: |
|
| 1492 |
+ * tables and then reload them. |
|
| 1493 |
+ */ |
|
| 1503 | 1494 |
|
| 1504 |
- static cycle_t vmware_clock_get_cycles(struct clocksource *cs) |
|
| 1505 |
- {
|
|
| 1506 |
-- return __native_read_tsc(); |
|
| 1507 |
-+ return rdtsc(); |
|
| 1495 |
++#ifdef CONFIG_VMWARE_ONLY |
|
| 1496 |
++ /* |
|
| 1497 |
++ * Read a TSC value first |
|
| 1498 |
++ */ |
|
| 1499 |
++ rdtsc |
|
| 1500 |
++ shl $0x20, %rdx |
|
| 1501 |
++ or %rax, %rdx |
|
| 1502 |
++ mov %rdx, tsc_at_head(%rip) |
|
| 1503 |
++#endif |
|
| 1504 |
++ |
|
| 1505 |
+ /* Sanitize CPU configuration */ |
|
| 1506 |
+ call verify_cpu |
|
| 1507 |
+ |
|
| 1508 |
+diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c |
|
| 1509 |
+index f534a0e..93b24e4 100644 |
|
| 1510 |
+--- a/arch/x86/kernel/paravirt.c |
|
| 1511 |
+@@ -218,6 +218,12 @@ static u64 native_steal_clock(int cpu) |
|
| 1512 |
+ return 0; |
|
| 1508 | 1513 |
} |
| 1509 | 1514 |
|
| 1510 |
- static struct clocksource clocksource_vmware = {
|
|
| 1511 |
-@@ -154,7 +154,7 @@ static u64 vmware_sched_clock(void) |
|
| 1512 |
- {
|
|
| 1513 |
- u64 ret; |
|
| 1515 |
++static void native_read_boot_clock64(struct timespec64 *ts) |
|
| 1516 |
++{
|
|
| 1517 |
++ ts->tv_sec = 0; |
|
| 1518 |
++ ts->tv_nsec = 0; |
|
| 1519 |
++} |
|
| 1520 |
++ |
|
| 1521 |
+ /* These are in entry.S */ |
|
| 1522 |
+ extern void native_iret(void); |
|
| 1523 |
+ extern void native_irq_enable_sysexit(void); |
|
| 1524 |
+@@ -328,6 +334,7 @@ struct pv_init_ops pv_init_ops = {
|
|
| 1525 |
+ struct pv_time_ops pv_time_ops = {
|
|
| 1526 |
+ .sched_clock = native_sched_clock, |
|
| 1527 |
+ .steal_clock = native_steal_clock, |
|
| 1528 |
++ .read_boot_clock64 = native_read_boot_clock64, |
|
| 1529 |
+ }; |
|
| 1514 | 1530 |
|
| 1515 |
-- ret = __native_read_tsc() - vmware_cyc2ns.cyc2ns_offset; |
|
| 1516 |
-+ ret = rdtsc() - vmware_cyc2ns.cyc2ns_offset; |
|
| 1517 |
- ret = mul_u64_u32_shr(ret, vmware_cyc2ns.cyc2ns_mul, CYC2NS_SCALE_FACTOR); |
|
| 1518 |
- return ret; |
|
| 1531 |
+ __visible struct pv_irq_ops pv_irq_ops = {
|
|
| 1532 |
+diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c |
|
| 1533 |
+index e67b834..8b78a86 100644 |
|
| 1534 |
+--- a/arch/x86/kernel/setup.c |
|
| 1535 |
+@@ -1287,3 +1287,12 @@ static int __init register_kernel_offset_dumper(void) |
|
| 1536 |
+ return 0; |
|
| 1519 | 1537 |
} |
| 1520 |
-@@ -169,7 +169,7 @@ static void vmware_read_boot_clock64(struct timespec64 *ts) |
|
| 1521 |
- u32 rem; |
|
| 1522 |
- |
|
| 1523 |
- read_persistent_clock64(&now); |
|
| 1524 |
-- delta = __native_read_tsc() - vmware_cyc2ns.cyc2ns_offset; |
|
| 1525 |
-+ delta = rdtsc() - vmware_cyc2ns.cyc2ns_offset; |
|
| 1526 |
- delta_nsec = mul_u64_u32_shr(delta, vmware_cyc2ns.cyc2ns_mul, |
|
| 1527 |
- CYC2NS_SCALE_FACTOR); |
|
| 1528 |
- ts->tv_sec = now.tv_sec - div_s64_rem(delta_nsec, NSEC_PER_SEC, &rem); |
|
| 1529 |
-@@ -369,7 +369,7 @@ static void __init vmware_platform_setup(void) |
|
| 1530 |
- static uint32_t __init vmware_platform(void) |
|
| 1531 |
- {
|
|
| 1532 |
- #ifndef CONFIG_VMWARE_ONLY |
|
| 1533 |
-- tsc_at_head = __native_read_tsc(); |
|
| 1534 |
-+ tsc_at_head = rdtsc(); |
|
| 1535 |
- #endif |
|
| 1536 |
- if (cpu_has_hypervisor) {
|
|
| 1537 |
- unsigned int eax; |
|
| 1538 |
-2.11.0 |
|
| 1539 |
- |
|
| 1540 |
- |
|
| 1541 |
-From 42ac37f4ec59aee6b37b7beed93c7e1055d14522 Mon Sep 17 00:00:00 2001 |
|
| 1542 |
-From: Alexey Makhalov <amakhalov@vmware.com> |
|
| 1543 |
-Date: Thu, 6 Oct 2016 11:24:55 -0700 |
|
| 1544 |
-Subject: [PATCH 14/15] Fix lapic_timer_frequency |
|
| 1545 |
- |
|
| 1546 |
- arch/x86/kernel/cpu/vmware.c | 15 +++++++++------ |
|
| 1547 |
- 1 file changed, 9 insertions(+), 6 deletions(-) |
|
| 1548 |
- |
|
| 1549 |
-diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c |
|
| 1550 |
-index 57cef56c8ccb..63fe6c826609 100644 |
|
| 1551 |
-+++ b/arch/x86/kernel/cpu/vmware.c |
|
| 1552 |
-@@ -291,7 +291,7 @@ arch_initcall(activate_jump_labels); |
|
| 1553 |
- static void __init paravirt_ops_setup(void) |
|
| 1538 |
+ __initcall(register_kernel_offset_dumper); |
|
| 1539 |
++ |
|
| 1540 |
++/* We need to define a real function for read_boot_clock64, to override the |
|
| 1541 |
++ weak default version */ |
|
| 1542 |
++#ifdef CONFIG_PARAVIRT |
|
| 1543 |
++void read_boot_clock64(struct timespec64 *ts) |
|
| 1544 |
++{
|
|
| 1545 |
++ paravirt_read_boot_clock64(ts); |
|
| 1546 |
++} |
|
| 1547 |
++#endif |
|
| 1548 |
+diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c |
|
| 1549 |
+index fbabe4f..5a18dd6 100644 |
|
| 1550 |
+--- a/arch/x86/kernel/smpboot.c |
|
| 1551 |
+@@ -557,7 +557,7 @@ wakeup_secondary_cpu_via_nmi(int apicid, unsigned long start_eip) |
|
| 1552 |
+ /* |
|
| 1553 |
+ * Give the other CPU some time to accept the IPI. |
|
| 1554 |
+ */ |
|
| 1555 |
+- udelay(200); |
|
| 1556 |
++// udelay(200); |
|
| 1557 |
+ if (APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
|
|
| 1558 |
+ maxlvt = lapic_get_maxlvt(); |
|
| 1559 |
+ if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */ |
|
| 1560 |
+diff --git a/kernel/sched/clock.c b/kernel/sched/clock.c |
|
| 1561 |
+index caf4041..377ab5a 100644 |
|
| 1562 |
+--- a/kernel/sched/clock.c |
|
| 1563 |
+@@ -385,8 +385,15 @@ u64 cpu_clock(int cpu) |
|
| 1564 |
+ */ |
|
| 1565 |
+ u64 local_clock(void) |
|
| 1554 | 1566 |
{
|
| 1555 |
- pv_info.name = "VMware"; |
|
| 1556 |
-- pv_cpu_ops.io_delay = paravirt_nop, |
|
| 1557 |
-+ pv_cpu_ops.io_delay = paravirt_nop; |
|
| 1558 |
- pv_time_ops.sched_clock = vmware_sched_clock; |
|
| 1559 |
- pv_time_ops.read_boot_clock64 = vmware_read_boot_clock64; |
|
| 1560 |
- |
|
| 1561 |
-@@ -319,8 +319,15 @@ static void __init vmware_platform_setup(void) |
|
| 1562 |
- |
|
| 1563 |
- VMWARE_PORT(GETHZ, eax, ebx, ecx, edx); |
|
| 1564 |
- |
|
| 1565 |
-- if (ebx != UINT_MAX) |
|
| 1566 |
-+ if (ebx != UINT_MAX) {
|
|
| 1567 |
- x86_platform.calibrate_tsc = vmware_get_tsc_khz; |
|
| 1568 |
-+#ifdef CONFIG_X86_LOCAL_APIC |
|
| 1569 |
-+ /* Skip lapic calibration since we know the bus frequency. */ |
|
| 1570 |
-+ lapic_timer_frequency = ecx / HZ; |
|
| 1571 |
-+ pr_info("Host bus clock speed read from hypervisor : %u Hz\n",
|
|
| 1572 |
-+ ecx); |
|
| 1567 |
++ /* |
|
| 1568 |
++ * sched_clock is stable and running for VMware guest. |
|
| 1569 |
++ * Let's disable this checking. It will allow us to have |
|
| 1570 |
++ * printk timestamps from the beginning |
|
| 1571 |
++ */ |
|
| 1572 |
++#if !defined(CONFIG_VMWARE_ONLY) || !defined(CONFIG_PRINTK_TIME) |
|
| 1573 |
+ if (!sched_clock_stable()) |
|
| 1574 |
+ return sched_clock_cpu(raw_smp_processor_id()); |
|
| 1573 | 1575 |
+#endif |
| 1574 |
-+ } |
|
| 1575 |
- else |
|
| 1576 |
- printk(KERN_WARNING |
|
| 1577 |
- "Failed to get TSC freq from the hypervisor\n"); |
|
| 1578 |
-@@ -330,10 +337,6 @@ static void __init vmware_platform_setup(void) |
|
| 1579 |
- printk(KERN_INFO "Pre Kernel boot time: %dms\n", |
|
| 1580 |
- (unsigned int) (tsc_at_head / vtsc_khz)); |
|
| 1581 | 1576 |
|
| 1582 |
--#ifdef CONFIG_X86_LOCAL_APIC |
|
| 1583 |
-- /* Skip lapic calibration since we know bus frequency. */ |
|
| 1584 |
-- lapic_timer_frequency = ecx; |
|
| 1585 |
--#endif |
|
| 1586 |
- vmware_cyc2ns.cyc2ns_mul = |
|
| 1587 |
- DIV_ROUND_CLOSEST(NSEC_PER_MSEC << CYC2NS_SCALE_FACTOR, |
|
| 1588 |
- vtsc_khz); |
|
| 1589 |
-2.11.0 |
|
| 1590 |
- |
|
| 1591 |
- |
|
| 1592 |
-From 5dbe97455f3584ba0aee180321d095f0ed0c26ef Mon Sep 17 00:00:00 2001 |
|
| 1593 |
-From: Alexey Makhalov <amakhalov@vmware.com> |
|
| 1594 |
-Date: Thu, 27 Apr 2017 16:29:20 -0700 |
|
| 1595 |
-Subject: [PATCH 15/15] clocksource_vmware: use rdtsc_ordered() |
|
| 1596 |
- |
|
| 1597 |
-It adds a barrier, thus preventing observable non-monotonicity. |
|
| 1598 |
-It fixes bug #1852790 |
|
| 1599 |
- arch/x86/kernel/cpu/vmware.c | 2 +- |
|
| 1600 |
- 1 file changed, 1 insertion(+), 1 deletion(-) |
|
| 1601 |
- |
|
| 1602 |
-diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c |
|
| 1603 |
-index 63fe6c826609..5f36b36c0d5e 100644 |
|
| 1604 |
-+++ b/arch/x86/kernel/cpu/vmware.c |
|
| 1605 |
-@@ -130,7 +130,7 @@ uint64_t __initdata vtsc_khz; |
|
| 1606 |
- |
|
| 1607 |
- static cycle_t vmware_clock_get_cycles(struct clocksource *cs) |
|
| 1608 |
- {
|
|
| 1609 |
-- return rdtsc(); |
|
| 1610 |
-+ return (cycle_t)rdtsc_ordered(); |
|
| 1577 |
+ return sched_clock(); |
|
| 1611 | 1578 |
} |
| 1612 |
- |
|
| 1613 |
- static struct clocksource clocksource_vmware = {
|
|
| 1614 | 1579 |
-- |
| 1615 |
-2.11.0 |
|
| 1580 |
+2.8.1 |
|
| 1616 | 1581 |
|
| ... | ... |
@@ -4271,6 +4271,7 @@ CONFIG_CRYPTO_HASH2=y |
| 4271 | 4271 |
CONFIG_CRYPTO_RNG=m |
| 4272 | 4272 |
CONFIG_CRYPTO_RNG2=y |
| 4273 | 4273 |
CONFIG_CRYPTO_RNG_DEFAULT=m |
| 4274 |
+CONFIG_CRYPTO_PCOMP=m |
|
| 4274 | 4275 |
CONFIG_CRYPTO_PCOMP2=y |
| 4275 | 4276 |
CONFIG_CRYPTO_AKCIPHER2=y |
| 4276 | 4277 |
CONFIG_CRYPTO_AKCIPHER=y |
| ... | ... |
@@ -4294,8 +4295,8 @@ CONFIG_CRYPTO_GLUE_HELPER_X86=m |
| 4294 | 4294 |
# |
| 4295 | 4295 |
# Authenticated Encryption with Associated Data |
| 4296 | 4296 |
# |
| 4297 |
-# CONFIG_CRYPTO_CCM is not set |
|
| 4298 |
-# CONFIG_CRYPTO_GCM is not set |
|
| 4297 |
+CONFIG_CRYPTO_CCM=m |
|
| 4298 |
+CONFIG_CRYPTO_GCM=m |
|
| 4299 | 4299 |
# CONFIG_CRYPTO_CHACHA20POLY1305 is not set |
| 4300 | 4300 |
CONFIG_CRYPTO_SEQIV=m |
| 4301 | 4301 |
CONFIG_CRYPTO_ECHAINIV=m |
| ... | ... |
@@ -4329,7 +4330,7 @@ CONFIG_CRYPTO_CRC32C_INTEL=m |
| 4329 | 4329 |
# CONFIG_CRYPTO_CRC32_PCLMUL is not set |
| 4330 | 4330 |
CONFIG_CRYPTO_CRCT10DIF=y |
| 4331 | 4331 |
# CONFIG_CRYPTO_CRCT10DIF_PCLMUL is not set |
| 4332 |
-# CONFIG_CRYPTO_GHASH is not set |
|
| 4332 |
+CONFIG_CRYPTO_GHASH=m |
|
| 4333 | 4333 |
# CONFIG_CRYPTO_POLY1305 is not set |
| 4334 | 4334 |
# CONFIG_CRYPTO_POLY1305_X86_64 is not set |
| 4335 | 4335 |
CONFIG_CRYPTO_MD4=m |
| ... | ... |
@@ -4391,8 +4392,8 @@ CONFIG_CRYPTO_DES=m |
| 4391 | 4391 |
# Compression |
| 4392 | 4392 |
# |
| 4393 | 4393 |
CONFIG_CRYPTO_DEFLATE=m |
| 4394 |
-# CONFIG_CRYPTO_ZLIB is not set |
|
| 4395 |
-# CONFIG_CRYPTO_LZO is not set |
|
| 4394 |
+CONFIG_CRYPTO_ZLIB=m |
|
| 4395 |
+CONFIG_CRYPTO_LZO=m |
|
| 4396 | 4396 |
# CONFIG_CRYPTO_842 is not set |
| 4397 | 4397 |
# CONFIG_CRYPTO_LZ4 is not set |
| 4398 | 4398 |
# CONFIG_CRYPTO_LZ4HC is not set |
| 392 | 391 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,51 @@ |
| 0 |
+From 6399f1fae4ec29fab5ec76070435555e256ca3a6 Mon Sep 17 00:00:00 2001 |
|
| 1 |
+From: Sabrina Dubroca <sd@queasysnail.net> |
|
| 2 |
+Date: Wed, 19 Jul 2017 22:28:55 +0200 |
|
| 3 |
+Subject: [PATCH] ipv6: avoid overflow of offset in ip6_find_1stfragopt |
|
| 4 |
+ |
|
| 5 |
+In some cases, offset can overflow and can cause an infinite loop in |
|
| 6 |
+ip6_find_1stfragopt(). Make it unsigned int to prevent the overflow, and |
|
| 7 |
+cap it at IPV6_MAXPLEN, since packets larger than that should be invalid. |
|
| 8 |
+ |
|
| 9 |
+This problem has been here since before the beginning of git history. |
|
| 10 |
+ |
|
| 11 |
+Signed-off-by: Sabrina Dubroca <sd@queasysnail.net> |
|
| 12 |
+Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org> |
|
| 13 |
+Signed-off-by: David S. Miller <davem@davemloft.net> |
|
| 14 |
+--- |
|
| 15 |
+ net/ipv6/output_core.c | 8 ++++++-- |
|
| 16 |
+ 1 file changed, 6 insertions(+), 2 deletions(-) |
|
| 17 |
+ |
|
| 18 |
+diff --git a/net/ipv6/output_core.c b/net/ipv6/output_core.c |
|
| 19 |
+index e9065b8d3af85..abb2c307fbe83 100644 |
|
| 20 |
+--- a/net/ipv6/output_core.c |
|
| 21 |
+@@ -78,7 +78,7 @@ EXPORT_SYMBOL(ipv6_select_ident); |
|
| 22 |
+ |
|
| 23 |
+ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) |
|
| 24 |
+ {
|
|
| 25 |
+- u16 offset = sizeof(struct ipv6hdr); |
|
| 26 |
++ unsigned int offset = sizeof(struct ipv6hdr); |
|
| 27 |
+ unsigned int packet_len = skb_tail_pointer(skb) - |
|
| 28 |
+ skb_network_header(skb); |
|
| 29 |
+ int found_rhdr = 0; |
|
| 30 |
+@@ -86,6 +86,7 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) |
|
| 31 |
+ |
|
| 32 |
+ while (offset <= packet_len) {
|
|
| 33 |
+ struct ipv6_opt_hdr *exthdr; |
|
| 34 |
++ unsigned int len; |
|
| 35 |
+ |
|
| 36 |
+ switch (**nexthdr) {
|
|
| 37 |
+ |
|
| 38 |
+@@ -111,7 +112,10 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) |
|
| 39 |
+ |
|
| 40 |
+ exthdr = (struct ipv6_opt_hdr *)(skb_network_header(skb) + |
|
| 41 |
+ offset); |
|
| 42 |
+- offset += ipv6_optlen(exthdr); |
|
| 43 |
++ len = ipv6_optlen(exthdr); |
|
| 44 |
++ if (len + offset >= IPV6_MAXPLEN) |
|
| 45 |
++ return -EINVAL; |
|
| 46 |
++ offset += len; |
|
| 47 |
+ *nexthdr = &exthdr->nexthdr; |
|
| 48 |
+ } |
|
| 49 |
+ |
| ... | ... |
@@ -2,7 +2,7 @@ |
| 2 | 2 |
Summary: Kernel |
| 3 | 3 |
Name: linux-esx |
| 4 | 4 |
Version: 4.4.79 |
| 5 |
-Release: 1%{?dist}
|
|
| 5 |
+Release: 2%{?dist}
|
|
| 6 | 6 |
License: GPLv2 |
| 7 | 7 |
URL: http://www.kernel.org/ |
| 8 | 8 |
Group: System Environment/Kernel |
| ... | ... |
@@ -35,6 +35,9 @@ Patch20: vmci-1.1.4.0-use-32bit-atomics-for-queue-headers.patch |
| 35 | 35 |
Patch21: vmci-1.1.5.0-doorbell-create-and-destroy-fixes.patch |
| 36 | 36 |
Patch22: net-9p-vsock.patch |
| 37 | 37 |
Patch23: p9fs_dir_readdir-offset-support.patch |
| 38 |
+# Fix CVE-2017-7542 |
|
| 39 |
+Patch24: ipv6-avoid-overflow-of-offset-in-ip6_find_1stfragopt.patch |
|
| 40 |
+ |
|
| 38 | 41 |
BuildRequires: bc |
| 39 | 42 |
BuildRequires: kbd |
| 40 | 43 |
BuildRequires: kmod |
| ... | ... |
@@ -94,6 +97,7 @@ The Linux package contains the Linux kernel doc files |
| 94 | 94 |
%patch21 -p1 |
| 95 | 95 |
%patch22 -p1 |
| 96 | 96 |
%patch23 -p1 |
| 97 |
+%patch24 -p1 |
|
| 97 | 98 |
|
| 98 | 99 |
%build |
| 99 | 100 |
# patch vmw_balloon driver |
| ... | ... |
@@ -182,6 +186,9 @@ ln -sf linux-%{uname_r}.cfg /boot/photon.cfg
|
| 182 | 182 |
/usr/src/linux-headers-%{uname_r}
|
| 183 | 183 |
|
| 184 | 184 |
%changelog |
| 185 |
+* Tue Aug 08 2017 Alexey Makhalov <amakhalov@vmware.com> 4.4.79-2 |
|
| 186 |
+- [bugfix] Do not fallback to syscall from VDSO on clock_gettime(MONOTONIC) |
|
| 187 |
+- Fix CVE-2017-7542 |
|
| 185 | 188 |
* Fri Jul 28 2017 Alexey Makhalov <amakhalov@vmware.com> 4.4.79-1 |
| 186 | 189 |
- [feature] p9fs_dir_readdir() offset support |
| 187 | 190 |
- Fix CVE-2017-11473 |
| ... | ... |
@@ -2,7 +2,7 @@ |
| 2 | 2 |
Summary: Kernel |
| 3 | 3 |
Name: linux |
| 4 | 4 |
Version: 4.4.79 |
| 5 |
-Release: 1%{?dist}
|
|
| 5 |
+Release: 2%{?dist}
|
|
| 6 | 6 |
License: GPLv2 |
| 7 | 7 |
URL: http://www.kernel.org/ |
| 8 | 8 |
Group: System Environment/Kernel |
| ... | ... |
@@ -36,6 +36,10 @@ Patch16: net-9p-vsock.patch |
| 36 | 36 |
#allow some algorithms in FIPS mode |
| 37 | 37 |
Patch17: 0001-Revert-crypto-testmgr-Disable-fips-allowed-for-authe.patch |
| 38 | 38 |
Patch18: 0002-allow-also-ecb-cipher_null.patch |
| 39 |
+# Fix CVE-2017-10911 |
|
| 40 |
+Patch19: xen-blkback-dont-leak-stack-data-via-response-ring.patch |
|
| 41 |
+# Fix CVE-2017-7542 |
|
| 42 |
+Patch20: ipv6-avoid-overflow-of-offset-in-ip6_find_1stfragopt.patch |
|
| 39 | 43 |
|
| 40 | 44 |
BuildRequires: bc |
| 41 | 45 |
BuildRequires: kbd |
| ... | ... |
@@ -125,6 +129,8 @@ This package contains the 'perf' performance analysis tools for Linux kernel. |
| 125 | 125 |
%patch16 -p1 |
| 126 | 126 |
%patch17 -p1 |
| 127 | 127 |
%patch18 -p1 |
| 128 |
+%patch19 -p1 |
|
| 129 |
+%patch20 -p1 |
|
| 128 | 130 |
|
| 129 | 131 |
%build |
| 130 | 132 |
make mrproper |
| ... | ... |
@@ -277,6 +283,10 @@ ln -sf %{name}-%{uname_r}.cfg /boot/photon.cfg
|
| 277 | 277 |
/usr/share/perf-core |
| 278 | 278 |
|
| 279 | 279 |
%changelog |
| 280 |
+* Tue Aug 08 2017 Alexey Makhalov <amakhalov@vmware.com> 4.4.79-2 |
|
| 281 |
+- Fix CVE-2017-10911, CVE-2017-7542 |
|
| 282 |
+- [bugfix] Added ccm,gcm,ghash,zlib,lzo crypto modules to avoid |
|
| 283 |
+ panic on modprobe tcrypt |
|
| 280 | 284 |
* Wed Aug 02 2017 Alexey Makhalov <amakhalov@vmware.com> 4.4.79-1 |
| 281 | 285 |
- Fix CVE-2017-11473 |
| 282 | 286 |
* Tue Aug 01 2017 Anish Swaminathan <anishs@vmware.com> 4.4.77-2 |
| 283 | 287 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,125 @@ |
| 0 |
+From 089bc0143f489bd3a4578bdff5f4ca68fb26f341 Mon Sep 17 00:00:00 2001 |
|
| 1 |
+From: Jan Beulich <jbeulich@suse.com> |
|
| 2 |
+Date: Tue, 13 Jun 2017 16:28:27 -0400 |
|
| 3 |
+Subject: [PATCH] xen-blkback: don't leak stack data via response ring |
|
| 4 |
+ |
|
| 5 |
+Rather than constructing a local structure instance on the stack, fill |
|
| 6 |
+the fields directly on the shared ring, just like other backends do. |
|
| 7 |
+Build on the fact that all response structure flavors are actually |
|
| 8 |
+identical (the old code did make this assumption too). |
|
| 9 |
+ |
|
| 10 |
+This is XSA-216. |
|
| 11 |
+ |
|
| 12 |
+Cc: stable@vger.kernel.org |
|
| 13 |
+ |
|
| 14 |
+Signed-off-by: Jan Beulich <jbeulich@suse.com> |
|
| 15 |
+Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> |
|
| 16 |
+Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> |
|
| 17 |
+--- |
|
| 18 |
+ drivers/block/xen-blkback/blkback.c | 23 ++++++++++++----------- |
|
| 19 |
+ drivers/block/xen-blkback/common.h | 25 +++++-------------------- |
|
| 20 |
+ 2 files changed, 17 insertions(+), 31 deletions(-) |
|
| 21 |
+ |
|
| 22 |
+diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c |
|
| 23 |
+index 6b14c509f3c7b..0e824091a12fa 100644 |
|
| 24 |
+--- a/drivers/block/xen-blkback/blkback.c |
|
| 25 |
+@@ -1433,33 +1433,34 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, |
|
| 26 |
+ static void make_response(struct xen_blkif *blkif, u64 id, |
|
| 27 |
+ unsigned short op, int st) |
|
| 28 |
+ {
|
|
| 29 |
+- struct blkif_response resp; |
|
| 30 |
++ struct blkif_response *resp; |
|
| 31 |
+ unsigned long flags; |
|
| 32 |
+ union blkif_back_rings *blk_rings = &blkif->blk_rings; |
|
| 33 |
+ int notify; |
|
| 34 |
+ |
|
| 35 |
+- resp.id = id; |
|
| 36 |
+- resp.operation = op; |
|
| 37 |
+- resp.status = st; |
|
| 38 |
+- |
|
| 39 |
+ spin_lock_irqsave(&blkif->blk_ring_lock, flags); |
|
| 40 |
+ /* Place on the response ring for the relevant domain. */ |
|
| 41 |
+ switch (blkif->blk_protocol) {
|
|
| 42 |
+ case BLKIF_PROTOCOL_NATIVE: |
|
| 43 |
+- memcpy(RING_GET_RESPONSE(&blk_rings->native, blk_rings->native.rsp_prod_pvt), |
|
| 44 |
+- &resp, sizeof(resp)); |
|
| 45 |
++ resp = RING_GET_RESPONSE(&blk_rings->native, |
|
| 46 |
++ blk_rings->native.rsp_prod_pvt); |
|
| 47 |
+ break; |
|
| 48 |
+ case BLKIF_PROTOCOL_X86_32: |
|
| 49 |
+- memcpy(RING_GET_RESPONSE(&blk_rings->x86_32, blk_rings->x86_32.rsp_prod_pvt), |
|
| 50 |
+- &resp, sizeof(resp)); |
|
| 51 |
++ resp = RING_GET_RESPONSE(&blk_rings->x86_32, |
|
| 52 |
++ blk_rings->x86_32.rsp_prod_pvt); |
|
| 53 |
+ break; |
|
| 54 |
+ case BLKIF_PROTOCOL_X86_64: |
|
| 55 |
+- memcpy(RING_GET_RESPONSE(&blk_rings->x86_64, blk_rings->x86_64.rsp_prod_pvt), |
|
| 56 |
+- &resp, sizeof(resp)); |
|
| 57 |
++ resp = RING_GET_RESPONSE(&blk_rings->x86_64, |
|
| 58 |
++ blk_rings->x86_64.rsp_prod_pvt); |
|
| 59 |
+ break; |
|
| 60 |
+ default: |
|
| 61 |
+ BUG(); |
|
| 62 |
+ } |
|
| 63 |
++ |
|
| 64 |
++ resp->id = id; |
|
| 65 |
++ resp->operation = op; |
|
| 66 |
++ resp->status = st; |
|
| 67 |
++ |
|
| 68 |
+ blk_rings->common.rsp_prod_pvt++; |
|
| 69 |
+ RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&blk_rings->common, notify); |
|
| 70 |
+ spin_unlock_irqrestore(&blkif->blk_ring_lock, flags); |
|
| 71 |
+diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h |
|
| 72 |
+index 638597b17a38c..ecb35fe8ca8db 100644 |
|
| 73 |
+--- a/drivers/block/xen-blkback/common.h |
|
| 74 |
+@@ -75,9 +75,8 @@ extern unsigned int xenblk_max_queues; |
|
| 75 |
+ struct blkif_common_request {
|
|
| 76 |
+ char dummy; |
|
| 77 |
+ }; |
|
| 78 |
+-struct blkif_common_response {
|
|
| 79 |
+- char dummy; |
|
| 80 |
+-}; |
|
| 81 |
++ |
|
| 82 |
++/* i386 protocol version */ |
|
| 83 |
+ |
|
| 84 |
+ struct blkif_x86_32_request_rw {
|
|
| 85 |
+ uint8_t nr_segments; /* number of segments */ |
|
| 86 |
+@@ -129,14 +128,6 @@ struct blkif_x86_32_request {
|
|
| 87 |
+ } u; |
|
| 88 |
+ } __attribute__((__packed__)); |
|
| 89 |
+ |
|
| 90 |
+-/* i386 protocol version */ |
|
| 91 |
+-#pragma pack(push, 4) |
|
| 92 |
+-struct blkif_x86_32_response {
|
|
| 93 |
+- uint64_t id; /* copied from request */ |
|
| 94 |
+- uint8_t operation; /* copied from request */ |
|
| 95 |
+- int16_t status; /* BLKIF_RSP_??? */ |
|
| 96 |
+-}; |
|
| 97 |
+-#pragma pack(pop) |
|
| 98 |
+ /* x86_64 protocol version */ |
|
| 99 |
+ |
|
| 100 |
+ struct blkif_x86_64_request_rw {
|
|
| 101 |
+@@ -193,18 +184,12 @@ struct blkif_x86_64_request {
|
|
| 102 |
+ } u; |
|
| 103 |
+ } __attribute__((__packed__)); |
|
| 104 |
+ |
|
| 105 |
+-struct blkif_x86_64_response {
|
|
| 106 |
+- uint64_t __attribute__((__aligned__(8))) id; |
|
| 107 |
+- uint8_t operation; /* copied from request */ |
|
| 108 |
+- int16_t status; /* BLKIF_RSP_??? */ |
|
| 109 |
+-}; |
|
| 110 |
+- |
|
| 111 |
+ DEFINE_RING_TYPES(blkif_common, struct blkif_common_request, |
|
| 112 |
+- struct blkif_common_response); |
|
| 113 |
++ struct blkif_response); |
|
| 114 |
+ DEFINE_RING_TYPES(blkif_x86_32, struct blkif_x86_32_request, |
|
| 115 |
+- struct blkif_x86_32_response); |
|
| 116 |
++ struct blkif_response __packed); |
|
| 117 |
+ DEFINE_RING_TYPES(blkif_x86_64, struct blkif_x86_64_request, |
|
| 118 |
+- struct blkif_x86_64_response); |
|
| 119 |
++ struct blkif_response); |
|
| 120 |
+ |
|
| 121 |
+ union blkif_back_rings {
|
|
| 122 |
+ struct blkif_back_ring native; |