Browse code

linux-esx: Read TSC only during the startup of the boot-CPU

At the time of CPU startup, we want to read a TSC value and store it
in the variable named 'tsc_at_head'. This operation is supposed to be
performed only when the first CPU starts (the boot CPU), i.e., inside
startup_64(). However, the current code puts this logic inside
secondary_startup_64(), which is the initialization logic for all the
other CPUs (non-boot or secondary CPUs).

Fix this by moving the read-tsc logic to the beginning of the boot CPU
init sequence (startup_64()).

Change-Id: I12671d47169570cbbdada261baf8abd5b1d9198c
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/6468
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: Alexey Makhalov <amakhalov@vmware.com>

Srivatsa S. Bhat (VMware) authored on 2019/01/09 09:54:22
Showing 2 changed files
... ...
@@ -13,10 +13,10 @@ Subject: [PATCH] x86/vmware: pv-ops boot_clock
13 13
  6 files changed, 57 insertions(+), 1 deletion(-)
14 14
 
15 15
 diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
16
-index ce932812f142..3d4ba2a999cb 100644
16
+index 24af8b1..65af182 100644
17 17
 --- a/arch/x86/include/asm/paravirt.h
18 18
 +++ b/arch/x86/include/asm/paravirt.h
19
-@@ -193,6 +193,11 @@ static inline u64 paravirt_steal_clock(int cpu)
19
+@@ -194,6 +194,11 @@ static inline u64 paravirt_steal_clock(int cpu)
20 20
  	return PVOP_CALL1(u64, pv_time_ops.steal_clock, cpu);
21 21
  }
22 22
  
