diff options
Diffstat (limited to 'arch/x86/xen')
-rw-r--r-- | arch/x86/xen/enlighten.c | 46 | ||||
-rw-r--r-- | arch/x86/xen/mmu.c | 7 | ||||
-rw-r--r-- | arch/x86/xen/smp.c | 15 | ||||
-rw-r--r-- | arch/x86/xen/xen-asm.S | 2 |
4 files changed, 63 insertions, 7 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 4f51bebac02c..95dccce8e979 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -63,6 +63,7 @@ | |||
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> | 65 | #include <asm/mwait.h> |
66 | #include <asm/pci_x86.h> | ||
66 | 67 | ||
67 | #ifdef CONFIG_ACPI | 68 | #ifdef CONFIG_ACPI |
68 | #include <linux/acpi.h> | 69 | #include <linux/acpi.h> |
@@ -261,7 +262,8 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx, | |||
261 | 262 | ||
262 | static bool __init xen_check_mwait(void) | 263 | static bool __init xen_check_mwait(void) |
263 | { | 264 | { |
264 | #ifdef CONFIG_ACPI | 265 | #if defined(CONFIG_ACPI) && !defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR) && \ |
266 | !defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR_MODULE) | ||
265 | struct xen_platform_op op = { | 267 | struct xen_platform_op op = { |
266 | .cmd = XENPF_set_processor_pminfo, | 268 | .cmd = XENPF_set_processor_pminfo, |
267 | .u.set_pminfo.id = -1, | 269 | .u.set_pminfo.id = -1, |
@@ -349,7 +351,6 @@ static void __init xen_init_cpuid_mask(void) | |||
349 | /* Xen will set CR4.OSXSAVE if supported and not disabled by force */ | 351 | /* Xen will set CR4.OSXSAVE if supported and not disabled by force */ |
350 | if ((cx & xsave_mask) != xsave_mask) | 352 | if ((cx & xsave_mask) != xsave_mask) |
351 | cpuid_leaf1_ecx_mask &= ~xsave_mask; /* disable XSAVE & OSXSAVE */ | 353 | cpuid_leaf1_ecx_mask &= ~xsave_mask; /* disable XSAVE & OSXSAVE */ |
352 | |||
353 | if (xen_check_mwait()) | 354 | if (xen_check_mwait()) |
354 | cpuid_leaf1_ecx_set_mask = (1 << (X86_FEATURE_MWAIT % 32)); | 355 | cpuid_leaf1_ecx_set_mask = (1 << (X86_FEATURE_MWAIT % 32)); |
355 | } | 356 | } |
@@ -809,9 +810,40 @@ static void xen_io_delay(void) | |||
809 | } | 810 | } |
810 | 811 | ||
811 | #ifdef CONFIG_X86_LOCAL_APIC | 812 | #ifdef CONFIG_X86_LOCAL_APIC |
813 | static unsigned long xen_set_apic_id(unsigned int x) | ||
814 | { | ||
815 | WARN_ON(1); | ||
816 | return x; | ||
817 | } | ||
818 | static unsigned int xen_get_apic_id(unsigned long x) | ||
819 | { | ||
820 | return ((x)>>24) & 0xFFu; | ||
821 | } | ||
812 | static u32 xen_apic_read(u32 reg) | 822 | static u32 xen_apic_read(u32 reg) |
813 | { | 823 | { |
814 | return 0; | 824 | struct xen_platform_op op = { |
825 | .cmd = XENPF_get_cpuinfo, | ||
826 | .interface_version = XENPF_INTERFACE_VERSION, | ||
827 | .u.pcpu_info.xen_cpuid = 0, | ||
828 | }; | ||
829 | int ret = 0; | ||
830 | |||
831 | /* Shouldn't need this as APIC is turned off for PV, and we only | ||
832 | * get called on the bootup processor. But just in case. */ | ||
833 | if (!xen_initial_domain() || smp_processor_id()) | ||
834 | return 0; | ||
835 | |||
836 | if (reg == APIC_LVR) | ||
837 | return 0x10; | ||
838 | |||
839 | if (reg != APIC_ID) | ||
840 | return 0; | ||
841 | |||
842 | ret = HYPERVISOR_dom0_op(&op); | ||
843 | if (ret) | ||
844 | return 0; | ||
845 | |||
846 | return op.u.pcpu_info.apic_id << 24; | ||
815 | } | 847 | } |
816 | 848 | ||
817 | static void xen_apic_write(u32 reg, u32 val) | 849 | static void xen_apic_write(u32 reg, u32 val) |
@@ -849,6 +881,8 @@ static void set_xen_basic_apic_ops(void) | |||
849 | apic->icr_write = xen_apic_icr_write; | 881 | apic->icr_write = xen_apic_icr_write; |
850 | apic->wait_icr_idle = xen_apic_wait_icr_idle; | 882 | apic->wait_icr_idle = xen_apic_wait_icr_idle; |
851 | apic->safe_wait_icr_idle = xen_safe_apic_wait_icr_idle; | 883 | apic->safe_wait_icr_idle = xen_safe_apic_wait_icr_idle; |
884 | apic->set_apic_id = xen_set_apic_id; | ||
885 | apic->get_apic_id = xen_get_apic_id; | ||
852 | } | 886 | } |
853 | 887 | ||
854 | #endif | 888 | #endif |
@@ -1365,8 +1399,10 @@ asmlinkage void __init xen_start_kernel(void) | |||
1365 | /* Make sure ACS will be enabled */ | 1399 | /* Make sure ACS will be enabled */ |
1366 | pci_request_acs(); | 1400 | pci_request_acs(); |
1367 | } | 1401 | } |
1368 | 1402 | #ifdef CONFIG_PCI | |
1369 | 1403 | /* PCI BIOS service won't work from a PV guest. */ | |
1404 | pci_probe &= ~PCI_PROBE_BIOS; | ||
1405 | #endif | ||
1370 | xen_raw_console_write("about to get started...\n"); | 1406 | xen_raw_console_write("about to get started...\n"); |
1371 | 1407 | ||
1372 | xen_setup_runstate_info(0); | 1408 | xen_setup_runstate_info(0); |
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index b8e279479a6b..69f5857660ac 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
@@ -353,8 +353,13 @@ static pteval_t pte_mfn_to_pfn(pteval_t val) | |||
353 | { | 353 | { |
354 | if (val & _PAGE_PRESENT) { | 354 | if (val & _PAGE_PRESENT) { |
355 | unsigned long mfn = (val & PTE_PFN_MASK) >> PAGE_SHIFT; | 355 | unsigned long mfn = (val & PTE_PFN_MASK) >> PAGE_SHIFT; |
356 | unsigned long pfn = mfn_to_pfn(mfn); | ||
357 | |||
356 | pteval_t flags = val & PTE_FLAGS_MASK; | 358 | pteval_t flags = val & PTE_FLAGS_MASK; |
357 | val = ((pteval_t)mfn_to_pfn(mfn) << PAGE_SHIFT) | flags; | 359 | if (unlikely(pfn == ~0)) |
360 | val = flags & ~_PAGE_PRESENT; | ||
361 | else | ||
362 | val = ((pteval_t)pfn << PAGE_SHIFT) | flags; | ||
358 | } | 363 | } |
359 | 364 | ||
360 | return val; | 365 | return val; |
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 5fac6919b957..0503c0c493a9 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c | |||
@@ -178,6 +178,7 @@ static void __init xen_fill_possible_map(void) | |||
178 | static void __init xen_filter_cpu_maps(void) | 178 | static void __init xen_filter_cpu_maps(void) |
179 | { | 179 | { |
180 | int i, rc; | 180 | int i, rc; |
181 | unsigned int subtract = 0; | ||
181 | 182 | ||
182 | if (!xen_initial_domain()) | 183 | if (!xen_initial_domain()) |
183 | return; | 184 | return; |
@@ -192,8 +193,22 @@ static void __init xen_filter_cpu_maps(void) | |||
192 | } else { | 193 | } else { |
193 | set_cpu_possible(i, false); | 194 | set_cpu_possible(i, false); |
194 | set_cpu_present(i, false); | 195 | set_cpu_present(i, false); |
196 | subtract++; | ||
195 | } | 197 | } |
196 | } | 198 | } |
199 | #ifdef CONFIG_HOTPLUG_CPU | ||
200 | /* This is akin to using 'nr_cpus' on the Linux command line. | ||
201 | * Which is OK as when we use 'dom0_max_vcpus=X' we can only | ||
202 | * have up to X, while nr_cpu_ids is greater than X. This | ||
203 | * normally is not a problem, except when CPU hotplugging | ||
204 | * is involved and then there might be more than X CPUs | ||
205 | * in the guest - which will not work as there is no | ||
206 | * hypercall to expand the max number of VCPUs an already | ||
207 | * running guest has. So cap it up to X. */ | ||
208 | if (subtract) | ||
209 | nr_cpu_ids = nr_cpu_ids - subtract; | ||
210 | #endif | ||
211 | |||
197 | } | 212 | } |
198 | 213 | ||
199 | static void __init xen_smp_prepare_boot_cpu(void) | 214 | static void __init xen_smp_prepare_boot_cpu(void) |
diff --git a/arch/x86/xen/xen-asm.S b/arch/x86/xen/xen-asm.S index 79d7362ad6d1..3e45aa000718 100644 --- a/arch/x86/xen/xen-asm.S +++ b/arch/x86/xen/xen-asm.S | |||
@@ -96,7 +96,7 @@ ENTRY(xen_restore_fl_direct) | |||
96 | 96 | ||
97 | /* check for unmasked and pending */ | 97 | /* check for unmasked and pending */ |
98 | cmpw $0x0001, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_pending | 98 | cmpw $0x0001, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_pending |
99 | jz 1f | 99 | jnz 1f |
100 | 2: call check_events | 100 | 2: call check_events |
101 | 1: | 101 | 1: |
102 | ENDPATCH(xen_restore_fl_direct) | 102 | ENDPATCH(xen_restore_fl_direct) |