aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/xen
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/xen')
-rw-r--r--arch/x86/xen/enlighten.c99
-rw-r--r--arch/x86/xen/irq.c8
-rw-r--r--arch/x86/xen/mmu.c20
-rw-r--r--arch/x86/xen/multicalls.h2
-rw-r--r--arch/x86/xen/setup.c3
-rw-r--r--arch/x86/xen/smp.c8
6 files changed, 119 insertions, 21 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 4172af8ceeb3..b132ade26f77 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -62,6 +62,15 @@
62#include <asm/reboot.h> 62#include <asm/reboot.h>
63#include <asm/stackprotector.h> 63#include <asm/stackprotector.h>
64#include <asm/hypervisor.h> 64#include <asm/hypervisor.h>
65#include <asm/mwait.h>
66
67#ifdef CONFIG_ACPI
68#include <linux/acpi.h>
69#include <asm/acpi.h>
70#include <acpi/pdc_intel.h>
71#include <acpi/processor.h>
72#include <xen/interface/platform.h>
73#endif
65 74
66#include "xen-ops.h" 75#include "xen-ops.h"
67#include "mmu.h" 76#include "mmu.h"
@@ -200,13 +209,17 @@ static void __init xen_banner(void)
200static __read_mostly unsigned int cpuid_leaf1_edx_mask = ~0; 209static __read_mostly unsigned int cpuid_leaf1_edx_mask = ~0;
201static __read_mostly unsigned int cpuid_leaf1_ecx_mask = ~0; 210static __read_mostly unsigned int cpuid_leaf1_ecx_mask = ~0;
202 211
212static __read_mostly unsigned int cpuid_leaf1_ecx_set_mask;
213static __read_mostly unsigned int cpuid_leaf5_ecx_val;
214static __read_mostly unsigned int cpuid_leaf5_edx_val;
215
203static void xen_cpuid(unsigned int *ax, unsigned int *bx, 216static void xen_cpuid(unsigned int *ax, unsigned int *bx,
204 unsigned int *cx, unsigned int *dx) 217 unsigned int *cx, unsigned int *dx)
205{ 218{
206 unsigned maskebx = ~0; 219 unsigned maskebx = ~0;
207 unsigned maskecx = ~0; 220 unsigned maskecx = ~0;
208 unsigned maskedx = ~0; 221 unsigned maskedx = ~0;
209 222 unsigned setecx = 0;
210 /* 223 /*
211 * Mask out inconvenient features, to try and disable as many 224 * Mask out inconvenient features, to try and disable as many
212 * unsupported kernel subsystems as possible. 225 * unsupported kernel subsystems as possible.
@@ -214,9 +227,18 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx,
214 switch (*ax) { 227 switch (*ax) {
215 case 1: 228 case 1:
216 maskecx = cpuid_leaf1_ecx_mask; 229 maskecx = cpuid_leaf1_ecx_mask;
230 setecx = cpuid_leaf1_ecx_set_mask;
217 maskedx = cpuid_leaf1_edx_mask; 231 maskedx = cpuid_leaf1_edx_mask;
218 break; 232 break;
219 233
234 case CPUID_MWAIT_LEAF:
235 /* Synthesize the values.. */
236 *ax = 0;
237 *bx = 0;
238 *cx = cpuid_leaf5_ecx_val;
239 *dx = cpuid_leaf5_edx_val;
240 return;
241
220 case 0xb: 242 case 0xb:
221 /* Suppress extended topology stuff */ 243 /* Suppress extended topology stuff */
222 maskebx = 0; 244 maskebx = 0;
@@ -232,9 +254,75 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx,
232 254
233 *bx &= maskebx; 255 *bx &= maskebx;
234 *cx &= maskecx; 256 *cx &= maskecx;
257 *cx |= setecx;
235 *dx &= maskedx; 258 *dx &= maskedx;
259
236} 260}
237 261
262static bool __init xen_check_mwait(void)
263{
264#ifdef CONFIG_ACPI
265 struct xen_platform_op op = {
266 .cmd = XENPF_set_processor_pminfo,
267 .u.set_pminfo.id = -1,
268 .u.set_pminfo.type = XEN_PM_PDC,
269 };
270 uint32_t buf[3];
271 unsigned int ax, bx, cx, dx;
272 unsigned int mwait_mask;
273
274 /* We need to determine whether it is OK to expose the MWAIT
275 * capability to the kernel to harvest deeper than C3 states from ACPI
276 * _CST using the processor_harvest_xen.c module. For this to work, we
277 * need to gather the MWAIT_LEAF values (which the cstate.c code
278 * checks against). The hypervisor won't expose the MWAIT flag because
279 * it would break backwards compatibility; so we will find out directly
280 * from the hardware and hypercall.
281 */
282 if (!xen_initial_domain())
283 return false;
284
285 ax = 1;
286 cx = 0;
287
288 native_cpuid(&ax, &bx, &cx, &dx);
289
290 mwait_mask = (1 << (X86_FEATURE_EST % 32)) |
291 (1 << (X86_FEATURE_MWAIT % 32));
292
293 if ((cx & mwait_mask) != mwait_mask)
294 return false;
295
296 /* We need to emulate the MWAIT_LEAF and for that we need both
297 * ecx and edx. The hypercall provides only partial information.
298 */
299
300 ax = CPUID_MWAIT_LEAF;
301 bx = 0;
302 cx = 0;
303 dx = 0;
304
305 native_cpuid(&ax, &bx, &cx, &dx);
306
307 /* Ask the Hypervisor whether to clear ACPI_PDC_C_C2C3_FFH. If so,
308 * don't expose MWAIT_LEAF and let ACPI pick the IOPORT version of C3.
309 */
310 buf[0] = ACPI_PDC_REVISION_ID;
311 buf[1] = 1;
312 buf[2] = (ACPI_PDC_C_CAPABILITY_SMP | ACPI_PDC_EST_CAPABILITY_SWSMP);
313
314 set_xen_guest_handle(op.u.set_pminfo.pdc, buf);
315
316 if ((HYPERVISOR_dom0_op(&op) == 0) &&
317 (buf[2] & (ACPI_PDC_C_C1_FFH | ACPI_PDC_C_C2C3_FFH))) {
318 cpuid_leaf5_ecx_val = cx;
319 cpuid_leaf5_edx_val = dx;
320 }
321 return true;
322#else
323 return false;
324#endif
325}
238static void __init xen_init_cpuid_mask(void) 326static void __init xen_init_cpuid_mask(void)
239{ 327{
240 unsigned int ax, bx, cx, dx; 328 unsigned int ax, bx, cx, dx;
@@ -261,6 +349,9 @@ static void __init xen_init_cpuid_mask(void)
261 /* Xen will set CR4.OSXSAVE if supported and not disabled by force */ 349 /* Xen will set CR4.OSXSAVE if supported and not disabled by force */
262 if ((cx & xsave_mask) != xsave_mask) 350 if ((cx & xsave_mask) != xsave_mask)
263 cpuid_leaf1_ecx_mask &= ~xsave_mask; /* disable XSAVE & OSXSAVE */ 351 cpuid_leaf1_ecx_mask &= ~xsave_mask; /* disable XSAVE & OSXSAVE */
352
353 if (xen_check_mwait())
354 cpuid_leaf1_ecx_set_mask = (1 << (X86_FEATURE_MWAIT % 32));
264} 355}
265 356
266static void xen_set_debugreg(int reg, unsigned long val) 357static void xen_set_debugreg(int reg, unsigned long val)
@@ -777,11 +868,11 @@ static DEFINE_PER_CPU(unsigned long, xen_cr0_value);
777 868
778static unsigned long xen_read_cr0(void) 869static unsigned long xen_read_cr0(void)
779{ 870{
780 unsigned long cr0 = percpu_read(xen_cr0_value); 871 unsigned long cr0 = this_cpu_read(xen_cr0_value);
781 872
782 if (unlikely(cr0 == 0)) { 873 if (unlikely(cr0 == 0)) {
783 cr0 = native_read_cr0(); 874 cr0 = native_read_cr0();
784 percpu_write(xen_cr0_value, cr0); 875 this_cpu_write(xen_cr0_value, cr0);
785 } 876 }
786 877
787 return cr0; 878 return cr0;
@@ -791,7 +882,7 @@ static void xen_write_cr0(unsigned long cr0)
791{ 882{
792 struct multicall_space mcs; 883 struct multicall_space mcs;
793 884
794 percpu_write(xen_cr0_value, cr0); 885 this_cpu_write(xen_cr0_value, cr0);
795 886
796 /* Only pay attention to cr0.TS; everything else is 887 /* Only pay attention to cr0.TS; everything else is
797 ignored. */ 888 ignored. */
diff --git a/arch/x86/xen/irq.c b/arch/x86/xen/irq.c
index 8bbb465b6f0a..157337657971 100644
--- a/arch/x86/xen/irq.c
+++ b/arch/x86/xen/irq.c
@@ -26,7 +26,7 @@ static unsigned long xen_save_fl(void)
26 struct vcpu_info *vcpu; 26 struct vcpu_info *vcpu;
27 unsigned long flags; 27 unsigned long flags;
28 28
29 vcpu = percpu_read(xen_vcpu); 29 vcpu = this_cpu_read(xen_vcpu);
30 30
31 /* flag has opposite sense of mask */ 31 /* flag has opposite sense of mask */
32 flags = !vcpu->evtchn_upcall_mask; 32 flags = !vcpu->evtchn_upcall_mask;
@@ -50,7 +50,7 @@ static void xen_restore_fl(unsigned long flags)
50 make sure we're don't switch CPUs between getting the vcpu 50 make sure we're don't switch CPUs between getting the vcpu
51 pointer and updating the mask. */ 51 pointer and updating the mask. */
52 preempt_disable(); 52 preempt_disable();
53 vcpu = percpu_read(xen_vcpu); 53 vcpu = this_cpu_read(xen_vcpu);
54 vcpu->evtchn_upcall_mask = flags; 54 vcpu->evtchn_upcall_mask = flags;
55 preempt_enable_no_resched(); 55 preempt_enable_no_resched();
56 56
@@ -72,7 +72,7 @@ static void xen_irq_disable(void)
72 make sure we're don't switch CPUs between getting the vcpu 72 make sure we're don't switch CPUs between getting the vcpu
73 pointer and updating the mask. */ 73 pointer and updating the mask. */
74 preempt_disable(); 74 preempt_disable();
75 percpu_read(xen_vcpu)->evtchn_upcall_mask = 1; 75 this_cpu_read(xen_vcpu)->evtchn_upcall_mask = 1;
76 preempt_enable_no_resched(); 76 preempt_enable_no_resched();
77} 77}
78PV_CALLEE_SAVE_REGS_THUNK(xen_irq_disable); 78PV_CALLEE_SAVE_REGS_THUNK(xen_irq_disable);
@@ -86,7 +86,7 @@ static void xen_irq_enable(void)
86 the caller is confused and is trying to re-enable interrupts 86 the caller is confused and is trying to re-enable interrupts
87 on an indeterminate processor. */ 87 on an indeterminate processor. */
88 88
89 vcpu = percpu_read(xen_vcpu); 89 vcpu = this_cpu_read(xen_vcpu);
90 vcpu->evtchn_upcall_mask = 0; 90 vcpu->evtchn_upcall_mask = 0;
91 91
92 /* Doesn't matter if we get preempted here, because any 92 /* Doesn't matter if we get preempted here, because any
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 95c1cf60c669..988828b479ed 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -1071,14 +1071,14 @@ static void drop_other_mm_ref(void *info)
1071 struct mm_struct *mm = info; 1071 struct mm_struct *mm = info;
1072 struct mm_struct *active_mm; 1072 struct mm_struct *active_mm;
1073 1073
1074 active_mm = percpu_read(cpu_tlbstate.active_mm); 1074 active_mm = this_cpu_read(cpu_tlbstate.active_mm);
1075 1075
1076 if (active_mm == mm && percpu_read(cpu_tlbstate.state) != TLBSTATE_OK) 1076 if (active_mm == mm && this_cpu_read(cpu_tlbstate.state) != TLBSTATE_OK)
1077 leave_mm(smp_processor_id()); 1077 leave_mm(smp_processor_id());
1078 1078
1079 /* If this cpu still has a stale cr3 reference, then make sure 1079 /* If this cpu still has a stale cr3 reference, then make sure
1080 it has been flushed. */ 1080 it has been flushed. */
1081 if (percpu_read(xen_current_cr3) == __pa(mm->pgd)) 1081 if (this_cpu_read(xen_current_cr3) == __pa(mm->pgd))
1082 load_cr3(swapper_pg_dir); 1082 load_cr3(swapper_pg_dir);
1083} 1083}
1084 1084
@@ -1185,17 +1185,17 @@ static void __init xen_pagetable_setup_done(pgd_t *base)
1185 1185
1186static void xen_write_cr2(unsigned long cr2) 1186static void xen_write_cr2(unsigned long cr2)
1187{ 1187{
1188 percpu_read(xen_vcpu)->arch.cr2 = cr2; 1188 this_cpu_read(xen_vcpu)->arch.cr2 = cr2;
1189} 1189}
1190 1190
1191static unsigned long xen_read_cr2(void) 1191static unsigned long xen_read_cr2(void)
1192{ 1192{
1193 return percpu_read(xen_vcpu)->arch.cr2; 1193 return this_cpu_read(xen_vcpu)->arch.cr2;
1194} 1194}
1195 1195
1196unsigned long xen_read_cr2_direct(void) 1196unsigned long xen_read_cr2_direct(void)
1197{ 1197{
1198 return percpu_read(xen_vcpu_info.arch.cr2); 1198 return this_cpu_read(xen_vcpu_info.arch.cr2);
1199} 1199}
1200 1200
1201static void xen_flush_tlb(void) 1201static void xen_flush_tlb(void)
@@ -1278,12 +1278,12 @@ static void xen_flush_tlb_others(const struct cpumask *cpus,
1278 1278
1279static unsigned long xen_read_cr3(void) 1279static unsigned long xen_read_cr3(void)
1280{ 1280{
1281 return percpu_read(xen_cr3); 1281 return this_cpu_read(xen_cr3);
1282} 1282}
1283 1283
1284static void set_current_cr3(void *v) 1284static void set_current_cr3(void *v)
1285{ 1285{
1286 percpu_write(xen_current_cr3, (unsigned long)v); 1286 this_cpu_write(xen_current_cr3, (unsigned long)v);
1287} 1287}
1288 1288
1289static void __xen_write_cr3(bool kernel, unsigned long cr3) 1289static void __xen_write_cr3(bool kernel, unsigned long cr3)
@@ -1306,7 +1306,7 @@ static void __xen_write_cr3(bool kernel, unsigned long cr3)
1306 xen_extend_mmuext_op(&op); 1306 xen_extend_mmuext_op(&op);
1307 1307
1308 if (kernel) { 1308 if (kernel) {
1309 percpu_write(xen_cr3, cr3); 1309 this_cpu_write(xen_cr3, cr3);
1310 1310
1311 /* Update xen_current_cr3 once the batch has actually 1311 /* Update xen_current_cr3 once the batch has actually
1312 been submitted. */ 1312 been submitted. */
@@ -1322,7 +1322,7 @@ static void xen_write_cr3(unsigned long cr3)
1322 1322
1323 /* Update while interrupts are disabled, so its atomic with 1323 /* Update while interrupts are disabled, so its atomic with
1324 respect to ipis */ 1324 respect to ipis */
1325 percpu_write(xen_cr3, cr3); 1325 this_cpu_write(xen_cr3, cr3);
1326 1326
1327 __xen_write_cr3(true, cr3); 1327 __xen_write_cr3(true, cr3);
1328 1328
diff --git a/arch/x86/xen/multicalls.h b/arch/x86/xen/multicalls.h
index dee79b78a90f..9c2e74f9096c 100644
--- a/arch/x86/xen/multicalls.h
+++ b/arch/x86/xen/multicalls.h
@@ -47,7 +47,7 @@ static inline void xen_mc_issue(unsigned mode)
47 xen_mc_flush(); 47 xen_mc_flush();
48 48
49 /* restore flags saved in xen_mc_batch */ 49 /* restore flags saved in xen_mc_batch */
50 local_irq_restore(percpu_read(xen_mc_irq_flags)); 50 local_irq_restore(this_cpu_read(xen_mc_irq_flags));
51} 51}
52 52
53/* Set up a callback to be called when the current batch is flushed */ 53/* Set up a callback to be called when the current batch is flushed */
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index e03c63692176..1ba8dff26753 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -10,6 +10,7 @@
10#include <linux/pm.h> 10#include <linux/pm.h>
11#include <linux/memblock.h> 11#include <linux/memblock.h>
12#include <linux/cpuidle.h> 12#include <linux/cpuidle.h>
13#include <linux/cpufreq.h>
13 14
14#include <asm/elf.h> 15#include <asm/elf.h>
15#include <asm/vdso.h> 16#include <asm/vdso.h>
@@ -420,7 +421,7 @@ void __init xen_arch_setup(void)
420 boot_cpu_data.hlt_works_ok = 1; 421 boot_cpu_data.hlt_works_ok = 1;
421#endif 422#endif
422 disable_cpuidle(); 423 disable_cpuidle();
423 boot_option_idle_override = IDLE_HALT; 424 disable_cpufreq();
424 WARN_ON(set_pm_idle_to_default()); 425 WARN_ON(set_pm_idle_to_default());
425 fiddle_vdso(); 426 fiddle_vdso();
426} 427}
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 501d4e0244ba..02900e8ce26c 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -75,8 +75,14 @@ static void __cpuinit cpu_bringup(void)
75 75
76 xen_setup_cpu_clockevents(); 76 xen_setup_cpu_clockevents();
77 77
78 notify_cpu_starting(cpu);
79
80 ipi_call_lock();
78 set_cpu_online(cpu, true); 81 set_cpu_online(cpu, true);
79 percpu_write(cpu_state, CPU_ONLINE); 82 ipi_call_unlock();
83
84 this_cpu_write(cpu_state, CPU_ONLINE);
85
80 wmb(); 86 wmb();
81 87
82 /* We can take interrupts now: we're officially "up". */ 88 /* We can take interrupts now: we're officially "up". */