diff options
29 files changed, 1264 insertions, 80 deletions
diff --git a/arch/ia64/include/asm/xen/interface.h b/arch/ia64/include/asm/xen/interface.h index fbb519828aa1..09d5f7fd9db1 100644 --- a/arch/ia64/include/asm/xen/interface.h +++ b/arch/ia64/include/asm/xen/interface.h | |||
@@ -77,6 +77,7 @@ DEFINE_GUEST_HANDLE(int); | |||
77 | DEFINE_GUEST_HANDLE(long); | 77 | DEFINE_GUEST_HANDLE(long); |
78 | DEFINE_GUEST_HANDLE(void); | 78 | DEFINE_GUEST_HANDLE(void); |
79 | DEFINE_GUEST_HANDLE(uint64_t); | 79 | DEFINE_GUEST_HANDLE(uint64_t); |
80 | DEFINE_GUEST_HANDLE(uint32_t); | ||
80 | 81 | ||
81 | typedef unsigned long xen_pfn_t; | 82 | typedef unsigned long xen_pfn_t; |
82 | DEFINE_GUEST_HANDLE(xen_pfn_t); | 83 | DEFINE_GUEST_HANDLE(xen_pfn_t); |
diff --git a/arch/x86/include/asm/xen/interface.h b/arch/x86/include/asm/xen/interface.h index a1f2db5f1170..cbf0c9d50b92 100644 --- a/arch/x86/include/asm/xen/interface.h +++ b/arch/x86/include/asm/xen/interface.h | |||
@@ -56,6 +56,7 @@ DEFINE_GUEST_HANDLE(int); | |||
56 | DEFINE_GUEST_HANDLE(long); | 56 | DEFINE_GUEST_HANDLE(long); |
57 | DEFINE_GUEST_HANDLE(void); | 57 | DEFINE_GUEST_HANDLE(void); |
58 | DEFINE_GUEST_HANDLE(uint64_t); | 58 | DEFINE_GUEST_HANDLE(uint64_t); |
59 | DEFINE_GUEST_HANDLE(uint32_t); | ||
59 | #endif | 60 | #endif |
60 | 61 | ||
61 | #ifndef HYPERVISOR_VIRT_START | 62 | #ifndef HYPERVISOR_VIRT_START |
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index d99346ea8fdb..7415aa927913 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c | |||
@@ -324,6 +324,32 @@ static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
324 | out: | 324 | out: |
325 | return ret; | 325 | return ret; |
326 | } | 326 | } |
327 | |||
328 | static void xen_initdom_restore_msi_irqs(struct pci_dev *dev, int irq) | ||
329 | { | ||
330 | int ret = 0; | ||
331 | |||
332 | if (pci_seg_supported) { | ||
333 | struct physdev_pci_device restore_ext; | ||
334 | |||
335 | restore_ext.seg = pci_domain_nr(dev->bus); | ||
336 | restore_ext.bus = dev->bus->number; | ||
337 | restore_ext.devfn = dev->devfn; | ||
338 | ret = HYPERVISOR_physdev_op(PHYSDEVOP_restore_msi_ext, | ||
339 | &restore_ext); | ||
340 | if (ret == -ENOSYS) | ||
341 | pci_seg_supported = false; | ||
342 | WARN(ret && ret != -ENOSYS, "restore_msi_ext -> %d\n", ret); | ||
343 | } | ||
344 | if (!pci_seg_supported) { | ||
345 | struct physdev_restore_msi restore; | ||
346 | |||
347 | restore.bus = dev->bus->number; | ||
348 | restore.devfn = dev->devfn; | ||
349 | ret = HYPERVISOR_physdev_op(PHYSDEVOP_restore_msi, &restore); | ||
350 | WARN(ret && ret != -ENOSYS, "restore_msi -> %d\n", ret); | ||
351 | } | ||
352 | } | ||
327 | #endif | 353 | #endif |
328 | 354 | ||
329 | static void xen_teardown_msi_irqs(struct pci_dev *dev) | 355 | static void xen_teardown_msi_irqs(struct pci_dev *dev) |
@@ -446,6 +472,7 @@ int __init pci_xen_initial_domain(void) | |||
446 | #ifdef CONFIG_PCI_MSI | 472 | #ifdef CONFIG_PCI_MSI |
447 | x86_msi.setup_msi_irqs = xen_initdom_setup_msi_irqs; | 473 | x86_msi.setup_msi_irqs = xen_initdom_setup_msi_irqs; |
448 | x86_msi.teardown_msi_irq = xen_teardown_msi_irq; | 474 | x86_msi.teardown_msi_irq = xen_teardown_msi_irq; |
475 | x86_msi.restore_msi_irqs = xen_initdom_restore_msi_irqs; | ||
449 | #endif | 476 | #endif |
450 | xen_setup_acpi_sci(); | 477 | xen_setup_acpi_sci(); |
451 | __acpi_register_gsi = acpi_register_gsi_xen; | 478 | __acpi_register_gsi = acpi_register_gsi_xen; |
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) | |||
200 | static __read_mostly unsigned int cpuid_leaf1_edx_mask = ~0; | 209 | static __read_mostly unsigned int cpuid_leaf1_edx_mask = ~0; |
201 | static __read_mostly unsigned int cpuid_leaf1_ecx_mask = ~0; | 210 | static __read_mostly unsigned int cpuid_leaf1_ecx_mask = ~0; |
202 | 211 | ||
212 | static __read_mostly unsigned int cpuid_leaf1_ecx_set_mask; | ||
213 | static __read_mostly unsigned int cpuid_leaf5_ecx_val; | ||
214 | static __read_mostly unsigned int cpuid_leaf5_edx_val; | ||
215 | |||
203 | static void xen_cpuid(unsigned int *ax, unsigned int *bx, | 216 | static 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 | ||
262 | static 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 | } | ||
238 | static void __init xen_init_cpuid_mask(void) | 326 | static 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 | ||
266 | static void xen_set_debugreg(int reg, unsigned long val) | 357 | static void xen_set_debugreg(int reg, unsigned long val) |
@@ -777,11 +868,11 @@ static DEFINE_PER_CPU(unsigned long, xen_cr0_value); | |||
777 | 868 | ||
778 | static unsigned long xen_read_cr0(void) | 869 | static 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 | } |
78 | PV_CALLEE_SAVE_REGS_THUNK(xen_irq_disable); | 78 | PV_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 | ||
1186 | static void xen_write_cr2(unsigned long cr2) | 1186 | static 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 | ||
1191 | static unsigned long xen_read_cr2(void) | 1191 | static 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 | ||
1196 | unsigned long xen_read_cr2_direct(void) | 1196 | unsigned 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 | ||
1201 | static void xen_flush_tlb(void) | 1201 | static void xen_flush_tlb(void) |
@@ -1278,12 +1278,12 @@ static void xen_flush_tlb_others(const struct cpumask *cpus, | |||
1278 | 1278 | ||
1279 | static unsigned long xen_read_cr3(void) | 1279 | static 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 | ||
1284 | static void set_current_cr3(void *v) | 1284 | static 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 | ||
1289 | static void __xen_write_cr3(bool kernel, unsigned long cr3) | 1289 | static 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..12366238d07d 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c | |||
@@ -420,7 +420,6 @@ void __init xen_arch_setup(void) | |||
420 | boot_cpu_data.hlt_works_ok = 1; | 420 | boot_cpu_data.hlt_works_ok = 1; |
421 | #endif | 421 | #endif |
422 | disable_cpuidle(); | 422 | disable_cpuidle(); |
423 | boot_option_idle_override = IDLE_HALT; | ||
424 | WARN_ON(set_pm_idle_to_default()); | 423 | WARN_ON(set_pm_idle_to_default()); |
425 | fiddle_vdso(); | 424 | fiddle_vdso(); |
426 | } | 425 | } |
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 501d4e0244ba..315d8fa0c8fb 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c | |||
@@ -76,7 +76,7 @@ static void __cpuinit cpu_bringup(void) | |||
76 | xen_setup_cpu_clockevents(); | 76 | xen_setup_cpu_clockevents(); |
77 | 77 | ||
78 | set_cpu_online(cpu, true); | 78 | set_cpu_online(cpu, true); |
79 | percpu_write(cpu_state, CPU_ONLINE); | 79 | this_cpu_write(cpu_state, CPU_ONLINE); |
80 | wmb(); | 80 | wmb(); |
81 | 81 | ||
82 | /* We can take interrupts now: we're officially "up". */ | 82 | /* We can take interrupts now: we're officially "up". */ |
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 7b46781c30c9..8f675ae20916 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig | |||
@@ -558,7 +558,7 @@ config INPUT_CMA3000_I2C | |||
558 | 558 | ||
559 | config INPUT_XEN_KBDDEV_FRONTEND | 559 | config INPUT_XEN_KBDDEV_FRONTEND |
560 | tristate "Xen virtual keyboard and mouse support" | 560 | tristate "Xen virtual keyboard and mouse support" |
561 | depends on XEN_FBDEV_FRONTEND | 561 | depends on XEN |
562 | default y | 562 | default y |
563 | select XEN_XENBUS_FRONTEND | 563 | select XEN_XENBUS_FRONTEND |
564 | help | 564 | help |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index af295bb21d62..053670e09e2b 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -3163,6 +3163,31 @@ int __pci_reset_function(struct pci_dev *dev) | |||
3163 | EXPORT_SYMBOL_GPL(__pci_reset_function); | 3163 | EXPORT_SYMBOL_GPL(__pci_reset_function); |
3164 | 3164 | ||
3165 | /** | 3165 | /** |
3166 | * __pci_reset_function_locked - reset a PCI device function while holding | ||
3167 | * the @dev mutex lock. | ||
3168 | * @dev: PCI device to reset | ||
3169 | * | ||
3170 | * Some devices allow an individual function to be reset without affecting | ||
3171 | * other functions in the same device. The PCI device must be responsive | ||
3172 | * to PCI config space in order to use this function. | ||
3173 | * | ||
3174 | * The device function is presumed to be unused and the caller is holding | ||
3175 | * the device mutex lock when this function is called. | ||
3176 | * Resetting the device will make the contents of PCI configuration space | ||
3177 | * random, so any caller of this must be prepared to reinitialise the | ||
3178 | * device including MSI, bus mastering, BARs, decoding IO and memory spaces, | ||
3179 | * etc. | ||
3180 | * | ||
3181 | * Returns 0 if the device function was successfully reset or negative if the | ||
3182 | * device doesn't support resetting a single function. | ||
3183 | */ | ||
3184 | int __pci_reset_function_locked(struct pci_dev *dev) | ||
3185 | { | ||
3186 | return pci_dev_reset(dev, 1); | ||
3187 | } | ||
3188 | EXPORT_SYMBOL_GPL(__pci_reset_function_locked); | ||
3189 | |||
3190 | /** | ||
3166 | * pci_probe_reset_function - check whether the device can be safely reset | 3191 | * pci_probe_reset_function - check whether the device can be safely reset |
3167 | * @dev: PCI device to reset | 3192 | * @dev: PCI device to reset |
3168 | * | 3193 | * |
diff --git a/drivers/tty/hvc/Kconfig b/drivers/tty/hvc/Kconfig index 48cb8d3d1758..0282a83f51fb 100644 --- a/drivers/tty/hvc/Kconfig +++ b/drivers/tty/hvc/Kconfig | |||
@@ -66,6 +66,14 @@ config HVC_XEN | |||
66 | help | 66 | help |
67 | Xen virtual console device driver | 67 | Xen virtual console device driver |
68 | 68 | ||
69 | config HVC_XEN_FRONTEND | ||
70 | bool "Xen Hypervisor Multiple Consoles support" | ||
71 | depends on HVC_XEN | ||
72 | select XEN_XENBUS_FRONTEND | ||
73 | default y | ||
74 | help | ||
75 | Xen driver for secondary virtual consoles | ||
76 | |||
69 | config HVC_UDBG | 77 | config HVC_UDBG |
70 | bool "udbg based fake hypervisor console" | 78 | bool "udbg based fake hypervisor console" |
71 | depends on PPC && EXPERIMENTAL | 79 | depends on PPC && EXPERIMENTAL |
diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c index a1b0a75c3eae..83d5c88e7165 100644 --- a/drivers/tty/hvc/hvc_xen.c +++ b/drivers/tty/hvc/hvc_xen.c | |||
@@ -23,44 +23,74 @@ | |||
23 | #include <linux/err.h> | 23 | #include <linux/err.h> |
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <linux/types.h> | 25 | #include <linux/types.h> |
26 | #include <linux/list.h> | ||
26 | 27 | ||
28 | #include <asm/io.h> | ||
27 | #include <asm/xen/hypervisor.h> | 29 | #include <asm/xen/hypervisor.h> |
28 | 30 | ||
29 | #include <xen/xen.h> | 31 | #include <xen/xen.h> |
32 | #include <xen/interface/xen.h> | ||
33 | #include <xen/hvm.h> | ||
34 | #include <xen/grant_table.h> | ||
30 | #include <xen/page.h> | 35 | #include <xen/page.h> |
31 | #include <xen/events.h> | 36 | #include <xen/events.h> |
32 | #include <xen/interface/io/console.h> | 37 | #include <xen/interface/io/console.h> |
33 | #include <xen/hvc-console.h> | 38 | #include <xen/hvc-console.h> |
39 | #include <xen/xenbus.h> | ||
34 | 40 | ||
35 | #include "hvc_console.h" | 41 | #include "hvc_console.h" |
36 | 42 | ||
37 | #define HVC_COOKIE 0x58656e /* "Xen" in hex */ | 43 | #define HVC_COOKIE 0x58656e /* "Xen" in hex */ |
38 | 44 | ||
39 | static struct hvc_struct *hvc; | 45 | struct xencons_info { |
40 | static int xencons_irq; | 46 | struct list_head list; |
47 | struct xenbus_device *xbdev; | ||
48 | struct xencons_interface *intf; | ||
49 | unsigned int evtchn; | ||
50 | struct hvc_struct *hvc; | ||
51 | int irq; | ||
52 | int vtermno; | ||
53 | grant_ref_t gntref; | ||
54 | }; | ||
55 | |||
56 | static LIST_HEAD(xenconsoles); | ||
57 | static DEFINE_SPINLOCK(xencons_lock); | ||
41 | 58 | ||
42 | /* ------------------------------------------------------------------ */ | 59 | /* ------------------------------------------------------------------ */ |
43 | 60 | ||
44 | static unsigned long console_pfn = ~0ul; | 61 | static struct xencons_info *vtermno_to_xencons(int vtermno) |
62 | { | ||
63 | struct xencons_info *entry, *n, *ret = NULL; | ||
64 | |||
65 | if (list_empty(&xenconsoles)) | ||
66 | return NULL; | ||
67 | |||
68 | list_for_each_entry_safe(entry, n, &xenconsoles, list) { | ||
69 | if (entry->vtermno == vtermno) { | ||
70 | ret = entry; | ||
71 | break; | ||
72 | } | ||
73 | } | ||
74 | |||
75 | return ret; | ||
76 | } | ||
45 | 77 | ||
46 | static inline struct xencons_interface *xencons_interface(void) | 78 | static inline int xenbus_devid_to_vtermno(int devid) |
47 | { | 79 | { |
48 | if (console_pfn == ~0ul) | 80 | return devid + HVC_COOKIE; |
49 | return mfn_to_virt(xen_start_info->console.domU.mfn); | ||
50 | else | ||
51 | return __va(console_pfn << PAGE_SHIFT); | ||
52 | } | 81 | } |
53 | 82 | ||
54 | static inline void notify_daemon(void) | 83 | static inline void notify_daemon(struct xencons_info *cons) |
55 | { | 84 | { |
56 | /* Use evtchn: this is called early, before irq is set up. */ | 85 | /* Use evtchn: this is called early, before irq is set up. */ |
57 | notify_remote_via_evtchn(xen_start_info->console.domU.evtchn); | 86 | notify_remote_via_evtchn(cons->evtchn); |
58 | } | 87 | } |
59 | 88 | ||
60 | static int __write_console(const char *data, int len) | 89 | static int __write_console(struct xencons_info *xencons, |
90 | const char *data, int len) | ||
61 | { | 91 | { |
62 | struct xencons_interface *intf = xencons_interface(); | ||
63 | XENCONS_RING_IDX cons, prod; | 92 | XENCONS_RING_IDX cons, prod; |
93 | struct xencons_interface *intf = xencons->intf; | ||
64 | int sent = 0; | 94 | int sent = 0; |
65 | 95 | ||
66 | cons = intf->out_cons; | 96 | cons = intf->out_cons; |
@@ -75,13 +105,16 @@ static int __write_console(const char *data, int len) | |||
75 | intf->out_prod = prod; | 105 | intf->out_prod = prod; |
76 | 106 | ||
77 | if (sent) | 107 | if (sent) |
78 | notify_daemon(); | 108 | notify_daemon(xencons); |
79 | return sent; | 109 | return sent; |
80 | } | 110 | } |
81 | 111 | ||
82 | static int domU_write_console(uint32_t vtermno, const char *data, int len) | 112 | static int domU_write_console(uint32_t vtermno, const char *data, int len) |
83 | { | 113 | { |
84 | int ret = len; | 114 | int ret = len; |
115 | struct xencons_info *cons = vtermno_to_xencons(vtermno); | ||
116 | if (cons == NULL) | ||
117 | return -EINVAL; | ||
85 | 118 | ||
86 | /* | 119 | /* |
87 | * Make sure the whole buffer is emitted, polling if | 120 | * Make sure the whole buffer is emitted, polling if |
@@ -90,7 +123,7 @@ static int domU_write_console(uint32_t vtermno, const char *data, int len) | |||
90 | * kernel is crippled. | 123 | * kernel is crippled. |
91 | */ | 124 | */ |
92 | while (len) { | 125 | while (len) { |
93 | int sent = __write_console(data, len); | 126 | int sent = __write_console(cons, data, len); |
94 | 127 | ||
95 | data += sent; | 128 | data += sent; |
96 | len -= sent; | 129 | len -= sent; |
@@ -104,9 +137,13 @@ static int domU_write_console(uint32_t vtermno, const char *data, int len) | |||
104 | 137 | ||
105 | static int domU_read_console(uint32_t vtermno, char *buf, int len) | 138 | static int domU_read_console(uint32_t vtermno, char *buf, int len) |
106 | { | 139 | { |
107 | struct xencons_interface *intf = xencons_interface(); | 140 | struct xencons_interface *intf; |
108 | XENCONS_RING_IDX cons, prod; | 141 | XENCONS_RING_IDX cons, prod; |
109 | int recv = 0; | 142 | int recv = 0; |
143 | struct xencons_info *xencons = vtermno_to_xencons(vtermno); | ||
144 | if (xencons == NULL) | ||
145 | return -EINVAL; | ||
146 | intf = xencons->intf; | ||
110 | 147 | ||
111 | cons = intf->in_cons; | 148 | cons = intf->in_cons; |
112 | prod = intf->in_prod; | 149 | prod = intf->in_prod; |
@@ -119,7 +156,7 @@ static int domU_read_console(uint32_t vtermno, char *buf, int len) | |||
119 | mb(); /* read ring before consuming */ | 156 | mb(); /* read ring before consuming */ |
120 | intf->in_cons = cons; | 157 | intf->in_cons = cons; |
121 | 158 | ||
122 | notify_daemon(); | 159 | notify_daemon(xencons); |
123 | return recv; | 160 | return recv; |
124 | } | 161 | } |
125 | 162 | ||
@@ -157,68 +194,407 @@ static struct hv_ops dom0_hvc_ops = { | |||
157 | .notifier_hangup = notifier_hangup_irq, | 194 | .notifier_hangup = notifier_hangup_irq, |
158 | }; | 195 | }; |
159 | 196 | ||
160 | static int __init xen_hvc_init(void) | 197 | static int xen_hvm_console_init(void) |
198 | { | ||
199 | int r; | ||
200 | uint64_t v = 0; | ||
201 | unsigned long mfn; | ||
202 | struct xencons_info *info; | ||
203 | |||
204 | if (!xen_hvm_domain()) | ||
205 | return -ENODEV; | ||
206 | |||
207 | info = vtermno_to_xencons(HVC_COOKIE); | ||
208 | if (!info) { | ||
209 | info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL | __GFP_ZERO); | ||
210 | if (!info) | ||
211 | return -ENOMEM; | ||
212 | } | ||
213 | |||
214 | /* already configured */ | ||
215 | if (info->intf != NULL) | ||
216 | return 0; | ||
217 | |||
218 | r = hvm_get_parameter(HVM_PARAM_CONSOLE_EVTCHN, &v); | ||
219 | if (r < 0) { | ||
220 | kfree(info); | ||
221 | return -ENODEV; | ||
222 | } | ||
223 | info->evtchn = v; | ||
224 | hvm_get_parameter(HVM_PARAM_CONSOLE_PFN, &v); | ||
225 | if (r < 0) { | ||
226 | kfree(info); | ||
227 | return -ENODEV; | ||
228 | } | ||
229 | mfn = v; | ||
230 | info->intf = ioremap(mfn << PAGE_SHIFT, PAGE_SIZE); | ||
231 | if (info->intf == NULL) { | ||
232 | kfree(info); | ||
233 | return -ENODEV; | ||
234 | } | ||
235 | info->vtermno = HVC_COOKIE; | ||
236 | |||
237 | spin_lock(&xencons_lock); | ||
238 | list_add_tail(&info->list, &xenconsoles); | ||
239 | spin_unlock(&xencons_lock); | ||
240 | |||
241 | return 0; | ||
242 | } | ||
243 | |||
244 | static int xen_pv_console_init(void) | ||
161 | { | 245 | { |
162 | struct hvc_struct *hp; | 246 | struct xencons_info *info; |
163 | struct hv_ops *ops; | ||
164 | 247 | ||
165 | if (!xen_pv_domain()) | 248 | if (!xen_pv_domain()) |
166 | return -ENODEV; | 249 | return -ENODEV; |
167 | 250 | ||
168 | if (xen_initial_domain()) { | 251 | if (!xen_start_info->console.domU.evtchn) |
169 | ops = &dom0_hvc_ops; | 252 | return -ENODEV; |
170 | xencons_irq = bind_virq_to_irq(VIRQ_CONSOLE, 0); | ||
171 | } else { | ||
172 | if (!xen_start_info->console.domU.evtchn) | ||
173 | return -ENODEV; | ||
174 | 253 | ||
175 | ops = &domU_hvc_ops; | 254 | info = vtermno_to_xencons(HVC_COOKIE); |
176 | xencons_irq = bind_evtchn_to_irq(xen_start_info->console.domU.evtchn); | 255 | if (!info) { |
256 | info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL | __GFP_ZERO); | ||
257 | if (!info) | ||
258 | return -ENOMEM; | ||
177 | } | 259 | } |
178 | if (xencons_irq < 0) | ||
179 | xencons_irq = 0; | ||
180 | else | ||
181 | irq_set_noprobe(xencons_irq); | ||
182 | 260 | ||
183 | hp = hvc_alloc(HVC_COOKIE, xencons_irq, ops, 256); | 261 | /* already configured */ |
184 | if (IS_ERR(hp)) | 262 | if (info->intf != NULL) |
185 | return PTR_ERR(hp); | 263 | return 0; |
264 | |||
265 | info->evtchn = xen_start_info->console.domU.evtchn; | ||
266 | info->intf = mfn_to_virt(xen_start_info->console.domU.mfn); | ||
267 | info->vtermno = HVC_COOKIE; | ||
268 | |||
269 | spin_lock(&xencons_lock); | ||
270 | list_add_tail(&info->list, &xenconsoles); | ||
271 | spin_unlock(&xencons_lock); | ||
272 | |||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | static int xen_initial_domain_console_init(void) | ||
277 | { | ||
278 | struct xencons_info *info; | ||
279 | |||
280 | if (!xen_initial_domain()) | ||
281 | return -ENODEV; | ||
282 | |||
283 | info = vtermno_to_xencons(HVC_COOKIE); | ||
284 | if (!info) { | ||
285 | info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL | __GFP_ZERO); | ||
286 | if (!info) | ||
287 | return -ENOMEM; | ||
288 | } | ||
186 | 289 | ||
187 | hvc = hp; | 290 | info->irq = bind_virq_to_irq(VIRQ_CONSOLE, 0); |
291 | info->vtermno = HVC_COOKIE; | ||
188 | 292 | ||
189 | console_pfn = mfn_to_pfn(xen_start_info->console.domU.mfn); | 293 | spin_lock(&xencons_lock); |
294 | list_add_tail(&info->list, &xenconsoles); | ||
295 | spin_unlock(&xencons_lock); | ||
190 | 296 | ||
191 | return 0; | 297 | return 0; |
192 | } | 298 | } |
193 | 299 | ||
194 | void xen_console_resume(void) | 300 | void xen_console_resume(void) |
195 | { | 301 | { |
196 | if (xencons_irq) | 302 | struct xencons_info *info = vtermno_to_xencons(HVC_COOKIE); |
197 | rebind_evtchn_irq(xen_start_info->console.domU.evtchn, xencons_irq); | 303 | if (info != NULL && info->irq) |
304 | rebind_evtchn_irq(info->evtchn, info->irq); | ||
305 | } | ||
306 | |||
307 | static void xencons_disconnect_backend(struct xencons_info *info) | ||
308 | { | ||
309 | if (info->irq > 0) | ||
310 | unbind_from_irqhandler(info->irq, NULL); | ||
311 | info->irq = 0; | ||
312 | if (info->evtchn > 0) | ||
313 | xenbus_free_evtchn(info->xbdev, info->evtchn); | ||
314 | info->evtchn = 0; | ||
315 | if (info->gntref > 0) | ||
316 | gnttab_free_grant_references(info->gntref); | ||
317 | info->gntref = 0; | ||
318 | if (info->hvc != NULL) | ||
319 | hvc_remove(info->hvc); | ||
320 | info->hvc = NULL; | ||
321 | } | ||
322 | |||
323 | static void xencons_free(struct xencons_info *info) | ||
324 | { | ||
325 | free_page((unsigned long)info->intf); | ||
326 | info->intf = NULL; | ||
327 | info->vtermno = 0; | ||
328 | kfree(info); | ||
329 | } | ||
330 | |||
331 | static int xen_console_remove(struct xencons_info *info) | ||
332 | { | ||
333 | xencons_disconnect_backend(info); | ||
334 | spin_lock(&xencons_lock); | ||
335 | list_del(&info->list); | ||
336 | spin_unlock(&xencons_lock); | ||
337 | if (info->xbdev != NULL) | ||
338 | xencons_free(info); | ||
339 | else { | ||
340 | if (xen_hvm_domain()) | ||
341 | iounmap(info->intf); | ||
342 | kfree(info); | ||
343 | } | ||
344 | return 0; | ||
345 | } | ||
346 | |||
347 | #ifdef CONFIG_HVC_XEN_FRONTEND | ||
348 | static struct xenbus_driver xencons_driver; | ||
349 | |||
350 | static int xencons_remove(struct xenbus_device *dev) | ||
351 | { | ||
352 | return xen_console_remove(dev_get_drvdata(&dev->dev)); | ||
353 | } | ||
354 | |||
355 | static int xencons_connect_backend(struct xenbus_device *dev, | ||
356 | struct xencons_info *info) | ||
357 | { | ||
358 | int ret, evtchn, devid, ref, irq; | ||
359 | struct xenbus_transaction xbt; | ||
360 | grant_ref_t gref_head; | ||
361 | unsigned long mfn; | ||
362 | |||
363 | ret = xenbus_alloc_evtchn(dev, &evtchn); | ||
364 | if (ret) | ||
365 | return ret; | ||
366 | info->evtchn = evtchn; | ||
367 | irq = bind_evtchn_to_irq(evtchn); | ||
368 | if (irq < 0) | ||
369 | return irq; | ||
370 | info->irq = irq; | ||
371 | devid = dev->nodename[strlen(dev->nodename) - 1] - '0'; | ||
372 | info->hvc = hvc_alloc(xenbus_devid_to_vtermno(devid), | ||
373 | irq, &domU_hvc_ops, 256); | ||
374 | if (IS_ERR(info->hvc)) | ||
375 | return PTR_ERR(info->hvc); | ||
376 | if (xen_pv_domain()) | ||
377 | mfn = virt_to_mfn(info->intf); | ||
378 | else | ||
379 | mfn = __pa(info->intf) >> PAGE_SHIFT; | ||
380 | ret = gnttab_alloc_grant_references(1, &gref_head); | ||
381 | if (ret < 0) | ||
382 | return ret; | ||
383 | info->gntref = gref_head; | ||
384 | ref = gnttab_claim_grant_reference(&gref_head); | ||
385 | if (ref < 0) | ||
386 | return ref; | ||
387 | gnttab_grant_foreign_access_ref(ref, info->xbdev->otherend_id, | ||
388 | mfn, 0); | ||
389 | |||
390 | again: | ||
391 | ret = xenbus_transaction_start(&xbt); | ||
392 | if (ret) { | ||
393 | xenbus_dev_fatal(dev, ret, "starting transaction"); | ||
394 | return ret; | ||
395 | } | ||
396 | ret = xenbus_printf(xbt, dev->nodename, "ring-ref", "%d", ref); | ||
397 | if (ret) | ||
398 | goto error_xenbus; | ||
399 | ret = xenbus_printf(xbt, dev->nodename, "port", "%u", | ||
400 | evtchn); | ||
401 | if (ret) | ||
402 | goto error_xenbus; | ||
403 | ret = xenbus_printf(xbt, dev->nodename, "type", "ioemu"); | ||
404 | if (ret) | ||
405 | goto error_xenbus; | ||
406 | ret = xenbus_transaction_end(xbt, 0); | ||
407 | if (ret) { | ||
408 | if (ret == -EAGAIN) | ||
409 | goto again; | ||
410 | xenbus_dev_fatal(dev, ret, "completing transaction"); | ||
411 | return ret; | ||
412 | } | ||
413 | |||
414 | xenbus_switch_state(dev, XenbusStateInitialised); | ||
415 | return 0; | ||
416 | |||
417 | error_xenbus: | ||
418 | xenbus_transaction_end(xbt, 1); | ||
419 | xenbus_dev_fatal(dev, ret, "writing xenstore"); | ||
420 | return ret; | ||
421 | } | ||
422 | |||
423 | static int __devinit xencons_probe(struct xenbus_device *dev, | ||
424 | const struct xenbus_device_id *id) | ||
425 | { | ||
426 | int ret, devid; | ||
427 | struct xencons_info *info; | ||
428 | |||
429 | devid = dev->nodename[strlen(dev->nodename) - 1] - '0'; | ||
430 | if (devid == 0) | ||
431 | return -ENODEV; | ||
432 | |||
433 | info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL | __GFP_ZERO); | ||
434 | if (!info) | ||
435 | goto error_nomem; | ||
436 | dev_set_drvdata(&dev->dev, info); | ||
437 | info->xbdev = dev; | ||
438 | info->vtermno = xenbus_devid_to_vtermno(devid); | ||
439 | info->intf = (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO); | ||
440 | if (!info->intf) | ||
441 | goto error_nomem; | ||
442 | |||
443 | ret = xencons_connect_backend(dev, info); | ||
444 | if (ret < 0) | ||
445 | goto error; | ||
446 | spin_lock(&xencons_lock); | ||
447 | list_add_tail(&info->list, &xenconsoles); | ||
448 | spin_unlock(&xencons_lock); | ||
449 | |||
450 | return 0; | ||
451 | |||
452 | error_nomem: | ||
453 | ret = -ENOMEM; | ||
454 | xenbus_dev_fatal(dev, ret, "allocating device memory"); | ||
455 | error: | ||
456 | xencons_disconnect_backend(info); | ||
457 | xencons_free(info); | ||
458 | return ret; | ||
459 | } | ||
460 | |||
461 | static int xencons_resume(struct xenbus_device *dev) | ||
462 | { | ||
463 | struct xencons_info *info = dev_get_drvdata(&dev->dev); | ||
464 | |||
465 | xencons_disconnect_backend(info); | ||
466 | memset(info->intf, 0, PAGE_SIZE); | ||
467 | return xencons_connect_backend(dev, info); | ||
468 | } | ||
469 | |||
470 | static void xencons_backend_changed(struct xenbus_device *dev, | ||
471 | enum xenbus_state backend_state) | ||
472 | { | ||
473 | switch (backend_state) { | ||
474 | case XenbusStateReconfiguring: | ||
475 | case XenbusStateReconfigured: | ||
476 | case XenbusStateInitialising: | ||
477 | case XenbusStateInitialised: | ||
478 | case XenbusStateUnknown: | ||
479 | case XenbusStateClosed: | ||
480 | break; | ||
481 | |||
482 | case XenbusStateInitWait: | ||
483 | break; | ||
484 | |||
485 | case XenbusStateConnected: | ||
486 | xenbus_switch_state(dev, XenbusStateConnected); | ||
487 | break; | ||
488 | |||
489 | case XenbusStateClosing: | ||
490 | xenbus_frontend_closed(dev); | ||
491 | break; | ||
492 | } | ||
493 | } | ||
494 | |||
495 | static const struct xenbus_device_id xencons_ids[] = { | ||
496 | { "console" }, | ||
497 | { "" } | ||
498 | }; | ||
499 | |||
500 | |||
501 | static DEFINE_XENBUS_DRIVER(xencons, "xenconsole", | ||
502 | .probe = xencons_probe, | ||
503 | .remove = xencons_remove, | ||
504 | .resume = xencons_resume, | ||
505 | .otherend_changed = xencons_backend_changed, | ||
506 | ); | ||
507 | #endif /* CONFIG_HVC_XEN_FRONTEND */ | ||
508 | |||
509 | static int __init xen_hvc_init(void) | ||
510 | { | ||
511 | int r; | ||
512 | struct xencons_info *info; | ||
513 | const struct hv_ops *ops; | ||
514 | |||
515 | if (!xen_domain()) | ||
516 | return -ENODEV; | ||
517 | |||
518 | if (xen_initial_domain()) { | ||
519 | ops = &dom0_hvc_ops; | ||
520 | r = xen_initial_domain_console_init(); | ||
521 | if (r < 0) | ||
522 | return r; | ||
523 | info = vtermno_to_xencons(HVC_COOKIE); | ||
524 | } else { | ||
525 | ops = &domU_hvc_ops; | ||
526 | if (xen_hvm_domain()) | ||
527 | r = xen_hvm_console_init(); | ||
528 | else | ||
529 | r = xen_pv_console_init(); | ||
530 | if (r < 0) | ||
531 | return r; | ||
532 | |||
533 | info = vtermno_to_xencons(HVC_COOKIE); | ||
534 | info->irq = bind_evtchn_to_irq(info->evtchn); | ||
535 | } | ||
536 | if (info->irq < 0) | ||
537 | info->irq = 0; /* NO_IRQ */ | ||
538 | else | ||
539 | irq_set_noprobe(info->irq); | ||
540 | |||
541 | info->hvc = hvc_alloc(HVC_COOKIE, info->irq, ops, 256); | ||
542 | if (IS_ERR(info->hvc)) { | ||
543 | r = PTR_ERR(info->hvc); | ||
544 | spin_lock(&xencons_lock); | ||
545 | list_del(&info->list); | ||
546 | spin_unlock(&xencons_lock); | ||
547 | if (info->irq) | ||
548 | unbind_from_irqhandler(info->irq, NULL); | ||
549 | kfree(info); | ||
550 | return r; | ||
551 | } | ||
552 | |||
553 | r = 0; | ||
554 | #ifdef CONFIG_HVC_XEN_FRONTEND | ||
555 | r = xenbus_register_frontend(&xencons_driver); | ||
556 | #endif | ||
557 | return r; | ||
198 | } | 558 | } |
199 | 559 | ||
200 | static void __exit xen_hvc_fini(void) | 560 | static void __exit xen_hvc_fini(void) |
201 | { | 561 | { |
202 | if (hvc) | 562 | struct xencons_info *entry, *next; |
203 | hvc_remove(hvc); | 563 | |
564 | if (list_empty(&xenconsoles)) | ||
565 | return; | ||
566 | |||
567 | list_for_each_entry_safe(entry, next, &xenconsoles, list) { | ||
568 | xen_console_remove(entry); | ||
569 | } | ||
204 | } | 570 | } |
205 | 571 | ||
206 | static int xen_cons_init(void) | 572 | static int xen_cons_init(void) |
207 | { | 573 | { |
208 | struct hv_ops *ops; | 574 | const struct hv_ops *ops; |
209 | 575 | ||
210 | if (!xen_pv_domain()) | 576 | if (!xen_domain()) |
211 | return 0; | 577 | return 0; |
212 | 578 | ||
213 | if (xen_initial_domain()) | 579 | if (xen_initial_domain()) |
214 | ops = &dom0_hvc_ops; | 580 | ops = &dom0_hvc_ops; |
215 | else | 581 | else { |
582 | int r; | ||
216 | ops = &domU_hvc_ops; | 583 | ops = &domU_hvc_ops; |
217 | 584 | ||
585 | if (xen_hvm_domain()) | ||
586 | r = xen_hvm_console_init(); | ||
587 | else | ||
588 | r = xen_pv_console_init(); | ||
589 | if (r < 0) | ||
590 | return r; | ||
591 | } | ||
592 | |||
218 | hvc_instantiate(HVC_COOKIE, 0, ops); | 593 | hvc_instantiate(HVC_COOKIE, 0, ops); |
219 | return 0; | 594 | return 0; |
220 | } | 595 | } |
221 | 596 | ||
597 | |||
222 | module_init(xen_hvc_init); | 598 | module_init(xen_hvc_init); |
223 | module_exit(xen_hvc_fini); | 599 | module_exit(xen_hvc_fini); |
224 | console_initcall(xen_cons_init); | 600 | console_initcall(xen_cons_init); |
@@ -230,6 +606,9 @@ static void xenboot_write_console(struct console *console, const char *string, | |||
230 | unsigned int linelen, off = 0; | 606 | unsigned int linelen, off = 0; |
231 | const char *pos; | 607 | const char *pos; |
232 | 608 | ||
609 | if (!xen_pv_domain()) | ||
610 | return; | ||
611 | |||
233 | dom0_write_console(0, string, len); | 612 | dom0_write_console(0, string, len); |
234 | 613 | ||
235 | if (xen_initial_domain()) | 614 | if (xen_initial_domain()) |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 6ca0c407c144..eca60c73ef1f 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -2269,6 +2269,7 @@ config XEN_FBDEV_FRONTEND | |||
2269 | select FB_SYS_IMAGEBLIT | 2269 | select FB_SYS_IMAGEBLIT |
2270 | select FB_SYS_FOPS | 2270 | select FB_SYS_FOPS |
2271 | select FB_DEFERRED_IO | 2271 | select FB_DEFERRED_IO |
2272 | select INPUT_XEN_KBDDEV_FRONTEND | ||
2272 | select XEN_XENBUS_FRONTEND | 2273 | select XEN_XENBUS_FRONTEND |
2273 | default y | 2274 | default y |
2274 | help | 2275 | help |
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig index a1ced521cf74..648bcd4195c5 100644 --- a/drivers/xen/Kconfig +++ b/drivers/xen/Kconfig | |||
@@ -178,4 +178,21 @@ config XEN_PRIVCMD | |||
178 | depends on XEN | 178 | depends on XEN |
179 | default m | 179 | default m |
180 | 180 | ||
181 | config XEN_ACPI_PROCESSOR | ||
182 | tristate "Xen ACPI processor" | ||
183 | depends on XEN && X86 && ACPI_PROCESSOR | ||
184 | default y if (X86_ACPI_CPUFREQ = y || X86_POWERNOW_K8 = y) | ||
185 | default m if (X86_ACPI_CPUFREQ = m || X86_POWERNOW_K8 = m) | ||
186 | help | ||
187 | This ACPI processor uploads Power Management information to the Xen hypervisor. | ||
188 | |||
189 | To do that the driver parses the Power Management data and uploads said | ||
190 | information to the Xen hypervisor. Then the Xen hypervisor can select the | ||
191 | proper Cx and Pxx states. It also registers itslef as the SMM so that | ||
192 | other drivers (such as ACPI cpufreq scaling driver) will not load. | ||
193 | |||
194 | To compile this driver as a module, choose M here: the | ||
195 | module will be called xen_acpi_processor If you do not know what to choose, | ||
196 | select M here. If the CPUFREQ drivers are built in, select Y here. | ||
197 | |||
181 | endmenu | 198 | endmenu |
diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile index aa31337192cc..9adc5be57b13 100644 --- a/drivers/xen/Makefile +++ b/drivers/xen/Makefile | |||
@@ -20,7 +20,7 @@ obj-$(CONFIG_SWIOTLB_XEN) += swiotlb-xen.o | |||
20 | obj-$(CONFIG_XEN_DOM0) += pci.o | 20 | obj-$(CONFIG_XEN_DOM0) += pci.o |
21 | obj-$(CONFIG_XEN_PCIDEV_BACKEND) += xen-pciback/ | 21 | obj-$(CONFIG_XEN_PCIDEV_BACKEND) += xen-pciback/ |
22 | obj-$(CONFIG_XEN_PRIVCMD) += xen-privcmd.o | 22 | obj-$(CONFIG_XEN_PRIVCMD) += xen-privcmd.o |
23 | 23 | obj-$(CONFIG_XEN_ACPI_PROCESSOR) += xen-acpi-processor.o | |
24 | xen-evtchn-y := evtchn.o | 24 | xen-evtchn-y := evtchn.o |
25 | xen-gntdev-y := gntdev.o | 25 | xen-gntdev-y := gntdev.o |
26 | xen-gntalloc-y := gntalloc.o | 26 | xen-gntalloc-y := gntalloc.o |
diff --git a/drivers/xen/sys-hypervisor.c b/drivers/xen/sys-hypervisor.c index 1e0fe01eb670..fdb6d229c9bb 100644 --- a/drivers/xen/sys-hypervisor.c +++ b/drivers/xen/sys-hypervisor.c | |||
@@ -97,7 +97,7 @@ static struct attribute *version_attrs[] = { | |||
97 | NULL | 97 | NULL |
98 | }; | 98 | }; |
99 | 99 | ||
100 | static struct attribute_group version_group = { | 100 | static const struct attribute_group version_group = { |
101 | .name = "version", | 101 | .name = "version", |
102 | .attrs = version_attrs, | 102 | .attrs = version_attrs, |
103 | }; | 103 | }; |
@@ -210,7 +210,7 @@ static struct attribute *xen_compile_attrs[] = { | |||
210 | NULL | 210 | NULL |
211 | }; | 211 | }; |
212 | 212 | ||
213 | static struct attribute_group xen_compilation_group = { | 213 | static const struct attribute_group xen_compilation_group = { |
214 | .name = "compilation", | 214 | .name = "compilation", |
215 | .attrs = xen_compile_attrs, | 215 | .attrs = xen_compile_attrs, |
216 | }; | 216 | }; |
@@ -340,7 +340,7 @@ static struct attribute *xen_properties_attrs[] = { | |||
340 | NULL | 340 | NULL |
341 | }; | 341 | }; |
342 | 342 | ||
343 | static struct attribute_group xen_properties_group = { | 343 | static const struct attribute_group xen_properties_group = { |
344 | .name = "properties", | 344 | .name = "properties", |
345 | .attrs = xen_properties_attrs, | 345 | .attrs = xen_properties_attrs, |
346 | }; | 346 | }; |
diff --git a/drivers/xen/xen-acpi-processor.c b/drivers/xen/xen-acpi-processor.c new file mode 100644 index 000000000000..5c2be963aa18 --- /dev/null +++ b/drivers/xen/xen-acpi-processor.c | |||
@@ -0,0 +1,562 @@ | |||
1 | /* | ||
2 | * Copyright 2012 by Oracle Inc | ||
3 | * Author: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | ||
4 | * | ||
5 | * This code borrows ideas from https://lkml.org/lkml/2011/11/30/249 | ||
6 | * so many thanks go to Kevin Tian <kevin.tian@intel.com> | ||
7 | * and Yu Ke <ke.yu@intel.com>. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms and conditions of the GNU General Public License, | ||
11 | * version 2, as published by the Free Software Foundation. | ||
12 | * | ||
13 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
16 | * more details. | ||
17 | * | ||
18 | */ | ||
19 | |||
20 | #include <linux/cpumask.h> | ||
21 | #include <linux/cpufreq.h> | ||
22 | #include <linux/freezer.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/kthread.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/types.h> | ||
28 | #include <acpi/acpi_bus.h> | ||
29 | #include <acpi/acpi_drivers.h> | ||
30 | #include <acpi/processor.h> | ||
31 | |||
32 | #include <xen/interface/platform.h> | ||
33 | #include <asm/xen/hypercall.h> | ||
34 | |||
35 | #define DRV_NAME "xen-acpi-processor: " | ||
36 | |||
37 | static int no_hypercall; | ||
38 | MODULE_PARM_DESC(off, "Inhibit the hypercall."); | ||
39 | module_param_named(off, no_hypercall, int, 0400); | ||
40 | |||
41 | /* | ||
42 | * Note: Do not convert the acpi_id* below to cpumask_var_t or use cpumask_bit | ||
43 | * - as those shrink to nr_cpu_bits (which is dependent on possible_cpu), which | ||
44 | * can be less than what we want to put in. Instead use the 'nr_acpi_bits' | ||
45 | * which is dynamically computed based on the MADT or x2APIC table. | ||
46 | */ | ||
47 | static unsigned int nr_acpi_bits; | ||
48 | /* Mutex to protect the acpi_ids_done - for CPU hotplug use. */ | ||
49 | static DEFINE_MUTEX(acpi_ids_mutex); | ||
50 | /* Which ACPI ID we have processed from 'struct acpi_processor'. */ | ||
51 | static unsigned long *acpi_ids_done; | ||
52 | /* Which ACPI ID exist in the SSDT/DSDT processor definitions. */ | ||
53 | static unsigned long __initdata *acpi_id_present; | ||
54 | /* And if there is an _CST definition (or a PBLK) for the ACPI IDs */ | ||
55 | static unsigned long __initdata *acpi_id_cst_present; | ||
56 | |||
57 | static int push_cxx_to_hypervisor(struct acpi_processor *_pr) | ||
58 | { | ||
59 | struct xen_platform_op op = { | ||
60 | .cmd = XENPF_set_processor_pminfo, | ||
61 | .interface_version = XENPF_INTERFACE_VERSION, | ||
62 | .u.set_pminfo.id = _pr->acpi_id, | ||
63 | .u.set_pminfo.type = XEN_PM_CX, | ||
64 | }; | ||
65 | struct xen_processor_cx *dst_cx, *dst_cx_states = NULL; | ||
66 | struct acpi_processor_cx *cx; | ||
67 | unsigned int i, ok; | ||
68 | int ret = 0; | ||
69 | |||
70 | dst_cx_states = kcalloc(_pr->power.count, | ||
71 | sizeof(struct xen_processor_cx), GFP_KERNEL); | ||
72 | if (!dst_cx_states) | ||
73 | return -ENOMEM; | ||
74 | |||
75 | for (ok = 0, i = 1; i <= _pr->power.count; i++) { | ||
76 | cx = &_pr->power.states[i]; | ||
77 | if (!cx->valid) | ||
78 | continue; | ||
79 | |||
80 | dst_cx = &(dst_cx_states[ok++]); | ||
81 | |||
82 | dst_cx->reg.space_id = ACPI_ADR_SPACE_SYSTEM_IO; | ||
83 | if (cx->entry_method == ACPI_CSTATE_SYSTEMIO) { | ||
84 | dst_cx->reg.bit_width = 8; | ||
85 | dst_cx->reg.bit_offset = 0; | ||
86 | dst_cx->reg.access_size = 1; | ||
87 | } else { | ||
88 | dst_cx->reg.space_id = ACPI_ADR_SPACE_FIXED_HARDWARE; | ||
89 | if (cx->entry_method == ACPI_CSTATE_FFH) { | ||
90 | /* NATIVE_CSTATE_BEYOND_HALT */ | ||
91 | dst_cx->reg.bit_offset = 2; | ||
92 | dst_cx->reg.bit_width = 1; /* VENDOR_INTEL */ | ||
93 | } | ||
94 | dst_cx->reg.access_size = 0; | ||
95 | } | ||
96 | dst_cx->reg.address = cx->address; | ||
97 | |||
98 | dst_cx->type = cx->type; | ||
99 | dst_cx->latency = cx->latency; | ||
100 | dst_cx->power = cx->power; | ||
101 | |||
102 | dst_cx->dpcnt = 0; | ||
103 | set_xen_guest_handle(dst_cx->dp, NULL); | ||
104 | } | ||
105 | if (!ok) { | ||
106 | pr_debug(DRV_NAME "No _Cx for ACPI CPU %u\n", _pr->acpi_id); | ||
107 | kfree(dst_cx_states); | ||
108 | return -EINVAL; | ||
109 | } | ||
110 | op.u.set_pminfo.power.count = ok; | ||
111 | op.u.set_pminfo.power.flags.bm_control = _pr->flags.bm_control; | ||
112 | op.u.set_pminfo.power.flags.bm_check = _pr->flags.bm_check; | ||
113 | op.u.set_pminfo.power.flags.has_cst = _pr->flags.has_cst; | ||
114 | op.u.set_pminfo.power.flags.power_setup_done = | ||
115 | _pr->flags.power_setup_done; | ||
116 | |||
117 | set_xen_guest_handle(op.u.set_pminfo.power.states, dst_cx_states); | ||
118 | |||
119 | if (!no_hypercall) | ||
120 | ret = HYPERVISOR_dom0_op(&op); | ||
121 | |||
122 | if (!ret) { | ||
123 | pr_debug("ACPI CPU%u - C-states uploaded.\n", _pr->acpi_id); | ||
124 | for (i = 1; i <= _pr->power.count; i++) { | ||
125 | cx = &_pr->power.states[i]; | ||
126 | if (!cx->valid) | ||
127 | continue; | ||
128 | pr_debug(" C%d: %s %d uS\n", | ||
129 | cx->type, cx->desc, (u32)cx->latency); | ||
130 | } | ||
131 | } else | ||
132 | pr_err(DRV_NAME "(CX): Hypervisor error (%d) for ACPI CPU%u\n", | ||
133 | ret, _pr->acpi_id); | ||
134 | |||
135 | kfree(dst_cx_states); | ||
136 | |||
137 | return ret; | ||
138 | } | ||
139 | static struct xen_processor_px * | ||
140 | xen_copy_pss_data(struct acpi_processor *_pr, | ||
141 | struct xen_processor_performance *dst_perf) | ||
142 | { | ||
143 | struct xen_processor_px *dst_states = NULL; | ||
144 | unsigned int i; | ||
145 | |||
146 | BUILD_BUG_ON(sizeof(struct xen_processor_px) != | ||
147 | sizeof(struct acpi_processor_px)); | ||
148 | |||
149 | dst_states = kcalloc(_pr->performance->state_count, | ||
150 | sizeof(struct xen_processor_px), GFP_KERNEL); | ||
151 | if (!dst_states) | ||
152 | return ERR_PTR(-ENOMEM); | ||
153 | |||
154 | dst_perf->state_count = _pr->performance->state_count; | ||
155 | for (i = 0; i < _pr->performance->state_count; i++) { | ||
156 | /* Fortunatly for us, they are both the same size */ | ||
157 | memcpy(&(dst_states[i]), &(_pr->performance->states[i]), | ||
158 | sizeof(struct acpi_processor_px)); | ||
159 | } | ||
160 | return dst_states; | ||
161 | } | ||
162 | static int xen_copy_psd_data(struct acpi_processor *_pr, | ||
163 | struct xen_processor_performance *dst) | ||
164 | { | ||
165 | struct acpi_psd_package *pdomain; | ||
166 | |||
167 | BUILD_BUG_ON(sizeof(struct xen_psd_package) != | ||
168 | sizeof(struct acpi_psd_package)); | ||
169 | |||
170 | /* This information is enumerated only if acpi_processor_preregister_performance | ||
171 | * has been called. | ||
172 | */ | ||
173 | dst->shared_type = _pr->performance->shared_type; | ||
174 | |||
175 | pdomain = &(_pr->performance->domain_info); | ||
176 | |||
177 | /* 'acpi_processor_preregister_performance' does not parse if the | ||
178 | * num_processors <= 1, but Xen still requires it. Do it manually here. | ||
179 | */ | ||
180 | if (pdomain->num_processors <= 1) { | ||
181 | if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ALL) | ||
182 | dst->shared_type = CPUFREQ_SHARED_TYPE_ALL; | ||
183 | else if (pdomain->coord_type == DOMAIN_COORD_TYPE_HW_ALL) | ||
184 | dst->shared_type = CPUFREQ_SHARED_TYPE_HW; | ||
185 | else if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ANY) | ||
186 | dst->shared_type = CPUFREQ_SHARED_TYPE_ANY; | ||
187 | |||
188 | } | ||
189 | memcpy(&(dst->domain_info), pdomain, sizeof(struct acpi_psd_package)); | ||
190 | return 0; | ||
191 | } | ||
192 | static int xen_copy_pct_data(struct acpi_pct_register *pct, | ||
193 | struct xen_pct_register *dst_pct) | ||
194 | { | ||
195 | /* It would be nice if you could just do 'memcpy(pct, dst_pct') but | ||
196 | * sadly the Xen structure did not have the proper padding so the | ||
197 | * descriptor field takes two (dst_pct) bytes instead of one (pct). | ||
198 | */ | ||
199 | dst_pct->descriptor = pct->descriptor; | ||
200 | dst_pct->length = pct->length; | ||
201 | dst_pct->space_id = pct->space_id; | ||
202 | dst_pct->bit_width = pct->bit_width; | ||
203 | dst_pct->bit_offset = pct->bit_offset; | ||
204 | dst_pct->reserved = pct->reserved; | ||
205 | dst_pct->address = pct->address; | ||
206 | return 0; | ||
207 | } | ||
208 | static int push_pxx_to_hypervisor(struct acpi_processor *_pr) | ||
209 | { | ||
210 | int ret = 0; | ||
211 | struct xen_platform_op op = { | ||
212 | .cmd = XENPF_set_processor_pminfo, | ||
213 | .interface_version = XENPF_INTERFACE_VERSION, | ||
214 | .u.set_pminfo.id = _pr->acpi_id, | ||
215 | .u.set_pminfo.type = XEN_PM_PX, | ||
216 | }; | ||
217 | struct xen_processor_performance *dst_perf; | ||
218 | struct xen_processor_px *dst_states = NULL; | ||
219 | |||
220 | dst_perf = &op.u.set_pminfo.perf; | ||
221 | |||
222 | dst_perf->platform_limit = _pr->performance_platform_limit; | ||
223 | dst_perf->flags |= XEN_PX_PPC; | ||
224 | xen_copy_pct_data(&(_pr->performance->control_register), | ||
225 | &dst_perf->control_register); | ||
226 | xen_copy_pct_data(&(_pr->performance->status_register), | ||
227 | &dst_perf->status_register); | ||
228 | dst_perf->flags |= XEN_PX_PCT; | ||
229 | dst_states = xen_copy_pss_data(_pr, dst_perf); | ||
230 | if (!IS_ERR_OR_NULL(dst_states)) { | ||
231 | set_xen_guest_handle(dst_perf->states, dst_states); | ||
232 | dst_perf->flags |= XEN_PX_PSS; | ||
233 | } | ||
234 | if (!xen_copy_psd_data(_pr, dst_perf)) | ||
235 | dst_perf->flags |= XEN_PX_PSD; | ||
236 | |||
237 | if (dst_perf->flags != (XEN_PX_PSD | XEN_PX_PSS | XEN_PX_PCT | XEN_PX_PPC)) { | ||
238 | pr_warn(DRV_NAME "ACPI CPU%u missing some P-state data (%x), skipping.\n", | ||
239 | _pr->acpi_id, dst_perf->flags); | ||
240 | ret = -ENODEV; | ||
241 | goto err_free; | ||
242 | } | ||
243 | |||
244 | if (!no_hypercall) | ||
245 | ret = HYPERVISOR_dom0_op(&op); | ||
246 | |||
247 | if (!ret) { | ||
248 | struct acpi_processor_performance *perf; | ||
249 | unsigned int i; | ||
250 | |||
251 | perf = _pr->performance; | ||
252 | pr_debug("ACPI CPU%u - P-states uploaded.\n", _pr->acpi_id); | ||
253 | for (i = 0; i < perf->state_count; i++) { | ||
254 | pr_debug(" %cP%d: %d MHz, %d mW, %d uS\n", | ||
255 | (i == perf->state ? '*' : ' '), i, | ||
256 | (u32) perf->states[i].core_frequency, | ||
257 | (u32) perf->states[i].power, | ||
258 | (u32) perf->states[i].transition_latency); | ||
259 | } | ||
260 | } else if (ret != -EINVAL) | ||
261 | /* EINVAL means the ACPI ID is incorrect - meaning the ACPI | ||
262 | * table is referencing a non-existing CPU - which can happen | ||
263 | * with broken ACPI tables. */ | ||
264 | pr_warn(DRV_NAME "(_PXX): Hypervisor error (%d) for ACPI CPU%u\n", | ||
265 | ret, _pr->acpi_id); | ||
266 | err_free: | ||
267 | if (!IS_ERR_OR_NULL(dst_states)) | ||
268 | kfree(dst_states); | ||
269 | |||
270 | return ret; | ||
271 | } | ||
272 | static int upload_pm_data(struct acpi_processor *_pr) | ||
273 | { | ||
274 | int err = 0; | ||
275 | |||
276 | mutex_lock(&acpi_ids_mutex); | ||
277 | if (__test_and_set_bit(_pr->acpi_id, acpi_ids_done)) { | ||
278 | mutex_unlock(&acpi_ids_mutex); | ||
279 | return -EBUSY; | ||
280 | } | ||
281 | if (_pr->flags.power) | ||
282 | err = push_cxx_to_hypervisor(_pr); | ||
283 | |||
284 | if (_pr->performance && _pr->performance->states) | ||
285 | err |= push_pxx_to_hypervisor(_pr); | ||
286 | |||
287 | mutex_unlock(&acpi_ids_mutex); | ||
288 | return err; | ||
289 | } | ||
290 | static unsigned int __init get_max_acpi_id(void) | ||
291 | { | ||
292 | struct xenpf_pcpuinfo *info; | ||
293 | struct xen_platform_op op = { | ||
294 | .cmd = XENPF_get_cpuinfo, | ||
295 | .interface_version = XENPF_INTERFACE_VERSION, | ||
296 | }; | ||
297 | int ret = 0; | ||
298 | unsigned int i, last_cpu, max_acpi_id = 0; | ||
299 | |||
300 | info = &op.u.pcpu_info; | ||
301 | info->xen_cpuid = 0; | ||
302 | |||
303 | ret = HYPERVISOR_dom0_op(&op); | ||
304 | if (ret) | ||
305 | return NR_CPUS; | ||
306 | |||
307 | /* The max_present is the same irregardless of the xen_cpuid */ | ||
308 | last_cpu = op.u.pcpu_info.max_present; | ||
309 | for (i = 0; i <= last_cpu; i++) { | ||
310 | info->xen_cpuid = i; | ||
311 | ret = HYPERVISOR_dom0_op(&op); | ||
312 | if (ret) | ||
313 | continue; | ||
314 | max_acpi_id = max(info->acpi_id, max_acpi_id); | ||
315 | } | ||
316 | max_acpi_id *= 2; /* Slack for CPU hotplug support. */ | ||
317 | pr_debug(DRV_NAME "Max ACPI ID: %u\n", max_acpi_id); | ||
318 | return max_acpi_id; | ||
319 | } | ||
320 | /* | ||
321 | * The read_acpi_id and check_acpi_ids are there to support the Xen | ||
322 | * oddity of virtual CPUs != physical CPUs in the initial domain. | ||
323 | * The user can supply 'xen_max_vcpus=X' on the Xen hypervisor line | ||
324 | * which will band the amount of CPUs the initial domain can see. | ||
325 | * In general that is OK, except it plays havoc with any of the | ||
326 | * for_each_[present|online]_cpu macros which are banded to the virtual | ||
327 | * CPU amount. | ||
328 | */ | ||
329 | static acpi_status __init | ||
330 | read_acpi_id(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
331 | { | ||
332 | u32 acpi_id; | ||
333 | acpi_status status; | ||
334 | acpi_object_type acpi_type; | ||
335 | unsigned long long tmp; | ||
336 | union acpi_object object = { 0 }; | ||
337 | struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; | ||
338 | acpi_io_address pblk = 0; | ||
339 | |||
340 | status = acpi_get_type(handle, &acpi_type); | ||
341 | if (ACPI_FAILURE(status)) | ||
342 | return AE_OK; | ||
343 | |||
344 | switch (acpi_type) { | ||
345 | case ACPI_TYPE_PROCESSOR: | ||
346 | status = acpi_evaluate_object(handle, NULL, NULL, &buffer); | ||
347 | if (ACPI_FAILURE(status)) | ||
348 | return AE_OK; | ||
349 | acpi_id = object.processor.proc_id; | ||
350 | pblk = object.processor.pblk_address; | ||
351 | break; | ||
352 | case ACPI_TYPE_DEVICE: | ||
353 | status = acpi_evaluate_integer(handle, "_UID", NULL, &tmp); | ||
354 | if (ACPI_FAILURE(status)) | ||
355 | return AE_OK; | ||
356 | acpi_id = tmp; | ||
357 | break; | ||
358 | default: | ||
359 | return AE_OK; | ||
360 | } | ||
361 | /* There are more ACPI Processor objects than in x2APIC or MADT. | ||
362 | * This can happen with incorrect ACPI SSDT declerations. */ | ||
363 | if (acpi_id > nr_acpi_bits) { | ||
364 | pr_debug(DRV_NAME "We only have %u, trying to set %u\n", | ||
365 | nr_acpi_bits, acpi_id); | ||
366 | return AE_OK; | ||
367 | } | ||
368 | /* OK, There is a ACPI Processor object */ | ||
369 | __set_bit(acpi_id, acpi_id_present); | ||
370 | |||
371 | pr_debug(DRV_NAME "ACPI CPU%u w/ PBLK:0x%lx\n", acpi_id, | ||
372 | (unsigned long)pblk); | ||
373 | |||
374 | status = acpi_evaluate_object(handle, "_CST", NULL, &buffer); | ||
375 | if (ACPI_FAILURE(status)) { | ||
376 | if (!pblk) | ||
377 | return AE_OK; | ||
378 | } | ||
379 | /* .. and it has a C-state */ | ||
380 | __set_bit(acpi_id, acpi_id_cst_present); | ||
381 | |||
382 | return AE_OK; | ||
383 | } | ||
384 | static int __init check_acpi_ids(struct acpi_processor *pr_backup) | ||
385 | { | ||
386 | |||
387 | if (!pr_backup) | ||
388 | return -ENODEV; | ||
389 | |||
390 | /* All online CPUs have been processed at this stage. Now verify | ||
391 | * whether in fact "online CPUs" == physical CPUs. | ||
392 | */ | ||
393 | acpi_id_present = kcalloc(BITS_TO_LONGS(nr_acpi_bits), sizeof(unsigned long), GFP_KERNEL); | ||
394 | if (!acpi_id_present) | ||
395 | return -ENOMEM; | ||
396 | |||
397 | acpi_id_cst_present = kcalloc(BITS_TO_LONGS(nr_acpi_bits), sizeof(unsigned long), GFP_KERNEL); | ||
398 | if (!acpi_id_cst_present) { | ||
399 | kfree(acpi_id_present); | ||
400 | return -ENOMEM; | ||
401 | } | ||
402 | |||
403 | acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, | ||
404 | ACPI_UINT32_MAX, | ||
405 | read_acpi_id, NULL, NULL, NULL); | ||
406 | acpi_get_devices("ACPI0007", read_acpi_id, NULL, NULL); | ||
407 | |||
408 | if (!bitmap_equal(acpi_id_present, acpi_ids_done, nr_acpi_bits)) { | ||
409 | unsigned int i; | ||
410 | for_each_set_bit(i, acpi_id_present, nr_acpi_bits) { | ||
411 | pr_backup->acpi_id = i; | ||
412 | /* Mask out C-states if there are no _CST or PBLK */ | ||
413 | pr_backup->flags.power = test_bit(i, acpi_id_cst_present); | ||
414 | (void)upload_pm_data(pr_backup); | ||
415 | } | ||
416 | } | ||
417 | kfree(acpi_id_present); | ||
418 | acpi_id_present = NULL; | ||
419 | kfree(acpi_id_cst_present); | ||
420 | acpi_id_cst_present = NULL; | ||
421 | return 0; | ||
422 | } | ||
423 | static int __init check_prereq(void) | ||
424 | { | ||
425 | struct cpuinfo_x86 *c = &cpu_data(0); | ||
426 | |||
427 | if (!xen_initial_domain()) | ||
428 | return -ENODEV; | ||
429 | |||
430 | if (!acpi_gbl_FADT.smi_command) | ||
431 | return -ENODEV; | ||
432 | |||
433 | if (c->x86_vendor == X86_VENDOR_INTEL) { | ||
434 | if (!cpu_has(c, X86_FEATURE_EST)) | ||
435 | return -ENODEV; | ||
436 | |||
437 | return 0; | ||
438 | } | ||
439 | if (c->x86_vendor == X86_VENDOR_AMD) { | ||
440 | /* Copied from powernow-k8.h, can't include ../cpufreq/powernow | ||
441 | * as we get compile warnings for the static functions. | ||
442 | */ | ||
443 | #define CPUID_FREQ_VOLT_CAPABILITIES 0x80000007 | ||
444 | #define USE_HW_PSTATE 0x00000080 | ||
445 | u32 eax, ebx, ecx, edx; | ||
446 | cpuid(CPUID_FREQ_VOLT_CAPABILITIES, &eax, &ebx, &ecx, &edx); | ||
447 | if ((edx & USE_HW_PSTATE) != USE_HW_PSTATE) | ||
448 | return -ENODEV; | ||
449 | return 0; | ||
450 | } | ||
451 | return -ENODEV; | ||
452 | } | ||
453 | /* acpi_perf_data is a pointer to percpu data. */ | ||
454 | static struct acpi_processor_performance __percpu *acpi_perf_data; | ||
455 | |||
456 | static void free_acpi_perf_data(void) | ||
457 | { | ||
458 | unsigned int i; | ||
459 | |||
460 | /* Freeing a NULL pointer is OK, and alloc_percpu zeroes. */ | ||
461 | for_each_possible_cpu(i) | ||
462 | free_cpumask_var(per_cpu_ptr(acpi_perf_data, i) | ||
463 | ->shared_cpu_map); | ||
464 | free_percpu(acpi_perf_data); | ||
465 | } | ||
466 | |||
467 | static int __init xen_acpi_processor_init(void) | ||
468 | { | ||
469 | struct acpi_processor *pr_backup = NULL; | ||
470 | unsigned int i; | ||
471 | int rc = check_prereq(); | ||
472 | |||
473 | if (rc) | ||
474 | return rc; | ||
475 | |||
476 | nr_acpi_bits = get_max_acpi_id() + 1; | ||
477 | acpi_ids_done = kcalloc(BITS_TO_LONGS(nr_acpi_bits), sizeof(unsigned long), GFP_KERNEL); | ||
478 | if (!acpi_ids_done) | ||
479 | return -ENOMEM; | ||
480 | |||
481 | acpi_perf_data = alloc_percpu(struct acpi_processor_performance); | ||
482 | if (!acpi_perf_data) { | ||
483 | pr_debug(DRV_NAME "Memory allocation error for acpi_perf_data.\n"); | ||
484 | kfree(acpi_ids_done); | ||
485 | return -ENOMEM; | ||
486 | } | ||
487 | for_each_possible_cpu(i) { | ||
488 | if (!zalloc_cpumask_var_node( | ||
489 | &per_cpu_ptr(acpi_perf_data, i)->shared_cpu_map, | ||
490 | GFP_KERNEL, cpu_to_node(i))) { | ||
491 | rc = -ENOMEM; | ||
492 | goto err_out; | ||
493 | } | ||
494 | } | ||
495 | |||
496 | /* Do initialization in ACPI core. It is OK to fail here. */ | ||
497 | (void)acpi_processor_preregister_performance(acpi_perf_data); | ||
498 | |||
499 | for_each_possible_cpu(i) { | ||
500 | struct acpi_processor_performance *perf; | ||
501 | |||
502 | perf = per_cpu_ptr(acpi_perf_data, i); | ||
503 | rc = acpi_processor_register_performance(perf, i); | ||
504 | if (WARN_ON(rc)) | ||
505 | goto err_out; | ||
506 | } | ||
507 | rc = acpi_processor_notify_smm(THIS_MODULE); | ||
508 | if (WARN_ON(rc)) | ||
509 | goto err_unregister; | ||
510 | |||
511 | for_each_possible_cpu(i) { | ||
512 | struct acpi_processor *_pr; | ||
513 | _pr = per_cpu(processors, i /* APIC ID */); | ||
514 | if (!_pr) | ||
515 | continue; | ||
516 | |||
517 | if (!pr_backup) { | ||
518 | pr_backup = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL); | ||
519 | memcpy(pr_backup, _pr, sizeof(struct acpi_processor)); | ||
520 | } | ||
521 | (void)upload_pm_data(_pr); | ||
522 | } | ||
523 | rc = check_acpi_ids(pr_backup); | ||
524 | if (rc) | ||
525 | goto err_unregister; | ||
526 | |||
527 | kfree(pr_backup); | ||
528 | |||
529 | return 0; | ||
530 | err_unregister: | ||
531 | for_each_possible_cpu(i) { | ||
532 | struct acpi_processor_performance *perf; | ||
533 | perf = per_cpu_ptr(acpi_perf_data, i); | ||
534 | acpi_processor_unregister_performance(perf, i); | ||
535 | } | ||
536 | err_out: | ||
537 | /* Freeing a NULL pointer is OK: alloc_percpu zeroes. */ | ||
538 | free_acpi_perf_data(); | ||
539 | kfree(acpi_ids_done); | ||
540 | return rc; | ||
541 | } | ||
542 | static void __exit xen_acpi_processor_exit(void) | ||
543 | { | ||
544 | int i; | ||
545 | |||
546 | kfree(acpi_ids_done); | ||
547 | for_each_possible_cpu(i) { | ||
548 | struct acpi_processor_performance *perf; | ||
549 | perf = per_cpu_ptr(acpi_perf_data, i); | ||
550 | acpi_processor_unregister_performance(perf, i); | ||
551 | } | ||
552 | free_acpi_perf_data(); | ||
553 | } | ||
554 | |||
555 | MODULE_AUTHOR("Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>"); | ||
556 | MODULE_DESCRIPTION("Xen ACPI Processor P-states (and Cx) driver which uploads PM data to Xen hypervisor"); | ||
557 | MODULE_LICENSE("GPL"); | ||
558 | |||
559 | /* We want to be loaded before the CPU freq scaling drivers are loaded. | ||
560 | * They are loaded in late_initcall. */ | ||
561 | device_initcall(xen_acpi_processor_init); | ||
562 | module_exit(xen_acpi_processor_exit); | ||
diff --git a/drivers/xen/xen-balloon.c b/drivers/xen/xen-balloon.c index 596e6a7b17d6..8f37e23f6d13 100644 --- a/drivers/xen/xen-balloon.c +++ b/drivers/xen/xen-balloon.c | |||
@@ -207,7 +207,7 @@ static struct attribute *balloon_info_attrs[] = { | |||
207 | NULL | 207 | NULL |
208 | }; | 208 | }; |
209 | 209 | ||
210 | static struct attribute_group balloon_info_group = { | 210 | static const struct attribute_group balloon_info_group = { |
211 | .name = "info", | 211 | .name = "info", |
212 | .attrs = balloon_info_attrs | 212 | .attrs = balloon_info_attrs |
213 | }; | 213 | }; |
diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c index 19834d1c7c36..097e536e8672 100644 --- a/drivers/xen/xen-pciback/pci_stub.c +++ b/drivers/xen/xen-pciback/pci_stub.c | |||
@@ -85,19 +85,34 @@ static struct pcistub_device *pcistub_device_alloc(struct pci_dev *dev) | |||
85 | static void pcistub_device_release(struct kref *kref) | 85 | static void pcistub_device_release(struct kref *kref) |
86 | { | 86 | { |
87 | struct pcistub_device *psdev; | 87 | struct pcistub_device *psdev; |
88 | struct xen_pcibk_dev_data *dev_data; | ||
88 | 89 | ||
89 | psdev = container_of(kref, struct pcistub_device, kref); | 90 | psdev = container_of(kref, struct pcistub_device, kref); |
91 | dev_data = pci_get_drvdata(psdev->dev); | ||
90 | 92 | ||
91 | dev_dbg(&psdev->dev->dev, "pcistub_device_release\n"); | 93 | dev_dbg(&psdev->dev->dev, "pcistub_device_release\n"); |
92 | 94 | ||
93 | xen_unregister_device_domain_owner(psdev->dev); | 95 | xen_unregister_device_domain_owner(psdev->dev); |
94 | 96 | ||
95 | /* Clean-up the device */ | 97 | /* Call the reset function which does not take lock as this |
98 | * is called from "unbind" which takes a device_lock mutex. | ||
99 | */ | ||
100 | __pci_reset_function_locked(psdev->dev); | ||
101 | if (pci_load_and_free_saved_state(psdev->dev, | ||
102 | &dev_data->pci_saved_state)) { | ||
103 | dev_dbg(&psdev->dev->dev, "Could not reload PCI state\n"); | ||
104 | } else | ||
105 | pci_restore_state(psdev->dev); | ||
106 | |||
107 | /* Disable the device */ | ||
96 | xen_pcibk_reset_device(psdev->dev); | 108 | xen_pcibk_reset_device(psdev->dev); |
109 | |||
110 | kfree(dev_data); | ||
111 | pci_set_drvdata(psdev->dev, NULL); | ||
112 | |||
113 | /* Clean-up the device */ | ||
97 | xen_pcibk_config_free_dyn_fields(psdev->dev); | 114 | xen_pcibk_config_free_dyn_fields(psdev->dev); |
98 | xen_pcibk_config_free_dev(psdev->dev); | 115 | xen_pcibk_config_free_dev(psdev->dev); |
99 | kfree(pci_get_drvdata(psdev->dev)); | ||
100 | pci_set_drvdata(psdev->dev, NULL); | ||
101 | 116 | ||
102 | psdev->dev->dev_flags &= ~PCI_DEV_FLAGS_ASSIGNED; | 117 | psdev->dev->dev_flags &= ~PCI_DEV_FLAGS_ASSIGNED; |
103 | pci_dev_put(psdev->dev); | 118 | pci_dev_put(psdev->dev); |
@@ -231,7 +246,17 @@ void pcistub_put_pci_dev(struct pci_dev *dev) | |||
231 | /* Cleanup our device | 246 | /* Cleanup our device |
232 | * (so it's ready for the next domain) | 247 | * (so it's ready for the next domain) |
233 | */ | 248 | */ |
249 | |||
250 | /* This is OK - we are running from workqueue context | ||
251 | * and want to inhibit the user from fiddling with 'reset' | ||
252 | */ | ||
253 | pci_reset_function(dev); | ||
254 | pci_restore_state(psdev->dev); | ||
255 | |||
256 | /* This disables the device. */ | ||
234 | xen_pcibk_reset_device(found_psdev->dev); | 257 | xen_pcibk_reset_device(found_psdev->dev); |
258 | |||
259 | /* And cleanup up our emulated fields. */ | ||
235 | xen_pcibk_config_free_dyn_fields(found_psdev->dev); | 260 | xen_pcibk_config_free_dyn_fields(found_psdev->dev); |
236 | xen_pcibk_config_reset_dev(found_psdev->dev); | 261 | xen_pcibk_config_reset_dev(found_psdev->dev); |
237 | 262 | ||
@@ -328,6 +353,16 @@ static int __devinit pcistub_init_device(struct pci_dev *dev) | |||
328 | if (err) | 353 | if (err) |
329 | goto config_release; | 354 | goto config_release; |
330 | 355 | ||
356 | dev_dbg(&dev->dev, "reseting (FLR, D3, etc) the device\n"); | ||
357 | __pci_reset_function_locked(dev); | ||
358 | |||
359 | /* We need the device active to save the state. */ | ||
360 | dev_dbg(&dev->dev, "save state of device\n"); | ||
361 | pci_save_state(dev); | ||
362 | dev_data->pci_saved_state = pci_store_saved_state(dev); | ||
363 | if (!dev_data->pci_saved_state) | ||
364 | dev_err(&dev->dev, "Could not store PCI conf saved state!\n"); | ||
365 | |||
331 | /* Now disable the device (this also ensures some private device | 366 | /* Now disable the device (this also ensures some private device |
332 | * data is setup before we export) | 367 | * data is setup before we export) |
333 | */ | 368 | */ |
diff --git a/drivers/xen/xen-pciback/pciback.h b/drivers/xen/xen-pciback/pciback.h index e9b4011c5f9a..a7def010eba3 100644 --- a/drivers/xen/xen-pciback/pciback.h +++ b/drivers/xen/xen-pciback/pciback.h | |||
@@ -41,6 +41,7 @@ struct xen_pcibk_device { | |||
41 | 41 | ||
42 | struct xen_pcibk_dev_data { | 42 | struct xen_pcibk_dev_data { |
43 | struct list_head config_fields; | 43 | struct list_head config_fields; |
44 | struct pci_saved_state *pci_saved_state; | ||
44 | unsigned int permissive:1; | 45 | unsigned int permissive:1; |
45 | unsigned int warned_on_write:1; | 46 | unsigned int warned_on_write:1; |
46 | unsigned int enable_intx:1; | 47 | unsigned int enable_intx:1; |
diff --git a/drivers/xen/xen-selfballoon.c b/drivers/xen/xen-selfballoon.c index 767ff656d5a7..146c94897016 100644 --- a/drivers/xen/xen-selfballoon.c +++ b/drivers/xen/xen-selfballoon.c | |||
@@ -488,7 +488,7 @@ static struct attribute *selfballoon_attrs[] = { | |||
488 | NULL | 488 | NULL |
489 | }; | 489 | }; |
490 | 490 | ||
491 | static struct attribute_group selfballoon_group = { | 491 | static const struct attribute_group selfballoon_group = { |
492 | .name = "selfballoon", | 492 | .name = "selfballoon", |
493 | .attrs = selfballoon_attrs | 493 | .attrs = selfballoon_attrs |
494 | }; | 494 | }; |
diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c index 566d2adbd6ea..b3e146edb51d 100644 --- a/drivers/xen/xenbus/xenbus_client.c +++ b/drivers/xen/xenbus/xenbus_client.c | |||
@@ -569,7 +569,7 @@ int xenbus_map_ring(struct xenbus_device *dev, int gnt_ref, | |||
569 | { | 569 | { |
570 | struct gnttab_map_grant_ref op; | 570 | struct gnttab_map_grant_ref op; |
571 | 571 | ||
572 | gnttab_set_map_op(&op, (phys_addr_t)vaddr, GNTMAP_host_map, gnt_ref, | 572 | gnttab_set_map_op(&op, (unsigned long)vaddr, GNTMAP_host_map, gnt_ref, |
573 | dev->otherend_id); | 573 | dev->otherend_id); |
574 | 574 | ||
575 | if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1)) | 575 | if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1)) |
@@ -662,7 +662,7 @@ static int xenbus_unmap_ring_vfree_hvm(struct xenbus_device *dev, void *vaddr) | |||
662 | goto found; | 662 | goto found; |
663 | } | 663 | } |
664 | } | 664 | } |
665 | node = NULL; | 665 | node = addr = NULL; |
666 | found: | 666 | found: |
667 | spin_unlock(&xenbus_valloc_lock); | 667 | spin_unlock(&xenbus_valloc_lock); |
668 | 668 | ||
@@ -698,7 +698,7 @@ int xenbus_unmap_ring(struct xenbus_device *dev, | |||
698 | { | 698 | { |
699 | struct gnttab_unmap_grant_ref op; | 699 | struct gnttab_unmap_grant_ref op; |
700 | 700 | ||
701 | gnttab_set_unmap_op(&op, (phys_addr_t)vaddr, GNTMAP_host_map, handle); | 701 | gnttab_set_unmap_op(&op, (unsigned long)vaddr, GNTMAP_host_map, handle); |
702 | 702 | ||
703 | if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)) | 703 | if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)) |
704 | BUG(); | 704 | BUG(); |
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c index 3864967202b5..b793723e724d 100644 --- a/drivers/xen/xenbus/xenbus_probe.c +++ b/drivers/xen/xenbus/xenbus_probe.c | |||
@@ -257,11 +257,12 @@ int xenbus_dev_remove(struct device *_dev) | |||
257 | DPRINTK("%s", dev->nodename); | 257 | DPRINTK("%s", dev->nodename); |
258 | 258 | ||
259 | free_otherend_watch(dev); | 259 | free_otherend_watch(dev); |
260 | free_otherend_details(dev); | ||
261 | 260 | ||
262 | if (drv->remove) | 261 | if (drv->remove) |
263 | drv->remove(dev); | 262 | drv->remove(dev); |
264 | 263 | ||
264 | free_otherend_details(dev); | ||
265 | |||
265 | xenbus_switch_state(dev, XenbusStateClosed); | 266 | xenbus_switch_state(dev, XenbusStateClosed); |
266 | return 0; | 267 | return 0; |
267 | } | 268 | } |
diff --git a/drivers/xen/xenbus/xenbus_probe_frontend.c b/drivers/xen/xenbus/xenbus_probe_frontend.c index 9c57819df51a..f20c5f178b40 100644 --- a/drivers/xen/xenbus/xenbus_probe_frontend.c +++ b/drivers/xen/xenbus/xenbus_probe_frontend.c | |||
@@ -53,6 +53,12 @@ static int xenbus_probe_frontend(struct xen_bus_type *bus, const char *type, | |||
53 | char *nodename; | 53 | char *nodename; |
54 | int err; | 54 | int err; |
55 | 55 | ||
56 | /* ignore console/0 */ | ||
57 | if (!strncmp(type, "console", 7) && !strncmp(name, "0", 1)) { | ||
58 | DPRINTK("Ignoring buggy device entry console/0"); | ||
59 | return 0; | ||
60 | } | ||
61 | |||
56 | nodename = kasprintf(GFP_KERNEL, "%s/%s/%s", bus->root, type, name); | 62 | nodename = kasprintf(GFP_KERNEL, "%s/%s/%s", bus->root, type, name); |
57 | if (!nodename) | 63 | if (!nodename) |
58 | return -ENOMEM; | 64 | return -ENOMEM; |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 27bf521bcebd..900da5db60ee 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -817,6 +817,7 @@ int pcie_set_readrq(struct pci_dev *dev, int rq); | |||
817 | int pcie_get_mps(struct pci_dev *dev); | 817 | int pcie_get_mps(struct pci_dev *dev); |
818 | int pcie_set_mps(struct pci_dev *dev, int mps); | 818 | int pcie_set_mps(struct pci_dev *dev, int mps); |
819 | int __pci_reset_function(struct pci_dev *dev); | 819 | int __pci_reset_function(struct pci_dev *dev); |
820 | int __pci_reset_function_locked(struct pci_dev *dev); | ||
820 | int pci_reset_function(struct pci_dev *dev); | 821 | int pci_reset_function(struct pci_dev *dev); |
821 | void pci_update_resource(struct pci_dev *dev, int resno); | 822 | void pci_update_resource(struct pci_dev *dev, int resno); |
822 | int __must_check pci_assign_resource(struct pci_dev *dev, int i); | 823 | int __must_check pci_assign_resource(struct pci_dev *dev, int i); |
diff --git a/include/xen/interface/hvm/params.h b/include/xen/interface/hvm/params.h index 1888d8c157e6..1b4f923d7086 100644 --- a/include/xen/interface/hvm/params.h +++ b/include/xen/interface/hvm/params.h | |||
@@ -90,6 +90,10 @@ | |||
90 | /* Boolean: Enable aligning all periodic vpts to reduce interrupts */ | 90 | /* Boolean: Enable aligning all periodic vpts to reduce interrupts */ |
91 | #define HVM_PARAM_VPT_ALIGN 16 | 91 | #define HVM_PARAM_VPT_ALIGN 16 |
92 | 92 | ||
93 | #define HVM_NR_PARAMS 17 | 93 | /* Console debug shared memory ring and event channel */ |
94 | #define HVM_PARAM_CONSOLE_PFN 17 | ||
95 | #define HVM_PARAM_CONSOLE_EVTCHN 18 | ||
96 | |||
97 | #define HVM_NR_PARAMS 19 | ||
94 | 98 | ||
95 | #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */ | 99 | #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */ |
diff --git a/include/xen/interface/physdev.h b/include/xen/interface/physdev.h index c1080d9c705d..0c28989007fb 100644 --- a/include/xen/interface/physdev.h +++ b/include/xen/interface/physdev.h | |||
@@ -145,6 +145,13 @@ struct physdev_manage_pci { | |||
145 | uint8_t devfn; | 145 | uint8_t devfn; |
146 | }; | 146 | }; |
147 | 147 | ||
148 | #define PHYSDEVOP_restore_msi 19 | ||
149 | struct physdev_restore_msi { | ||
150 | /* IN */ | ||
151 | uint8_t bus; | ||
152 | uint8_t devfn; | ||
153 | }; | ||
154 | |||
148 | #define PHYSDEVOP_manage_pci_add_ext 20 | 155 | #define PHYSDEVOP_manage_pci_add_ext 20 |
149 | struct physdev_manage_pci_ext { | 156 | struct physdev_manage_pci_ext { |
150 | /* IN */ | 157 | /* IN */ |
diff --git a/include/xen/interface/platform.h b/include/xen/interface/platform.h index c1684680431b..486653f0dd8f 100644 --- a/include/xen/interface/platform.h +++ b/include/xen/interface/platform.h | |||
@@ -200,7 +200,7 @@ DEFINE_GUEST_HANDLE_STRUCT(xenpf_getidletime_t); | |||
200 | #define XEN_PM_CX 0 | 200 | #define XEN_PM_CX 0 |
201 | #define XEN_PM_PX 1 | 201 | #define XEN_PM_PX 1 |
202 | #define XEN_PM_TX 2 | 202 | #define XEN_PM_TX 2 |
203 | 203 | #define XEN_PM_PDC 3 | |
204 | /* Px sub info type */ | 204 | /* Px sub info type */ |
205 | #define XEN_PX_PCT 1 | 205 | #define XEN_PX_PCT 1 |
206 | #define XEN_PX_PSS 2 | 206 | #define XEN_PX_PSS 2 |
@@ -293,10 +293,27 @@ struct xenpf_set_processor_pminfo { | |||
293 | union { | 293 | union { |
294 | struct xen_processor_power power;/* Cx: _CST/_CSD */ | 294 | struct xen_processor_power power;/* Cx: _CST/_CSD */ |
295 | struct xen_processor_performance perf; /* Px: _PPC/_PCT/_PSS/_PSD */ | 295 | struct xen_processor_performance perf; /* Px: _PPC/_PCT/_PSS/_PSD */ |
296 | GUEST_HANDLE(uint32_t) pdc; | ||
296 | }; | 297 | }; |
297 | }; | 298 | }; |
298 | DEFINE_GUEST_HANDLE_STRUCT(xenpf_set_processor_pminfo); | 299 | DEFINE_GUEST_HANDLE_STRUCT(xenpf_set_processor_pminfo); |
299 | 300 | ||
301 | #define XENPF_get_cpuinfo 55 | ||
302 | struct xenpf_pcpuinfo { | ||
303 | /* IN */ | ||
304 | uint32_t xen_cpuid; | ||
305 | /* OUT */ | ||
306 | /* The maxium cpu_id that is present */ | ||
307 | uint32_t max_present; | ||
308 | #define XEN_PCPU_FLAGS_ONLINE 1 | ||
309 | /* Correponding xen_cpuid is not present*/ | ||
310 | #define XEN_PCPU_FLAGS_INVALID 2 | ||
311 | uint32_t flags; | ||
312 | uint32_t apic_id; | ||
313 | uint32_t acpi_id; | ||
314 | }; | ||
315 | DEFINE_GUEST_HANDLE_STRUCT(xenpf_pcpuinfo); | ||
316 | |||
300 | struct xen_platform_op { | 317 | struct xen_platform_op { |
301 | uint32_t cmd; | 318 | uint32_t cmd; |
302 | uint32_t interface_version; /* XENPF_INTERFACE_VERSION */ | 319 | uint32_t interface_version; /* XENPF_INTERFACE_VERSION */ |
@@ -312,6 +329,7 @@ struct xen_platform_op { | |||
312 | struct xenpf_change_freq change_freq; | 329 | struct xenpf_change_freq change_freq; |
313 | struct xenpf_getidletime getidletime; | 330 | struct xenpf_getidletime getidletime; |
314 | struct xenpf_set_processor_pminfo set_pminfo; | 331 | struct xenpf_set_processor_pminfo set_pminfo; |
332 | struct xenpf_pcpuinfo pcpu_info; | ||
315 | uint8_t pad[128]; | 333 | uint8_t pad[128]; |
316 | } u; | 334 | } u; |
317 | }; | 335 | }; |