... ...
@@ -29,10 +29,10 @@ index ce932812f142..3d4ba2a999cb 100644
29 29
  {
30 30
  	return PVOP_CALL1(u64, pv_cpu_ops.read_pmc, counter);
31 31
 diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h
32
-index 0f400c0e4979..5f09979f612d 100644
32
+index 04b7971..b3c7f41 100644
33 33
 --- a/arch/x86/include/asm/paravirt_types.h
34 34
 +++ b/arch/x86/include/asm/paravirt_types.h
35
-@@ -51,6 +51,10 @@ struct mm_struct;
35
+@@ -52,6 +52,10 @@ struct mm_struct;
36 36
  struct desc_struct;
37 37
  struct task_struct;
38 38
  struct cpumask;
... ...
@@ -43,7 +43,7 @@ index 0f400c0e4979..5f09979f612d 100644
43 43
  
44 44
  /*
45 45
   * Wrapper type for pointers to code which uses the non-standard
46
-@@ -96,6 +100,7 @@ struct pv_lazy_ops {
46
+@@ -97,6 +101,7 @@ struct pv_lazy_ops {
47 47
  struct pv_time_ops {
48 48
  	unsigned long long (*sched_clock)(void);
49 49
  	unsigned long long (*steal_clock)(int cpu);
... ...
@@ -52,7 +52,7 @@ index 0f400c0e4979..5f09979f612d 100644
52 52
  
53 53
  struct pv_cpu_ops {
54 54
 diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c
55
-index 987ac571d16c..0e1fc6e17efc 100644
55
+index 569356f..ad82ac3 100644
56 56
 --- a/arch/x86/kernel/cpu/vmware.c
57 57
 +++ b/arch/x86/kernel/cpu/vmware.c
58 58
 @@ -124,6 +124,7 @@ static struct kmsg_dumper kmsg_dumper = {
... ...
@@ -72,7 +72,7 @@ index 987ac571d16c..0e1fc6e17efc 100644
72 72
  
73 73
  	clocks_calc_mult_shift(&d->cyc2ns_mul, &d->cyc2ns_shift,
74 74
  			       vmware_tsc_khz, NSEC_PER_MSEC, 0);
75
-@@ -175,6 +176,26 @@ struct clocksource * __init clocksource_default_clock(void)
75
+@@ -176,6 +177,26 @@ struct clocksource * __init clocksource_default_clock(void)
76 76
  	return &clocksource_vmware;
77 77
  }
78 78
  
... ...
@@ -99,7 +99,7 @@ index 987ac571d16c..0e1fc6e17efc 100644
99 99
  static uint64_t vmware_steal_clock(int cpu)
100 100
  {
101 101
  	struct vmware_steal_time *steal;
102
-@@ -311,6 +332,7 @@ static void __init vmware_paravirt_ops_setup(void)
102
+@@ -312,6 +333,7 @@ static void __init vmware_paravirt_ops_setup(void)
103 103
  #endif
104 104
  	}
105 105
  	clocksource_register_khz(&clocksource_vmware, vmware_tsc_khz);
... ...
@@ -108,14 +108,13 @@ index 987ac571d16c..0e1fc6e17efc 100644
108 108
  #else
109 109
  #define vmware_paravirt_ops_setup() do {} while (0)
110 110
 diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
111
-index b4421cc191b0..f7b8017fa90a 100644
111
+index 9d72cf5..42d8307 100644
112 112
 --- a/arch/x86/kernel/head_64.S
113 113
 +++ b/arch/x86/kernel/head_64.S
114
-@@ -184,6 +184,14 @@ ENTRY(secondary_startup_64)
115
- 	 * after the boot processor executes this code.
114
+@@ -68,6 +68,14 @@ startup_64:
116 115
  	 */
117 116
  
118
-+	/*
117
+ 	/*
119 118
 +	 * Read a TSC value first
120 119
 +	 */
121 120
 +	rdtsc
... ...
@@ -123,14 +122,15 @@ index b4421cc191b0..f7b8017fa90a 100644
123 123
 +	or	%rax, %rdx
124 124
 +	mov	%rdx, tsc_at_head(%rip)
125 125
 +
126
- 	/* Sanitize CPU configuration */
127
- 	call verify_cpu
128
- 
126
++	/*
127
+ 	 * Setup stack for verify_cpu(). "-8" because initial_stack is defined
128
+ 	 * this way, see below. Our best guess is a NULL ptr for stack
129
+ 	 * termination heuristics and we don't want to break anything which
129 130
 diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
130
-index bbf3d5933eaa..10bbdb3e6651 100644
131
+index bf9552b..22319ab 100644
131 132
 --- a/arch/x86/kernel/paravirt.c
132 133
 +++ b/arch/x86/kernel/paravirt.c
133
-@@ -203,6 +203,12 @@ static u64 native_steal_clock(int cpu)
134
+@@ -209,6 +209,12 @@ static u64 native_steal_clock(int cpu)
134 135
  	return 0;
135 136
  }
136 137
  
... ...
@@ -143,7 +143,7 @@ index bbf3d5933eaa..10bbdb3e6651 100644
143 143
  /* These are in entry.S */
144 144
  extern void native_iret(void);
145 145
  extern void native_usergs_sysret64(void);
146
-@@ -310,6 +316,7 @@ struct pv_init_ops pv_init_ops = {
146
+@@ -316,6 +322,7 @@ struct pv_init_ops pv_init_ops = {
147 147
  struct pv_time_ops pv_time_ops = {
148 148
  	.sched_clock = native_sched_clock,
149 149
  	.steal_clock = native_steal_clock,
... ...
@@ -152,10 +152,10 @@ index bbf3d5933eaa..10bbdb3e6651 100644
152 152
  
153 153
  __visible struct pv_irq_ops pv_irq_ops = {
154 154
 diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
155
-index 9c337b0e8ba7..67a42e58b118 100644
155
+index 49960ec..87d7870 100644
156 156
 --- a/arch/x86/kernel/setup.c
157 157
 +++ b/arch/x86/kernel/setup.c
158
-@@ -1302,3 +1302,12 @@ void arch_show_smap(struct seq_file *m, struct vm_area_struct *vma)
158
+@@ -1322,3 +1322,12 @@ void arch_show_smap(struct seq_file *m, struct vm_area_struct *vma)
159 159
  
160 160
  	seq_printf(m, "ProtectionKey:  %8u\n", vma_pkey(vma));
161 161
  }
... ...
@@ -168,6 +168,3 @@ index 9c337b0e8ba7..67a42e58b118 100644
168 168
 +	paravirt_read_boot_clock64(ts);
169 169
 +}
170 170
 +#endif
171
-2.11.0
172
-
... ...
@@ -2,7 +2,7 @@
2 2
 Summary:        Kernel
3 3
 Name:           linux-esx
4 4
 Version:        4.9.140
5
-Release:        2%{?dist}
5
+Release:        3%{?dist}
6 6
 License:        GPLv2
7 7
 URL:            http://www.kernel.org/
8 8
 Group:          System Environment/Kernel
... ...
@@ -233,6 +233,8 @@ ln -sf linux-%{uname_r}.cfg /boot/photon.cfg
233 233
 /usr/src/linux-headers-%{uname_r}
234 234
 
235 235
 %changelog
236
+*   Tue Jan 08 2019 Srivatsa S. Bhat (VMware) <srivatsa@csail.mit.edu> 4.9.140-3
237
+-   Read TSC only during the startup of the boot-CPU.
236 238
 *   Mon Dec 03 2018 Alexey Makhalov <amakhalov@vmware.com> 4.9.140-2
237 239
 -   Fix BAR4 is zero issue for IDE devices
238 240
 *   Mon Nov 26 2018 Srivatsa S. Bhat (VMware) <srivatsa@csail.mit.edu> 4.9.140-1