diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-09-24 03:56:20 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-09-24 03:56:20 -0400 |
commit | ebdd90a8cb2e3963f55499850f02ce6003558b55 (patch) | |
tree | d153f917ed41d257ddafa22f9cc2201bfddf8f9c /arch/x86/kernel | |
parent | 3c9339049df5cc3a468c11de6c4101a1ea8c3d83 (diff) | |
parent | 72d31053f62c4bc464c2783974926969614a8649 (diff) |
Merge commit 'v2.6.27-rc7' into x86/pebs
Diffstat (limited to 'arch/x86/kernel')
73 files changed, 1131 insertions, 668 deletions
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index fa88a1d71290..bfd10fd211cd 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
@@ -97,6 +97,8 @@ static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE; | |||
97 | #warning ACPI uses CMPXCHG, i486 and later hardware | 97 | #warning ACPI uses CMPXCHG, i486 and later hardware |
98 | #endif | 98 | #endif |
99 | 99 | ||
100 | static int acpi_mcfg_64bit_base_addr __initdata = FALSE; | ||
101 | |||
100 | /* -------------------------------------------------------------------------- | 102 | /* -------------------------------------------------------------------------- |
101 | Boot-time Configuration | 103 | Boot-time Configuration |
102 | -------------------------------------------------------------------------- */ | 104 | -------------------------------------------------------------------------- */ |
@@ -158,6 +160,14 @@ char *__init __acpi_map_table(unsigned long phys, unsigned long size) | |||
158 | struct acpi_mcfg_allocation *pci_mmcfg_config; | 160 | struct acpi_mcfg_allocation *pci_mmcfg_config; |
159 | int pci_mmcfg_config_num; | 161 | int pci_mmcfg_config_num; |
160 | 162 | ||
163 | static int __init acpi_mcfg_oem_check(struct acpi_table_mcfg *mcfg) | ||
164 | { | ||
165 | if (!strcmp(mcfg->header.oem_id, "SGI")) | ||
166 | acpi_mcfg_64bit_base_addr = TRUE; | ||
167 | |||
168 | return 0; | ||
169 | } | ||
170 | |||
161 | int __init acpi_parse_mcfg(struct acpi_table_header *header) | 171 | int __init acpi_parse_mcfg(struct acpi_table_header *header) |
162 | { | 172 | { |
163 | struct acpi_table_mcfg *mcfg; | 173 | struct acpi_table_mcfg *mcfg; |
@@ -190,8 +200,12 @@ int __init acpi_parse_mcfg(struct acpi_table_header *header) | |||
190 | } | 200 | } |
191 | 201 | ||
192 | memcpy(pci_mmcfg_config, &mcfg[1], config_size); | 202 | memcpy(pci_mmcfg_config, &mcfg[1], config_size); |
203 | |||
204 | acpi_mcfg_oem_check(mcfg); | ||
205 | |||
193 | for (i = 0; i < pci_mmcfg_config_num; ++i) { | 206 | for (i = 0; i < pci_mmcfg_config_num; ++i) { |
194 | if (pci_mmcfg_config[i].address > 0xFFFFFFFF) { | 207 | if ((pci_mmcfg_config[i].address > 0xFFFFFFFF) && |
208 | !acpi_mcfg_64bit_base_addr) { | ||
195 | printk(KERN_ERR PREFIX | 209 | printk(KERN_ERR PREFIX |
196 | "MMCONFIG not in low 4GB of memory\n"); | 210 | "MMCONFIG not in low 4GB of memory\n"); |
197 | kfree(pci_mmcfg_config); | 211 | kfree(pci_mmcfg_config); |
diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c index 9220cf46aa10..c2502eb9aa83 100644 --- a/arch/x86/kernel/acpi/cstate.c +++ b/arch/x86/kernel/acpi/cstate.c | |||
@@ -73,7 +73,6 @@ int acpi_processor_ffh_cstate_probe(unsigned int cpu, | |||
73 | struct cpuinfo_x86 *c = &cpu_data(cpu); | 73 | struct cpuinfo_x86 *c = &cpu_data(cpu); |
74 | 74 | ||
75 | cpumask_t saved_mask; | 75 | cpumask_t saved_mask; |
76 | cpumask_of_cpu_ptr(new_mask, cpu); | ||
77 | int retval; | 76 | int retval; |
78 | unsigned int eax, ebx, ecx, edx; | 77 | unsigned int eax, ebx, ecx, edx; |
79 | unsigned int edx_part; | 78 | unsigned int edx_part; |
@@ -92,7 +91,7 @@ int acpi_processor_ffh_cstate_probe(unsigned int cpu, | |||
92 | 91 | ||
93 | /* Make sure we are running on right CPU */ | 92 | /* Make sure we are running on right CPU */ |
94 | saved_mask = current->cpus_allowed; | 93 | saved_mask = current->cpus_allowed; |
95 | retval = set_cpus_allowed_ptr(current, new_mask); | 94 | retval = set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu)); |
96 | if (retval) | 95 | if (retval) |
97 | return -1; | 96 | return -1; |
98 | 97 | ||
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index fa2161d5003b..426e5d91b63a 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c | |||
@@ -20,7 +20,7 @@ unsigned long acpi_realmode_flags; | |||
20 | /* address in low memory of the wakeup routine. */ | 20 | /* address in low memory of the wakeup routine. */ |
21 | static unsigned long acpi_realmode; | 21 | static unsigned long acpi_realmode; |
22 | 22 | ||
23 | #ifdef CONFIG_64BIT | 23 | #if defined(CONFIG_SMP) && defined(CONFIG_64BIT) |
24 | static char temp_stack[10240]; | 24 | static char temp_stack[10240]; |
25 | #endif | 25 | #endif |
26 | 26 | ||
@@ -86,7 +86,7 @@ int acpi_save_state_mem(void) | |||
86 | #endif /* !CONFIG_64BIT */ | 86 | #endif /* !CONFIG_64BIT */ |
87 | 87 | ||
88 | header->pmode_cr0 = read_cr0(); | 88 | header->pmode_cr0 = read_cr0(); |
89 | header->pmode_cr4 = read_cr4(); | 89 | header->pmode_cr4 = read_cr4_safe(); |
90 | header->realmode_flags = acpi_realmode_flags; | 90 | header->realmode_flags = acpi_realmode_flags; |
91 | header->real_magic = 0x12345678; | 91 | header->real_magic = 0x12345678; |
92 | 92 | ||
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 2763cb37b553..65a0c1b48696 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c | |||
@@ -145,35 +145,25 @@ static const unsigned char *const p6_nops[ASM_NOP_MAX+1] = { | |||
145 | extern char __vsyscall_0; | 145 | extern char __vsyscall_0; |
146 | const unsigned char *const *find_nop_table(void) | 146 | const unsigned char *const *find_nop_table(void) |
147 | { | 147 | { |
148 | return boot_cpu_data.x86_vendor != X86_VENDOR_INTEL || | 148 | if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && |
149 | boot_cpu_data.x86 < 6 ? k8_nops : p6_nops; | 149 | boot_cpu_has(X86_FEATURE_NOPL)) |
150 | return p6_nops; | ||
151 | else | ||
152 | return k8_nops; | ||
150 | } | 153 | } |
151 | 154 | ||
152 | #else /* CONFIG_X86_64 */ | 155 | #else /* CONFIG_X86_64 */ |
153 | 156 | ||
154 | static const struct nop { | ||
155 | int cpuid; | ||
156 | const unsigned char *const *noptable; | ||
157 | } noptypes[] = { | ||
158 | { X86_FEATURE_K8, k8_nops }, | ||
159 | { X86_FEATURE_K7, k7_nops }, | ||
160 | { X86_FEATURE_P4, p6_nops }, | ||
161 | { X86_FEATURE_P3, p6_nops }, | ||
162 | { -1, NULL } | ||
163 | }; | ||
164 | |||
165 | const unsigned char *const *find_nop_table(void) | 157 | const unsigned char *const *find_nop_table(void) |
166 | { | 158 | { |
167 | const unsigned char *const *noptable = intel_nops; | 159 | if (boot_cpu_has(X86_FEATURE_K8)) |
168 | int i; | 160 | return k8_nops; |
169 | 161 | else if (boot_cpu_has(X86_FEATURE_K7)) | |
170 | for (i = 0; noptypes[i].cpuid >= 0; i++) { | 162 | return k7_nops; |
171 | if (boot_cpu_has(noptypes[i].cpuid)) { | 163 | else if (boot_cpu_has(X86_FEATURE_NOPL)) |
172 | noptable = noptypes[i].noptable; | 164 | return p6_nops; |
173 | break; | 165 | else |
174 | } | 166 | return intel_nops; |
175 | } | ||
176 | return noptable; | ||
177 | } | 167 | } |
178 | 168 | ||
179 | #endif /* CONFIG_X86_64 */ | 169 | #endif /* CONFIG_X86_64 */ |
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index c25210e6ac88..69b4d060b21c 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c | |||
@@ -29,9 +29,6 @@ | |||
29 | 29 | ||
30 | #define CMD_SET_TYPE(cmd, t) ((cmd)->data[1] |= ((t) << 28)) | 30 | #define CMD_SET_TYPE(cmd, t) ((cmd)->data[1] |= ((t) << 28)) |
31 | 31 | ||
32 | #define to_pages(addr, size) \ | ||
33 | (round_up(((addr) & ~PAGE_MASK) + (size), PAGE_SIZE) >> PAGE_SHIFT) | ||
34 | |||
35 | #define EXIT_LOOP_COUNT 10000000 | 32 | #define EXIT_LOOP_COUNT 10000000 |
36 | 33 | ||
37 | static DEFINE_RWLOCK(amd_iommu_devtable_lock); | 34 | static DEFINE_RWLOCK(amd_iommu_devtable_lock); |
@@ -68,7 +65,7 @@ static int __iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd) | |||
68 | u8 *target; | 65 | u8 *target; |
69 | 66 | ||
70 | tail = readl(iommu->mmio_base + MMIO_CMD_TAIL_OFFSET); | 67 | tail = readl(iommu->mmio_base + MMIO_CMD_TAIL_OFFSET); |
71 | target = (iommu->cmd_buf + tail); | 68 | target = iommu->cmd_buf + tail; |
72 | memcpy_toio(target, cmd, sizeof(*cmd)); | 69 | memcpy_toio(target, cmd, sizeof(*cmd)); |
73 | tail = (tail + sizeof(*cmd)) % iommu->cmd_buf_size; | 70 | tail = (tail + sizeof(*cmd)) % iommu->cmd_buf_size; |
74 | head = readl(iommu->mmio_base + MMIO_CMD_HEAD_OFFSET); | 71 | head = readl(iommu->mmio_base + MMIO_CMD_HEAD_OFFSET); |
@@ -104,16 +101,13 @@ static int iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd) | |||
104 | */ | 101 | */ |
105 | static int iommu_completion_wait(struct amd_iommu *iommu) | 102 | static int iommu_completion_wait(struct amd_iommu *iommu) |
106 | { | 103 | { |
107 | int ret; | 104 | int ret, ready = 0; |
105 | unsigned status = 0; | ||
108 | struct iommu_cmd cmd; | 106 | struct iommu_cmd cmd; |
109 | volatile u64 ready = 0; | ||
110 | unsigned long ready_phys = virt_to_phys(&ready); | ||
111 | unsigned long i = 0; | 107 | unsigned long i = 0; |
112 | 108 | ||
113 | memset(&cmd, 0, sizeof(cmd)); | 109 | memset(&cmd, 0, sizeof(cmd)); |
114 | cmd.data[0] = LOW_U32(ready_phys) | CMD_COMPL_WAIT_STORE_MASK; | 110 | cmd.data[0] = CMD_COMPL_WAIT_INT_MASK; |
115 | cmd.data[1] = upper_32_bits(ready_phys); | ||
116 | cmd.data[2] = 1; /* value written to 'ready' */ | ||
117 | CMD_SET_TYPE(&cmd, CMD_COMPL_WAIT); | 111 | CMD_SET_TYPE(&cmd, CMD_COMPL_WAIT); |
118 | 112 | ||
119 | iommu->need_sync = 0; | 113 | iommu->need_sync = 0; |
@@ -125,9 +119,15 @@ static int iommu_completion_wait(struct amd_iommu *iommu) | |||
125 | 119 | ||
126 | while (!ready && (i < EXIT_LOOP_COUNT)) { | 120 | while (!ready && (i < EXIT_LOOP_COUNT)) { |
127 | ++i; | 121 | ++i; |
128 | cpu_relax(); | 122 | /* wait for the bit to become one */ |
123 | status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET); | ||
124 | ready = status & MMIO_STATUS_COM_WAIT_INT_MASK; | ||
129 | } | 125 | } |
130 | 126 | ||
127 | /* set bit back to zero */ | ||
128 | status &= ~MMIO_STATUS_COM_WAIT_INT_MASK; | ||
129 | writel(status, iommu->mmio_base + MMIO_STATUS_OFFSET); | ||
130 | |||
131 | if (unlikely((i == EXIT_LOOP_COUNT) && printk_ratelimit())) | 131 | if (unlikely((i == EXIT_LOOP_COUNT) && printk_ratelimit())) |
132 | printk(KERN_WARNING "AMD IOMMU: Completion wait loop failed\n"); | 132 | printk(KERN_WARNING "AMD IOMMU: Completion wait loop failed\n"); |
133 | 133 | ||
@@ -164,7 +164,7 @@ static int iommu_queue_inv_iommu_pages(struct amd_iommu *iommu, | |||
164 | address &= PAGE_MASK; | 164 | address &= PAGE_MASK; |
165 | CMD_SET_TYPE(&cmd, CMD_INV_IOMMU_PAGES); | 165 | CMD_SET_TYPE(&cmd, CMD_INV_IOMMU_PAGES); |
166 | cmd.data[1] |= domid; | 166 | cmd.data[1] |= domid; |
167 | cmd.data[2] = LOW_U32(address); | 167 | cmd.data[2] = lower_32_bits(address); |
168 | cmd.data[3] = upper_32_bits(address); | 168 | cmd.data[3] = upper_32_bits(address); |
169 | if (s) /* size bit - we flush more than one 4kb page */ | 169 | if (s) /* size bit - we flush more than one 4kb page */ |
170 | cmd.data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK; | 170 | cmd.data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK; |
@@ -185,7 +185,7 @@ static int iommu_flush_pages(struct amd_iommu *iommu, u16 domid, | |||
185 | u64 address, size_t size) | 185 | u64 address, size_t size) |
186 | { | 186 | { |
187 | int s = 0; | 187 | int s = 0; |
188 | unsigned pages = to_pages(address, size); | 188 | unsigned pages = iommu_num_pages(address, size); |
189 | 189 | ||
190 | address &= PAGE_MASK; | 190 | address &= PAGE_MASK; |
191 | 191 | ||
@@ -557,8 +557,8 @@ static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu, | |||
557 | if (iommu->exclusion_start && | 557 | if (iommu->exclusion_start && |
558 | iommu->exclusion_start < dma_dom->aperture_size) { | 558 | iommu->exclusion_start < dma_dom->aperture_size) { |
559 | unsigned long startpage = iommu->exclusion_start >> PAGE_SHIFT; | 559 | unsigned long startpage = iommu->exclusion_start >> PAGE_SHIFT; |
560 | int pages = to_pages(iommu->exclusion_start, | 560 | int pages = iommu_num_pages(iommu->exclusion_start, |
561 | iommu->exclusion_length); | 561 | iommu->exclusion_length); |
562 | dma_ops_reserve_addresses(dma_dom, startpage, pages); | 562 | dma_ops_reserve_addresses(dma_dom, startpage, pages); |
563 | } | 563 | } |
564 | 564 | ||
@@ -667,7 +667,7 @@ static int get_device_resources(struct device *dev, | |||
667 | _bdf = calc_devid(pcidev->bus->number, pcidev->devfn); | 667 | _bdf = calc_devid(pcidev->bus->number, pcidev->devfn); |
668 | 668 | ||
669 | /* device not translated by any IOMMU in the system? */ | 669 | /* device not translated by any IOMMU in the system? */ |
670 | if (_bdf >= amd_iommu_last_bdf) { | 670 | if (_bdf > amd_iommu_last_bdf) { |
671 | *iommu = NULL; | 671 | *iommu = NULL; |
672 | *domain = NULL; | 672 | *domain = NULL; |
673 | *bdf = 0xffff; | 673 | *bdf = 0xffff; |
@@ -767,7 +767,7 @@ static dma_addr_t __map_single(struct device *dev, | |||
767 | unsigned int pages; | 767 | unsigned int pages; |
768 | int i; | 768 | int i; |
769 | 769 | ||
770 | pages = to_pages(paddr, size); | 770 | pages = iommu_num_pages(paddr, size); |
771 | paddr &= PAGE_MASK; | 771 | paddr &= PAGE_MASK; |
772 | 772 | ||
773 | address = dma_ops_alloc_addresses(dev, dma_dom, pages); | 773 | address = dma_ops_alloc_addresses(dev, dma_dom, pages); |
@@ -802,7 +802,7 @@ static void __unmap_single(struct amd_iommu *iommu, | |||
802 | if ((dma_addr == 0) || (dma_addr + size > dma_dom->aperture_size)) | 802 | if ((dma_addr == 0) || (dma_addr + size > dma_dom->aperture_size)) |
803 | return; | 803 | return; |
804 | 804 | ||
805 | pages = to_pages(dma_addr, size); | 805 | pages = iommu_num_pages(dma_addr, size); |
806 | dma_addr &= PAGE_MASK; | 806 | dma_addr &= PAGE_MASK; |
807 | start = dma_addr; | 807 | start = dma_addr; |
808 | 808 | ||
@@ -1085,7 +1085,7 @@ void prealloc_protection_domains(void) | |||
1085 | 1085 | ||
1086 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { | 1086 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { |
1087 | devid = (dev->bus->number << 8) | dev->devfn; | 1087 | devid = (dev->bus->number << 8) | dev->devfn; |
1088 | if (devid >= amd_iommu_last_bdf) | 1088 | if (devid > amd_iommu_last_bdf) |
1089 | continue; | 1089 | continue; |
1090 | devid = amd_iommu_alias_table[devid]; | 1090 | devid = amd_iommu_alias_table[devid]; |
1091 | if (domain_for_device(devid)) | 1091 | if (domain_for_device(devid)) |
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index c9d8ff2eb130..a69cc0f52042 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c | |||
@@ -732,7 +732,7 @@ static int __init init_exclusion_range(struct ivmd_header *m) | |||
732 | set_device_exclusion_range(m->devid, m); | 732 | set_device_exclusion_range(m->devid, m); |
733 | break; | 733 | break; |
734 | case ACPI_IVMD_TYPE_ALL: | 734 | case ACPI_IVMD_TYPE_ALL: |
735 | for (i = 0; i < amd_iommu_last_bdf; ++i) | 735 | for (i = 0; i <= amd_iommu_last_bdf; ++i) |
736 | set_device_exclusion_range(i, m); | 736 | set_device_exclusion_range(i, m); |
737 | break; | 737 | break; |
738 | case ACPI_IVMD_TYPE_RANGE: | 738 | case ACPI_IVMD_TYPE_RANGE: |
@@ -801,6 +801,21 @@ static int __init init_memory_definitions(struct acpi_table_header *table) | |||
801 | } | 801 | } |
802 | 802 | ||
803 | /* | 803 | /* |
804 | * Init the device table to not allow DMA access for devices and | ||
805 | * suppress all page faults | ||
806 | */ | ||
807 | static void init_device_table(void) | ||
808 | { | ||
809 | u16 devid; | ||
810 | |||
811 | for (devid = 0; devid <= amd_iommu_last_bdf; ++devid) { | ||
812 | set_dev_entry_bit(devid, DEV_ENTRY_VALID); | ||
813 | set_dev_entry_bit(devid, DEV_ENTRY_TRANSLATION); | ||
814 | set_dev_entry_bit(devid, DEV_ENTRY_NO_PAGE_FAULT); | ||
815 | } | ||
816 | } | ||
817 | |||
818 | /* | ||
804 | * This function finally enables all IOMMUs found in the system after | 819 | * This function finally enables all IOMMUs found in the system after |
805 | * they have been initialized | 820 | * they have been initialized |
806 | */ | 821 | */ |
@@ -931,10 +946,13 @@ int __init amd_iommu_init(void) | |||
931 | if (amd_iommu_pd_alloc_bitmap == NULL) | 946 | if (amd_iommu_pd_alloc_bitmap == NULL) |
932 | goto free; | 947 | goto free; |
933 | 948 | ||
949 | /* init the device table */ | ||
950 | init_device_table(); | ||
951 | |||
934 | /* | 952 | /* |
935 | * let all alias entries point to itself | 953 | * let all alias entries point to itself |
936 | */ | 954 | */ |
937 | for (i = 0; i < amd_iommu_last_bdf; ++i) | 955 | for (i = 0; i <= amd_iommu_last_bdf; ++i) |
938 | amd_iommu_alias_table[i] = i; | 956 | amd_iommu_alias_table[i] = i; |
939 | 957 | ||
940 | /* | 958 | /* |
@@ -954,15 +972,15 @@ int __init amd_iommu_init(void) | |||
954 | if (acpi_table_parse("IVRS", init_memory_definitions) != 0) | 972 | if (acpi_table_parse("IVRS", init_memory_definitions) != 0) |
955 | goto free; | 973 | goto free; |
956 | 974 | ||
957 | ret = amd_iommu_init_dma_ops(); | 975 | ret = sysdev_class_register(&amd_iommu_sysdev_class); |
958 | if (ret) | 976 | if (ret) |
959 | goto free; | 977 | goto free; |
960 | 978 | ||
961 | ret = sysdev_class_register(&amd_iommu_sysdev_class); | 979 | ret = sysdev_register(&device_amd_iommu); |
962 | if (ret) | 980 | if (ret) |
963 | goto free; | 981 | goto free; |
964 | 982 | ||
965 | ret = sysdev_register(&device_amd_iommu); | 983 | ret = amd_iommu_init_dma_ops(); |
966 | if (ret) | 984 | if (ret) |
967 | goto free; | 985 | goto free; |
968 | 986 | ||
diff --git a/arch/x86/kernel/apic_32.c b/arch/x86/kernel/apic_32.c index d6c898358371..f88bd0d982b0 100644 --- a/arch/x86/kernel/apic_32.c +++ b/arch/x86/kernel/apic_32.c | |||
@@ -1454,8 +1454,6 @@ void disconnect_bsp_APIC(int virt_wire_setup) | |||
1454 | } | 1454 | } |
1455 | } | 1455 | } |
1456 | 1456 | ||
1457 | unsigned int __cpuinitdata maxcpus = NR_CPUS; | ||
1458 | |||
1459 | void __cpuinit generic_processor_info(int apicid, int version) | 1457 | void __cpuinit generic_processor_info(int apicid, int version) |
1460 | { | 1458 | { |
1461 | int cpu; | 1459 | int cpu; |
@@ -1482,12 +1480,6 @@ void __cpuinit generic_processor_info(int apicid, int version) | |||
1482 | return; | 1480 | return; |
1483 | } | 1481 | } |
1484 | 1482 | ||
1485 | if (num_processors >= maxcpus) { | ||
1486 | printk(KERN_WARNING "WARNING: maxcpus limit of %i reached." | ||
1487 | " Processor ignored.\n", maxcpus); | ||
1488 | return; | ||
1489 | } | ||
1490 | |||
1491 | num_processors++; | 1483 | num_processors++; |
1492 | cpus_complement(tmp_map, cpu_present_map); | 1484 | cpus_complement(tmp_map, cpu_present_map); |
1493 | cpu = first_cpu(tmp_map); | 1485 | cpu = first_cpu(tmp_map); |
@@ -1720,15 +1712,19 @@ static int __init parse_lapic_timer_c2_ok(char *arg) | |||
1720 | } | 1712 | } |
1721 | early_param("lapic_timer_c2_ok", parse_lapic_timer_c2_ok); | 1713 | early_param("lapic_timer_c2_ok", parse_lapic_timer_c2_ok); |
1722 | 1714 | ||
1723 | static int __init apic_set_verbosity(char *str) | 1715 | static int __init apic_set_verbosity(char *arg) |
1724 | { | 1716 | { |
1725 | if (strcmp("debug", str) == 0) | 1717 | if (!arg) |
1718 | return -EINVAL; | ||
1719 | |||
1720 | if (strcmp(arg, "debug") == 0) | ||
1726 | apic_verbosity = APIC_DEBUG; | 1721 | apic_verbosity = APIC_DEBUG; |
1727 | else if (strcmp("verbose", str) == 0) | 1722 | else if (strcmp(arg, "verbose") == 0) |
1728 | apic_verbosity = APIC_VERBOSE; | 1723 | apic_verbosity = APIC_VERBOSE; |
1729 | return 1; | 1724 | |
1725 | return 0; | ||
1730 | } | 1726 | } |
1731 | __setup("apic=", apic_set_verbosity); | 1727 | early_param("apic", apic_set_verbosity); |
1732 | 1728 | ||
1733 | static int __init lapic_insert_resource(void) | 1729 | static int __init lapic_insert_resource(void) |
1734 | { | 1730 | { |
diff --git a/arch/x86/kernel/apic_64.c b/arch/x86/kernel/apic_64.c index 7f1f030da7ee..446c062e831c 100644 --- a/arch/x86/kernel/apic_64.c +++ b/arch/x86/kernel/apic_64.c | |||
@@ -90,7 +90,6 @@ static unsigned long apic_phys; | |||
90 | 90 | ||
91 | unsigned long mp_lapic_addr; | 91 | unsigned long mp_lapic_addr; |
92 | 92 | ||
93 | unsigned int __cpuinitdata maxcpus = NR_CPUS; | ||
94 | /* | 93 | /* |
95 | * Get the LAPIC version | 94 | * Get the LAPIC version |
96 | */ | 95 | */ |
@@ -1062,12 +1061,6 @@ void __cpuinit generic_processor_info(int apicid, int version) | |||
1062 | return; | 1061 | return; |
1063 | } | 1062 | } |
1064 | 1063 | ||
1065 | if (num_processors >= maxcpus) { | ||
1066 | printk(KERN_WARNING "WARNING: maxcpus limit of %i reached." | ||
1067 | " Processor ignored.\n", maxcpus); | ||
1068 | return; | ||
1069 | } | ||
1070 | |||
1071 | num_processors++; | 1064 | num_processors++; |
1072 | cpus_complement(tmp_map, cpu_present_map); | 1065 | cpus_complement(tmp_map, cpu_present_map); |
1073 | cpu = first_cpu(tmp_map); | 1066 | cpu = first_cpu(tmp_map); |
diff --git a/arch/x86/kernel/cpu/addon_cpuid_features.c b/arch/x86/kernel/cpu/addon_cpuid_features.c index 84a8220a6072..a6ef672adbba 100644 --- a/arch/x86/kernel/cpu/addon_cpuid_features.c +++ b/arch/x86/kernel/cpu/addon_cpuid_features.c | |||
@@ -56,9 +56,22 @@ void __cpuinit validate_pat_support(struct cpuinfo_x86 *c) | |||
56 | 56 | ||
57 | switch (c->x86_vendor) { | 57 | switch (c->x86_vendor) { |
58 | case X86_VENDOR_INTEL: | 58 | case X86_VENDOR_INTEL: |
59 | if (c->x86 == 0xF || (c->x86 == 6 && c->x86_model >= 15)) | 59 | /* |
60 | * There is a known erratum on Pentium III and Core Solo | ||
61 | * and Core Duo CPUs. | ||
62 | * " Page with PAT set to WC while associated MTRR is UC | ||
63 | * may consolidate to UC " | ||
64 | * Because of this erratum, it is better to stick with | ||
65 | * setting WC in MTRR rather than using PAT on these CPUs. | ||
66 | * | ||
67 | * Enable PAT WC only on P4, Core 2 or later CPUs. | ||
68 | */ | ||
69 | if (c->x86 > 0x6 || (c->x86 == 6 && c->x86_model >= 15)) | ||
60 | return; | 70 | return; |
61 | break; | 71 | |
72 | pat_disable("PAT WC disabled due to known CPU erratum."); | ||
73 | return; | ||
74 | |||
62 | case X86_VENDOR_AMD: | 75 | case X86_VENDOR_AMD: |
63 | case X86_VENDOR_CENTAUR: | 76 | case X86_VENDOR_CENTAUR: |
64 | case X86_VENDOR_TRANSMETA: | 77 | case X86_VENDOR_TRANSMETA: |
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index cae9cabc3031..18514ed26104 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c | |||
@@ -31,6 +31,11 @@ static void __cpuinit early_init_amd(struct cpuinfo_x86 *c) | |||
31 | if (c->x86_power & (1<<8)) | 31 | if (c->x86_power & (1<<8)) |
32 | set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); | 32 | set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); |
33 | } | 33 | } |
34 | |||
35 | /* Set MTRR capability flag if appropriate */ | ||
36 | if (c->x86_model == 13 || c->x86_model == 9 || | ||
37 | (c->x86_model == 8 && c->x86_mask >= 8)) | ||
38 | set_cpu_cap(c, X86_FEATURE_K6_MTRR); | ||
34 | } | 39 | } |
35 | 40 | ||
36 | static void __cpuinit init_amd(struct cpuinfo_x86 *c) | 41 | static void __cpuinit init_amd(struct cpuinfo_x86 *c) |
@@ -166,10 +171,6 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) | |||
166 | mbytes); | 171 | mbytes); |
167 | } | 172 | } |
168 | 173 | ||
169 | /* Set MTRR capability flag if appropriate */ | ||
170 | if (c->x86_model == 13 || c->x86_model == 9 || | ||
171 | (c->x86_model == 8 && c->x86_mask >= 8)) | ||
172 | set_cpu_cap(c, X86_FEATURE_K6_MTRR); | ||
173 | break; | 174 | break; |
174 | } | 175 | } |
175 | 176 | ||
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index c9b58a806e85..c8e315f1aa83 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c | |||
@@ -50,6 +50,8 @@ static double __initdata y = 3145727.0; | |||
50 | */ | 50 | */ |
51 | static void __init check_fpu(void) | 51 | static void __init check_fpu(void) |
52 | { | 52 | { |
53 | s32 fdiv_bug; | ||
54 | |||
53 | if (!boot_cpu_data.hard_math) { | 55 | if (!boot_cpu_data.hard_math) { |
54 | #ifndef CONFIG_MATH_EMULATION | 56 | #ifndef CONFIG_MATH_EMULATION |
55 | printk(KERN_EMERG "No coprocessor found and no math emulation present.\n"); | 57 | printk(KERN_EMERG "No coprocessor found and no math emulation present.\n"); |
@@ -74,8 +76,10 @@ static void __init check_fpu(void) | |||
74 | "fistpl %0\n\t" | 76 | "fistpl %0\n\t" |
75 | "fwait\n\t" | 77 | "fwait\n\t" |
76 | "fninit" | 78 | "fninit" |
77 | : "=m" (*&boot_cpu_data.fdiv_bug) | 79 | : "=m" (*&fdiv_bug) |
78 | : "m" (*&x), "m" (*&y)); | 80 | : "m" (*&x), "m" (*&y)); |
81 | |||
82 | boot_cpu_data.fdiv_bug = fdiv_bug; | ||
79 | if (boot_cpu_data.fdiv_bug) | 83 | if (boot_cpu_data.fdiv_bug) |
80 | printk("Hmm, FPU with FDIV bug.\n"); | 84 | printk("Hmm, FPU with FDIV bug.\n"); |
81 | } | 85 | } |
diff --git a/arch/x86/kernel/cpu/centaur.c b/arch/x86/kernel/cpu/centaur.c index e0f45edd6a55..a0534c04d38a 100644 --- a/arch/x86/kernel/cpu/centaur.c +++ b/arch/x86/kernel/cpu/centaur.c | |||
@@ -314,6 +314,16 @@ enum { | |||
314 | EAMD3D = 1<<20, | 314 | EAMD3D = 1<<20, |
315 | }; | 315 | }; |
316 | 316 | ||
317 | static void __cpuinit early_init_centaur(struct cpuinfo_x86 *c) | ||
318 | { | ||
319 | switch (c->x86) { | ||
320 | case 5: | ||
321 | /* Emulate MTRRs using Centaur's MCR. */ | ||
322 | set_cpu_cap(c, X86_FEATURE_CENTAUR_MCR); | ||
323 | break; | ||
324 | } | ||
325 | } | ||
326 | |||
317 | static void __cpuinit init_centaur(struct cpuinfo_x86 *c) | 327 | static void __cpuinit init_centaur(struct cpuinfo_x86 *c) |
318 | { | 328 | { |
319 | 329 | ||
@@ -462,6 +472,7 @@ centaur_size_cache(struct cpuinfo_x86 *c, unsigned int size) | |||
462 | static struct cpu_dev centaur_cpu_dev __cpuinitdata = { | 472 | static struct cpu_dev centaur_cpu_dev __cpuinitdata = { |
463 | .c_vendor = "Centaur", | 473 | .c_vendor = "Centaur", |
464 | .c_ident = { "CentaurHauls" }, | 474 | .c_ident = { "CentaurHauls" }, |
475 | .c_early_init = early_init_centaur, | ||
465 | .c_init = init_centaur, | 476 | .c_init = init_centaur, |
466 | .c_size_cache = centaur_size_cache, | 477 | .c_size_cache = centaur_size_cache, |
467 | }; | 478 | }; |
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 80ab20d4fa39..4e456bd955bb 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <asm/mtrr.h> | 13 | #include <asm/mtrr.h> |
14 | #include <asm/mce.h> | 14 | #include <asm/mce.h> |
15 | #include <asm/pat.h> | 15 | #include <asm/pat.h> |
16 | #include <asm/asm.h> | ||
16 | #ifdef CONFIG_X86_LOCAL_APIC | 17 | #ifdef CONFIG_X86_LOCAL_APIC |
17 | #include <asm/mpspec.h> | 18 | #include <asm/mpspec.h> |
18 | #include <asm/apic.h> | 19 | #include <asm/apic.h> |
@@ -334,11 +335,24 @@ static void __init early_cpu_detect(void) | |||
334 | 335 | ||
335 | get_cpu_vendor(c, 1); | 336 | get_cpu_vendor(c, 1); |
336 | 337 | ||
338 | early_get_cap(c); | ||
339 | |||
337 | if (c->x86_vendor != X86_VENDOR_UNKNOWN && | 340 | if (c->x86_vendor != X86_VENDOR_UNKNOWN && |
338 | cpu_devs[c->x86_vendor]->c_early_init) | 341 | cpu_devs[c->x86_vendor]->c_early_init) |
339 | cpu_devs[c->x86_vendor]->c_early_init(c); | 342 | cpu_devs[c->x86_vendor]->c_early_init(c); |
343 | } | ||
340 | 344 | ||
341 | early_get_cap(c); | 345 | /* |
346 | * The NOPL instruction is supposed to exist on all CPUs with | ||
347 | * family >= 6; unfortunately, that's not true in practice because | ||
348 | * of early VIA chips and (more importantly) broken virtualizers that | ||
349 | * are not easy to detect. In the latter case it doesn't even *fail* | ||
350 | * reliably, so probing for it doesn't even work. Disable it completely | ||
351 | * unless we can find a reliable way to detect all the broken cases. | ||
352 | */ | ||
353 | static void __cpuinit detect_nopl(struct cpuinfo_x86 *c) | ||
354 | { | ||
355 | clear_cpu_cap(c, X86_FEATURE_NOPL); | ||
342 | } | 356 | } |
343 | 357 | ||
344 | static void __cpuinit generic_identify(struct cpuinfo_x86 *c) | 358 | static void __cpuinit generic_identify(struct cpuinfo_x86 *c) |
@@ -395,8 +409,8 @@ static void __cpuinit generic_identify(struct cpuinfo_x86 *c) | |||
395 | } | 409 | } |
396 | 410 | ||
397 | init_scattered_cpuid_features(c); | 411 | init_scattered_cpuid_features(c); |
412 | detect_nopl(c); | ||
398 | } | 413 | } |
399 | |||
400 | } | 414 | } |
401 | 415 | ||
402 | static void __cpuinit squash_the_stupid_serial_number(struct cpuinfo_x86 *c) | 416 | static void __cpuinit squash_the_stupid_serial_number(struct cpuinfo_x86 *c) |
diff --git a/arch/x86/kernel/cpu/common_64.c b/arch/x86/kernel/cpu/common_64.c index dd6e3f15017e..a11f5d4477cd 100644 --- a/arch/x86/kernel/cpu/common_64.c +++ b/arch/x86/kernel/cpu/common_64.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <asm/mtrr.h> | 18 | #include <asm/mtrr.h> |
19 | #include <asm/mce.h> | 19 | #include <asm/mce.h> |
20 | #include <asm/pat.h> | 20 | #include <asm/pat.h> |
21 | #include <asm/asm.h> | ||
21 | #include <asm/numa.h> | 22 | #include <asm/numa.h> |
22 | #ifdef CONFIG_X86_LOCAL_APIC | 23 | #ifdef CONFIG_X86_LOCAL_APIC |
23 | #include <asm/mpspec.h> | 24 | #include <asm/mpspec.h> |
@@ -215,6 +216,39 @@ static void __init early_cpu_support_print(void) | |||
215 | } | 216 | } |
216 | } | 217 | } |
217 | 218 | ||
219 | /* | ||
220 | * The NOPL instruction is supposed to exist on all CPUs with | ||
221 | * family >= 6, unfortunately, that's not true in practice because | ||
222 | * of early VIA chips and (more importantly) broken virtualizers that | ||
223 | * are not easy to detect. Hence, probe for it based on first | ||
224 | * principles. | ||
225 | * | ||
226 | * Note: no 64-bit chip is known to lack these, but put the code here | ||
227 | * for consistency with 32 bits, and to make it utterly trivial to | ||
228 | * diagnose the problem should it ever surface. | ||
229 | */ | ||
230 | static void __cpuinit detect_nopl(struct cpuinfo_x86 *c) | ||
231 | { | ||
232 | const u32 nopl_signature = 0x888c53b1; /* Random number */ | ||
233 | u32 has_nopl = nopl_signature; | ||
234 | |||
235 | clear_cpu_cap(c, X86_FEATURE_NOPL); | ||
236 | if (c->x86 >= 6) { | ||
237 | asm volatile("\n" | ||
238 | "1: .byte 0x0f,0x1f,0xc0\n" /* nopl %eax */ | ||
239 | "2:\n" | ||
240 | " .section .fixup,\"ax\"\n" | ||
241 | "3: xor %0,%0\n" | ||
242 | " jmp 2b\n" | ||
243 | " .previous\n" | ||
244 | _ASM_EXTABLE(1b,3b) | ||
245 | : "+a" (has_nopl)); | ||
246 | |||
247 | if (has_nopl == nopl_signature) | ||
248 | set_cpu_cap(c, X86_FEATURE_NOPL); | ||
249 | } | ||
250 | } | ||
251 | |||
218 | static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c); | 252 | static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c); |
219 | 253 | ||
220 | void __init early_cpu_init(void) | 254 | void __init early_cpu_init(void) |
@@ -313,6 +347,8 @@ static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c) | |||
313 | c->x86_phys_bits = eax & 0xff; | 347 | c->x86_phys_bits = eax & 0xff; |
314 | } | 348 | } |
315 | 349 | ||
350 | detect_nopl(c); | ||
351 | |||
316 | if (c->x86_vendor != X86_VENDOR_UNKNOWN && | 352 | if (c->x86_vendor != X86_VENDOR_UNKNOWN && |
317 | cpu_devs[c->x86_vendor]->c_early_init) | 353 | cpu_devs[c->x86_vendor]->c_early_init) |
318 | cpu_devs[c->x86_vendor]->c_early_init(c); | 354 | cpu_devs[c->x86_vendor]->c_early_init(c); |
@@ -493,17 +529,20 @@ void pda_init(int cpu) | |||
493 | /* others are initialized in smpboot.c */ | 529 | /* others are initialized in smpboot.c */ |
494 | pda->pcurrent = &init_task; | 530 | pda->pcurrent = &init_task; |
495 | pda->irqstackptr = boot_cpu_stack; | 531 | pda->irqstackptr = boot_cpu_stack; |
532 | pda->irqstackptr += IRQSTACKSIZE - 64; | ||
496 | } else { | 533 | } else { |
497 | pda->irqstackptr = (char *) | 534 | if (!pda->irqstackptr) { |
498 | __get_free_pages(GFP_ATOMIC, IRQSTACK_ORDER); | 535 | pda->irqstackptr = (char *) |
499 | if (!pda->irqstackptr) | 536 | __get_free_pages(GFP_ATOMIC, IRQSTACK_ORDER); |
500 | panic("cannot allocate irqstack for cpu %d", cpu); | 537 | if (!pda->irqstackptr) |
538 | panic("cannot allocate irqstack for cpu %d", | ||
539 | cpu); | ||
540 | pda->irqstackptr += IRQSTACKSIZE - 64; | ||
541 | } | ||
501 | 542 | ||
502 | if (pda->nodenumber == 0 && cpu_to_node(cpu) != NUMA_NO_NODE) | 543 | if (pda->nodenumber == 0 && cpu_to_node(cpu) != NUMA_NO_NODE) |
503 | pda->nodenumber = cpu_to_node(cpu); | 544 | pda->nodenumber = cpu_to_node(cpu); |
504 | } | 545 | } |
505 | |||
506 | pda->irqstackptr += IRQSTACKSIZE-64; | ||
507 | } | 546 | } |
508 | 547 | ||
509 | char boot_exception_stacks[(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + | 548 | char boot_exception_stacks[(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + |
@@ -601,19 +640,22 @@ void __cpuinit cpu_init(void) | |||
601 | /* | 640 | /* |
602 | * set up and load the per-CPU TSS | 641 | * set up and load the per-CPU TSS |
603 | */ | 642 | */ |
604 | for (v = 0; v < N_EXCEPTION_STACKS; v++) { | 643 | if (!orig_ist->ist[0]) { |
605 | static const unsigned int order[N_EXCEPTION_STACKS] = { | 644 | static const unsigned int order[N_EXCEPTION_STACKS] = { |
606 | [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STACK_ORDER, | 645 | [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STACK_ORDER, |
607 | [DEBUG_STACK - 1] = DEBUG_STACK_ORDER | 646 | [DEBUG_STACK - 1] = DEBUG_STACK_ORDER |
608 | }; | 647 | }; |
609 | if (cpu) { | 648 | for (v = 0; v < N_EXCEPTION_STACKS; v++) { |
610 | estacks = (char *)__get_free_pages(GFP_ATOMIC, order[v]); | 649 | if (cpu) { |
611 | if (!estacks) | 650 | estacks = (char *)__get_free_pages(GFP_ATOMIC, order[v]); |
612 | panic("Cannot allocate exception stack %ld %d\n", | 651 | if (!estacks) |
613 | v, cpu); | 652 | panic("Cannot allocate exception " |
653 | "stack %ld %d\n", v, cpu); | ||
654 | } | ||
655 | estacks += PAGE_SIZE << order[v]; | ||
656 | orig_ist->ist[v] = t->x86_tss.ist[v] = | ||
657 | (unsigned long)estacks; | ||
614 | } | 658 | } |
615 | estacks += PAGE_SIZE << order[v]; | ||
616 | orig_ist->ist[v] = t->x86_tss.ist[v] = (unsigned long)estacks; | ||
617 | } | 659 | } |
618 | 660 | ||
619 | t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap); | 661 | t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap); |
diff --git a/arch/x86/kernel/cpu/cpufreq/Kconfig b/arch/x86/kernel/cpu/cpufreq/Kconfig index cb7a5715596d..efae3b22a0ff 100644 --- a/arch/x86/kernel/cpu/cpufreq/Kconfig +++ b/arch/x86/kernel/cpu/cpufreq/Kconfig | |||
@@ -235,9 +235,9 @@ config X86_LONGHAUL | |||
235 | If in doubt, say N. | 235 | If in doubt, say N. |
236 | 236 | ||
237 | config X86_E_POWERSAVER | 237 | config X86_E_POWERSAVER |
238 | tristate "VIA C7 Enhanced PowerSaver (EXPERIMENTAL)" | 238 | tristate "VIA C7 Enhanced PowerSaver" |
239 | select CPU_FREQ_TABLE | 239 | select CPU_FREQ_TABLE |
240 | depends on X86_32 && EXPERIMENTAL | 240 | depends on X86_32 |
241 | help | 241 | help |
242 | This adds the CPUFreq driver for VIA C7 processors. | 242 | This adds the CPUFreq driver for VIA C7 processors. |
243 | 243 | ||
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index ff2fff56f0a8..dd097b835839 100644 --- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | |||
@@ -200,12 +200,10 @@ static void drv_read(struct drv_cmd *cmd) | |||
200 | static void drv_write(struct drv_cmd *cmd) | 200 | static void drv_write(struct drv_cmd *cmd) |
201 | { | 201 | { |
202 | cpumask_t saved_mask = current->cpus_allowed; | 202 | cpumask_t saved_mask = current->cpus_allowed; |
203 | cpumask_of_cpu_ptr_declare(cpu_mask); | ||
204 | unsigned int i; | 203 | unsigned int i; |
205 | 204 | ||
206 | for_each_cpu_mask_nr(i, cmd->mask) { | 205 | for_each_cpu_mask_nr(i, cmd->mask) { |
207 | cpumask_of_cpu_ptr_next(cpu_mask, i); | 206 | set_cpus_allowed_ptr(current, &cpumask_of_cpu(i)); |
208 | set_cpus_allowed_ptr(current, cpu_mask); | ||
209 | do_drv_write(cmd); | 207 | do_drv_write(cmd); |
210 | } | 208 | } |
211 | 209 | ||
@@ -269,12 +267,11 @@ static unsigned int get_measured_perf(unsigned int cpu) | |||
269 | } aperf_cur, mperf_cur; | 267 | } aperf_cur, mperf_cur; |
270 | 268 | ||
271 | cpumask_t saved_mask; | 269 | cpumask_t saved_mask; |
272 | cpumask_of_cpu_ptr(cpu_mask, cpu); | ||
273 | unsigned int perf_percent; | 270 | unsigned int perf_percent; |
274 | unsigned int retval; | 271 | unsigned int retval; |
275 | 272 | ||
276 | saved_mask = current->cpus_allowed; | 273 | saved_mask = current->cpus_allowed; |
277 | set_cpus_allowed_ptr(current, cpu_mask); | 274 | set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu)); |
278 | if (get_cpu() != cpu) { | 275 | if (get_cpu() != cpu) { |
279 | /* We were not able to run on requested processor */ | 276 | /* We were not able to run on requested processor */ |
280 | put_cpu(); | 277 | put_cpu(); |
@@ -340,7 +337,6 @@ static unsigned int get_measured_perf(unsigned int cpu) | |||
340 | 337 | ||
341 | static unsigned int get_cur_freq_on_cpu(unsigned int cpu) | 338 | static unsigned int get_cur_freq_on_cpu(unsigned int cpu) |
342 | { | 339 | { |
343 | cpumask_of_cpu_ptr(cpu_mask, cpu); | ||
344 | struct acpi_cpufreq_data *data = per_cpu(drv_data, cpu); | 340 | struct acpi_cpufreq_data *data = per_cpu(drv_data, cpu); |
345 | unsigned int freq; | 341 | unsigned int freq; |
346 | unsigned int cached_freq; | 342 | unsigned int cached_freq; |
@@ -353,7 +349,7 @@ static unsigned int get_cur_freq_on_cpu(unsigned int cpu) | |||
353 | } | 349 | } |
354 | 350 | ||
355 | cached_freq = data->freq_table[data->acpi_data->state].frequency; | 351 | cached_freq = data->freq_table[data->acpi_data->state].frequency; |
356 | freq = extract_freq(get_cur_val(cpu_mask), data); | 352 | freq = extract_freq(get_cur_val(&cpumask_of_cpu(cpu)), data); |
357 | if (freq != cached_freq) { | 353 | if (freq != cached_freq) { |
358 | /* | 354 | /* |
359 | * The dreaded BIOS frequency change behind our back. | 355 | * The dreaded BIOS frequency change behind our back. |
diff --git a/arch/x86/kernel/cpu/cpufreq/elanfreq.c b/arch/x86/kernel/cpu/cpufreq/elanfreq.c index 94619c22f563..e4a4bf870e94 100644 --- a/arch/x86/kernel/cpu/cpufreq/elanfreq.c +++ b/arch/x86/kernel/cpu/cpufreq/elanfreq.c | |||
@@ -44,7 +44,7 @@ struct s_elan_multiplier { | |||
44 | * It is important that the frequencies | 44 | * It is important that the frequencies |
45 | * are listed in ascending order here! | 45 | * are listed in ascending order here! |
46 | */ | 46 | */ |
47 | struct s_elan_multiplier elan_multiplier[] = { | 47 | static struct s_elan_multiplier elan_multiplier[] = { |
48 | {1000, 0x02, 0x18}, | 48 | {1000, 0x02, 0x18}, |
49 | {2000, 0x02, 0x10}, | 49 | {2000, 0x02, 0x10}, |
50 | {4000, 0x02, 0x08}, | 50 | {4000, 0x02, 0x08}, |
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index 53c7b6936973..84bb395038d8 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c | |||
@@ -66,7 +66,6 @@ static u32 find_freq_from_fid(u32 fid) | |||
66 | return 800 + (fid * 100); | 66 | return 800 + (fid * 100); |
67 | } | 67 | } |
68 | 68 | ||
69 | |||
70 | /* Return a frequency in KHz, given an input fid */ | 69 | /* Return a frequency in KHz, given an input fid */ |
71 | static u32 find_khz_freq_from_fid(u32 fid) | 70 | static u32 find_khz_freq_from_fid(u32 fid) |
72 | { | 71 | { |
@@ -78,7 +77,6 @@ static u32 find_khz_freq_from_pstate(struct cpufreq_frequency_table *data, u32 p | |||
78 | return data[pstate].frequency; | 77 | return data[pstate].frequency; |
79 | } | 78 | } |
80 | 79 | ||
81 | |||
82 | /* Return the vco fid for an input fid | 80 | /* Return the vco fid for an input fid |
83 | * | 81 | * |
84 | * Each "low" fid has corresponding "high" fid, and you can get to "low" fids | 82 | * Each "low" fid has corresponding "high" fid, and you can get to "low" fids |
@@ -166,7 +164,6 @@ static void fidvid_msr_init(void) | |||
166 | wrmsr(MSR_FIDVID_CTL, lo, hi); | 164 | wrmsr(MSR_FIDVID_CTL, lo, hi); |
167 | } | 165 | } |
168 | 166 | ||
169 | |||
170 | /* write the new fid value along with the other control fields to the msr */ | 167 | /* write the new fid value along with the other control fields to the msr */ |
171 | static int write_new_fid(struct powernow_k8_data *data, u32 fid) | 168 | static int write_new_fid(struct powernow_k8_data *data, u32 fid) |
172 | { | 169 | { |
@@ -479,12 +476,11 @@ static int core_voltage_post_transition(struct powernow_k8_data *data, u32 reqvi | |||
479 | static int check_supported_cpu(unsigned int cpu) | 476 | static int check_supported_cpu(unsigned int cpu) |
480 | { | 477 | { |
481 | cpumask_t oldmask; | 478 | cpumask_t oldmask; |
482 | cpumask_of_cpu_ptr(cpu_mask, cpu); | ||
483 | u32 eax, ebx, ecx, edx; | 479 | u32 eax, ebx, ecx, edx; |
484 | unsigned int rc = 0; | 480 | unsigned int rc = 0; |
485 | 481 | ||
486 | oldmask = current->cpus_allowed; | 482 | oldmask = current->cpus_allowed; |
487 | set_cpus_allowed_ptr(current, cpu_mask); | 483 | set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu)); |
488 | 484 | ||
489 | if (smp_processor_id() != cpu) { | 485 | if (smp_processor_id() != cpu) { |
490 | printk(KERN_ERR PFX "limiting to cpu %u failed\n", cpu); | 486 | printk(KERN_ERR PFX "limiting to cpu %u failed\n", cpu); |
@@ -1017,7 +1013,6 @@ static int transition_frequency_pstate(struct powernow_k8_data *data, unsigned i | |||
1017 | static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsigned relation) | 1013 | static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsigned relation) |
1018 | { | 1014 | { |
1019 | cpumask_t oldmask; | 1015 | cpumask_t oldmask; |
1020 | cpumask_of_cpu_ptr(cpu_mask, pol->cpu); | ||
1021 | struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); | 1016 | struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); |
1022 | u32 checkfid; | 1017 | u32 checkfid; |
1023 | u32 checkvid; | 1018 | u32 checkvid; |
@@ -1032,7 +1027,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi | |||
1032 | 1027 | ||
1033 | /* only run on specific CPU from here on */ | 1028 | /* only run on specific CPU from here on */ |
1034 | oldmask = current->cpus_allowed; | 1029 | oldmask = current->cpus_allowed; |
1035 | set_cpus_allowed_ptr(current, cpu_mask); | 1030 | set_cpus_allowed_ptr(current, &cpumask_of_cpu(pol->cpu)); |
1036 | 1031 | ||
1037 | if (smp_processor_id() != pol->cpu) { | 1032 | if (smp_processor_id() != pol->cpu) { |
1038 | printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu); | 1033 | printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu); |
@@ -1107,7 +1102,6 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1107 | { | 1102 | { |
1108 | struct powernow_k8_data *data; | 1103 | struct powernow_k8_data *data; |
1109 | cpumask_t oldmask; | 1104 | cpumask_t oldmask; |
1110 | cpumask_of_cpu_ptr_declare(newmask); | ||
1111 | int rc; | 1105 | int rc; |
1112 | 1106 | ||
1113 | if (!cpu_online(pol->cpu)) | 1107 | if (!cpu_online(pol->cpu)) |
@@ -1159,8 +1153,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1159 | 1153 | ||
1160 | /* only run on specific CPU from here on */ | 1154 | /* only run on specific CPU from here on */ |
1161 | oldmask = current->cpus_allowed; | 1155 | oldmask = current->cpus_allowed; |
1162 | cpumask_of_cpu_ptr_next(newmask, pol->cpu); | 1156 | set_cpus_allowed_ptr(current, &cpumask_of_cpu(pol->cpu)); |
1163 | set_cpus_allowed_ptr(current, newmask); | ||
1164 | 1157 | ||
1165 | if (smp_processor_id() != pol->cpu) { | 1158 | if (smp_processor_id() != pol->cpu) { |
1166 | printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu); | 1159 | printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu); |
@@ -1182,7 +1175,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1182 | set_cpus_allowed_ptr(current, &oldmask); | 1175 | set_cpus_allowed_ptr(current, &oldmask); |
1183 | 1176 | ||
1184 | if (cpu_family == CPU_HW_PSTATE) | 1177 | if (cpu_family == CPU_HW_PSTATE) |
1185 | pol->cpus = *newmask; | 1178 | pol->cpus = cpumask_of_cpu(pol->cpu); |
1186 | else | 1179 | else |
1187 | pol->cpus = per_cpu(cpu_core_map, pol->cpu); | 1180 | pol->cpus = per_cpu(cpu_core_map, pol->cpu); |
1188 | data->available_cores = &(pol->cpus); | 1181 | data->available_cores = &(pol->cpus); |
@@ -1248,7 +1241,6 @@ static unsigned int powernowk8_get (unsigned int cpu) | |||
1248 | { | 1241 | { |
1249 | struct powernow_k8_data *data; | 1242 | struct powernow_k8_data *data; |
1250 | cpumask_t oldmask = current->cpus_allowed; | 1243 | cpumask_t oldmask = current->cpus_allowed; |
1251 | cpumask_of_cpu_ptr(newmask, cpu); | ||
1252 | unsigned int khz = 0; | 1244 | unsigned int khz = 0; |
1253 | unsigned int first; | 1245 | unsigned int first; |
1254 | 1246 | ||
@@ -1258,7 +1250,7 @@ static unsigned int powernowk8_get (unsigned int cpu) | |||
1258 | if (!data) | 1250 | if (!data) |
1259 | return -EINVAL; | 1251 | return -EINVAL; |
1260 | 1252 | ||
1261 | set_cpus_allowed_ptr(current, newmask); | 1253 | set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu)); |
1262 | if (smp_processor_id() != cpu) { | 1254 | if (smp_processor_id() != cpu) { |
1263 | printk(KERN_ERR PFX | 1255 | printk(KERN_ERR PFX |
1264 | "limiting to CPU %d failed in powernowk8_get\n", cpu); | 1256 | "limiting to CPU %d failed in powernowk8_get\n", cpu); |
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c index ca2ac13b7af2..15e13c01cc36 100644 --- a/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c +++ b/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c | |||
@@ -324,10 +324,9 @@ static unsigned int get_cur_freq(unsigned int cpu) | |||
324 | unsigned l, h; | 324 | unsigned l, h; |
325 | unsigned clock_freq; | 325 | unsigned clock_freq; |
326 | cpumask_t saved_mask; | 326 | cpumask_t saved_mask; |
327 | cpumask_of_cpu_ptr(new_mask, cpu); | ||
328 | 327 | ||
329 | saved_mask = current->cpus_allowed; | 328 | saved_mask = current->cpus_allowed; |
330 | set_cpus_allowed_ptr(current, new_mask); | 329 | set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu)); |
331 | if (smp_processor_id() != cpu) | 330 | if (smp_processor_id() != cpu) |
332 | return 0; | 331 | return 0; |
333 | 332 | ||
@@ -585,15 +584,12 @@ static int centrino_target (struct cpufreq_policy *policy, | |||
585 | * Best effort undo.. | 584 | * Best effort undo.. |
586 | */ | 585 | */ |
587 | 586 | ||
588 | if (!cpus_empty(*covered_cpus)) { | 587 | if (!cpus_empty(*covered_cpus)) |
589 | cpumask_of_cpu_ptr_declare(new_mask); | ||
590 | |||
591 | for_each_cpu_mask_nr(j, *covered_cpus) { | 588 | for_each_cpu_mask_nr(j, *covered_cpus) { |
592 | cpumask_of_cpu_ptr_next(new_mask, j); | 589 | set_cpus_allowed_ptr(current, |
593 | set_cpus_allowed_ptr(current, new_mask); | 590 | &cpumask_of_cpu(j)); |
594 | wrmsr(MSR_IA32_PERF_CTL, oldmsr, h); | 591 | wrmsr(MSR_IA32_PERF_CTL, oldmsr, h); |
595 | } | 592 | } |
596 | } | ||
597 | 593 | ||
598 | tmp = freqs.new; | 594 | tmp = freqs.new; |
599 | freqs.new = freqs.old; | 595 | freqs.new = freqs.old; |
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c index 2f3728dc24f6..191f7263c61d 100644 --- a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c +++ b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c | |||
@@ -244,8 +244,7 @@ static unsigned int _speedstep_get(const cpumask_t *cpus) | |||
244 | 244 | ||
245 | static unsigned int speedstep_get(unsigned int cpu) | 245 | static unsigned int speedstep_get(unsigned int cpu) |
246 | { | 246 | { |
247 | cpumask_of_cpu_ptr(newmask, cpu); | 247 | return _speedstep_get(&cpumask_of_cpu(cpu)); |
248 | return _speedstep_get(newmask); | ||
249 | } | 248 | } |
250 | 249 | ||
251 | /** | 250 | /** |
diff --git a/arch/x86/kernel/cpu/cyrix.c b/arch/x86/kernel/cpu/cyrix.c index 3fd7a67bb06a..898a5a2002ed 100644 --- a/arch/x86/kernel/cpu/cyrix.c +++ b/arch/x86/kernel/cpu/cyrix.c | |||
@@ -15,13 +15,11 @@ | |||
15 | /* | 15 | /* |
16 | * Read NSC/Cyrix DEVID registers (DIR) to get more detailed info. about the CPU | 16 | * Read NSC/Cyrix DEVID registers (DIR) to get more detailed info. about the CPU |
17 | */ | 17 | */ |
18 | static void __cpuinit do_cyrix_devid(unsigned char *dir0, unsigned char *dir1) | 18 | static void __cpuinit __do_cyrix_devid(unsigned char *dir0, unsigned char *dir1) |
19 | { | 19 | { |
20 | unsigned char ccr2, ccr3; | 20 | unsigned char ccr2, ccr3; |
21 | unsigned long flags; | ||
22 | 21 | ||
23 | /* we test for DEVID by checking whether CCR3 is writable */ | 22 | /* we test for DEVID by checking whether CCR3 is writable */ |
24 | local_irq_save(flags); | ||
25 | ccr3 = getCx86(CX86_CCR3); | 23 | ccr3 = getCx86(CX86_CCR3); |
26 | setCx86(CX86_CCR3, ccr3 ^ 0x80); | 24 | setCx86(CX86_CCR3, ccr3 ^ 0x80); |
27 | getCx86(0xc0); /* dummy to change bus */ | 25 | getCx86(0xc0); /* dummy to change bus */ |
@@ -44,9 +42,16 @@ static void __cpuinit do_cyrix_devid(unsigned char *dir0, unsigned char *dir1) | |||
44 | *dir0 = getCx86(CX86_DIR0); | 42 | *dir0 = getCx86(CX86_DIR0); |
45 | *dir1 = getCx86(CX86_DIR1); | 43 | *dir1 = getCx86(CX86_DIR1); |
46 | } | 44 | } |
47 | local_irq_restore(flags); | ||
48 | } | 45 | } |
49 | 46 | ||
47 | static void __cpuinit do_cyrix_devid(unsigned char *dir0, unsigned char *dir1) | ||
48 | { | ||
49 | unsigned long flags; | ||
50 | |||
51 | local_irq_save(flags); | ||
52 | __do_cyrix_devid(dir0, dir1); | ||
53 | local_irq_restore(flags); | ||
54 | } | ||
50 | /* | 55 | /* |
51 | * Cx86_dir0_msb is a HACK needed by check_cx686_cpuid/slop in bugs.h in | 56 | * Cx86_dir0_msb is a HACK needed by check_cx686_cpuid/slop in bugs.h in |
52 | * order to identify the Cyrix CPU model after we're out of setup.c | 57 | * order to identify the Cyrix CPU model after we're out of setup.c |
@@ -134,23 +139,6 @@ static void __cpuinit set_cx86_memwb(void) | |||
134 | setCx86(CX86_CCR2, getCx86(CX86_CCR2) | 0x14); | 139 | setCx86(CX86_CCR2, getCx86(CX86_CCR2) | 0x14); |
135 | } | 140 | } |
136 | 141 | ||
137 | static void __cpuinit set_cx86_inc(void) | ||
138 | { | ||
139 | unsigned char ccr3; | ||
140 | |||
141 | printk(KERN_INFO "Enable Incrementor on Cyrix/NSC processor.\n"); | ||
142 | |||
143 | ccr3 = getCx86(CX86_CCR3); | ||
144 | setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */ | ||
145 | /* PCR1 -- Performance Control */ | ||
146 | /* Incrementor on, whatever that is */ | ||
147 | setCx86(CX86_PCR1, getCx86(CX86_PCR1) | 0x02); | ||
148 | /* PCR0 -- Performance Control */ | ||
149 | /* Incrementor Margin 10 */ | ||
150 | setCx86(CX86_PCR0, getCx86(CX86_PCR0) | 0x04); | ||
151 | setCx86(CX86_CCR3, ccr3); /* disable MAPEN */ | ||
152 | } | ||
153 | |||
154 | /* | 142 | /* |
155 | * Configure later MediaGX and/or Geode processor. | 143 | * Configure later MediaGX and/or Geode processor. |
156 | */ | 144 | */ |
@@ -174,11 +162,28 @@ static void __cpuinit geode_configure(void) | |||
174 | 162 | ||
175 | set_cx86_memwb(); | 163 | set_cx86_memwb(); |
176 | set_cx86_reorder(); | 164 | set_cx86_reorder(); |
177 | set_cx86_inc(); | ||
178 | 165 | ||
179 | local_irq_restore(flags); | 166 | local_irq_restore(flags); |
180 | } | 167 | } |
181 | 168 | ||
169 | static void __cpuinit early_init_cyrix(struct cpuinfo_x86 *c) | ||
170 | { | ||
171 | unsigned char dir0, dir0_msn, dir1 = 0; | ||
172 | |||
173 | __do_cyrix_devid(&dir0, &dir1); | ||
174 | dir0_msn = dir0 >> 4; /* identifies CPU "family" */ | ||
175 | |||
176 | switch (dir0_msn) { | ||
177 | case 3: /* 6x86/6x86L */ | ||
178 | /* Emulate MTRRs using Cyrix's ARRs. */ | ||
179 | set_cpu_cap(c, X86_FEATURE_CYRIX_ARR); | ||
180 | break; | ||
181 | case 5: /* 6x86MX/M II */ | ||
182 | /* Emulate MTRRs using Cyrix's ARRs. */ | ||
183 | set_cpu_cap(c, X86_FEATURE_CYRIX_ARR); | ||
184 | break; | ||
185 | } | ||
186 | } | ||
182 | 187 | ||
183 | static void __cpuinit init_cyrix(struct cpuinfo_x86 *c) | 188 | static void __cpuinit init_cyrix(struct cpuinfo_x86 *c) |
184 | { | 189 | { |
@@ -434,6 +439,7 @@ static void __cpuinit cyrix_identify(struct cpuinfo_x86 *c) | |||
434 | static struct cpu_dev cyrix_cpu_dev __cpuinitdata = { | 439 | static struct cpu_dev cyrix_cpu_dev __cpuinitdata = { |
435 | .c_vendor = "Cyrix", | 440 | .c_vendor = "Cyrix", |
436 | .c_ident = { "CyrixInstead" }, | 441 | .c_ident = { "CyrixInstead" }, |
442 | .c_early_init = early_init_cyrix, | ||
437 | .c_init = init_cyrix, | 443 | .c_init = init_cyrix, |
438 | .c_identify = cyrix_identify, | 444 | .c_identify = cyrix_identify, |
439 | }; | 445 | }; |
diff --git a/arch/x86/kernel/cpu/feature_names.c b/arch/x86/kernel/cpu/feature_names.c index e43ad4ad4cba..c9017799497c 100644 --- a/arch/x86/kernel/cpu/feature_names.c +++ b/arch/x86/kernel/cpu/feature_names.c | |||
@@ -39,7 +39,8 @@ const char * const x86_cap_flags[NCAPINTS*32] = { | |||
39 | NULL, NULL, NULL, NULL, | 39 | NULL, NULL, NULL, NULL, |
40 | "constant_tsc", "up", NULL, "arch_perfmon", | 40 | "constant_tsc", "up", NULL, "arch_perfmon", |
41 | "pebs", "bts", NULL, NULL, | 41 | "pebs", "bts", NULL, NULL, |
42 | "rep_good", NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 42 | "rep_good", NULL, NULL, NULL, |
43 | "nopl", NULL, NULL, NULL, | ||
43 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 44 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
44 | 45 | ||
45 | /* Intel-defined (#2) */ | 46 | /* Intel-defined (#2) */ |
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index 650d40f7912b..6b0a10b002f1 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c | |||
@@ -516,7 +516,6 @@ static int __cpuinit detect_cache_attributes(unsigned int cpu) | |||
516 | unsigned long j; | 516 | unsigned long j; |
517 | int retval; | 517 | int retval; |
518 | cpumask_t oldmask; | 518 | cpumask_t oldmask; |
519 | cpumask_of_cpu_ptr(newmask, cpu); | ||
520 | 519 | ||
521 | if (num_cache_leaves == 0) | 520 | if (num_cache_leaves == 0) |
522 | return -ENOENT; | 521 | return -ENOENT; |
@@ -527,7 +526,7 @@ static int __cpuinit detect_cache_attributes(unsigned int cpu) | |||
527 | return -ENOMEM; | 526 | return -ENOMEM; |
528 | 527 | ||
529 | oldmask = current->cpus_allowed; | 528 | oldmask = current->cpus_allowed; |
530 | retval = set_cpus_allowed_ptr(current, newmask); | 529 | retval = set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu)); |
531 | if (retval) | 530 | if (retval) |
532 | goto out; | 531 | goto out; |
533 | 532 | ||
diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c index 65a339678ece..726a5fcdf341 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_64.c | |||
@@ -759,6 +759,7 @@ static struct sysdev_class mce_sysclass = { | |||
759 | }; | 759 | }; |
760 | 760 | ||
761 | DEFINE_PER_CPU(struct sys_device, device_mce); | 761 | DEFINE_PER_CPU(struct sys_device, device_mce); |
762 | void (*threshold_cpu_callback)(unsigned long action, unsigned int cpu) __cpuinitdata; | ||
762 | 763 | ||
763 | /* Why are there no generic functions for this? */ | 764 | /* Why are there no generic functions for this? */ |
764 | #define ACCESSOR(name, var, start) \ | 765 | #define ACCESSOR(name, var, start) \ |
@@ -883,9 +884,13 @@ static int __cpuinit mce_cpu_callback(struct notifier_block *nfb, | |||
883 | case CPU_ONLINE: | 884 | case CPU_ONLINE: |
884 | case CPU_ONLINE_FROZEN: | 885 | case CPU_ONLINE_FROZEN: |
885 | mce_create_device(cpu); | 886 | mce_create_device(cpu); |
887 | if (threshold_cpu_callback) | ||
888 | threshold_cpu_callback(action, cpu); | ||
886 | break; | 889 | break; |
887 | case CPU_DEAD: | 890 | case CPU_DEAD: |
888 | case CPU_DEAD_FROZEN: | 891 | case CPU_DEAD_FROZEN: |
892 | if (threshold_cpu_callback) | ||
893 | threshold_cpu_callback(action, cpu); | ||
889 | mce_remove_device(cpu); | 894 | mce_remove_device(cpu); |
890 | break; | 895 | break; |
891 | } | 896 | } |
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c index 88736cadbaa6..5eb390a4b2e9 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c | |||
@@ -628,6 +628,7 @@ static void threshold_remove_bank(unsigned int cpu, int bank) | |||
628 | deallocate_threshold_block(cpu, bank); | 628 | deallocate_threshold_block(cpu, bank); |
629 | 629 | ||
630 | free_out: | 630 | free_out: |
631 | kobject_del(b->kobj); | ||
631 | kobject_put(b->kobj); | 632 | kobject_put(b->kobj); |
632 | kfree(b); | 633 | kfree(b); |
633 | per_cpu(threshold_banks, cpu)[bank] = NULL; | 634 | per_cpu(threshold_banks, cpu)[bank] = NULL; |
@@ -645,14 +646,11 @@ static void threshold_remove_device(unsigned int cpu) | |||
645 | } | 646 | } |
646 | 647 | ||
647 | /* get notified when a cpu comes on/off */ | 648 | /* get notified when a cpu comes on/off */ |
648 | static int __cpuinit threshold_cpu_callback(struct notifier_block *nfb, | 649 | static void __cpuinit amd_64_threshold_cpu_callback(unsigned long action, |
649 | unsigned long action, void *hcpu) | 650 | unsigned int cpu) |
650 | { | 651 | { |
651 | /* cpu was unsigned int to begin with */ | ||
652 | unsigned int cpu = (unsigned long)hcpu; | ||
653 | |||
654 | if (cpu >= NR_CPUS) | 652 | if (cpu >= NR_CPUS) |
655 | goto out; | 653 | return; |
656 | 654 | ||
657 | switch (action) { | 655 | switch (action) { |
658 | case CPU_ONLINE: | 656 | case CPU_ONLINE: |
@@ -666,14 +664,8 @@ static int __cpuinit threshold_cpu_callback(struct notifier_block *nfb, | |||
666 | default: | 664 | default: |
667 | break; | 665 | break; |
668 | } | 666 | } |
669 | out: | ||
670 | return NOTIFY_OK; | ||
671 | } | 667 | } |
672 | 668 | ||
673 | static struct notifier_block threshold_cpu_notifier __cpuinitdata = { | ||
674 | .notifier_call = threshold_cpu_callback, | ||
675 | }; | ||
676 | |||
677 | static __init int threshold_init_device(void) | 669 | static __init int threshold_init_device(void) |
678 | { | 670 | { |
679 | unsigned lcpu = 0; | 671 | unsigned lcpu = 0; |
@@ -684,7 +676,7 @@ static __init int threshold_init_device(void) | |||
684 | if (err) | 676 | if (err) |
685 | return err; | 677 | return err; |
686 | } | 678 | } |
687 | register_hotcpu_notifier(&threshold_cpu_notifier); | 679 | threshold_cpu_callback = amd_64_threshold_cpu_callback; |
688 | return 0; | 680 | return 0; |
689 | } | 681 | } |
690 | 682 | ||
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c index 509bd3d9eacd..cb7d3b6a80eb 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c | |||
@@ -379,6 +379,7 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base, | |||
379 | unsigned long *size, mtrr_type *type) | 379 | unsigned long *size, mtrr_type *type) |
380 | { | 380 | { |
381 | unsigned int mask_lo, mask_hi, base_lo, base_hi; | 381 | unsigned int mask_lo, mask_hi, base_lo, base_hi; |
382 | unsigned int tmp, hi; | ||
382 | 383 | ||
383 | rdmsr(MTRRphysMask_MSR(reg), mask_lo, mask_hi); | 384 | rdmsr(MTRRphysMask_MSR(reg), mask_lo, mask_hi); |
384 | if ((mask_lo & 0x800) == 0) { | 385 | if ((mask_lo & 0x800) == 0) { |
@@ -392,8 +393,23 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base, | |||
392 | rdmsr(MTRRphysBase_MSR(reg), base_lo, base_hi); | 393 | rdmsr(MTRRphysBase_MSR(reg), base_lo, base_hi); |
393 | 394 | ||
394 | /* Work out the shifted address mask. */ | 395 | /* Work out the shifted address mask. */ |
395 | mask_lo = size_or_mask | mask_hi << (32 - PAGE_SHIFT) | 396 | tmp = mask_hi << (32 - PAGE_SHIFT) | mask_lo >> PAGE_SHIFT; |
396 | | mask_lo >> PAGE_SHIFT; | 397 | mask_lo = size_or_mask | tmp; |
398 | /* Expand tmp with high bits to all 1s*/ | ||
399 | hi = fls(tmp); | ||
400 | if (hi > 0) { | ||
401 | tmp |= ~((1<<(hi - 1)) - 1); | ||
402 | |||
403 | if (tmp != mask_lo) { | ||
404 | static int once = 1; | ||
405 | |||
406 | if (once) { | ||
407 | printk(KERN_INFO "mtrr: your BIOS has set up an incorrect mask, fixing it up.\n"); | ||
408 | once = 0; | ||
409 | } | ||
410 | mask_lo = tmp; | ||
411 | } | ||
412 | } | ||
397 | 413 | ||
398 | /* This works correctly if size is a power of two, i.e. a | 414 | /* This works correctly if size is a power of two, i.e. a |
399 | contiguous range. */ | 415 | contiguous range. */ |
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c index 6f23969c8faf..b117d7f8a564 100644 --- a/arch/x86/kernel/cpu/mtrr/main.c +++ b/arch/x86/kernel/cpu/mtrr/main.c | |||
@@ -1496,11 +1496,8 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn) | |||
1496 | 1496 | ||
1497 | /* kvm/qemu doesn't have mtrr set right, don't trim them all */ | 1497 | /* kvm/qemu doesn't have mtrr set right, don't trim them all */ |
1498 | if (!highest_pfn) { | 1498 | if (!highest_pfn) { |
1499 | if (!kvm_para_available()) { | 1499 | WARN(!kvm_para_available(), KERN_WARNING |
1500 | printk(KERN_WARNING | ||
1501 | "WARNING: strange, CPU MTRRs all blank?\n"); | 1500 | "WARNING: strange, CPU MTRRs all blank?\n"); |
1502 | WARN_ON(1); | ||
1503 | } | ||
1504 | return 0; | 1501 | return 0; |
1505 | } | 1502 | } |
1506 | 1503 | ||
diff --git a/arch/x86/kernel/cpu/perfctr-watchdog.c b/arch/x86/kernel/cpu/perfctr-watchdog.c index de7439f82b92..05cc22dbd4ff 100644 --- a/arch/x86/kernel/cpu/perfctr-watchdog.c +++ b/arch/x86/kernel/cpu/perfctr-watchdog.c | |||
@@ -478,7 +478,13 @@ static int setup_p4_watchdog(unsigned nmi_hz) | |||
478 | perfctr_msr = MSR_P4_IQ_PERFCTR1; | 478 | perfctr_msr = MSR_P4_IQ_PERFCTR1; |
479 | evntsel_msr = MSR_P4_CRU_ESCR0; | 479 | evntsel_msr = MSR_P4_CRU_ESCR0; |
480 | cccr_msr = MSR_P4_IQ_CCCR1; | 480 | cccr_msr = MSR_P4_IQ_CCCR1; |
481 | cccr_val = P4_CCCR_OVF_PMI1 | P4_CCCR_ESCR_SELECT(4); | 481 | |
482 | /* Pentium 4 D processors don't support P4_CCCR_OVF_PMI1 */ | ||
483 | if (boot_cpu_data.x86_model == 4 && boot_cpu_data.x86_mask == 4) | ||
484 | cccr_val = P4_CCCR_OVF_PMI0; | ||
485 | else | ||
486 | cccr_val = P4_CCCR_OVF_PMI1; | ||
487 | cccr_val |= P4_CCCR_ESCR_SELECT(4); | ||
482 | } | 488 | } |
483 | 489 | ||
484 | evntsel = P4_ESCR_EVENT_SELECT(0x3F) | 490 | evntsel = P4_ESCR_EVENT_SELECT(0x3F) |
diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c index 14b11b3be31c..8e9cd6a8ec12 100644 --- a/arch/x86/kernel/cpuid.c +++ b/arch/x86/kernel/cpuid.c | |||
@@ -89,6 +89,8 @@ static ssize_t cpuid_read(struct file *file, char __user *buf, | |||
89 | struct cpuid_regs cmd; | 89 | struct cpuid_regs cmd; |
90 | int cpu = iminor(file->f_path.dentry->d_inode); | 90 | int cpu = iminor(file->f_path.dentry->d_inode); |
91 | u64 pos = *ppos; | 91 | u64 pos = *ppos; |
92 | ssize_t bytes = 0; | ||
93 | int err = 0; | ||
92 | 94 | ||
93 | if (count % 16) | 95 | if (count % 16) |
94 | return -EINVAL; /* Invalid chunk size */ | 96 | return -EINVAL; /* Invalid chunk size */ |
@@ -96,14 +98,19 @@ static ssize_t cpuid_read(struct file *file, char __user *buf, | |||
96 | for (; count; count -= 16) { | 98 | for (; count; count -= 16) { |
97 | cmd.eax = pos; | 99 | cmd.eax = pos; |
98 | cmd.ecx = pos >> 32; | 100 | cmd.ecx = pos >> 32; |
99 | smp_call_function_single(cpu, cpuid_smp_cpuid, &cmd, 1); | 101 | err = smp_call_function_single(cpu, cpuid_smp_cpuid, &cmd, 1); |
100 | if (copy_to_user(tmp, &cmd, 16)) | 102 | if (err) |
101 | return -EFAULT; | 103 | break; |
104 | if (copy_to_user(tmp, &cmd, 16)) { | ||
105 | err = -EFAULT; | ||
106 | break; | ||
107 | } | ||
102 | tmp += 16; | 108 | tmp += 16; |
109 | bytes += 16; | ||
103 | *ppos = ++pos; | 110 | *ppos = ++pos; |
104 | } | 111 | } |
105 | 112 | ||
106 | return tmp - buf; | 113 | return bytes ? bytes : err; |
107 | } | 114 | } |
108 | 115 | ||
109 | static int cpuid_open(struct inode *inode, struct file *file) | 116 | static int cpuid_open(struct inode *inode, struct file *file) |
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 9af89078f7bb..66e48aa2dd1b 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c | |||
@@ -1203,7 +1203,7 @@ static int __init parse_memmap_opt(char *p) | |||
1203 | if (!p) | 1203 | if (!p) |
1204 | return -EINVAL; | 1204 | return -EINVAL; |
1205 | 1205 | ||
1206 | if (!strcmp(p, "exactmap")) { | 1206 | if (!strncmp(p, "exactmap", 8)) { |
1207 | #ifdef CONFIG_CRASH_DUMP | 1207 | #ifdef CONFIG_CRASH_DUMP |
1208 | /* | 1208 | /* |
1209 | * If we are doing a crash dump, we still need to know | 1209 | * If we are doing a crash dump, we still need to know |
diff --git a/arch/x86/kernel/efi_32.c b/arch/x86/kernel/efi_32.c index 4b63c8e1f13b..5cab48ee61a4 100644 --- a/arch/x86/kernel/efi_32.c +++ b/arch/x86/kernel/efi_32.c | |||
@@ -53,7 +53,7 @@ void efi_call_phys_prelog(void) | |||
53 | * directory. If I have PAE, I just need to duplicate one entry in | 53 | * directory. If I have PAE, I just need to duplicate one entry in |
54 | * page directory. | 54 | * page directory. |
55 | */ | 55 | */ |
56 | cr4 = read_cr4(); | 56 | cr4 = read_cr4_safe(); |
57 | 57 | ||
58 | if (cr4 & X86_CR4_PAE) { | 58 | if (cr4 & X86_CR4_PAE) { |
59 | efi_bak_pg_dir_pointer[0].pgd = | 59 | efi_bak_pg_dir_pointer[0].pgd = |
@@ -91,7 +91,7 @@ void efi_call_phys_epilog(void) | |||
91 | gdt_descr.size = GDT_SIZE - 1; | 91 | gdt_descr.size = GDT_SIZE - 1; |
92 | load_gdt(&gdt_descr); | 92 | load_gdt(&gdt_descr); |
93 | 93 | ||
94 | cr4 = read_cr4(); | 94 | cr4 = read_cr4_safe(); |
95 | 95 | ||
96 | if (cr4 & X86_CR4_PAE) { | 96 | if (cr4 & X86_CR4_PAE) { |
97 | swapper_pg_dir[pgd_index(0)].pgd = | 97 | swapper_pg_dir[pgd_index(0)].pgd = |
diff --git a/arch/x86/kernel/genapic_64.c b/arch/x86/kernel/genapic_64.c index 1fa8be5bd217..eaff0bbb1444 100644 --- a/arch/x86/kernel/genapic_64.c +++ b/arch/x86/kernel/genapic_64.c | |||
@@ -99,3 +99,4 @@ int is_uv_system(void) | |||
99 | { | 99 | { |
100 | return uv_system_type != UV_NONE; | 100 | return uv_system_type != UV_NONE; |
101 | } | 101 | } |
102 | EXPORT_SYMBOL_GPL(is_uv_system); | ||
diff --git a/arch/x86/kernel/genx2apic_uv_x.c b/arch/x86/kernel/genx2apic_uv_x.c index 2cfcbded888a..bfa837cb16be 100644 --- a/arch/x86/kernel/genx2apic_uv_x.c +++ b/arch/x86/kernel/genx2apic_uv_x.c | |||
@@ -222,7 +222,7 @@ static __init void map_low_mmrs(void) | |||
222 | 222 | ||
223 | enum map_type {map_wb, map_uc}; | 223 | enum map_type {map_wb, map_uc}; |
224 | 224 | ||
225 | static void map_high(char *id, unsigned long base, int shift, enum map_type map_type) | 225 | static __init void map_high(char *id, unsigned long base, int shift, enum map_type map_type) |
226 | { | 226 | { |
227 | unsigned long bytes, paddr; | 227 | unsigned long bytes, paddr; |
228 | 228 | ||
@@ -293,7 +293,9 @@ static __init void uv_rtc_init(void) | |||
293 | sn_rtc_cycles_per_second = ticks_per_sec; | 293 | sn_rtc_cycles_per_second = ticks_per_sec; |
294 | } | 294 | } |
295 | 295 | ||
296 | static __init void uv_system_init(void) | 296 | static bool uv_system_inited; |
297 | |||
298 | void __init uv_system_init(void) | ||
297 | { | 299 | { |
298 | union uvh_si_addr_map_config_u m_n_config; | 300 | union uvh_si_addr_map_config_u m_n_config; |
299 | union uvh_node_id_u node_id; | 301 | union uvh_node_id_u node_id; |
@@ -383,6 +385,7 @@ static __init void uv_system_init(void) | |||
383 | map_mmr_high(max_pnode); | 385 | map_mmr_high(max_pnode); |
384 | map_config_high(max_pnode); | 386 | map_config_high(max_pnode); |
385 | map_mmioh_high(max_pnode); | 387 | map_mmioh_high(max_pnode); |
388 | uv_system_inited = true; | ||
386 | } | 389 | } |
387 | 390 | ||
388 | /* | 391 | /* |
@@ -391,8 +394,7 @@ static __init void uv_system_init(void) | |||
391 | */ | 394 | */ |
392 | void __cpuinit uv_cpu_init(void) | 395 | void __cpuinit uv_cpu_init(void) |
393 | { | 396 | { |
394 | if (!uv_node_to_blade) | 397 | BUG_ON(!uv_system_inited); |
395 | uv_system_init(); | ||
396 | 398 | ||
397 | uv_blade_info[uv_numa_blade_id()].nr_online_cpus++; | 399 | uv_blade_info[uv_numa_blade_id()].nr_online_cpus++; |
398 | 400 | ||
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index 1b318e903bf6..9bfc4d72fb2e 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c | |||
@@ -88,6 +88,7 @@ void __init x86_64_start_kernel(char * real_mode_data) | |||
88 | BUILD_BUG_ON(!(MODULES_VADDR > __START_KERNEL)); | 88 | BUILD_BUG_ON(!(MODULES_VADDR > __START_KERNEL)); |
89 | BUILD_BUG_ON(!(((MODULES_END - 1) & PGDIR_MASK) == | 89 | BUILD_BUG_ON(!(((MODULES_END - 1) & PGDIR_MASK) == |
90 | (__START_KERNEL & PGDIR_MASK))); | 90 | (__START_KERNEL & PGDIR_MASK))); |
91 | BUILD_BUG_ON(__fix_to_virt(__end_of_fixed_addresses) <= MODULES_END); | ||
91 | 92 | ||
92 | /* clear bss before set_intr_gate with early_idt_handler */ | 93 | /* clear bss before set_intr_gate with early_idt_handler */ |
93 | clear_bss(); | 94 | clear_bss(); |
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index f67e93441caf..a7010c3a377a 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S | |||
@@ -456,9 +456,6 @@ is386: movl $2,%ecx # set MP | |||
456 | 1: | 456 | 1: |
457 | #endif /* CONFIG_SMP */ | 457 | #endif /* CONFIG_SMP */ |
458 | jmp *(initial_code) | 458 | jmp *(initial_code) |
459 | .align 4 | ||
460 | ENTRY(initial_code) | ||
461 | .long i386_start_kernel | ||
462 | 459 | ||
463 | /* | 460 | /* |
464 | * We depend on ET to be correct. This checks for 287/387. | 461 | * We depend on ET to be correct. This checks for 287/387. |
@@ -601,6 +598,11 @@ ignore_int: | |||
601 | #endif | 598 | #endif |
602 | iret | 599 | iret |
603 | 600 | ||
601 | .section .cpuinit.data,"wa" | ||
602 | .align 4 | ||
603 | ENTRY(initial_code) | ||
604 | .long i386_start_kernel | ||
605 | |||
604 | .section .text | 606 | .section .text |
605 | /* | 607 | /* |
606 | * Real beginning of normal "text" segment | 608 | * Real beginning of normal "text" segment |
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index ad2b15a1334d..73deaffadd03 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c | |||
@@ -210,8 +210,8 @@ static void hpet_legacy_clockevent_register(void) | |||
210 | /* Calculate the min / max delta */ | 210 | /* Calculate the min / max delta */ |
211 | hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF, | 211 | hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF, |
212 | &hpet_clockevent); | 212 | &hpet_clockevent); |
213 | hpet_clockevent.min_delta_ns = clockevent_delta2ns(0x30, | 213 | /* 5 usec minimum reprogramming delta. */ |
214 | &hpet_clockevent); | 214 | hpet_clockevent.min_delta_ns = 5000; |
215 | 215 | ||
216 | /* | 216 | /* |
217 | * Start hpet with the boot cpu mask and make it | 217 | * Start hpet with the boot cpu mask and make it |
@@ -270,15 +270,22 @@ static void hpet_legacy_set_mode(enum clock_event_mode mode, | |||
270 | } | 270 | } |
271 | 271 | ||
272 | static int hpet_legacy_next_event(unsigned long delta, | 272 | static int hpet_legacy_next_event(unsigned long delta, |
273 | struct clock_event_device *evt) | 273 | struct clock_event_device *evt) |
274 | { | 274 | { |
275 | unsigned long cnt; | 275 | u32 cnt; |
276 | 276 | ||
277 | cnt = hpet_readl(HPET_COUNTER); | 277 | cnt = hpet_readl(HPET_COUNTER); |
278 | cnt += delta; | 278 | cnt += (u32) delta; |
279 | hpet_writel(cnt, HPET_T0_CMP); | 279 | hpet_writel(cnt, HPET_T0_CMP); |
280 | 280 | ||
281 | return ((long)(hpet_readl(HPET_COUNTER) - cnt ) > 0) ? -ETIME : 0; | 281 | /* |
282 | * We need to read back the CMP register to make sure that | ||
283 | * what we wrote hit the chip before we compare it to the | ||
284 | * counter. | ||
285 | */ | ||
286 | WARN_ON((u32)hpet_readl(HPET_T0_CMP) != cnt); | ||
287 | |||
288 | return (s32)((u32)hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0; | ||
282 | } | 289 | } |
283 | 290 | ||
284 | /* | 291 | /* |
@@ -359,6 +366,7 @@ static int hpet_clocksource_register(void) | |||
359 | int __init hpet_enable(void) | 366 | int __init hpet_enable(void) |
360 | { | 367 | { |
361 | unsigned long id; | 368 | unsigned long id; |
369 | int i; | ||
362 | 370 | ||
363 | if (!is_hpet_capable()) | 371 | if (!is_hpet_capable()) |
364 | return 0; | 372 | return 0; |
@@ -369,6 +377,29 @@ int __init hpet_enable(void) | |||
369 | * Read the period and check for a sane value: | 377 | * Read the period and check for a sane value: |
370 | */ | 378 | */ |
371 | hpet_period = hpet_readl(HPET_PERIOD); | 379 | hpet_period = hpet_readl(HPET_PERIOD); |
380 | |||
381 | /* | ||
382 | * AMD SB700 based systems with spread spectrum enabled use a | ||
383 | * SMM based HPET emulation to provide proper frequency | ||
384 | * setting. The SMM code is initialized with the first HPET | ||
385 | * register access and takes some time to complete. During | ||
386 | * this time the config register reads 0xffffffff. We check | ||
387 | * for max. 1000 loops whether the config register reads a non | ||
388 | * 0xffffffff value to make sure that HPET is up and running | ||
389 | * before we go further. A counting loop is safe, as the HPET | ||
390 | * access takes thousands of CPU cycles. On non SB700 based | ||
391 | * machines this check is only done once and has no side | ||
392 | * effects. | ||
393 | */ | ||
394 | for (i = 0; hpet_readl(HPET_CFG) == 0xFFFFFFFF; i++) { | ||
395 | if (i == 1000) { | ||
396 | printk(KERN_WARNING | ||
397 | "HPET config register value = 0xFFFFFFFF. " | ||
398 | "Disabling HPET\n"); | ||
399 | goto out_nohpet; | ||
400 | } | ||
401 | } | ||
402 | |||
372 | if (hpet_period < HPET_MIN_PERIOD || hpet_period > HPET_MAX_PERIOD) | 403 | if (hpet_period < HPET_MIN_PERIOD || hpet_period > HPET_MAX_PERIOD) |
373 | goto out_nohpet; | 404 | goto out_nohpet; |
374 | 405 | ||
diff --git a/arch/x86/kernel/io_apic_32.c b/arch/x86/kernel/io_apic_32.c index de9aa0e3a9c5..09cddb57bec4 100644 --- a/arch/x86/kernel/io_apic_32.c +++ b/arch/x86/kernel/io_apic_32.c | |||
@@ -57,7 +57,7 @@ atomic_t irq_mis_count; | |||
57 | static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; | 57 | static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; |
58 | 58 | ||
59 | static DEFINE_SPINLOCK(ioapic_lock); | 59 | static DEFINE_SPINLOCK(ioapic_lock); |
60 | static DEFINE_SPINLOCK(vector_lock); | 60 | DEFINE_SPINLOCK(vector_lock); |
61 | 61 | ||
62 | int timer_through_8259 __initdata; | 62 | int timer_through_8259 __initdata; |
63 | 63 | ||
@@ -1209,10 +1209,6 @@ static int assign_irq_vector(int irq) | |||
1209 | return vector; | 1209 | return vector; |
1210 | } | 1210 | } |
1211 | 1211 | ||
1212 | void setup_vector_irq(int cpu) | ||
1213 | { | ||
1214 | } | ||
1215 | |||
1216 | static struct irq_chip ioapic_chip; | 1212 | static struct irq_chip ioapic_chip; |
1217 | 1213 | ||
1218 | #define IOAPIC_AUTO -1 | 1214 | #define IOAPIC_AUTO -1 |
diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c index 8269434d1707..61a83b70c18f 100644 --- a/arch/x86/kernel/io_apic_64.c +++ b/arch/x86/kernel/io_apic_64.c | |||
@@ -101,7 +101,7 @@ int timer_through_8259 __initdata; | |||
101 | static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; | 101 | static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; |
102 | 102 | ||
103 | static DEFINE_SPINLOCK(ioapic_lock); | 103 | static DEFINE_SPINLOCK(ioapic_lock); |
104 | DEFINE_SPINLOCK(vector_lock); | 104 | static DEFINE_SPINLOCK(vector_lock); |
105 | 105 | ||
106 | /* | 106 | /* |
107 | * # of IRQ routing registers | 107 | * # of IRQ routing registers |
@@ -697,6 +697,19 @@ static int pin_2_irq(int idx, int apic, int pin) | |||
697 | return irq; | 697 | return irq; |
698 | } | 698 | } |
699 | 699 | ||
700 | void lock_vector_lock(void) | ||
701 | { | ||
702 | /* Used to the online set of cpus does not change | ||
703 | * during assign_irq_vector. | ||
704 | */ | ||
705 | spin_lock(&vector_lock); | ||
706 | } | ||
707 | |||
708 | void unlock_vector_lock(void) | ||
709 | { | ||
710 | spin_unlock(&vector_lock); | ||
711 | } | ||
712 | |||
700 | static int __assign_irq_vector(int irq, cpumask_t mask) | 713 | static int __assign_irq_vector(int irq, cpumask_t mask) |
701 | { | 714 | { |
702 | /* | 715 | /* |
@@ -802,7 +815,7 @@ static void __clear_irq_vector(int irq) | |||
802 | cpus_clear(cfg->domain); | 815 | cpus_clear(cfg->domain); |
803 | } | 816 | } |
804 | 817 | ||
805 | static void __setup_vector_irq(int cpu) | 818 | void __setup_vector_irq(int cpu) |
806 | { | 819 | { |
807 | /* Initialize vector_irq on a new cpu */ | 820 | /* Initialize vector_irq on a new cpu */ |
808 | /* This function must be called with vector_lock held */ | 821 | /* This function must be called with vector_lock held */ |
@@ -825,14 +838,6 @@ static void __setup_vector_irq(int cpu) | |||
825 | } | 838 | } |
826 | } | 839 | } |
827 | 840 | ||
828 | void setup_vector_irq(int cpu) | ||
829 | { | ||
830 | spin_lock(&vector_lock); | ||
831 | __setup_vector_irq(smp_processor_id()); | ||
832 | spin_unlock(&vector_lock); | ||
833 | } | ||
834 | |||
835 | |||
836 | static struct irq_chip ioapic_chip; | 841 | static struct irq_chip ioapic_chip; |
837 | 842 | ||
838 | static void ioapic_register_intr(int irq, unsigned long trigger) | 843 | static void ioapic_register_intr(int irq, unsigned long trigger) |
diff --git a/arch/x86/kernel/io_delay.c b/arch/x86/kernel/io_delay.c index 1c3a66a67f83..720d2607aacb 100644 --- a/arch/x86/kernel/io_delay.c +++ b/arch/x86/kernel/io_delay.c | |||
@@ -92,6 +92,14 @@ static struct dmi_system_id __initdata io_delay_0xed_port_dmi_table[] = { | |||
92 | DMI_MATCH(DMI_BOARD_NAME, "30BF") | 92 | DMI_MATCH(DMI_BOARD_NAME, "30BF") |
93 | } | 93 | } |
94 | }, | 94 | }, |
95 | { | ||
96 | .callback = dmi_io_delay_0xed_port, | ||
97 | .ident = "Presario F700", | ||
98 | .matches = { | ||
99 | DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"), | ||
100 | DMI_MATCH(DMI_BOARD_NAME, "30D3") | ||
101 | } | ||
102 | }, | ||
95 | { } | 103 | { } |
96 | }; | 104 | }; |
97 | 105 | ||
diff --git a/arch/x86/kernel/kdebugfs.c b/arch/x86/kernel/kdebugfs.c index f2d43bc75514..ff7d3b0124f1 100644 --- a/arch/x86/kernel/kdebugfs.c +++ b/arch/x86/kernel/kdebugfs.c | |||
@@ -139,6 +139,7 @@ static int __init create_setup_data_nodes(struct dentry *parent) | |||
139 | if (PageHighMem(pg)) { | 139 | if (PageHighMem(pg)) { |
140 | data = ioremap_cache(pa_data, sizeof(*data)); | 140 | data = ioremap_cache(pa_data, sizeof(*data)); |
141 | if (!data) { | 141 | if (!data) { |
142 | kfree(node); | ||
142 | error = -ENXIO; | 143 | error = -ENXIO; |
143 | goto err_dir; | 144 | goto err_dir; |
144 | } | 145 | } |
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c index 43c019f85f0d..6c27679ec6aa 100644 --- a/arch/x86/kernel/kprobes.c +++ b/arch/x86/kernel/kprobes.c | |||
@@ -431,7 +431,6 @@ static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs) | |||
431 | regs->ip = (unsigned long)p->ainsn.insn; | 431 | regs->ip = (unsigned long)p->ainsn.insn; |
432 | } | 432 | } |
433 | 433 | ||
434 | /* Called with kretprobe_lock held */ | ||
435 | void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, | 434 | void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, |
436 | struct pt_regs *regs) | 435 | struct pt_regs *regs) |
437 | { | 436 | { |
@@ -682,8 +681,7 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs) | |||
682 | unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline; | 681 | unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline; |
683 | 682 | ||
684 | INIT_HLIST_HEAD(&empty_rp); | 683 | INIT_HLIST_HEAD(&empty_rp); |
685 | spin_lock_irqsave(&kretprobe_lock, flags); | 684 | kretprobe_hash_lock(current, &head, &flags); |
686 | head = kretprobe_inst_table_head(current); | ||
687 | /* fixup registers */ | 685 | /* fixup registers */ |
688 | #ifdef CONFIG_X86_64 | 686 | #ifdef CONFIG_X86_64 |
689 | regs->cs = __KERNEL_CS; | 687 | regs->cs = __KERNEL_CS; |
@@ -732,7 +730,7 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs) | |||
732 | 730 | ||
733 | kretprobe_assert(ri, orig_ret_address, trampoline_address); | 731 | kretprobe_assert(ri, orig_ret_address, trampoline_address); |
734 | 732 | ||
735 | spin_unlock_irqrestore(&kretprobe_lock, flags); | 733 | kretprobe_hash_unlock(current, &flags); |
736 | 734 | ||
737 | hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) { | 735 | hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) { |
738 | hlist_del(&ri->hlist); | 736 | hlist_del(&ri->hlist); |
diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c index 3fee2aa50f3f..b68e21f06f4f 100644 --- a/arch/x86/kernel/ldt.c +++ b/arch/x86/kernel/ldt.c | |||
@@ -62,12 +62,10 @@ static int alloc_ldt(mm_context_t *pc, int mincount, int reload) | |||
62 | 62 | ||
63 | if (reload) { | 63 | if (reload) { |
64 | #ifdef CONFIG_SMP | 64 | #ifdef CONFIG_SMP |
65 | cpumask_of_cpu_ptr_declare(mask); | ||
66 | |||
67 | preempt_disable(); | 65 | preempt_disable(); |
68 | load_LDT(pc); | 66 | load_LDT(pc); |
69 | cpumask_of_cpu_ptr_next(mask, smp_processor_id()); | 67 | if (!cpus_equal(current->mm->cpu_vm_mask, |
70 | if (!cpus_equal(current->mm->cpu_vm_mask, *mask)) | 68 | cpumask_of_cpu(smp_processor_id()))) |
71 | smp_call_function(flush_ldt, current->mm, 1); | 69 | smp_call_function(flush_ldt, current->mm, 1); |
72 | preempt_enable(); | 70 | preempt_enable(); |
73 | #else | 71 | #else |
diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c index 8864230d55af..0732adba05ca 100644 --- a/arch/x86/kernel/machine_kexec_32.c +++ b/arch/x86/kernel/machine_kexec_32.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/numa.h> | 13 | #include <linux/numa.h> |
14 | #include <linux/ftrace.h> | 14 | #include <linux/ftrace.h> |
15 | #include <linux/suspend.h> | ||
15 | 16 | ||
16 | #include <asm/pgtable.h> | 17 | #include <asm/pgtable.h> |
17 | #include <asm/pgalloc.h> | 18 | #include <asm/pgalloc.h> |
@@ -22,6 +23,7 @@ | |||
22 | #include <asm/cpufeature.h> | 23 | #include <asm/cpufeature.h> |
23 | #include <asm/desc.h> | 24 | #include <asm/desc.h> |
24 | #include <asm/system.h> | 25 | #include <asm/system.h> |
26 | #include <asm/cacheflush.h> | ||
25 | 27 | ||
26 | #define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE))) | 28 | #define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE))) |
27 | static u32 kexec_pgd[1024] PAGE_ALIGNED; | 29 | static u32 kexec_pgd[1024] PAGE_ALIGNED; |
@@ -77,7 +79,7 @@ static void load_segments(void) | |||
77 | /* | 79 | /* |
78 | * A architecture hook called to validate the | 80 | * A architecture hook called to validate the |
79 | * proposed image and prepare the control pages | 81 | * proposed image and prepare the control pages |
80 | * as needed. The pages for KEXEC_CONTROL_CODE_SIZE | 82 | * as needed. The pages for KEXEC_CONTROL_PAGE_SIZE |
81 | * have been allocated, but the segments have yet | 83 | * have been allocated, but the segments have yet |
82 | * been copied into the kernel. | 84 | * been copied into the kernel. |
83 | * | 85 | * |
@@ -85,10 +87,12 @@ static void load_segments(void) | |||
85 | * reboot code buffer to allow us to avoid allocations | 87 | * reboot code buffer to allow us to avoid allocations |
86 | * later. | 88 | * later. |
87 | * | 89 | * |
88 | * Currently nothing. | 90 | * Make control page executable. |
89 | */ | 91 | */ |
90 | int machine_kexec_prepare(struct kimage *image) | 92 | int machine_kexec_prepare(struct kimage *image) |
91 | { | 93 | { |
94 | if (nx_enabled) | ||
95 | set_pages_x(image->control_code_page, 1); | ||
92 | return 0; | 96 | return 0; |
93 | } | 97 | } |
94 | 98 | ||
@@ -98,27 +102,54 @@ int machine_kexec_prepare(struct kimage *image) | |||
98 | */ | 102 | */ |
99 | void machine_kexec_cleanup(struct kimage *image) | 103 | void machine_kexec_cleanup(struct kimage *image) |
100 | { | 104 | { |
105 | if (nx_enabled) | ||
106 | set_pages_nx(image->control_code_page, 1); | ||
101 | } | 107 | } |
102 | 108 | ||
103 | /* | 109 | /* |
104 | * Do not allocate memory (or fail in any way) in machine_kexec(). | 110 | * Do not allocate memory (or fail in any way) in machine_kexec(). |
105 | * We are past the point of no return, committed to rebooting now. | 111 | * We are past the point of no return, committed to rebooting now. |
106 | */ | 112 | */ |
107 | NORET_TYPE void machine_kexec(struct kimage *image) | 113 | void machine_kexec(struct kimage *image) |
108 | { | 114 | { |
109 | unsigned long page_list[PAGES_NR]; | 115 | unsigned long page_list[PAGES_NR]; |
110 | void *control_page; | 116 | void *control_page; |
117 | int save_ftrace_enabled; | ||
118 | asmlinkage unsigned long | ||
119 | (*relocate_kernel_ptr)(unsigned long indirection_page, | ||
120 | unsigned long control_page, | ||
121 | unsigned long start_address, | ||
122 | unsigned int has_pae, | ||
123 | unsigned int preserve_context); | ||
124 | |||
125 | #ifdef CONFIG_KEXEC_JUMP | ||
126 | if (kexec_image->preserve_context) | ||
127 | save_processor_state(); | ||
128 | #endif | ||
111 | 129 | ||
112 | tracer_disable(); | 130 | save_ftrace_enabled = __ftrace_enabled_save(); |
113 | 131 | ||
114 | /* Interrupts aren't acceptable while we reboot */ | 132 | /* Interrupts aren't acceptable while we reboot */ |
115 | local_irq_disable(); | 133 | local_irq_disable(); |
116 | 134 | ||
135 | if (image->preserve_context) { | ||
136 | #ifdef CONFIG_X86_IO_APIC | ||
137 | /* We need to put APICs in legacy mode so that we can | ||
138 | * get timer interrupts in second kernel. kexec/kdump | ||
139 | * paths already have calls to disable_IO_APIC() in | ||
140 | * one form or other. kexec jump path also need | ||
141 | * one. | ||
142 | */ | ||
143 | disable_IO_APIC(); | ||
144 | #endif | ||
145 | } | ||
146 | |||
117 | control_page = page_address(image->control_code_page); | 147 | control_page = page_address(image->control_code_page); |
118 | memcpy(control_page, relocate_kernel, PAGE_SIZE); | 148 | memcpy(control_page, relocate_kernel, KEXEC_CONTROL_CODE_MAX_SIZE); |
119 | 149 | ||
150 | relocate_kernel_ptr = control_page; | ||
120 | page_list[PA_CONTROL_PAGE] = __pa(control_page); | 151 | page_list[PA_CONTROL_PAGE] = __pa(control_page); |
121 | page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel; | 152 | page_list[VA_CONTROL_PAGE] = (unsigned long)control_page; |
122 | page_list[PA_PGD] = __pa(kexec_pgd); | 153 | page_list[PA_PGD] = __pa(kexec_pgd); |
123 | page_list[VA_PGD] = (unsigned long)kexec_pgd; | 154 | page_list[VA_PGD] = (unsigned long)kexec_pgd; |
124 | #ifdef CONFIG_X86_PAE | 155 | #ifdef CONFIG_X86_PAE |
@@ -131,6 +162,7 @@ NORET_TYPE void machine_kexec(struct kimage *image) | |||
131 | page_list[VA_PTE_0] = (unsigned long)kexec_pte0; | 162 | page_list[VA_PTE_0] = (unsigned long)kexec_pte0; |
132 | page_list[PA_PTE_1] = __pa(kexec_pte1); | 163 | page_list[PA_PTE_1] = __pa(kexec_pte1); |
133 | page_list[VA_PTE_1] = (unsigned long)kexec_pte1; | 164 | page_list[VA_PTE_1] = (unsigned long)kexec_pte1; |
165 | page_list[PA_SWAP_PAGE] = (page_to_pfn(image->swap_page) << PAGE_SHIFT); | ||
134 | 166 | ||
135 | /* The segment registers are funny things, they have both a | 167 | /* The segment registers are funny things, they have both a |
136 | * visible and an invisible part. Whenever the visible part is | 168 | * visible and an invisible part. Whenever the visible part is |
@@ -149,8 +181,17 @@ NORET_TYPE void machine_kexec(struct kimage *image) | |||
149 | set_idt(phys_to_virt(0),0); | 181 | set_idt(phys_to_virt(0),0); |
150 | 182 | ||
151 | /* now call it */ | 183 | /* now call it */ |
152 | relocate_kernel((unsigned long)image->head, (unsigned long)page_list, | 184 | image->start = relocate_kernel_ptr((unsigned long)image->head, |
153 | image->start, cpu_has_pae); | 185 | (unsigned long)page_list, |
186 | image->start, cpu_has_pae, | ||
187 | image->preserve_context); | ||
188 | |||
189 | #ifdef CONFIG_KEXEC_JUMP | ||
190 | if (kexec_image->preserve_context) | ||
191 | restore_processor_state(); | ||
192 | #endif | ||
193 | |||
194 | __ftrace_enabled_restore(save_ftrace_enabled); | ||
154 | } | 195 | } |
155 | 196 | ||
156 | void arch_crash_save_vmcoreinfo(void) | 197 | void arch_crash_save_vmcoreinfo(void) |
diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c index 9dd9262693a3..c43caa3a91f3 100644 --- a/arch/x86/kernel/machine_kexec_64.c +++ b/arch/x86/kernel/machine_kexec_64.c | |||
@@ -181,7 +181,7 @@ void machine_kexec_cleanup(struct kimage *image) | |||
181 | * Do not allocate memory (or fail in any way) in machine_kexec(). | 181 | * Do not allocate memory (or fail in any way) in machine_kexec(). |
182 | * We are past the point of no return, committed to rebooting now. | 182 | * We are past the point of no return, committed to rebooting now. |
183 | */ | 183 | */ |
184 | NORET_TYPE void machine_kexec(struct kimage *image) | 184 | void machine_kexec(struct kimage *image) |
185 | { | 185 | { |
186 | unsigned long page_list[PAGES_NR]; | 186 | unsigned long page_list[PAGES_NR]; |
187 | void *control_page; | 187 | void *control_page; |
diff --git a/arch/x86/kernel/mfgpt_32.c b/arch/x86/kernel/mfgpt_32.c index 07c0f828f488..3b599518c322 100644 --- a/arch/x86/kernel/mfgpt_32.c +++ b/arch/x86/kernel/mfgpt_32.c | |||
@@ -33,6 +33,8 @@ | |||
33 | #include <linux/module.h> | 33 | #include <linux/module.h> |
34 | #include <asm/geode.h> | 34 | #include <asm/geode.h> |
35 | 35 | ||
36 | #define MFGPT_DEFAULT_IRQ 7 | ||
37 | |||
36 | static struct mfgpt_timer_t { | 38 | static struct mfgpt_timer_t { |
37 | unsigned int avail:1; | 39 | unsigned int avail:1; |
38 | } mfgpt_timers[MFGPT_MAX_TIMERS]; | 40 | } mfgpt_timers[MFGPT_MAX_TIMERS]; |
@@ -157,29 +159,48 @@ int geode_mfgpt_toggle_event(int timer, int cmp, int event, int enable) | |||
157 | } | 159 | } |
158 | EXPORT_SYMBOL_GPL(geode_mfgpt_toggle_event); | 160 | EXPORT_SYMBOL_GPL(geode_mfgpt_toggle_event); |
159 | 161 | ||
160 | int geode_mfgpt_set_irq(int timer, int cmp, int irq, int enable) | 162 | int geode_mfgpt_set_irq(int timer, int cmp, int *irq, int enable) |
161 | { | 163 | { |
162 | u32 val, dummy; | 164 | u32 zsel, lpc, dummy; |
163 | int offset; | 165 | int shift; |
164 | 166 | ||
165 | if (timer < 0 || timer >= MFGPT_MAX_TIMERS) | 167 | if (timer < 0 || timer >= MFGPT_MAX_TIMERS) |
166 | return -EIO; | 168 | return -EIO; |
167 | 169 | ||
168 | if (geode_mfgpt_toggle_event(timer, cmp, MFGPT_EVENT_IRQ, enable)) | 170 | /* |
171 | * Unfortunately, MFGPTs come in pairs sharing their IRQ lines. If VSA | ||
172 | * is using the same CMP of the timer's Siamese twin, the IRQ is set to | ||
173 | * 2, and we mustn't use nor change it. | ||
174 | * XXX: Likewise, 2 Linux drivers might clash if the 2nd overwrites the | ||
175 | * IRQ of the 1st. This can only happen if forcing an IRQ, calling this | ||
176 | * with *irq==0 is safe. Currently there _are_ no 2 drivers. | ||
177 | */ | ||
178 | rdmsr(MSR_PIC_ZSEL_LOW, zsel, dummy); | ||
179 | shift = ((cmp == MFGPT_CMP1 ? 0 : 4) + timer % 4) * 4; | ||
180 | if (((zsel >> shift) & 0xF) == 2) | ||
169 | return -EIO; | 181 | return -EIO; |
170 | 182 | ||
171 | rdmsr(MSR_PIC_ZSEL_LOW, val, dummy); | 183 | /* Choose IRQ: if none supplied, keep IRQ already set or use default */ |
184 | if (!*irq) | ||
185 | *irq = (zsel >> shift) & 0xF; | ||
186 | if (!*irq) | ||
187 | *irq = MFGPT_DEFAULT_IRQ; | ||
172 | 188 | ||
173 | offset = (timer % 4) * 4; | 189 | /* Can't use IRQ if it's 0 (=disabled), 2, or routed to LPC */ |
174 | 190 | if (*irq < 1 || *irq == 2 || *irq > 15) | |
175 | val &= ~((0xF << offset) | (0xF << (offset + 16))); | 191 | return -EIO; |
192 | rdmsr(MSR_PIC_IRQM_LPC, lpc, dummy); | ||
193 | if (lpc & (1 << *irq)) | ||
194 | return -EIO; | ||
176 | 195 | ||
196 | /* All chosen and checked - go for it */ | ||
197 | if (geode_mfgpt_toggle_event(timer, cmp, MFGPT_EVENT_IRQ, enable)) | ||
198 | return -EIO; | ||
177 | if (enable) { | 199 | if (enable) { |
178 | val |= (irq & 0x0F) << (offset); | 200 | zsel = (zsel & ~(0xF << shift)) | (*irq << shift); |
179 | val |= (irq & 0x0F) << (offset + 16); | 201 | wrmsr(MSR_PIC_ZSEL_LOW, zsel, dummy); |
180 | } | 202 | } |
181 | 203 | ||
182 | wrmsr(MSR_PIC_ZSEL_LOW, val, dummy); | ||
183 | return 0; | 204 | return 0; |
184 | } | 205 | } |
185 | 206 | ||
@@ -242,7 +263,7 @@ EXPORT_SYMBOL_GPL(geode_mfgpt_alloc_timer); | |||
242 | static unsigned int mfgpt_tick_mode = CLOCK_EVT_MODE_SHUTDOWN; | 263 | static unsigned int mfgpt_tick_mode = CLOCK_EVT_MODE_SHUTDOWN; |
243 | static u16 mfgpt_event_clock; | 264 | static u16 mfgpt_event_clock; |
244 | 265 | ||
245 | static int irq = 7; | 266 | static int irq; |
246 | static int __init mfgpt_setup(char *str) | 267 | static int __init mfgpt_setup(char *str) |
247 | { | 268 | { |
248 | get_option(&str, &irq); | 269 | get_option(&str, &irq); |
@@ -346,7 +367,7 @@ int __init mfgpt_timer_setup(void) | |||
346 | mfgpt_event_clock = timer; | 367 | mfgpt_event_clock = timer; |
347 | 368 | ||
348 | /* Set up the IRQ on the MFGPT side */ | 369 | /* Set up the IRQ on the MFGPT side */ |
349 | if (geode_mfgpt_setup_irq(mfgpt_event_clock, MFGPT_CMP2, irq)) { | 370 | if (geode_mfgpt_setup_irq(mfgpt_event_clock, MFGPT_CMP2, &irq)) { |
350 | printk(KERN_ERR "mfgpt-timer: Could not set up IRQ %d\n", irq); | 371 | printk(KERN_ERR "mfgpt-timer: Could not set up IRQ %d\n", irq); |
351 | return -EIO; | 372 | return -EIO; |
352 | } | 373 | } |
@@ -374,13 +395,14 @@ int __init mfgpt_timer_setup(void) | |||
374 | &mfgpt_clockevent); | 395 | &mfgpt_clockevent); |
375 | 396 | ||
376 | printk(KERN_INFO | 397 | printk(KERN_INFO |
377 | "mfgpt-timer: registering the MFGPT timer as a clock event.\n"); | 398 | "mfgpt-timer: Registering MFGPT timer %d as a clock event, using IRQ %d\n", |
399 | timer, irq); | ||
378 | clockevents_register_device(&mfgpt_clockevent); | 400 | clockevents_register_device(&mfgpt_clockevent); |
379 | 401 | ||
380 | return 0; | 402 | return 0; |
381 | 403 | ||
382 | err: | 404 | err: |
383 | geode_mfgpt_release_irq(mfgpt_event_clock, MFGPT_CMP2, irq); | 405 | geode_mfgpt_release_irq(mfgpt_event_clock, MFGPT_CMP2, &irq); |
384 | printk(KERN_ERR | 406 | printk(KERN_ERR |
385 | "mfgpt-timer: Unable to set up the MFGPT clock source\n"); | 407 | "mfgpt-timer: Unable to set up the MFGPT clock source\n"); |
386 | return -EIO; | 408 | return -EIO; |
diff --git a/arch/x86/kernel/microcode.c b/arch/x86/kernel/microcode.c index 6994c751590e..652fa5c38ebe 100644 --- a/arch/x86/kernel/microcode.c +++ b/arch/x86/kernel/microcode.c | |||
@@ -388,7 +388,6 @@ static int do_microcode_update (void) | |||
388 | void *new_mc = NULL; | 388 | void *new_mc = NULL; |
389 | int cpu; | 389 | int cpu; |
390 | cpumask_t old; | 390 | cpumask_t old; |
391 | cpumask_of_cpu_ptr_declare(newmask); | ||
392 | 391 | ||
393 | old = current->cpus_allowed; | 392 | old = current->cpus_allowed; |
394 | 393 | ||
@@ -405,8 +404,7 @@ static int do_microcode_update (void) | |||
405 | 404 | ||
406 | if (!uci->valid) | 405 | if (!uci->valid) |
407 | continue; | 406 | continue; |
408 | cpumask_of_cpu_ptr_next(newmask, cpu); | 407 | set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu)); |
409 | set_cpus_allowed_ptr(current, newmask); | ||
410 | error = get_maching_microcode(new_mc, cpu); | 408 | error = get_maching_microcode(new_mc, cpu); |
411 | if (error < 0) | 409 | if (error < 0) |
412 | goto out; | 410 | goto out; |
@@ -576,7 +574,6 @@ static int apply_microcode_check_cpu(int cpu) | |||
576 | struct cpuinfo_x86 *c = &cpu_data(cpu); | 574 | struct cpuinfo_x86 *c = &cpu_data(cpu); |
577 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | 575 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; |
578 | cpumask_t old; | 576 | cpumask_t old; |
579 | cpumask_of_cpu_ptr(newmask, cpu); | ||
580 | unsigned int val[2]; | 577 | unsigned int val[2]; |
581 | int err = 0; | 578 | int err = 0; |
582 | 579 | ||
@@ -585,7 +582,7 @@ static int apply_microcode_check_cpu(int cpu) | |||
585 | return 0; | 582 | return 0; |
586 | 583 | ||
587 | old = current->cpus_allowed; | 584 | old = current->cpus_allowed; |
588 | set_cpus_allowed_ptr(current, newmask); | 585 | set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu)); |
589 | 586 | ||
590 | /* Check if the microcode we have in memory matches the CPU */ | 587 | /* Check if the microcode we have in memory matches the CPU */ |
591 | if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 || | 588 | if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 || |
@@ -623,12 +620,11 @@ static int apply_microcode_check_cpu(int cpu) | |||
623 | static void microcode_init_cpu(int cpu, int resume) | 620 | static void microcode_init_cpu(int cpu, int resume) |
624 | { | 621 | { |
625 | cpumask_t old; | 622 | cpumask_t old; |
626 | cpumask_of_cpu_ptr(newmask, cpu); | ||
627 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | 623 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; |
628 | 624 | ||
629 | old = current->cpus_allowed; | 625 | old = current->cpus_allowed; |
630 | 626 | ||
631 | set_cpus_allowed_ptr(current, newmask); | 627 | set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu)); |
632 | mutex_lock(µcode_mutex); | 628 | mutex_lock(µcode_mutex); |
633 | collect_cpu_info(cpu); | 629 | collect_cpu_info(cpu); |
634 | if (uci->valid && system_state == SYSTEM_RUNNING && !resume) | 630 | if (uci->valid && system_state == SYSTEM_RUNNING && !resume) |
@@ -661,13 +657,10 @@ static ssize_t reload_store(struct sys_device *dev, | |||
661 | if (end == buf) | 657 | if (end == buf) |
662 | return -EINVAL; | 658 | return -EINVAL; |
663 | if (val == 1) { | 659 | if (val == 1) { |
664 | cpumask_t old; | 660 | cpumask_t old = current->cpus_allowed; |
665 | cpumask_of_cpu_ptr(newmask, cpu); | ||
666 | |||
667 | old = current->cpus_allowed; | ||
668 | 661 | ||
669 | get_online_cpus(); | 662 | get_online_cpus(); |
670 | set_cpus_allowed_ptr(current, newmask); | 663 | set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu)); |
671 | 664 | ||
672 | mutex_lock(µcode_mutex); | 665 | mutex_lock(µcode_mutex); |
673 | if (uci->valid) | 666 | if (uci->valid) |
diff --git a/arch/x86/kernel/mmconf-fam10h_64.c b/arch/x86/kernel/mmconf-fam10h_64.c index fdfdc550b366..efc2f361fe85 100644 --- a/arch/x86/kernel/mmconf-fam10h_64.c +++ b/arch/x86/kernel/mmconf-fam10h_64.c | |||
@@ -238,7 +238,7 @@ static struct dmi_system_id __devinitdata mmconf_dmi_table[] = { | |||
238 | {} | 238 | {} |
239 | }; | 239 | }; |
240 | 240 | ||
241 | void __init check_enable_amd_mmconf_dmi(void) | 241 | void __cpuinit check_enable_amd_mmconf_dmi(void) |
242 | { | 242 | { |
243 | dmi_check_system(mmconf_dmi_table); | 243 | dmi_check_system(mmconf_dmi_table); |
244 | } | 244 | } |
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index 6ae005ccaed8..b3fb430725cb 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c | |||
@@ -49,7 +49,7 @@ static int __init mpf_checksum(unsigned char *mp, int len) | |||
49 | return sum & 0xFF; | 49 | return sum & 0xFF; |
50 | } | 50 | } |
51 | 51 | ||
52 | static void __cpuinit MP_processor_info(struct mpc_config_processor *m) | 52 | static void __init MP_processor_info(struct mpc_config_processor *m) |
53 | { | 53 | { |
54 | int apicid; | 54 | int apicid; |
55 | char *bootup_cpu = ""; | 55 | char *bootup_cpu = ""; |
@@ -83,7 +83,7 @@ static void __init MP_bus_info(struct mpc_config_bus *m) | |||
83 | if (x86_quirks->mpc_oem_bus_info) | 83 | if (x86_quirks->mpc_oem_bus_info) |
84 | x86_quirks->mpc_oem_bus_info(m, str); | 84 | x86_quirks->mpc_oem_bus_info(m, str); |
85 | else | 85 | else |
86 | printk(KERN_INFO "Bus #%d is %s\n", m->mpc_busid, str); | 86 | apic_printk(APIC_VERBOSE, "Bus #%d is %s\n", m->mpc_busid, str); |
87 | 87 | ||
88 | #if MAX_MP_BUSSES < 256 | 88 | #if MAX_MP_BUSSES < 256 |
89 | if (m->mpc_busid >= MAX_MP_BUSSES) { | 89 | if (m->mpc_busid >= MAX_MP_BUSSES) { |
@@ -154,7 +154,7 @@ static void __init MP_ioapic_info(struct mpc_config_ioapic *m) | |||
154 | 154 | ||
155 | static void print_MP_intsrc_info(struct mpc_config_intsrc *m) | 155 | static void print_MP_intsrc_info(struct mpc_config_intsrc *m) |
156 | { | 156 | { |
157 | printk(KERN_CONT "Int: type %d, pol %d, trig %d, bus %02x," | 157 | apic_printk(APIC_VERBOSE, "Int: type %d, pol %d, trig %d, bus %02x," |
158 | " IRQ %02x, APIC ID %x, APIC INT %02x\n", | 158 | " IRQ %02x, APIC ID %x, APIC INT %02x\n", |
159 | m->mpc_irqtype, m->mpc_irqflag & 3, | 159 | m->mpc_irqtype, m->mpc_irqflag & 3, |
160 | (m->mpc_irqflag >> 2) & 3, m->mpc_srcbus, | 160 | (m->mpc_irqflag >> 2) & 3, m->mpc_srcbus, |
@@ -163,7 +163,7 @@ static void print_MP_intsrc_info(struct mpc_config_intsrc *m) | |||
163 | 163 | ||
164 | static void __init print_mp_irq_info(struct mp_config_intsrc *mp_irq) | 164 | static void __init print_mp_irq_info(struct mp_config_intsrc *mp_irq) |
165 | { | 165 | { |
166 | printk(KERN_CONT "Int: type %d, pol %d, trig %d, bus %02x," | 166 | apic_printk(APIC_VERBOSE, "Int: type %d, pol %d, trig %d, bus %02x," |
167 | " IRQ %02x, APIC ID %x, APIC INT %02x\n", | 167 | " IRQ %02x, APIC ID %x, APIC INT %02x\n", |
168 | mp_irq->mp_irqtype, mp_irq->mp_irqflag & 3, | 168 | mp_irq->mp_irqtype, mp_irq->mp_irqflag & 3, |
169 | (mp_irq->mp_irqflag >> 2) & 3, mp_irq->mp_srcbus, | 169 | (mp_irq->mp_irqflag >> 2) & 3, mp_irq->mp_srcbus, |
@@ -235,7 +235,7 @@ static void __init MP_intsrc_info(struct mpc_config_intsrc *m) | |||
235 | 235 | ||
236 | static void __init MP_lintsrc_info(struct mpc_config_lintsrc *m) | 236 | static void __init MP_lintsrc_info(struct mpc_config_lintsrc *m) |
237 | { | 237 | { |
238 | printk(KERN_INFO "Lint: type %d, pol %d, trig %d, bus %02x," | 238 | apic_printk(APIC_VERBOSE, "Lint: type %d, pol %d, trig %d, bus %02x," |
239 | " IRQ %02x, APIC ID %x, APIC LINT %02x\n", | 239 | " IRQ %02x, APIC ID %x, APIC LINT %02x\n", |
240 | m->mpc_irqtype, m->mpc_irqflag & 3, | 240 | m->mpc_irqtype, m->mpc_irqflag & 3, |
241 | (m->mpc_irqflag >> 2) & 3, m->mpc_srcbusid, | 241 | (m->mpc_irqflag >> 2) & 3, m->mpc_srcbusid, |
@@ -484,7 +484,7 @@ static void __init construct_default_ioirq_mptable(int mpc_default_type) | |||
484 | } | 484 | } |
485 | 485 | ||
486 | 486 | ||
487 | static void construct_ioapic_table(int mpc_default_type) | 487 | static void __init construct_ioapic_table(int mpc_default_type) |
488 | { | 488 | { |
489 | struct mpc_config_ioapic ioapic; | 489 | struct mpc_config_ioapic ioapic; |
490 | struct mpc_config_bus bus; | 490 | struct mpc_config_bus bus; |
@@ -529,7 +529,7 @@ static void construct_ioapic_table(int mpc_default_type) | |||
529 | construct_default_ioirq_mptable(mpc_default_type); | 529 | construct_default_ioirq_mptable(mpc_default_type); |
530 | } | 530 | } |
531 | #else | 531 | #else |
532 | static inline void construct_ioapic_table(int mpc_default_type) { } | 532 | static inline void __init construct_ioapic_table(int mpc_default_type) { } |
533 | #endif | 533 | #endif |
534 | 534 | ||
535 | static inline void __init construct_default_ISA_mptable(int mpc_default_type) | 535 | static inline void __init construct_default_ISA_mptable(int mpc_default_type) |
@@ -695,7 +695,8 @@ static int __init smp_scan_config(unsigned long base, unsigned long length, | |||
695 | unsigned int *bp = phys_to_virt(base); | 695 | unsigned int *bp = phys_to_virt(base); |
696 | struct intel_mp_floating *mpf; | 696 | struct intel_mp_floating *mpf; |
697 | 697 | ||
698 | printk(KERN_DEBUG "Scan SMP from %p for %ld bytes.\n", bp, length); | 698 | apic_printk(APIC_VERBOSE, "Scan SMP from %p for %ld bytes.\n", |
699 | bp, length); | ||
699 | BUILD_BUG_ON(sizeof(*mpf) != 16); | 700 | BUILD_BUG_ON(sizeof(*mpf) != 16); |
700 | 701 | ||
701 | while (length > 0) { | 702 | while (length > 0) { |
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c index 9fd809552447..2e2af5d18191 100644 --- a/arch/x86/kernel/msr.c +++ b/arch/x86/kernel/msr.c | |||
@@ -72,21 +72,28 @@ static ssize_t msr_read(struct file *file, char __user *buf, | |||
72 | u32 data[2]; | 72 | u32 data[2]; |
73 | u32 reg = *ppos; | 73 | u32 reg = *ppos; |
74 | int cpu = iminor(file->f_path.dentry->d_inode); | 74 | int cpu = iminor(file->f_path.dentry->d_inode); |
75 | int err; | 75 | int err = 0; |
76 | ssize_t bytes = 0; | ||
76 | 77 | ||
77 | if (count % 8) | 78 | if (count % 8) |
78 | return -EINVAL; /* Invalid chunk size */ | 79 | return -EINVAL; /* Invalid chunk size */ |
79 | 80 | ||
80 | for (; count; count -= 8) { | 81 | for (; count; count -= 8) { |
81 | err = rdmsr_safe_on_cpu(cpu, reg, &data[0], &data[1]); | 82 | err = rdmsr_safe_on_cpu(cpu, reg, &data[0], &data[1]); |
82 | if (err) | 83 | if (err) { |
83 | return -EIO; | 84 | if (err == -EFAULT) /* Fix idiotic error code */ |
84 | if (copy_to_user(tmp, &data, 8)) | 85 | err = -EIO; |
85 | return -EFAULT; | 86 | break; |
87 | } | ||
88 | if (copy_to_user(tmp, &data, 8)) { | ||
89 | err = -EFAULT; | ||
90 | break; | ||
91 | } | ||
86 | tmp += 2; | 92 | tmp += 2; |
93 | bytes += 8; | ||
87 | } | 94 | } |
88 | 95 | ||
89 | return ((char __user *)tmp) - buf; | 96 | return bytes ? bytes : err; |
90 | } | 97 | } |
91 | 98 | ||
92 | static ssize_t msr_write(struct file *file, const char __user *buf, | 99 | static ssize_t msr_write(struct file *file, const char __user *buf, |
@@ -96,21 +103,28 @@ static ssize_t msr_write(struct file *file, const char __user *buf, | |||
96 | u32 data[2]; | 103 | u32 data[2]; |
97 | u32 reg = *ppos; | 104 | u32 reg = *ppos; |
98 | int cpu = iminor(file->f_path.dentry->d_inode); | 105 | int cpu = iminor(file->f_path.dentry->d_inode); |
99 | int err; | 106 | int err = 0; |
107 | ssize_t bytes = 0; | ||
100 | 108 | ||
101 | if (count % 8) | 109 | if (count % 8) |
102 | return -EINVAL; /* Invalid chunk size */ | 110 | return -EINVAL; /* Invalid chunk size */ |
103 | 111 | ||
104 | for (; count; count -= 8) { | 112 | for (; count; count -= 8) { |
105 | if (copy_from_user(&data, tmp, 8)) | 113 | if (copy_from_user(&data, tmp, 8)) { |
106 | return -EFAULT; | 114 | err = -EFAULT; |
115 | break; | ||
116 | } | ||
107 | err = wrmsr_safe_on_cpu(cpu, reg, data[0], data[1]); | 117 | err = wrmsr_safe_on_cpu(cpu, reg, data[0], data[1]); |
108 | if (err) | 118 | if (err) { |
109 | return -EIO; | 119 | if (err == -EFAULT) /* Fix idiotic error code */ |
120 | err = -EIO; | ||
121 | break; | ||
122 | } | ||
110 | tmp += 2; | 123 | tmp += 2; |
124 | bytes += 8; | ||
111 | } | 125 | } |
112 | 126 | ||
113 | return ((char __user *)tmp) - buf; | 127 | return bytes ? bytes : err; |
114 | } | 128 | } |
115 | 129 | ||
116 | static int msr_open(struct inode *inode, struct file *file) | 130 | static int msr_open(struct inode *inode, struct file *file) |
@@ -131,7 +145,7 @@ static int msr_open(struct inode *inode, struct file *file) | |||
131 | ret = -EIO; /* MSR not supported */ | 145 | ret = -EIO; /* MSR not supported */ |
132 | out: | 146 | out: |
133 | unlock_kernel(); | 147 | unlock_kernel(); |
134 | return 0; | 148 | return ret; |
135 | } | 149 | } |
136 | 150 | ||
137 | /* | 151 | /* |
diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c index ac6d51222e7d..abb78a2cc4ad 100644 --- a/arch/x86/kernel/nmi.c +++ b/arch/x86/kernel/nmi.c | |||
@@ -114,6 +114,23 @@ static __init void nmi_cpu_busy(void *data) | |||
114 | } | 114 | } |
115 | #endif | 115 | #endif |
116 | 116 | ||
117 | static void report_broken_nmi(int cpu, int *prev_nmi_count) | ||
118 | { | ||
119 | printk(KERN_CONT "\n"); | ||
120 | |||
121 | printk(KERN_WARNING | ||
122 | "WARNING: CPU#%d: NMI appears to be stuck (%d->%d)!\n", | ||
123 | cpu, prev_nmi_count[cpu], get_nmi_count(cpu)); | ||
124 | |||
125 | printk(KERN_WARNING | ||
126 | "Please report this to bugzilla.kernel.org,\n"); | ||
127 | printk(KERN_WARNING | ||
128 | "and attach the output of the 'dmesg' command.\n"); | ||
129 | |||
130 | per_cpu(wd_enabled, cpu) = 0; | ||
131 | atomic_dec(&nmi_active); | ||
132 | } | ||
133 | |||
117 | int __init check_nmi_watchdog(void) | 134 | int __init check_nmi_watchdog(void) |
118 | { | 135 | { |
119 | unsigned int *prev_nmi_count; | 136 | unsigned int *prev_nmi_count; |
@@ -141,15 +158,8 @@ int __init check_nmi_watchdog(void) | |||
141 | for_each_online_cpu(cpu) { | 158 | for_each_online_cpu(cpu) { |
142 | if (!per_cpu(wd_enabled, cpu)) | 159 | if (!per_cpu(wd_enabled, cpu)) |
143 | continue; | 160 | continue; |
144 | if (get_nmi_count(cpu) - prev_nmi_count[cpu] <= 5) { | 161 | if (get_nmi_count(cpu) - prev_nmi_count[cpu] <= 5) |
145 | printk(KERN_WARNING "WARNING: CPU#%d: NMI " | 162 | report_broken_nmi(cpu, prev_nmi_count); |
146 | "appears to be stuck (%d->%d)!\n", | ||
147 | cpu, | ||
148 | prev_nmi_count[cpu], | ||
149 | get_nmi_count(cpu)); | ||
150 | per_cpu(wd_enabled, cpu) = 0; | ||
151 | atomic_dec(&nmi_active); | ||
152 | } | ||
153 | } | 163 | } |
154 | endflag = 1; | 164 | endflag = 1; |
155 | if (!atomic_read(&nmi_active)) { | 165 | if (!atomic_read(&nmi_active)) { |
diff --git a/arch/x86/kernel/numaq_32.c b/arch/x86/kernel/numaq_32.c index b8c45610b20a..eecc8c18f010 100644 --- a/arch/x86/kernel/numaq_32.c +++ b/arch/x86/kernel/numaq_32.c | |||
@@ -73,7 +73,7 @@ static void __init smp_dump_qct(void) | |||
73 | } | 73 | } |
74 | 74 | ||
75 | 75 | ||
76 | void __init numaq_tsc_disable(void) | 76 | void __cpuinit numaq_tsc_disable(void) |
77 | { | 77 | { |
78 | if (!found_numaq) | 78 | if (!found_numaq) |
79 | return; | 79 | return; |
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index 94da4d52d798..300da17e61cb 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c | |||
@@ -471,7 +471,7 @@ struct pv_lock_ops pv_lock_ops = { | |||
471 | .spin_unlock = __ticket_spin_unlock, | 471 | .spin_unlock = __ticket_spin_unlock, |
472 | #endif | 472 | #endif |
473 | }; | 473 | }; |
474 | EXPORT_SYMBOL_GPL(pv_lock_ops); | 474 | EXPORT_SYMBOL(pv_lock_ops); |
475 | 475 | ||
476 | EXPORT_SYMBOL_GPL(pv_time_ops); | 476 | EXPORT_SYMBOL_GPL(pv_time_ops); |
477 | EXPORT_SYMBOL (pv_cpu_ops); | 477 | EXPORT_SYMBOL (pv_cpu_ops); |
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c index 151f2d171f7c..dcdac6c826e9 100644 --- a/arch/x86/kernel/pci-calgary_64.c +++ b/arch/x86/kernel/pci-calgary_64.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/mm.h> | 29 | #include <linux/mm.h> |
30 | #include <linux/spinlock.h> | 30 | #include <linux/spinlock.h> |
31 | #include <linux/string.h> | 31 | #include <linux/string.h> |
32 | #include <linux/crash_dump.h> | ||
32 | #include <linux/dma-mapping.h> | 33 | #include <linux/dma-mapping.h> |
33 | #include <linux/bitops.h> | 34 | #include <linux/bitops.h> |
34 | #include <linux/pci_ids.h> | 35 | #include <linux/pci_ids.h> |
@@ -36,6 +37,7 @@ | |||
36 | #include <linux/delay.h> | 37 | #include <linux/delay.h> |
37 | #include <linux/scatterlist.h> | 38 | #include <linux/scatterlist.h> |
38 | #include <linux/iommu-helper.h> | 39 | #include <linux/iommu-helper.h> |
40 | |||
39 | #include <asm/iommu.h> | 41 | #include <asm/iommu.h> |
40 | #include <asm/calgary.h> | 42 | #include <asm/calgary.h> |
41 | #include <asm/tce.h> | 43 | #include <asm/tce.h> |
@@ -167,6 +169,8 @@ static void calgary_dump_error_regs(struct iommu_table *tbl); | |||
167 | static void calioc2_handle_quirks(struct iommu_table *tbl, struct pci_dev *dev); | 169 | static void calioc2_handle_quirks(struct iommu_table *tbl, struct pci_dev *dev); |
168 | static void calioc2_tce_cache_blast(struct iommu_table *tbl); | 170 | static void calioc2_tce_cache_blast(struct iommu_table *tbl); |
169 | static void calioc2_dump_error_regs(struct iommu_table *tbl); | 171 | static void calioc2_dump_error_regs(struct iommu_table *tbl); |
172 | static void calgary_init_bitmap_from_tce_table(struct iommu_table *tbl); | ||
173 | static void get_tce_space_from_tar(void); | ||
170 | 174 | ||
171 | static struct cal_chipset_ops calgary_chip_ops = { | 175 | static struct cal_chipset_ops calgary_chip_ops = { |
172 | .handle_quirks = calgary_handle_quirks, | 176 | .handle_quirks = calgary_handle_quirks, |
@@ -339,9 +343,8 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr, | |||
339 | /* were we called with bad_dma_address? */ | 343 | /* were we called with bad_dma_address? */ |
340 | badend = bad_dma_address + (EMERGENCY_PAGES * PAGE_SIZE); | 344 | badend = bad_dma_address + (EMERGENCY_PAGES * PAGE_SIZE); |
341 | if (unlikely((dma_addr >= bad_dma_address) && (dma_addr < badend))) { | 345 | if (unlikely((dma_addr >= bad_dma_address) && (dma_addr < badend))) { |
342 | printk(KERN_ERR "Calgary: driver tried unmapping bad DMA " | 346 | WARN(1, KERN_ERR "Calgary: driver tried unmapping bad DMA " |
343 | "address 0x%Lx\n", dma_addr); | 347 | "address 0x%Lx\n", dma_addr); |
344 | WARN_ON(1); | ||
345 | return; | 348 | return; |
346 | } | 349 | } |
347 | 350 | ||
@@ -410,22 +413,6 @@ static void calgary_unmap_sg(struct device *dev, | |||
410 | } | 413 | } |
411 | } | 414 | } |
412 | 415 | ||
413 | static int calgary_nontranslate_map_sg(struct device* dev, | ||
414 | struct scatterlist *sg, int nelems, int direction) | ||
415 | { | ||
416 | struct scatterlist *s; | ||
417 | int i; | ||
418 | |||
419 | for_each_sg(sg, s, nelems, i) { | ||
420 | struct page *p = sg_page(s); | ||
421 | |||
422 | BUG_ON(!p); | ||
423 | s->dma_address = virt_to_bus(sg_virt(s)); | ||
424 | s->dma_length = s->length; | ||
425 | } | ||
426 | return nelems; | ||
427 | } | ||
428 | |||
429 | static int calgary_map_sg(struct device *dev, struct scatterlist *sg, | 416 | static int calgary_map_sg(struct device *dev, struct scatterlist *sg, |
430 | int nelems, int direction) | 417 | int nelems, int direction) |
431 | { | 418 | { |
@@ -436,9 +423,6 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg, | |||
436 | unsigned long entry; | 423 | unsigned long entry; |
437 | int i; | 424 | int i; |
438 | 425 | ||
439 | if (!translation_enabled(tbl)) | ||
440 | return calgary_nontranslate_map_sg(dev, sg, nelems, direction); | ||
441 | |||
442 | for_each_sg(sg, s, nelems, i) { | 426 | for_each_sg(sg, s, nelems, i) { |
443 | BUG_ON(!sg_page(s)); | 427 | BUG_ON(!sg_page(s)); |
444 | 428 | ||
@@ -474,7 +458,6 @@ error: | |||
474 | static dma_addr_t calgary_map_single(struct device *dev, phys_addr_t paddr, | 458 | static dma_addr_t calgary_map_single(struct device *dev, phys_addr_t paddr, |
475 | size_t size, int direction) | 459 | size_t size, int direction) |
476 | { | 460 | { |
477 | dma_addr_t dma_handle = bad_dma_address; | ||
478 | void *vaddr = phys_to_virt(paddr); | 461 | void *vaddr = phys_to_virt(paddr); |
479 | unsigned long uaddr; | 462 | unsigned long uaddr; |
480 | unsigned int npages; | 463 | unsigned int npages; |
@@ -483,12 +466,7 @@ static dma_addr_t calgary_map_single(struct device *dev, phys_addr_t paddr, | |||
483 | uaddr = (unsigned long)vaddr; | 466 | uaddr = (unsigned long)vaddr; |
484 | npages = num_dma_pages(uaddr, size); | 467 | npages = num_dma_pages(uaddr, size); |
485 | 468 | ||
486 | if (translation_enabled(tbl)) | 469 | return iommu_alloc(dev, tbl, vaddr, npages, direction); |
487 | dma_handle = iommu_alloc(dev, tbl, vaddr, npages, direction); | ||
488 | else | ||
489 | dma_handle = virt_to_bus(vaddr); | ||
490 | |||
491 | return dma_handle; | ||
492 | } | 470 | } |
493 | 471 | ||
494 | static void calgary_unmap_single(struct device *dev, dma_addr_t dma_handle, | 472 | static void calgary_unmap_single(struct device *dev, dma_addr_t dma_handle, |
@@ -497,9 +475,6 @@ static void calgary_unmap_single(struct device *dev, dma_addr_t dma_handle, | |||
497 | struct iommu_table *tbl = find_iommu_table(dev); | 475 | struct iommu_table *tbl = find_iommu_table(dev); |
498 | unsigned int npages; | 476 | unsigned int npages; |
499 | 477 | ||
500 | if (!translation_enabled(tbl)) | ||
501 | return; | ||
502 | |||
503 | npages = num_dma_pages(dma_handle, size); | 478 | npages = num_dma_pages(dma_handle, size); |
504 | iommu_free(tbl, dma_handle, npages); | 479 | iommu_free(tbl, dma_handle, npages); |
505 | } | 480 | } |
@@ -522,18 +497,12 @@ static void* calgary_alloc_coherent(struct device *dev, size_t size, | |||
522 | goto error; | 497 | goto error; |
523 | memset(ret, 0, size); | 498 | memset(ret, 0, size); |
524 | 499 | ||
525 | if (translation_enabled(tbl)) { | 500 | /* set up tces to cover the allocated range */ |
526 | /* set up tces to cover the allocated range */ | 501 | mapping = iommu_alloc(dev, tbl, ret, npages, DMA_BIDIRECTIONAL); |
527 | mapping = iommu_alloc(dev, tbl, ret, npages, DMA_BIDIRECTIONAL); | 502 | if (mapping == bad_dma_address) |
528 | if (mapping == bad_dma_address) | 503 | goto free; |
529 | goto free; | 504 | *dma_handle = mapping; |
530 | |||
531 | *dma_handle = mapping; | ||
532 | } else /* non translated slot */ | ||
533 | *dma_handle = virt_to_bus(ret); | ||
534 | |||
535 | return ret; | 505 | return ret; |
536 | |||
537 | free: | 506 | free: |
538 | free_pages((unsigned long)ret, get_order(size)); | 507 | free_pages((unsigned long)ret, get_order(size)); |
539 | ret = NULL; | 508 | ret = NULL; |
@@ -541,7 +510,7 @@ error: | |||
541 | return ret; | 510 | return ret; |
542 | } | 511 | } |
543 | 512 | ||
544 | static const struct dma_mapping_ops calgary_dma_ops = { | 513 | static struct dma_mapping_ops calgary_dma_ops = { |
545 | .alloc_coherent = calgary_alloc_coherent, | 514 | .alloc_coherent = calgary_alloc_coherent, |
546 | .map_single = calgary_map_single, | 515 | .map_single = calgary_map_single, |
547 | .unmap_single = calgary_unmap_single, | 516 | .unmap_single = calgary_unmap_single, |
@@ -830,7 +799,11 @@ static int __init calgary_setup_tar(struct pci_dev *dev, void __iomem *bbar) | |||
830 | 799 | ||
831 | tbl = pci_iommu(dev->bus); | 800 | tbl = pci_iommu(dev->bus); |
832 | tbl->it_base = (unsigned long)bus_info[dev->bus->number].tce_space; | 801 | tbl->it_base = (unsigned long)bus_info[dev->bus->number].tce_space; |
833 | tce_free(tbl, 0, tbl->it_size); | 802 | |
803 | if (is_kdump_kernel()) | ||
804 | calgary_init_bitmap_from_tce_table(tbl); | ||
805 | else | ||
806 | tce_free(tbl, 0, tbl->it_size); | ||
834 | 807 | ||
835 | if (is_calgary(dev->device)) | 808 | if (is_calgary(dev->device)) |
836 | tbl->chip_ops = &calgary_chip_ops; | 809 | tbl->chip_ops = &calgary_chip_ops; |
@@ -1209,6 +1182,10 @@ static int __init calgary_init(void) | |||
1209 | if (ret) | 1182 | if (ret) |
1210 | return ret; | 1183 | return ret; |
1211 | 1184 | ||
1185 | /* Purely for kdump kernel case */ | ||
1186 | if (is_kdump_kernel()) | ||
1187 | get_tce_space_from_tar(); | ||
1188 | |||
1212 | do { | 1189 | do { |
1213 | dev = pci_get_device(PCI_VENDOR_ID_IBM, PCI_ANY_ID, dev); | 1190 | dev = pci_get_device(PCI_VENDOR_ID_IBM, PCI_ANY_ID, dev); |
1214 | if (!dev) | 1191 | if (!dev) |
@@ -1230,6 +1207,16 @@ static int __init calgary_init(void) | |||
1230 | goto error; | 1207 | goto error; |
1231 | } while (1); | 1208 | } while (1); |
1232 | 1209 | ||
1210 | dev = NULL; | ||
1211 | for_each_pci_dev(dev) { | ||
1212 | struct iommu_table *tbl; | ||
1213 | |||
1214 | tbl = find_iommu_table(&dev->dev); | ||
1215 | |||
1216 | if (translation_enabled(tbl)) | ||
1217 | dev->dev.archdata.dma_ops = &calgary_dma_ops; | ||
1218 | } | ||
1219 | |||
1233 | return ret; | 1220 | return ret; |
1234 | 1221 | ||
1235 | error: | 1222 | error: |
@@ -1251,6 +1238,7 @@ error: | |||
1251 | calgary_disable_translation(dev); | 1238 | calgary_disable_translation(dev); |
1252 | calgary_free_bus(dev); | 1239 | calgary_free_bus(dev); |
1253 | pci_dev_put(dev); /* Undo calgary_init_one()'s pci_dev_get() */ | 1240 | pci_dev_put(dev); /* Undo calgary_init_one()'s pci_dev_get() */ |
1241 | dev->dev.archdata.dma_ops = NULL; | ||
1254 | } while (1); | 1242 | } while (1); |
1255 | 1243 | ||
1256 | return ret; | 1244 | return ret; |
@@ -1280,13 +1268,15 @@ static inline int __init determine_tce_table_size(u64 ram) | |||
1280 | static int __init build_detail_arrays(void) | 1268 | static int __init build_detail_arrays(void) |
1281 | { | 1269 | { |
1282 | unsigned long ptr; | 1270 | unsigned long ptr; |
1283 | int i, scal_detail_size, rio_detail_size; | 1271 | unsigned numnodes, i; |
1272 | int scal_detail_size, rio_detail_size; | ||
1284 | 1273 | ||
1285 | if (rio_table_hdr->num_scal_dev > MAX_NUMNODES){ | 1274 | numnodes = rio_table_hdr->num_scal_dev; |
1275 | if (numnodes > MAX_NUMNODES){ | ||
1286 | printk(KERN_WARNING | 1276 | printk(KERN_WARNING |
1287 | "Calgary: MAX_NUMNODES too low! Defined as %d, " | 1277 | "Calgary: MAX_NUMNODES too low! Defined as %d, " |
1288 | "but system has %d nodes.\n", | 1278 | "but system has %d nodes.\n", |
1289 | MAX_NUMNODES, rio_table_hdr->num_scal_dev); | 1279 | MAX_NUMNODES, numnodes); |
1290 | return -ENODEV; | 1280 | return -ENODEV; |
1291 | } | 1281 | } |
1292 | 1282 | ||
@@ -1307,8 +1297,7 @@ static int __init build_detail_arrays(void) | |||
1307 | } | 1297 | } |
1308 | 1298 | ||
1309 | ptr = ((unsigned long)rio_table_hdr) + 3; | 1299 | ptr = ((unsigned long)rio_table_hdr) + 3; |
1310 | for (i = 0; i < rio_table_hdr->num_scal_dev; | 1300 | for (i = 0; i < numnodes; i++, ptr += scal_detail_size) |
1311 | i++, ptr += scal_detail_size) | ||
1312 | scal_devs[i] = (struct scal_detail *)ptr; | 1301 | scal_devs[i] = (struct scal_detail *)ptr; |
1313 | 1302 | ||
1314 | for (i = 0; i < rio_table_hdr->num_rio_dev; | 1303 | for (i = 0; i < rio_table_hdr->num_rio_dev; |
@@ -1339,6 +1328,61 @@ static int __init calgary_bus_has_devices(int bus, unsigned short pci_dev) | |||
1339 | return (val != 0xffffffff); | 1328 | return (val != 0xffffffff); |
1340 | } | 1329 | } |
1341 | 1330 | ||
1331 | /* | ||
1332 | * calgary_init_bitmap_from_tce_table(): | ||
1333 | * Funtion for kdump case. In the second/kdump kernel initialize | ||
1334 | * the bitmap based on the tce table entries obtained from first kernel | ||
1335 | */ | ||
1336 | static void calgary_init_bitmap_from_tce_table(struct iommu_table *tbl) | ||
1337 | { | ||
1338 | u64 *tp; | ||
1339 | unsigned int index; | ||
1340 | tp = ((u64 *)tbl->it_base); | ||
1341 | for (index = 0 ; index < tbl->it_size; index++) { | ||
1342 | if (*tp != 0x0) | ||
1343 | set_bit(index, tbl->it_map); | ||
1344 | tp++; | ||
1345 | } | ||
1346 | } | ||
1347 | |||
1348 | /* | ||
1349 | * get_tce_space_from_tar(): | ||
1350 | * Function for kdump case. Get the tce tables from first kernel | ||
1351 | * by reading the contents of the base adress register of calgary iommu | ||
1352 | */ | ||
1353 | static void __init get_tce_space_from_tar(void) | ||
1354 | { | ||
1355 | int bus; | ||
1356 | void __iomem *target; | ||
1357 | unsigned long tce_space; | ||
1358 | |||
1359 | for (bus = 0; bus < MAX_PHB_BUS_NUM; bus++) { | ||
1360 | struct calgary_bus_info *info = &bus_info[bus]; | ||
1361 | unsigned short pci_device; | ||
1362 | u32 val; | ||
1363 | |||
1364 | val = read_pci_config(bus, 0, 0, 0); | ||
1365 | pci_device = (val & 0xFFFF0000) >> 16; | ||
1366 | |||
1367 | if (!is_cal_pci_dev(pci_device)) | ||
1368 | continue; | ||
1369 | if (info->translation_disabled) | ||
1370 | continue; | ||
1371 | |||
1372 | if (calgary_bus_has_devices(bus, pci_device) || | ||
1373 | translate_empty_slots) { | ||
1374 | target = calgary_reg(bus_info[bus].bbar, | ||
1375 | tar_offset(bus)); | ||
1376 | tce_space = be64_to_cpu(readq(target)); | ||
1377 | tce_space = tce_space & TAR_SW_BITS; | ||
1378 | |||
1379 | tce_space = tce_space & (~specified_table_size); | ||
1380 | info->tce_space = (u64 *)__va(tce_space); | ||
1381 | } | ||
1382 | } | ||
1383 | return; | ||
1384 | } | ||
1385 | |||
1342 | void __init detect_calgary(void) | 1386 | void __init detect_calgary(void) |
1343 | { | 1387 | { |
1344 | int bus; | 1388 | int bus; |
@@ -1394,7 +1438,8 @@ void __init detect_calgary(void) | |||
1394 | return; | 1438 | return; |
1395 | } | 1439 | } |
1396 | 1440 | ||
1397 | specified_table_size = determine_tce_table_size(max_pfn * PAGE_SIZE); | 1441 | specified_table_size = determine_tce_table_size((is_kdump_kernel() ? |
1442 | saved_max_pfn : max_pfn) * PAGE_SIZE); | ||
1398 | 1443 | ||
1399 | for (bus = 0; bus < MAX_PHB_BUS_NUM; bus++) { | 1444 | for (bus = 0; bus < MAX_PHB_BUS_NUM; bus++) { |
1400 | struct calgary_bus_info *info = &bus_info[bus]; | 1445 | struct calgary_bus_info *info = &bus_info[bus]; |
@@ -1412,10 +1457,16 @@ void __init detect_calgary(void) | |||
1412 | 1457 | ||
1413 | if (calgary_bus_has_devices(bus, pci_device) || | 1458 | if (calgary_bus_has_devices(bus, pci_device) || |
1414 | translate_empty_slots) { | 1459 | translate_empty_slots) { |
1415 | tbl = alloc_tce_table(); | 1460 | /* |
1416 | if (!tbl) | 1461 | * If it is kdump kernel, find and use tce tables |
1417 | goto cleanup; | 1462 | * from first kernel, else allocate tce tables here |
1418 | info->tce_space = tbl; | 1463 | */ |
1464 | if (!is_kdump_kernel()) { | ||
1465 | tbl = alloc_tce_table(); | ||
1466 | if (!tbl) | ||
1467 | goto cleanup; | ||
1468 | info->tce_space = tbl; | ||
1469 | } | ||
1419 | calgary_found = 1; | 1470 | calgary_found = 1; |
1420 | } | 1471 | } |
1421 | } | 1472 | } |
@@ -1430,6 +1481,10 @@ void __init detect_calgary(void) | |||
1430 | printk(KERN_INFO "PCI-DMA: Calgary TCE table spec is %d, " | 1481 | printk(KERN_INFO "PCI-DMA: Calgary TCE table spec is %d, " |
1431 | "CONFIG_IOMMU_DEBUG is %s.\n", specified_table_size, | 1482 | "CONFIG_IOMMU_DEBUG is %s.\n", specified_table_size, |
1432 | debugging ? "enabled" : "disabled"); | 1483 | debugging ? "enabled" : "disabled"); |
1484 | |||
1485 | /* swiotlb for devices that aren't behind the Calgary. */ | ||
1486 | if (max_pfn > MAX_DMA32_PFN) | ||
1487 | swiotlb = 1; | ||
1433 | } | 1488 | } |
1434 | return; | 1489 | return; |
1435 | 1490 | ||
@@ -1446,7 +1501,7 @@ int __init calgary_iommu_init(void) | |||
1446 | { | 1501 | { |
1447 | int ret; | 1502 | int ret; |
1448 | 1503 | ||
1449 | if (no_iommu || swiotlb) | 1504 | if (no_iommu || (swiotlb && !calgary_detected)) |
1450 | return -ENODEV; | 1505 | return -ENODEV; |
1451 | 1506 | ||
1452 | if (!calgary_detected) | 1507 | if (!calgary_detected) |
@@ -1459,15 +1514,14 @@ int __init calgary_iommu_init(void) | |||
1459 | if (ret) { | 1514 | if (ret) { |
1460 | printk(KERN_ERR "PCI-DMA: Calgary init failed %d, " | 1515 | printk(KERN_ERR "PCI-DMA: Calgary init failed %d, " |
1461 | "falling back to no_iommu\n", ret); | 1516 | "falling back to no_iommu\n", ret); |
1462 | if (max_pfn > MAX_DMA32_PFN) | ||
1463 | printk(KERN_ERR "WARNING more than 4GB of memory, " | ||
1464 | "32bit PCI may malfunction.\n"); | ||
1465 | return ret; | 1517 | return ret; |
1466 | } | 1518 | } |
1467 | 1519 | ||
1468 | force_iommu = 1; | 1520 | force_iommu = 1; |
1469 | bad_dma_address = 0x0; | 1521 | bad_dma_address = 0x0; |
1470 | dma_ops = &calgary_dma_ops; | 1522 | /* dma_ops is set to swiotlb or nommu */ |
1523 | if (!dma_ops) | ||
1524 | dma_ops = &nommu_dma_ops; | ||
1471 | 1525 | ||
1472 | return 0; | 1526 | return 0; |
1473 | } | 1527 | } |
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index cbecb05551bb..87d4d6964ec2 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c | |||
@@ -11,7 +11,7 @@ | |||
11 | 11 | ||
12 | static int forbid_dac __read_mostly; | 12 | static int forbid_dac __read_mostly; |
13 | 13 | ||
14 | const struct dma_mapping_ops *dma_ops; | 14 | struct dma_mapping_ops *dma_ops; |
15 | EXPORT_SYMBOL(dma_ops); | 15 | EXPORT_SYMBOL(dma_ops); |
16 | 16 | ||
17 | static int iommu_sac_force __read_mostly; | 17 | static int iommu_sac_force __read_mostly; |
@@ -123,6 +123,14 @@ void __init pci_iommu_alloc(void) | |||
123 | 123 | ||
124 | pci_swiotlb_init(); | 124 | pci_swiotlb_init(); |
125 | } | 125 | } |
126 | |||
127 | unsigned long iommu_num_pages(unsigned long addr, unsigned long len) | ||
128 | { | ||
129 | unsigned long size = roundup((addr & ~PAGE_MASK) + len, PAGE_SIZE); | ||
130 | |||
131 | return size >> PAGE_SHIFT; | ||
132 | } | ||
133 | EXPORT_SYMBOL(iommu_num_pages); | ||
126 | #endif | 134 | #endif |
127 | 135 | ||
128 | /* | 136 | /* |
@@ -192,126 +200,10 @@ static __init int iommu_setup(char *p) | |||
192 | } | 200 | } |
193 | early_param("iommu", iommu_setup); | 201 | early_param("iommu", iommu_setup); |
194 | 202 | ||
195 | #ifdef CONFIG_X86_32 | ||
196 | int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr, | ||
197 | dma_addr_t device_addr, size_t size, int flags) | ||
198 | { | ||
199 | void __iomem *mem_base = NULL; | ||
200 | int pages = size >> PAGE_SHIFT; | ||
201 | int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long); | ||
202 | |||
203 | if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0) | ||
204 | goto out; | ||
205 | if (!size) | ||
206 | goto out; | ||
207 | if (dev->dma_mem) | ||
208 | goto out; | ||
209 | |||
210 | /* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */ | ||
211 | |||
212 | mem_base = ioremap(bus_addr, size); | ||
213 | if (!mem_base) | ||
214 | goto out; | ||
215 | |||
216 | dev->dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL); | ||
217 | if (!dev->dma_mem) | ||
218 | goto out; | ||
219 | dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL); | ||
220 | if (!dev->dma_mem->bitmap) | ||
221 | goto free1_out; | ||
222 | |||
223 | dev->dma_mem->virt_base = mem_base; | ||
224 | dev->dma_mem->device_base = device_addr; | ||
225 | dev->dma_mem->size = pages; | ||
226 | dev->dma_mem->flags = flags; | ||
227 | |||
228 | if (flags & DMA_MEMORY_MAP) | ||
229 | return DMA_MEMORY_MAP; | ||
230 | |||
231 | return DMA_MEMORY_IO; | ||
232 | |||
233 | free1_out: | ||
234 | kfree(dev->dma_mem); | ||
235 | out: | ||
236 | if (mem_base) | ||
237 | iounmap(mem_base); | ||
238 | return 0; | ||
239 | } | ||
240 | EXPORT_SYMBOL(dma_declare_coherent_memory); | ||
241 | |||
242 | void dma_release_declared_memory(struct device *dev) | ||
243 | { | ||
244 | struct dma_coherent_mem *mem = dev->dma_mem; | ||
245 | |||
246 | if (!mem) | ||
247 | return; | ||
248 | dev->dma_mem = NULL; | ||
249 | iounmap(mem->virt_base); | ||
250 | kfree(mem->bitmap); | ||
251 | kfree(mem); | ||
252 | } | ||
253 | EXPORT_SYMBOL(dma_release_declared_memory); | ||
254 | |||
255 | void *dma_mark_declared_memory_occupied(struct device *dev, | ||
256 | dma_addr_t device_addr, size_t size) | ||
257 | { | ||
258 | struct dma_coherent_mem *mem = dev->dma_mem; | ||
259 | int pos, err; | ||
260 | int pages = (size + (device_addr & ~PAGE_MASK) + PAGE_SIZE - 1); | ||
261 | |||
262 | pages >>= PAGE_SHIFT; | ||
263 | |||
264 | if (!mem) | ||
265 | return ERR_PTR(-EINVAL); | ||
266 | |||
267 | pos = (device_addr - mem->device_base) >> PAGE_SHIFT; | ||
268 | err = bitmap_allocate_region(mem->bitmap, pos, get_order(pages)); | ||
269 | if (err != 0) | ||
270 | return ERR_PTR(err); | ||
271 | return mem->virt_base + (pos << PAGE_SHIFT); | ||
272 | } | ||
273 | EXPORT_SYMBOL(dma_mark_declared_memory_occupied); | ||
274 | |||
275 | static int dma_alloc_from_coherent_mem(struct device *dev, ssize_t size, | ||
276 | dma_addr_t *dma_handle, void **ret) | ||
277 | { | ||
278 | struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL; | ||
279 | int order = get_order(size); | ||
280 | |||
281 | if (mem) { | ||
282 | int page = bitmap_find_free_region(mem->bitmap, mem->size, | ||
283 | order); | ||
284 | if (page >= 0) { | ||
285 | *dma_handle = mem->device_base + (page << PAGE_SHIFT); | ||
286 | *ret = mem->virt_base + (page << PAGE_SHIFT); | ||
287 | memset(*ret, 0, size); | ||
288 | } | ||
289 | if (mem->flags & DMA_MEMORY_EXCLUSIVE) | ||
290 | *ret = NULL; | ||
291 | } | ||
292 | return (mem != NULL); | ||
293 | } | ||
294 | |||
295 | static int dma_release_coherent(struct device *dev, int order, void *vaddr) | ||
296 | { | ||
297 | struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL; | ||
298 | |||
299 | if (mem && vaddr >= mem->virt_base && vaddr < | ||
300 | (mem->virt_base + (mem->size << PAGE_SHIFT))) { | ||
301 | int page = (vaddr - mem->virt_base) >> PAGE_SHIFT; | ||
302 | |||
303 | bitmap_release_region(mem->bitmap, page, order); | ||
304 | return 1; | ||
305 | } | ||
306 | return 0; | ||
307 | } | ||
308 | #else | ||
309 | #define dma_alloc_from_coherent_mem(dev, size, handle, ret) (0) | ||
310 | #define dma_release_coherent(dev, order, vaddr) (0) | ||
311 | #endif /* CONFIG_X86_32 */ | ||
312 | |||
313 | int dma_supported(struct device *dev, u64 mask) | 203 | int dma_supported(struct device *dev, u64 mask) |
314 | { | 204 | { |
205 | struct dma_mapping_ops *ops = get_dma_ops(dev); | ||
206 | |||
315 | #ifdef CONFIG_PCI | 207 | #ifdef CONFIG_PCI |
316 | if (mask > 0xffffffff && forbid_dac > 0) { | 208 | if (mask > 0xffffffff && forbid_dac > 0) { |
317 | dev_info(dev, "PCI: Disallowing DAC for device\n"); | 209 | dev_info(dev, "PCI: Disallowing DAC for device\n"); |
@@ -319,8 +211,8 @@ int dma_supported(struct device *dev, u64 mask) | |||
319 | } | 211 | } |
320 | #endif | 212 | #endif |
321 | 213 | ||
322 | if (dma_ops->dma_supported) | 214 | if (ops->dma_supported) |
323 | return dma_ops->dma_supported(dev, mask); | 215 | return ops->dma_supported(dev, mask); |
324 | 216 | ||
325 | /* Copied from i386. Doesn't make much sense, because it will | 217 | /* Copied from i386. Doesn't make much sense, because it will |
326 | only work for pci_alloc_coherent. | 218 | only work for pci_alloc_coherent. |
@@ -367,6 +259,7 @@ void * | |||
367 | dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, | 259 | dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, |
368 | gfp_t gfp) | 260 | gfp_t gfp) |
369 | { | 261 | { |
262 | struct dma_mapping_ops *ops = get_dma_ops(dev); | ||
370 | void *memory = NULL; | 263 | void *memory = NULL; |
371 | struct page *page; | 264 | struct page *page; |
372 | unsigned long dma_mask = 0; | 265 | unsigned long dma_mask = 0; |
@@ -376,7 +269,7 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, | |||
376 | /* ignore region specifiers */ | 269 | /* ignore region specifiers */ |
377 | gfp &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32); | 270 | gfp &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32); |
378 | 271 | ||
379 | if (dma_alloc_from_coherent_mem(dev, size, dma_handle, &memory)) | 272 | if (dma_alloc_from_coherent(dev, size, dma_handle, &memory)) |
380 | return memory; | 273 | return memory; |
381 | 274 | ||
382 | if (!dev) { | 275 | if (!dev) { |
@@ -435,8 +328,8 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, | |||
435 | /* Let low level make its own zone decisions */ | 328 | /* Let low level make its own zone decisions */ |
436 | gfp &= ~(GFP_DMA32|GFP_DMA); | 329 | gfp &= ~(GFP_DMA32|GFP_DMA); |
437 | 330 | ||
438 | if (dma_ops->alloc_coherent) | 331 | if (ops->alloc_coherent) |
439 | return dma_ops->alloc_coherent(dev, size, | 332 | return ops->alloc_coherent(dev, size, |
440 | dma_handle, gfp); | 333 | dma_handle, gfp); |
441 | return NULL; | 334 | return NULL; |
442 | } | 335 | } |
@@ -448,14 +341,14 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, | |||
448 | } | 341 | } |
449 | } | 342 | } |
450 | 343 | ||
451 | if (dma_ops->alloc_coherent) { | 344 | if (ops->alloc_coherent) { |
452 | free_pages((unsigned long)memory, get_order(size)); | 345 | free_pages((unsigned long)memory, get_order(size)); |
453 | gfp &= ~(GFP_DMA|GFP_DMA32); | 346 | gfp &= ~(GFP_DMA|GFP_DMA32); |
454 | return dma_ops->alloc_coherent(dev, size, dma_handle, gfp); | 347 | return ops->alloc_coherent(dev, size, dma_handle, gfp); |
455 | } | 348 | } |
456 | 349 | ||
457 | if (dma_ops->map_simple) { | 350 | if (ops->map_simple) { |
458 | *dma_handle = dma_ops->map_simple(dev, virt_to_phys(memory), | 351 | *dma_handle = ops->map_simple(dev, virt_to_phys(memory), |
459 | size, | 352 | size, |
460 | PCI_DMA_BIDIRECTIONAL); | 353 | PCI_DMA_BIDIRECTIONAL); |
461 | if (*dma_handle != bad_dma_address) | 354 | if (*dma_handle != bad_dma_address) |
@@ -477,12 +370,14 @@ EXPORT_SYMBOL(dma_alloc_coherent); | |||
477 | void dma_free_coherent(struct device *dev, size_t size, | 370 | void dma_free_coherent(struct device *dev, size_t size, |
478 | void *vaddr, dma_addr_t bus) | 371 | void *vaddr, dma_addr_t bus) |
479 | { | 372 | { |
373 | struct dma_mapping_ops *ops = get_dma_ops(dev); | ||
374 | |||
480 | int order = get_order(size); | 375 | int order = get_order(size); |
481 | WARN_ON(irqs_disabled()); /* for portability */ | 376 | WARN_ON(irqs_disabled()); /* for portability */ |
482 | if (dma_release_coherent(dev, order, vaddr)) | 377 | if (dma_release_from_coherent(dev, order, vaddr)) |
483 | return; | 378 | return; |
484 | if (dma_ops->unmap_single) | 379 | if (ops->unmap_single) |
485 | dma_ops->unmap_single(dev, bus, size, 0); | 380 | ops->unmap_single(dev, bus, size, 0); |
486 | free_pages((unsigned long)vaddr, order); | 381 | free_pages((unsigned long)vaddr, order); |
487 | } | 382 | } |
488 | EXPORT_SYMBOL(dma_free_coherent); | 383 | EXPORT_SYMBOL(dma_free_coherent); |
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index df5f142657d2..49285f8fd4d5 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c | |||
@@ -67,9 +67,6 @@ static u32 gart_unmapped_entry; | |||
67 | (((x) & 0xfffff000) | (((x) >> 32) << 4) | GPTE_VALID | GPTE_COHERENT) | 67 | (((x) & 0xfffff000) | (((x) >> 32) << 4) | GPTE_VALID | GPTE_COHERENT) |
68 | #define GPTE_DECODE(x) (((x) & 0xfffff000) | (((u64)(x) & 0xff0) << 28)) | 68 | #define GPTE_DECODE(x) (((x) & 0xfffff000) | (((u64)(x) & 0xff0) << 28)) |
69 | 69 | ||
70 | #define to_pages(addr, size) \ | ||
71 | (round_up(((addr) & ~PAGE_MASK) + (size), PAGE_SIZE) >> PAGE_SHIFT) | ||
72 | |||
73 | #define EMERGENCY_PAGES 32 /* = 128KB */ | 70 | #define EMERGENCY_PAGES 32 /* = 128KB */ |
74 | 71 | ||
75 | #ifdef CONFIG_AGP | 72 | #ifdef CONFIG_AGP |
@@ -241,7 +238,7 @@ nonforced_iommu(struct device *dev, unsigned long addr, size_t size) | |||
241 | static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem, | 238 | static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem, |
242 | size_t size, int dir) | 239 | size_t size, int dir) |
243 | { | 240 | { |
244 | unsigned long npages = to_pages(phys_mem, size); | 241 | unsigned long npages = iommu_num_pages(phys_mem, size); |
245 | unsigned long iommu_page = alloc_iommu(dev, npages); | 242 | unsigned long iommu_page = alloc_iommu(dev, npages); |
246 | int i; | 243 | int i; |
247 | 244 | ||
@@ -304,7 +301,7 @@ static void gart_unmap_single(struct device *dev, dma_addr_t dma_addr, | |||
304 | return; | 301 | return; |
305 | 302 | ||
306 | iommu_page = (dma_addr - iommu_bus_base)>>PAGE_SHIFT; | 303 | iommu_page = (dma_addr - iommu_bus_base)>>PAGE_SHIFT; |
307 | npages = to_pages(dma_addr, size); | 304 | npages = iommu_num_pages(dma_addr, size); |
308 | for (i = 0; i < npages; i++) { | 305 | for (i = 0; i < npages; i++) { |
309 | iommu_gatt_base[iommu_page + i] = gart_unmapped_entry; | 306 | iommu_gatt_base[iommu_page + i] = gart_unmapped_entry; |
310 | CLEAR_LEAK(iommu_page + i); | 307 | CLEAR_LEAK(iommu_page + i); |
@@ -387,7 +384,7 @@ static int __dma_map_cont(struct device *dev, struct scatterlist *start, | |||
387 | } | 384 | } |
388 | 385 | ||
389 | addr = phys_addr; | 386 | addr = phys_addr; |
390 | pages = to_pages(s->offset, s->length); | 387 | pages = iommu_num_pages(s->offset, s->length); |
391 | while (pages--) { | 388 | while (pages--) { |
392 | iommu_gatt_base[iommu_page] = GPTE_ENCODE(addr); | 389 | iommu_gatt_base[iommu_page] = GPTE_ENCODE(addr); |
393 | SET_LEAK(iommu_page); | 390 | SET_LEAK(iommu_page); |
@@ -470,7 +467,7 @@ gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) | |||
470 | 467 | ||
471 | seg_size += s->length; | 468 | seg_size += s->length; |
472 | need = nextneed; | 469 | need = nextneed; |
473 | pages += to_pages(s->offset, s->length); | 470 | pages += iommu_num_pages(s->offset, s->length); |
474 | ps = s; | 471 | ps = s; |
475 | } | 472 | } |
476 | if (dma_map_cont(dev, start_sg, i - start, sgmap, pages, need) < 0) | 473 | if (dma_map_cont(dev, start_sg, i - start, sgmap, pages, need) < 0) |
@@ -692,8 +689,7 @@ static __init int init_k8_gatt(struct agp_kern_info *info) | |||
692 | 689 | ||
693 | extern int agp_amd64_init(void); | 690 | extern int agp_amd64_init(void); |
694 | 691 | ||
695 | static const struct dma_mapping_ops gart_dma_ops = { | 692 | static struct dma_mapping_ops gart_dma_ops = { |
696 | .mapping_error = NULL, | ||
697 | .map_single = gart_map_single, | 693 | .map_single = gart_map_single, |
698 | .map_simple = gart_map_simple, | 694 | .map_simple = gart_map_simple, |
699 | .unmap_single = gart_unmap_single, | 695 | .unmap_single = gart_unmap_single, |
diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c index 792b9179eff3..3f91f71cdc3e 100644 --- a/arch/x86/kernel/pci-nommu.c +++ b/arch/x86/kernel/pci-nommu.c | |||
@@ -72,21 +72,9 @@ static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg, | |||
72 | return nents; | 72 | return nents; |
73 | } | 73 | } |
74 | 74 | ||
75 | /* Make sure we keep the same behaviour */ | 75 | struct dma_mapping_ops nommu_dma_ops = { |
76 | static int nommu_mapping_error(dma_addr_t dma_addr) | ||
77 | { | ||
78 | #ifdef CONFIG_X86_32 | ||
79 | return 0; | ||
80 | #else | ||
81 | return (dma_addr == bad_dma_address); | ||
82 | #endif | ||
83 | } | ||
84 | |||
85 | |||
86 | const struct dma_mapping_ops nommu_dma_ops = { | ||
87 | .map_single = nommu_map_single, | 76 | .map_single = nommu_map_single, |
88 | .map_sg = nommu_map_sg, | 77 | .map_sg = nommu_map_sg, |
89 | .mapping_error = nommu_mapping_error, | ||
90 | .is_phys = 1, | 78 | .is_phys = 1, |
91 | }; | 79 | }; |
92 | 80 | ||
diff --git a/arch/x86/kernel/pci-swiotlb_64.c b/arch/x86/kernel/pci-swiotlb_64.c index 20df839b9c20..c4ce0332759e 100644 --- a/arch/x86/kernel/pci-swiotlb_64.c +++ b/arch/x86/kernel/pci-swiotlb_64.c | |||
@@ -18,7 +18,7 @@ swiotlb_map_single_phys(struct device *hwdev, phys_addr_t paddr, size_t size, | |||
18 | return swiotlb_map_single(hwdev, phys_to_virt(paddr), size, direction); | 18 | return swiotlb_map_single(hwdev, phys_to_virt(paddr), size, direction); |
19 | } | 19 | } |
20 | 20 | ||
21 | const struct dma_mapping_ops swiotlb_dma_ops = { | 21 | struct dma_mapping_ops swiotlb_dma_ops = { |
22 | .mapping_error = swiotlb_dma_mapping_error, | 22 | .mapping_error = swiotlb_dma_mapping_error, |
23 | .alloc_coherent = swiotlb_alloc_coherent, | 23 | .alloc_coherent = swiotlb_alloc_coherent, |
24 | .free_coherent = swiotlb_free_coherent, | 24 | .free_coherent = swiotlb_free_coherent, |
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 68f4ae2ac99a..ae584f87d06a 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c | |||
@@ -95,7 +95,6 @@ static inline void play_dead(void) | |||
95 | { | 95 | { |
96 | /* This must be done before dead CPU ack */ | 96 | /* This must be done before dead CPU ack */ |
97 | cpu_exit_clear(); | 97 | cpu_exit_clear(); |
98 | wbinvd(); | ||
99 | mb(); | 98 | mb(); |
100 | /* Ack it */ | 99 | /* Ack it */ |
101 | __get_cpu_var(cpu_state) = CPU_DEAD; | 100 | __get_cpu_var(cpu_state) = CPU_DEAD; |
@@ -104,8 +103,8 @@ static inline void play_dead(void) | |||
104 | * With physical CPU hotplug, we should halt the cpu | 103 | * With physical CPU hotplug, we should halt the cpu |
105 | */ | 104 | */ |
106 | local_irq_disable(); | 105 | local_irq_disable(); |
107 | while (1) | 106 | /* mask all interrupts, flush any and all caches, and halt */ |
108 | halt(); | 107 | wbinvd_halt(); |
109 | } | 108 | } |
110 | #else | 109 | #else |
111 | static inline void play_dead(void) | 110 | static inline void play_dead(void) |
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 91ffce47af8e..30ce4734edaa 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
@@ -93,14 +93,13 @@ DECLARE_PER_CPU(int, cpu_state); | |||
93 | static inline void play_dead(void) | 93 | static inline void play_dead(void) |
94 | { | 94 | { |
95 | idle_task_exit(); | 95 | idle_task_exit(); |
96 | wbinvd(); | ||
97 | mb(); | 96 | mb(); |
98 | /* Ack it */ | 97 | /* Ack it */ |
99 | __get_cpu_var(cpu_state) = CPU_DEAD; | 98 | __get_cpu_var(cpu_state) = CPU_DEAD; |
100 | 99 | ||
101 | local_irq_disable(); | 100 | local_irq_disable(); |
102 | while (1) | 101 | /* mask all interrupts, flush any and all caches, and halt */ |
103 | halt(); | 102 | wbinvd_halt(); |
104 | } | 103 | } |
105 | #else | 104 | #else |
106 | static inline void play_dead(void) | 105 | static inline void play_dead(void) |
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 06a9f643817e..724adfc63cb9 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c | |||
@@ -414,25 +414,20 @@ void native_machine_shutdown(void) | |||
414 | 414 | ||
415 | /* The boot cpu is always logical cpu 0 */ | 415 | /* The boot cpu is always logical cpu 0 */ |
416 | int reboot_cpu_id = 0; | 416 | int reboot_cpu_id = 0; |
417 | cpumask_of_cpu_ptr(newmask, reboot_cpu_id); | ||
418 | 417 | ||
419 | #ifdef CONFIG_X86_32 | 418 | #ifdef CONFIG_X86_32 |
420 | /* See if there has been given a command line override */ | 419 | /* See if there has been given a command line override */ |
421 | if ((reboot_cpu != -1) && (reboot_cpu < NR_CPUS) && | 420 | if ((reboot_cpu != -1) && (reboot_cpu < NR_CPUS) && |
422 | cpu_online(reboot_cpu)) { | 421 | cpu_online(reboot_cpu)) |
423 | reboot_cpu_id = reboot_cpu; | 422 | reboot_cpu_id = reboot_cpu; |
424 | cpumask_of_cpu_ptr_next(newmask, reboot_cpu_id); | ||
425 | } | ||
426 | #endif | 423 | #endif |
427 | 424 | ||
428 | /* Make certain the cpu I'm about to reboot on is online */ | 425 | /* Make certain the cpu I'm about to reboot on is online */ |
429 | if (!cpu_online(reboot_cpu_id)) { | 426 | if (!cpu_online(reboot_cpu_id)) |
430 | reboot_cpu_id = smp_processor_id(); | 427 | reboot_cpu_id = smp_processor_id(); |
431 | cpumask_of_cpu_ptr_next(newmask, reboot_cpu_id); | ||
432 | } | ||
433 | 428 | ||
434 | /* Make certain I only run on the appropriate processor */ | 429 | /* Make certain I only run on the appropriate processor */ |
435 | set_cpus_allowed_ptr(current, newmask); | 430 | set_cpus_allowed_ptr(current, &cpumask_of_cpu(reboot_cpu_id)); |
436 | 431 | ||
437 | /* O.K Now that I'm on the appropriate processor, | 432 | /* O.K Now that I'm on the appropriate processor, |
438 | * stop all of the others. | 433 | * stop all of the others. |
diff --git a/arch/x86/kernel/relocate_kernel_32.S b/arch/x86/kernel/relocate_kernel_32.S index c30fe25d470d..6f50664b2ba5 100644 --- a/arch/x86/kernel/relocate_kernel_32.S +++ b/arch/x86/kernel/relocate_kernel_32.S | |||
@@ -20,11 +20,45 @@ | |||
20 | #define PAGE_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) | 20 | #define PAGE_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) |
21 | #define PAE_PGD_ATTR (_PAGE_PRESENT) | 21 | #define PAE_PGD_ATTR (_PAGE_PRESENT) |
22 | 22 | ||
23 | /* control_page + KEXEC_CONTROL_CODE_MAX_SIZE | ||
24 | * ~ control_page + PAGE_SIZE are used as data storage and stack for | ||
25 | * jumping back | ||
26 | */ | ||
27 | #define DATA(offset) (KEXEC_CONTROL_CODE_MAX_SIZE+(offset)) | ||
28 | |||
29 | /* Minimal CPU state */ | ||
30 | #define ESP DATA(0x0) | ||
31 | #define CR0 DATA(0x4) | ||
32 | #define CR3 DATA(0x8) | ||
33 | #define CR4 DATA(0xc) | ||
34 | |||
35 | /* other data */ | ||
36 | #define CP_VA_CONTROL_PAGE DATA(0x10) | ||
37 | #define CP_PA_PGD DATA(0x14) | ||
38 | #define CP_PA_SWAP_PAGE DATA(0x18) | ||
39 | #define CP_PA_BACKUP_PAGES_MAP DATA(0x1c) | ||
40 | |||
23 | .text | 41 | .text |
24 | .align PAGE_SIZE | 42 | .align PAGE_SIZE |
25 | .globl relocate_kernel | 43 | .globl relocate_kernel |
26 | relocate_kernel: | 44 | relocate_kernel: |
27 | movl 8(%esp), %ebp /* list of pages */ | 45 | /* Save the CPU context, used for jumping back */ |
46 | |||
47 | pushl %ebx | ||
48 | pushl %esi | ||
49 | pushl %edi | ||
50 | pushl %ebp | ||
51 | pushf | ||
52 | |||
53 | movl 20+8(%esp), %ebp /* list of pages */ | ||
54 | movl PTR(VA_CONTROL_PAGE)(%ebp), %edi | ||
55 | movl %esp, ESP(%edi) | ||
56 | movl %cr0, %eax | ||
57 | movl %eax, CR0(%edi) | ||
58 | movl %cr3, %eax | ||
59 | movl %eax, CR3(%edi) | ||
60 | movl %cr4, %eax | ||
61 | movl %eax, CR4(%edi) | ||
28 | 62 | ||
29 | #ifdef CONFIG_X86_PAE | 63 | #ifdef CONFIG_X86_PAE |
30 | /* map the control page at its virtual address */ | 64 | /* map the control page at its virtual address */ |
@@ -138,15 +172,25 @@ relocate_kernel: | |||
138 | 172 | ||
139 | relocate_new_kernel: | 173 | relocate_new_kernel: |
140 | /* read the arguments and say goodbye to the stack */ | 174 | /* read the arguments and say goodbye to the stack */ |
141 | movl 4(%esp), %ebx /* page_list */ | 175 | movl 20+4(%esp), %ebx /* page_list */ |
142 | movl 8(%esp), %ebp /* list of pages */ | 176 | movl 20+8(%esp), %ebp /* list of pages */ |
143 | movl 12(%esp), %edx /* start address */ | 177 | movl 20+12(%esp), %edx /* start address */ |
144 | movl 16(%esp), %ecx /* cpu_has_pae */ | 178 | movl 20+16(%esp), %ecx /* cpu_has_pae */ |
179 | movl 20+20(%esp), %esi /* preserve_context */ | ||
145 | 180 | ||
146 | /* zero out flags, and disable interrupts */ | 181 | /* zero out flags, and disable interrupts */ |
147 | pushl $0 | 182 | pushl $0 |
148 | popfl | 183 | popfl |
149 | 184 | ||
185 | /* save some information for jumping back */ | ||
186 | movl PTR(VA_CONTROL_PAGE)(%ebp), %edi | ||
187 | movl %edi, CP_VA_CONTROL_PAGE(%edi) | ||
188 | movl PTR(PA_PGD)(%ebp), %eax | ||
189 | movl %eax, CP_PA_PGD(%edi) | ||
190 | movl PTR(PA_SWAP_PAGE)(%ebp), %eax | ||
191 | movl %eax, CP_PA_SWAP_PAGE(%edi) | ||
192 | movl %ebx, CP_PA_BACKUP_PAGES_MAP(%edi) | ||
193 | |||
150 | /* get physical address of control page now */ | 194 | /* get physical address of control page now */ |
151 | /* this is impossible after page table switch */ | 195 | /* this is impossible after page table switch */ |
152 | movl PTR(PA_CONTROL_PAGE)(%ebp), %edi | 196 | movl PTR(PA_CONTROL_PAGE)(%ebp), %edi |
@@ -197,8 +241,90 @@ identity_mapped: | |||
197 | xorl %eax, %eax | 241 | xorl %eax, %eax |
198 | movl %eax, %cr3 | 242 | movl %eax, %cr3 |
199 | 243 | ||
244 | movl CP_PA_SWAP_PAGE(%edi), %eax | ||
245 | pushl %eax | ||
246 | pushl %ebx | ||
247 | call swap_pages | ||
248 | addl $8, %esp | ||
249 | |||
250 | /* To be certain of avoiding problems with self-modifying code | ||
251 | * I need to execute a serializing instruction here. | ||
252 | * So I flush the TLB, it's handy, and not processor dependent. | ||
253 | */ | ||
254 | xorl %eax, %eax | ||
255 | movl %eax, %cr3 | ||
256 | |||
257 | /* set all of the registers to known values */ | ||
258 | /* leave %esp alone */ | ||
259 | |||
260 | testl %esi, %esi | ||
261 | jnz 1f | ||
262 | xorl %edi, %edi | ||
263 | xorl %eax, %eax | ||
264 | xorl %ebx, %ebx | ||
265 | xorl %ecx, %ecx | ||
266 | xorl %edx, %edx | ||
267 | xorl %esi, %esi | ||
268 | xorl %ebp, %ebp | ||
269 | ret | ||
270 | 1: | ||
271 | popl %edx | ||
272 | movl CP_PA_SWAP_PAGE(%edi), %esp | ||
273 | addl $PAGE_SIZE, %esp | ||
274 | 2: | ||
275 | call *%edx | ||
276 | |||
277 | /* get the re-entry point of the peer system */ | ||
278 | movl 0(%esp), %ebp | ||
279 | call 1f | ||
280 | 1: | ||
281 | popl %ebx | ||
282 | subl $(1b - relocate_kernel), %ebx | ||
283 | movl CP_VA_CONTROL_PAGE(%ebx), %edi | ||
284 | lea PAGE_SIZE(%ebx), %esp | ||
285 | movl CP_PA_SWAP_PAGE(%ebx), %eax | ||
286 | movl CP_PA_BACKUP_PAGES_MAP(%ebx), %edx | ||
287 | pushl %eax | ||
288 | pushl %edx | ||
289 | call swap_pages | ||
290 | addl $8, %esp | ||
291 | movl CP_PA_PGD(%ebx), %eax | ||
292 | movl %eax, %cr3 | ||
293 | movl %cr0, %eax | ||
294 | orl $(1<<31), %eax | ||
295 | movl %eax, %cr0 | ||
296 | lea PAGE_SIZE(%edi), %esp | ||
297 | movl %edi, %eax | ||
298 | addl $(virtual_mapped - relocate_kernel), %eax | ||
299 | pushl %eax | ||
300 | ret | ||
301 | |||
302 | virtual_mapped: | ||
303 | movl CR4(%edi), %eax | ||
304 | movl %eax, %cr4 | ||
305 | movl CR3(%edi), %eax | ||
306 | movl %eax, %cr3 | ||
307 | movl CR0(%edi), %eax | ||
308 | movl %eax, %cr0 | ||
309 | movl ESP(%edi), %esp | ||
310 | movl %ebp, %eax | ||
311 | |||
312 | popf | ||
313 | popl %ebp | ||
314 | popl %edi | ||
315 | popl %esi | ||
316 | popl %ebx | ||
317 | ret | ||
318 | |||
200 | /* Do the copies */ | 319 | /* Do the copies */ |
201 | movl %ebx, %ecx | 320 | swap_pages: |
321 | movl 8(%esp), %edx | ||
322 | movl 4(%esp), %ecx | ||
323 | pushl %ebp | ||
324 | pushl %ebx | ||
325 | pushl %edi | ||
326 | pushl %esi | ||
327 | movl %ecx, %ebx | ||
202 | jmp 1f | 328 | jmp 1f |
203 | 329 | ||
204 | 0: /* top, read another word from the indirection page */ | 330 | 0: /* top, read another word from the indirection page */ |
@@ -226,27 +352,31 @@ identity_mapped: | |||
226 | movl %ecx, %esi /* For every source page do a copy */ | 352 | movl %ecx, %esi /* For every source page do a copy */ |
227 | andl $0xfffff000, %esi | 353 | andl $0xfffff000, %esi |
228 | 354 | ||
355 | movl %edi, %eax | ||
356 | movl %esi, %ebp | ||
357 | |||
358 | movl %edx, %edi | ||
229 | movl $1024, %ecx | 359 | movl $1024, %ecx |
230 | rep ; movsl | 360 | rep ; movsl |
231 | jmp 0b | ||
232 | |||
233 | 3: | ||
234 | 361 | ||
235 | /* To be certain of avoiding problems with self-modifying code | 362 | movl %ebp, %edi |
236 | * I need to execute a serializing instruction here. | 363 | movl %eax, %esi |
237 | * So I flush the TLB, it's handy, and not processor dependent. | 364 | movl $1024, %ecx |
238 | */ | 365 | rep ; movsl |
239 | xorl %eax, %eax | ||
240 | movl %eax, %cr3 | ||
241 | 366 | ||
242 | /* set all of the registers to known values */ | 367 | movl %eax, %edi |
243 | /* leave %esp alone */ | 368 | movl %edx, %esi |
369 | movl $1024, %ecx | ||
370 | rep ; movsl | ||
244 | 371 | ||
245 | xorl %eax, %eax | 372 | lea PAGE_SIZE(%ebp), %esi |
246 | xorl %ebx, %ebx | 373 | jmp 0b |
247 | xorl %ecx, %ecx | 374 | 3: |
248 | xorl %edx, %edx | 375 | popl %esi |
249 | xorl %esi, %esi | 376 | popl %edi |
250 | xorl %edi, %edi | 377 | popl %ebx |
251 | xorl %ebp, %ebp | 378 | popl %ebp |
252 | ret | 379 | ret |
380 | |||
381 | .globl kexec_control_code_size | ||
382 | .set kexec_control_code_size, . - relocate_kernel | ||
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index b520dae02bf4..9838f2539dfc 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -445,7 +445,7 @@ static void __init reserve_early_setup_data(void) | |||
445 | * @size: Size of the crashkernel memory to reserve. | 445 | * @size: Size of the crashkernel memory to reserve. |
446 | * Returns the base address on success, and -1ULL on failure. | 446 | * Returns the base address on success, and -1ULL on failure. |
447 | */ | 447 | */ |
448 | unsigned long long find_and_reserve_crashkernel(unsigned long long size) | 448 | unsigned long long __init find_and_reserve_crashkernel(unsigned long long size) |
449 | { | 449 | { |
450 | const unsigned long long alignment = 16<<20; /* 16M */ | 450 | const unsigned long long alignment = 16<<20; /* 16M */ |
451 | unsigned long long start = 0LL; | 451 | unsigned long long start = 0LL; |
@@ -670,6 +670,18 @@ void __init setup_arch(char **cmdline_p) | |||
670 | 670 | ||
671 | parse_early_param(); | 671 | parse_early_param(); |
672 | 672 | ||
673 | #ifdef CONFIG_X86_64 | ||
674 | check_efer(); | ||
675 | #endif | ||
676 | |||
677 | #if defined(CONFIG_VMI) && defined(CONFIG_X86_32) | ||
678 | /* | ||
679 | * Must be before kernel pagetables are setup | ||
680 | * or fixmap area is touched. | ||
681 | */ | ||
682 | vmi_init(); | ||
683 | #endif | ||
684 | |||
673 | /* after early param, so could get panic from serial */ | 685 | /* after early param, so could get panic from serial */ |
674 | reserve_early_setup_data(); | 686 | reserve_early_setup_data(); |
675 | 687 | ||
@@ -730,7 +742,6 @@ void __init setup_arch(char **cmdline_p) | |||
730 | #else | 742 | #else |
731 | num_physpages = max_pfn; | 743 | num_physpages = max_pfn; |
732 | 744 | ||
733 | check_efer(); | ||
734 | 745 | ||
735 | /* How many end-of-memory variables you have, grandma! */ | 746 | /* How many end-of-memory variables you have, grandma! */ |
736 | /* need this before calling reserve_initrd */ | 747 | /* need this before calling reserve_initrd */ |
@@ -788,10 +799,6 @@ void __init setup_arch(char **cmdline_p) | |||
788 | 799 | ||
789 | initmem_init(0, max_pfn); | 800 | initmem_init(0, max_pfn); |
790 | 801 | ||
791 | #ifdef CONFIG_X86_64 | ||
792 | dma32_reserve_bootmem(); | ||
793 | #endif | ||
794 | |||
795 | #ifdef CONFIG_ACPI_SLEEP | 802 | #ifdef CONFIG_ACPI_SLEEP |
796 | /* | 803 | /* |
797 | * Reserve low memory region for sleep support. | 804 | * Reserve low memory region for sleep support. |
@@ -806,20 +813,21 @@ void __init setup_arch(char **cmdline_p) | |||
806 | #endif | 813 | #endif |
807 | reserve_crashkernel(); | 814 | reserve_crashkernel(); |
808 | 815 | ||
816 | #ifdef CONFIG_X86_64 | ||
817 | /* | ||
818 | * dma32_reserve_bootmem() allocates bootmem which may conflict | ||
819 | * with the crashkernel command line, so do that after | ||
820 | * reserve_crashkernel() | ||
821 | */ | ||
822 | dma32_reserve_bootmem(); | ||
823 | #endif | ||
824 | |||
809 | reserve_ibft_region(); | 825 | reserve_ibft_region(); |
810 | 826 | ||
811 | #ifdef CONFIG_KVM_CLOCK | 827 | #ifdef CONFIG_KVM_CLOCK |
812 | kvmclock_init(); | 828 | kvmclock_init(); |
813 | #endif | 829 | #endif |
814 | 830 | ||
815 | #if defined(CONFIG_VMI) && defined(CONFIG_X86_32) | ||
816 | /* | ||
817 | * Must be after max_low_pfn is determined, and before kernel | ||
818 | * pagetables are setup. | ||
819 | */ | ||
820 | vmi_init(); | ||
821 | #endif | ||
822 | |||
823 | paravirt_pagetable_setup_start(swapper_pg_dir); | 831 | paravirt_pagetable_setup_start(swapper_pg_dir); |
824 | paging_init(); | 832 | paging_init(); |
825 | paravirt_pagetable_setup_done(swapper_pg_dir); | 833 | paravirt_pagetable_setup_done(swapper_pg_dir); |
@@ -856,12 +864,6 @@ void __init setup_arch(char **cmdline_p) | |||
856 | init_apic_mappings(); | 864 | init_apic_mappings(); |
857 | ioapic_init_mappings(); | 865 | ioapic_init_mappings(); |
858 | 866 | ||
859 | #if defined(CONFIG_SMP) && defined(CONFIG_X86_PC) && defined(CONFIG_X86_32) | ||
860 | if (def_to_bigsmp) | ||
861 | printk(KERN_WARNING "More than 8 CPUs detected and " | ||
862 | "CONFIG_X86_PC cannot handle it.\nUse " | ||
863 | "CONFIG_X86_GENERICARCH or CONFIG_X86_BIGSMP.\n"); | ||
864 | #endif | ||
865 | kvm_guest_init(); | 867 | kvm_guest_init(); |
866 | 868 | ||
867 | e820_reserve_resources(); | 869 | e820_reserve_resources(); |
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index f7745f94c006..76e305e064f9 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c | |||
@@ -80,24 +80,6 @@ static void __init setup_per_cpu_maps(void) | |||
80 | #endif | 80 | #endif |
81 | } | 81 | } |
82 | 82 | ||
83 | #ifdef CONFIG_HAVE_CPUMASK_OF_CPU_MAP | ||
84 | cpumask_t *cpumask_of_cpu_map __read_mostly; | ||
85 | EXPORT_SYMBOL(cpumask_of_cpu_map); | ||
86 | |||
87 | /* requires nr_cpu_ids to be initialized */ | ||
88 | static void __init setup_cpumask_of_cpu(void) | ||
89 | { | ||
90 | int i; | ||
91 | |||
92 | /* alloc_bootmem zeroes memory */ | ||
93 | cpumask_of_cpu_map = alloc_bootmem_low(sizeof(cpumask_t) * nr_cpu_ids); | ||
94 | for (i = 0; i < nr_cpu_ids; i++) | ||
95 | cpu_set(i, cpumask_of_cpu_map[i]); | ||
96 | } | ||
97 | #else | ||
98 | static inline void setup_cpumask_of_cpu(void) { } | ||
99 | #endif | ||
100 | |||
101 | #ifdef CONFIG_X86_32 | 83 | #ifdef CONFIG_X86_32 |
102 | /* | 84 | /* |
103 | * Great future not-so-futuristic plan: make i386 and x86_64 do it | 85 | * Great future not-so-futuristic plan: make i386 and x86_64 do it |
@@ -197,9 +179,6 @@ void __init setup_per_cpu_areas(void) | |||
197 | 179 | ||
198 | /* Setup node to cpumask map */ | 180 | /* Setup node to cpumask map */ |
199 | setup_node_to_cpumask_map(); | 181 | setup_node_to_cpumask_map(); |
200 | |||
201 | /* Setup cpumask_of_cpu map */ | ||
202 | setup_cpumask_of_cpu(); | ||
203 | } | 182 | } |
204 | 183 | ||
205 | #endif | 184 | #endif |
diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c index b45ef8ddd651..ca316b5b742c 100644 --- a/arch/x86/kernel/signal_64.c +++ b/arch/x86/kernel/signal_64.c | |||
@@ -104,7 +104,16 @@ static inline int restore_i387(struct _fpstate __user *buf) | |||
104 | clts(); | 104 | clts(); |
105 | task_thread_info(current)->status |= TS_USEDFPU; | 105 | task_thread_info(current)->status |= TS_USEDFPU; |
106 | } | 106 | } |
107 | return restore_fpu_checking((__force struct i387_fxsave_struct *)buf); | 107 | err = restore_fpu_checking((__force struct i387_fxsave_struct *)buf); |
108 | if (unlikely(err)) { | ||
109 | /* | ||
110 | * Encountered an error while doing the restore from the | ||
111 | * user buffer, clear the fpu state. | ||
112 | */ | ||
113 | clear_fpu(tsk); | ||
114 | clear_used_math(); | ||
115 | } | ||
116 | return err; | ||
108 | } | 117 | } |
109 | 118 | ||
110 | /* | 119 | /* |
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 332512767f4f..7985c5b3f916 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
@@ -326,12 +326,16 @@ static void __cpuinit start_secondary(void *unused) | |||
326 | * for which cpus receive the IPI. Holding this | 326 | * for which cpus receive the IPI. Holding this |
327 | * lock helps us to not include this cpu in a currently in progress | 327 | * lock helps us to not include this cpu in a currently in progress |
328 | * smp_call_function(). | 328 | * smp_call_function(). |
329 | * | ||
330 | * We need to hold vector_lock so there the set of online cpus | ||
331 | * does not change while we are assigning vectors to cpus. Holding | ||
332 | * this lock ensures we don't half assign or remove an irq from a cpu. | ||
329 | */ | 333 | */ |
330 | ipi_call_lock_irq(); | 334 | ipi_call_lock_irq(); |
331 | #ifdef CONFIG_X86_IO_APIC | 335 | lock_vector_lock(); |
332 | setup_vector_irq(smp_processor_id()); | 336 | __setup_vector_irq(smp_processor_id()); |
333 | #endif | ||
334 | cpu_set(smp_processor_id(), cpu_online_map); | 337 | cpu_set(smp_processor_id(), cpu_online_map); |
338 | unlock_vector_lock(); | ||
335 | ipi_call_unlock_irq(); | 339 | ipi_call_unlock_irq(); |
336 | per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; | 340 | per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; |
337 | 341 | ||
@@ -752,6 +756,14 @@ static void __cpuinit do_fork_idle(struct work_struct *work) | |||
752 | } | 756 | } |
753 | 757 | ||
754 | #ifdef CONFIG_X86_64 | 758 | #ifdef CONFIG_X86_64 |
759 | |||
760 | /* __ref because it's safe to call free_bootmem when after_bootmem == 0. */ | ||
761 | static void __ref free_bootmem_pda(struct x8664_pda *oldpda) | ||
762 | { | ||
763 | if (!after_bootmem) | ||
764 | free_bootmem((unsigned long)oldpda, sizeof(*oldpda)); | ||
765 | } | ||
766 | |||
755 | /* | 767 | /* |
756 | * Allocate node local memory for the AP pda. | 768 | * Allocate node local memory for the AP pda. |
757 | * | 769 | * |
@@ -780,8 +792,7 @@ int __cpuinit get_local_pda(int cpu) | |||
780 | 792 | ||
781 | if (oldpda) { | 793 | if (oldpda) { |
782 | memcpy(newpda, oldpda, size); | 794 | memcpy(newpda, oldpda, size); |
783 | if (!after_bootmem) | 795 | free_bootmem_pda(oldpda); |
784 | free_bootmem((unsigned long)oldpda, size); | ||
785 | } | 796 | } |
786 | 797 | ||
787 | newpda->in_bootmem = 0; | 798 | newpda->in_bootmem = 0; |
@@ -1044,6 +1055,34 @@ static __init void disable_smp(void) | |||
1044 | static int __init smp_sanity_check(unsigned max_cpus) | 1055 | static int __init smp_sanity_check(unsigned max_cpus) |
1045 | { | 1056 | { |
1046 | preempt_disable(); | 1057 | preempt_disable(); |
1058 | |||
1059 | #if defined(CONFIG_X86_PC) && defined(CONFIG_X86_32) | ||
1060 | if (def_to_bigsmp && nr_cpu_ids > 8) { | ||
1061 | unsigned int cpu; | ||
1062 | unsigned nr; | ||
1063 | |||
1064 | printk(KERN_WARNING | ||
1065 | "More than 8 CPUs detected - skipping them.\n" | ||
1066 | "Use CONFIG_X86_GENERICARCH and CONFIG_X86_BIGSMP.\n"); | ||
1067 | |||
1068 | nr = 0; | ||
1069 | for_each_present_cpu(cpu) { | ||
1070 | if (nr >= 8) | ||
1071 | cpu_clear(cpu, cpu_present_map); | ||
1072 | nr++; | ||
1073 | } | ||
1074 | |||
1075 | nr = 0; | ||
1076 | for_each_possible_cpu(cpu) { | ||
1077 | if (nr >= 8) | ||
1078 | cpu_clear(cpu, cpu_possible_map); | ||
1079 | nr++; | ||
1080 | } | ||
1081 | |||
1082 | nr_cpu_ids = 8; | ||
1083 | } | ||
1084 | #endif | ||
1085 | |||
1047 | if (!physid_isset(hard_smp_processor_id(), phys_cpu_present_map)) { | 1086 | if (!physid_isset(hard_smp_processor_id(), phys_cpu_present_map)) { |
1048 | printk(KERN_WARNING "weird, boot CPU (#%d) not listed" | 1087 | printk(KERN_WARNING "weird, boot CPU (#%d) not listed" |
1049 | "by the BIOS.\n", hard_smp_processor_id()); | 1088 | "by the BIOS.\n", hard_smp_processor_id()); |
@@ -1182,6 +1221,9 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus) | |||
1182 | printk(KERN_INFO "CPU%d: ", 0); | 1221 | printk(KERN_INFO "CPU%d: ", 0); |
1183 | print_cpu_info(&cpu_data(0)); | 1222 | print_cpu_info(&cpu_data(0)); |
1184 | setup_boot_clock(); | 1223 | setup_boot_clock(); |
1224 | |||
1225 | if (is_uv_system()) | ||
1226 | uv_system_init(); | ||
1185 | out: | 1227 | out: |
1186 | preempt_enable(); | 1228 | preempt_enable(); |
1187 | } | 1229 | } |
@@ -1336,7 +1378,9 @@ int __cpu_disable(void) | |||
1336 | remove_siblinginfo(cpu); | 1378 | remove_siblinginfo(cpu); |
1337 | 1379 | ||
1338 | /* It's now safe to remove this processor from the online map */ | 1380 | /* It's now safe to remove this processor from the online map */ |
1381 | lock_vector_lock(); | ||
1339 | remove_cpu_from_maps(cpu); | 1382 | remove_cpu_from_maps(cpu); |
1383 | unlock_vector_lock(); | ||
1340 | fixup_irqs(cpu_online_map); | 1384 | fixup_irqs(cpu_online_map); |
1341 | return 0; | 1385 | return 0; |
1342 | } | 1386 | } |
@@ -1370,17 +1414,3 @@ void __cpu_die(unsigned int cpu) | |||
1370 | BUG(); | 1414 | BUG(); |
1371 | } | 1415 | } |
1372 | #endif | 1416 | #endif |
1373 | |||
1374 | /* | ||
1375 | * If the BIOS enumerates physical processors before logical, | ||
1376 | * maxcpus=N at enumeration-time can be used to disable HT. | ||
1377 | */ | ||
1378 | static int __init parse_maxcpus(char *arg) | ||
1379 | { | ||
1380 | extern unsigned int maxcpus; | ||
1381 | |||
1382 | if (arg) | ||
1383 | maxcpus = simple_strtoul(arg, NULL, 0); | ||
1384 | return 0; | ||
1385 | } | ||
1386 | early_param("maxcpus", parse_maxcpus); | ||
diff --git a/arch/x86/kernel/smpcommon.c b/arch/x86/kernel/smpcommon.c index 99941b37eca0..397e309839dd 100644 --- a/arch/x86/kernel/smpcommon.c +++ b/arch/x86/kernel/smpcommon.c | |||
@@ -8,18 +8,21 @@ | |||
8 | DEFINE_PER_CPU(unsigned long, this_cpu_off); | 8 | DEFINE_PER_CPU(unsigned long, this_cpu_off); |
9 | EXPORT_PER_CPU_SYMBOL(this_cpu_off); | 9 | EXPORT_PER_CPU_SYMBOL(this_cpu_off); |
10 | 10 | ||
11 | /* Initialize the CPU's GDT. This is either the boot CPU doing itself | 11 | /* |
12 | (still using the master per-cpu area), or a CPU doing it for a | 12 | * Initialize the CPU's GDT. This is either the boot CPU doing itself |
13 | secondary which will soon come up. */ | 13 | * (still using the master per-cpu area), or a CPU doing it for a |
14 | * secondary which will soon come up. | ||
15 | */ | ||
14 | __cpuinit void init_gdt(int cpu) | 16 | __cpuinit void init_gdt(int cpu) |
15 | { | 17 | { |
16 | struct desc_struct *gdt = get_cpu_gdt_table(cpu); | 18 | struct desc_struct gdt; |
17 | 19 | ||
18 | pack_descriptor(&gdt[GDT_ENTRY_PERCPU], | 20 | pack_descriptor(&gdt, __per_cpu_offset[cpu], 0xFFFFF, |
19 | __per_cpu_offset[cpu], 0xFFFFF, | ||
20 | 0x2 | DESCTYPE_S, 0x8); | 21 | 0x2 | DESCTYPE_S, 0x8); |
22 | gdt.s = 1; | ||
21 | 23 | ||
22 | gdt[GDT_ENTRY_PERCPU].s = 1; | 24 | write_gdt_entry(get_cpu_gdt_table(cpu), |
25 | GDT_ENTRY_PERCPU, &gdt, DESCTYPE_S); | ||
23 | 26 | ||
24 | per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu]; | 27 | per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu]; |
25 | per_cpu(cpu_number, cpu) = cpu; | 28 | per_cpu(cpu_number, cpu) = cpu; |
diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c index d0fbb7712ab0..8b8c0d6640fa 100644 --- a/arch/x86/kernel/tlb_uv.c +++ b/arch/x86/kernel/tlb_uv.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <asm/genapic.h> | 17 | #include <asm/genapic.h> |
18 | #include <asm/idle.h> | 18 | #include <asm/idle.h> |
19 | #include <asm/tsc.h> | 19 | #include <asm/tsc.h> |
20 | #include <asm/irq_vectors.h> | ||
20 | 21 | ||
21 | #include <mach_apic.h> | 22 | #include <mach_apic.h> |
22 | 23 | ||
@@ -783,7 +784,7 @@ static int __init uv_bau_init(void) | |||
783 | uv_init_blade(blade, node, cur_cpu); | 784 | uv_init_blade(blade, node, cur_cpu); |
784 | cur_cpu += uv_blade_nr_possible_cpus(blade); | 785 | cur_cpu += uv_blade_nr_possible_cpus(blade); |
785 | } | 786 | } |
786 | set_intr_gate(UV_BAU_MESSAGE, uv_bau_message_intr1); | 787 | alloc_intr_gate(UV_BAU_MESSAGE, uv_bau_message_intr1); |
787 | uv_enable_timeouts(); | 788 | uv_enable_timeouts(); |
788 | 789 | ||
789 | return 0; | 790 | return 0; |
diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c index 3f18d73f420c..513caaca7115 100644 --- a/arch/x86/kernel/traps_64.c +++ b/arch/x86/kernel/traps_64.c | |||
@@ -1131,7 +1131,14 @@ asmlinkage void math_state_restore(void) | |||
1131 | } | 1131 | } |
1132 | 1132 | ||
1133 | clts(); /* Allow maths ops (or we recurse) */ | 1133 | clts(); /* Allow maths ops (or we recurse) */ |
1134 | restore_fpu_checking(&me->thread.xstate->fxsave); | 1134 | /* |
1135 | * Paranoid restore. send a SIGSEGV if we fail to restore the state. | ||
1136 | */ | ||
1137 | if (unlikely(restore_fpu_checking(&me->thread.xstate->fxsave))) { | ||
1138 | stts(); | ||
1139 | force_sig(SIGSEGV, me); | ||
1140 | return; | ||
1141 | } | ||
1135 | task_thread_info(me)->status |= TS_USEDFPU; | 1142 | task_thread_info(me)->status |= TS_USEDFPU; |
1136 | me->fpu_counter++; | 1143 | me->fpu_counter++; |
1137 | } | 1144 | } |
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 7603c0553909..8f98e9de1b82 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c | |||
@@ -104,7 +104,7 @@ __setup("notsc", notsc_setup); | |||
104 | /* | 104 | /* |
105 | * Read TSC and the reference counters. Take care of SMI disturbance | 105 | * Read TSC and the reference counters. Take care of SMI disturbance |
106 | */ | 106 | */ |
107 | static u64 __init tsc_read_refs(u64 *pm, u64 *hpet) | 107 | static u64 tsc_read_refs(u64 *pm, u64 *hpet) |
108 | { | 108 | { |
109 | u64 t1, t2; | 109 | u64 t1, t2; |
110 | int i; | 110 | int i; |
@@ -122,80 +122,216 @@ static u64 __init tsc_read_refs(u64 *pm, u64 *hpet) | |||
122 | return ULLONG_MAX; | 122 | return ULLONG_MAX; |
123 | } | 123 | } |
124 | 124 | ||
125 | /** | 125 | /* |
126 | * native_calibrate_tsc - calibrate the tsc on boot | 126 | * Try to calibrate the TSC against the Programmable |
127 | * Interrupt Timer and return the frequency of the TSC | ||
128 | * in kHz. | ||
129 | * | ||
130 | * Return ULONG_MAX on failure to calibrate. | ||
127 | */ | 131 | */ |
128 | unsigned long native_calibrate_tsc(void) | 132 | static unsigned long pit_calibrate_tsc(void) |
129 | { | 133 | { |
130 | unsigned long flags; | 134 | u64 tsc, t1, t2, delta; |
131 | u64 tsc1, tsc2, tr1, tr2, delta, pm1, pm2, hpet1, hpet2; | 135 | unsigned long tscmin, tscmax; |
132 | int hpet = is_hpet_enabled(); | 136 | int pitcnt; |
133 | unsigned int tsc_khz_val = 0; | ||
134 | |||
135 | local_irq_save(flags); | ||
136 | |||
137 | tsc1 = tsc_read_refs(&pm1, hpet ? &hpet1 : NULL); | ||
138 | 137 | ||
138 | /* Set the Gate high, disable speaker */ | ||
139 | outb((inb(0x61) & ~0x02) | 0x01, 0x61); | 139 | outb((inb(0x61) & ~0x02) | 0x01, 0x61); |
140 | 140 | ||
141 | /* | ||
142 | * Setup CTC channel 2* for mode 0, (interrupt on terminal | ||
143 | * count mode), binary count. Set the latch register to 50ms | ||
144 | * (LSB then MSB) to begin countdown. | ||
145 | */ | ||
141 | outb(0xb0, 0x43); | 146 | outb(0xb0, 0x43); |
142 | outb((CLOCK_TICK_RATE / (1000 / 50)) & 0xff, 0x42); | 147 | outb((CLOCK_TICK_RATE / (1000 / 50)) & 0xff, 0x42); |
143 | outb((CLOCK_TICK_RATE / (1000 / 50)) >> 8, 0x42); | 148 | outb((CLOCK_TICK_RATE / (1000 / 50)) >> 8, 0x42); |
144 | tr1 = get_cycles(); | ||
145 | while ((inb(0x61) & 0x20) == 0); | ||
146 | tr2 = get_cycles(); | ||
147 | 149 | ||
148 | tsc2 = tsc_read_refs(&pm2, hpet ? &hpet2 : NULL); | 150 | tsc = t1 = t2 = get_cycles(); |
149 | 151 | ||
150 | local_irq_restore(flags); | 152 | pitcnt = 0; |
153 | tscmax = 0; | ||
154 | tscmin = ULONG_MAX; | ||
155 | while ((inb(0x61) & 0x20) == 0) { | ||
156 | t2 = get_cycles(); | ||
157 | delta = t2 - tsc; | ||
158 | tsc = t2; | ||
159 | if ((unsigned long) delta < tscmin) | ||
160 | tscmin = (unsigned int) delta; | ||
161 | if ((unsigned long) delta > tscmax) | ||
162 | tscmax = (unsigned int) delta; | ||
163 | pitcnt++; | ||
164 | } | ||
151 | 165 | ||
152 | /* | 166 | /* |
153 | * Preset the result with the raw and inaccurate PIT | 167 | * Sanity checks: |
154 | * calibration value | 168 | * |
169 | * If we were not able to read the PIT more than 5000 | ||
170 | * times, then we have been hit by a massive SMI | ||
171 | * | ||
172 | * If the maximum is 10 times larger than the minimum, | ||
173 | * then we got hit by an SMI as well. | ||
155 | */ | 174 | */ |
156 | delta = (tr2 - tr1); | 175 | if (pitcnt < 5000 || tscmax > 10 * tscmin) |
176 | return ULONG_MAX; | ||
177 | |||
178 | /* Calculate the PIT value */ | ||
179 | delta = t2 - t1; | ||
157 | do_div(delta, 50); | 180 | do_div(delta, 50); |
158 | tsc_khz_val = delta; | 181 | return delta; |
182 | } | ||
183 | |||
184 | |||
185 | /** | ||
186 | * native_calibrate_tsc - calibrate the tsc on boot | ||
187 | */ | ||
188 | unsigned long native_calibrate_tsc(void) | ||
189 | { | ||
190 | u64 tsc1, tsc2, delta, pm1, pm2, hpet1, hpet2; | ||
191 | unsigned long tsc_pit_min = ULONG_MAX, tsc_ref_min = ULONG_MAX; | ||
192 | unsigned long flags; | ||
193 | int hpet = is_hpet_enabled(), i; | ||
194 | |||
195 | /* | ||
196 | * Run 5 calibration loops to get the lowest frequency value | ||
197 | * (the best estimate). We use two different calibration modes | ||
198 | * here: | ||
199 | * | ||
200 | * 1) PIT loop. We set the PIT Channel 2 to oneshot mode and | ||
201 | * load a timeout of 50ms. We read the time right after we | ||
202 | * started the timer and wait until the PIT count down reaches | ||
203 | * zero. In each wait loop iteration we read the TSC and check | ||
204 | * the delta to the previous read. We keep track of the min | ||
205 | * and max values of that delta. The delta is mostly defined | ||
206 | * by the IO time of the PIT access, so we can detect when a | ||
207 | * SMI/SMM disturbance happend between the two reads. If the | ||
208 | * maximum time is significantly larger than the minimum time, | ||
209 | * then we discard the result and have another try. | ||
210 | * | ||
211 | * 2) Reference counter. If available we use the HPET or the | ||
212 | * PMTIMER as a reference to check the sanity of that value. | ||
213 | * We use separate TSC readouts and check inside of the | ||
214 | * reference read for a SMI/SMM disturbance. We dicard | ||
215 | * disturbed values here as well. We do that around the PIT | ||
216 | * calibration delay loop as we have to wait for a certain | ||
217 | * amount of time anyway. | ||
218 | */ | ||
219 | for (i = 0; i < 5; i++) { | ||
220 | unsigned long tsc_pit_khz; | ||
221 | |||
222 | /* | ||
223 | * Read the start value and the reference count of | ||
224 | * hpet/pmtimer when available. Then do the PIT | ||
225 | * calibration, which will take at least 50ms, and | ||
226 | * read the end value. | ||
227 | */ | ||
228 | local_irq_save(flags); | ||
229 | tsc1 = tsc_read_refs(&pm1, hpet ? &hpet1 : NULL); | ||
230 | tsc_pit_khz = pit_calibrate_tsc(); | ||
231 | tsc2 = tsc_read_refs(&pm2, hpet ? &hpet2 : NULL); | ||
232 | local_irq_restore(flags); | ||
233 | |||
234 | /* Pick the lowest PIT TSC calibration so far */ | ||
235 | tsc_pit_min = min(tsc_pit_min, tsc_pit_khz); | ||
236 | |||
237 | /* hpet or pmtimer available ? */ | ||
238 | if (!hpet && !pm1 && !pm2) | ||
239 | continue; | ||
240 | |||
241 | /* Check, whether the sampling was disturbed by an SMI */ | ||
242 | if (tsc1 == ULLONG_MAX || tsc2 == ULLONG_MAX) | ||
243 | continue; | ||
244 | |||
245 | tsc2 = (tsc2 - tsc1) * 1000000LL; | ||
246 | |||
247 | if (hpet) { | ||
248 | if (hpet2 < hpet1) | ||
249 | hpet2 += 0x100000000ULL; | ||
250 | hpet2 -= hpet1; | ||
251 | tsc1 = ((u64)hpet2 * hpet_readl(HPET_PERIOD)); | ||
252 | do_div(tsc1, 1000000); | ||
253 | } else { | ||
254 | if (pm2 < pm1) | ||
255 | pm2 += (u64)ACPI_PM_OVRRUN; | ||
256 | pm2 -= pm1; | ||
257 | tsc1 = pm2 * 1000000000LL; | ||
258 | do_div(tsc1, PMTMR_TICKS_PER_SEC); | ||
259 | } | ||
260 | |||
261 | do_div(tsc2, tsc1); | ||
262 | tsc_ref_min = min(tsc_ref_min, (unsigned long) tsc2); | ||
263 | } | ||
264 | |||
265 | /* | ||
266 | * Now check the results. | ||
267 | */ | ||
268 | if (tsc_pit_min == ULONG_MAX) { | ||
269 | /* PIT gave no useful value */ | ||
270 | printk(KERN_WARNING "TSC: Unable to calibrate against PIT\n"); | ||
271 | |||
272 | /* We don't have an alternative source, disable TSC */ | ||
273 | if (!hpet && !pm1 && !pm2) { | ||
274 | printk("TSC: No reference (HPET/PMTIMER) available\n"); | ||
275 | return 0; | ||
276 | } | ||
277 | |||
278 | /* The alternative source failed as well, disable TSC */ | ||
279 | if (tsc_ref_min == ULONG_MAX) { | ||
280 | printk(KERN_WARNING "TSC: HPET/PMTIMER calibration " | ||
281 | "failed due to SMI disturbance.\n"); | ||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | /* Use the alternative source */ | ||
286 | printk(KERN_INFO "TSC: using %s reference calibration\n", | ||
287 | hpet ? "HPET" : "PMTIMER"); | ||
288 | |||
289 | return tsc_ref_min; | ||
290 | } | ||
159 | 291 | ||
160 | /* hpet or pmtimer available ? */ | 292 | /* We don't have an alternative source, use the PIT calibration value */ |
161 | if (!hpet && !pm1 && !pm2) { | 293 | if (!hpet && !pm1 && !pm2) { |
162 | printk(KERN_INFO "TSC calibrated against PIT\n"); | 294 | printk(KERN_INFO "TSC: Using PIT calibration value\n"); |
163 | goto out; | 295 | return tsc_pit_min; |
164 | } | 296 | } |
165 | 297 | ||
166 | /* Check, whether the sampling was disturbed by an SMI */ | 298 | /* The alternative source failed, use the PIT calibration value */ |
167 | if (tsc1 == ULLONG_MAX || tsc2 == ULLONG_MAX) { | 299 | if (tsc_ref_min == ULONG_MAX) { |
168 | printk(KERN_WARNING "TSC calibration disturbed by SMI, " | 300 | printk(KERN_WARNING "TSC: HPET/PMTIMER calibration failed due " |
169 | "using PIT calibration result\n"); | 301 | "to SMI disturbance. Using PIT calibration\n"); |
170 | goto out; | 302 | return tsc_pit_min; |
171 | } | 303 | } |
172 | 304 | ||
173 | tsc2 = (tsc2 - tsc1) * 1000000LL; | 305 | /* Check the reference deviation */ |
174 | 306 | delta = ((u64) tsc_pit_min) * 100; | |
175 | if (hpet) { | 307 | do_div(delta, tsc_ref_min); |
176 | printk(KERN_INFO "TSC calibrated against HPET\n"); | 308 | |
177 | if (hpet2 < hpet1) | 309 | /* |
178 | hpet2 += 0x100000000ULL; | 310 | * If both calibration results are inside a 5% window, the we |
179 | hpet2 -= hpet1; | 311 | * use the lower frequency of those as it is probably the |
180 | tsc1 = ((u64)hpet2 * hpet_readl(HPET_PERIOD)); | 312 | * closest estimate. |
181 | do_div(tsc1, 1000000); | 313 | */ |
182 | } else { | 314 | if (delta >= 95 && delta <= 105) { |
183 | printk(KERN_INFO "TSC calibrated against PM_TIMER\n"); | 315 | printk(KERN_INFO "TSC: PIT calibration confirmed by %s.\n", |
184 | if (pm2 < pm1) | 316 | hpet ? "HPET" : "PMTIMER"); |
185 | pm2 += (u64)ACPI_PM_OVRRUN; | 317 | printk(KERN_INFO "TSC: using %s calibration value\n", |
186 | pm2 -= pm1; | 318 | tsc_pit_min <= tsc_ref_min ? "PIT" : |
187 | tsc1 = pm2 * 1000000000LL; | 319 | hpet ? "HPET" : "PMTIMER"); |
188 | do_div(tsc1, PMTMR_TICKS_PER_SEC); | 320 | return tsc_pit_min <= tsc_ref_min ? tsc_pit_min : tsc_ref_min; |
189 | } | 321 | } |
190 | 322 | ||
191 | do_div(tsc2, tsc1); | 323 | printk(KERN_WARNING "TSC: PIT calibration deviates from %s: %lu %lu.\n", |
192 | tsc_khz_val = tsc2; | 324 | hpet ? "HPET" : "PMTIMER", tsc_pit_min, tsc_ref_min); |
193 | 325 | ||
194 | out: | 326 | /* |
195 | return tsc_khz_val; | 327 | * The calibration values differ too much. In doubt, we use |
328 | * the PIT value as we know that there are PMTIMERs around | ||
329 | * running at double speed. | ||
330 | */ | ||
331 | printk(KERN_INFO "TSC: Using PIT calibration value\n"); | ||
332 | return tsc_pit_min; | ||
196 | } | 333 | } |
197 | 334 | ||
198 | |||
199 | #ifdef CONFIG_X86_32 | 335 | #ifdef CONFIG_X86_32 |
200 | /* Only called from the Powernow K7 cpu freq driver */ | 336 | /* Only called from the Powernow K7 cpu freq driver */ |
201 | int recalibrate_cpu_khz(void) | 337 | int recalibrate_cpu_khz(void) |
@@ -314,7 +450,7 @@ static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, | |||
314 | mark_tsc_unstable("cpufreq changes"); | 450 | mark_tsc_unstable("cpufreq changes"); |
315 | } | 451 | } |
316 | 452 | ||
317 | set_cyc2ns_scale(tsc_khz_ref, freq->cpu); | 453 | set_cyc2ns_scale(tsc_khz, freq->cpu); |
318 | 454 | ||
319 | return 0; | 455 | return 0; |
320 | } | 456 | } |
@@ -325,6 +461,10 @@ static struct notifier_block time_cpufreq_notifier_block = { | |||
325 | 461 | ||
326 | static int __init cpufreq_tsc(void) | 462 | static int __init cpufreq_tsc(void) |
327 | { | 463 | { |
464 | if (!cpu_has_tsc) | ||
465 | return 0; | ||
466 | if (boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) | ||
467 | return 0; | ||
328 | cpufreq_register_notifier(&time_cpufreq_notifier_block, | 468 | cpufreq_register_notifier(&time_cpufreq_notifier_block, |
329 | CPUFREQ_TRANSITION_NOTIFIER); | 469 | CPUFREQ_TRANSITION_NOTIFIER); |
330 | return 0; | 470 | return 0; |
diff --git a/arch/x86/kernel/tsc_sync.c b/arch/x86/kernel/tsc_sync.c index 0577825cf89b..9ffb01c31c40 100644 --- a/arch/x86/kernel/tsc_sync.c +++ b/arch/x86/kernel/tsc_sync.c | |||
@@ -88,11 +88,9 @@ static __cpuinit void check_tsc_warp(void) | |||
88 | __raw_spin_unlock(&sync_lock); | 88 | __raw_spin_unlock(&sync_lock); |
89 | } | 89 | } |
90 | } | 90 | } |
91 | if (!(now-start)) { | 91 | WARN(!(now-start), |
92 | printk("Warning: zero tsc calibration delta: %Ld [max: %Ld]\n", | 92 | "Warning: zero tsc calibration delta: %Ld [max: %Ld]\n", |
93 | now-start, end-start); | 93 | now-start, end-start); |
94 | WARN_ON(1); | ||
95 | } | ||
96 | } | 94 | } |
97 | 95 | ||
98 | /* | 96 | /* |
diff --git a/arch/x86/kernel/visws_quirks.c b/arch/x86/kernel/visws_quirks.c index 41e01b145c48..594ef47f0a63 100644 --- a/arch/x86/kernel/visws_quirks.c +++ b/arch/x86/kernel/visws_quirks.c | |||
@@ -184,8 +184,6 @@ static int __init visws_get_smp_config(unsigned int early) | |||
184 | return 1; | 184 | return 1; |
185 | } | 185 | } |
186 | 186 | ||
187 | extern unsigned int __cpuinitdata maxcpus; | ||
188 | |||
189 | /* | 187 | /* |
190 | * The Visual Workstation is Intel MP compliant in the hardware | 188 | * The Visual Workstation is Intel MP compliant in the hardware |
191 | * sense, but it doesn't have a BIOS(-configuration table). | 189 | * sense, but it doesn't have a BIOS(-configuration table). |
@@ -244,8 +242,8 @@ static int __init visws_find_smp_config(unsigned int reserve) | |||
244 | ncpus = CO_CPU_MAX; | 242 | ncpus = CO_CPU_MAX; |
245 | } | 243 | } |
246 | 244 | ||
247 | if (ncpus > maxcpus) | 245 | if (ncpus > setup_max_cpus) |
248 | ncpus = maxcpus; | 246 | ncpus = setup_max_cpus; |
249 | 247 | ||
250 | #ifdef CONFIG_X86_LOCAL_APIC | 248 | #ifdef CONFIG_X86_LOCAL_APIC |
251 | smp_found_config = 1; | 249 | smp_found_config = 1; |
diff --git a/arch/x86/kernel/vmi_32.c b/arch/x86/kernel/vmi_32.c index 0a1b1a9d922d..6ca515d6db54 100644 --- a/arch/x86/kernel/vmi_32.c +++ b/arch/x86/kernel/vmi_32.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <asm/timer.h> | 37 | #include <asm/timer.h> |
38 | #include <asm/vmi_time.h> | 38 | #include <asm/vmi_time.h> |
39 | #include <asm/kmap_types.h> | 39 | #include <asm/kmap_types.h> |
40 | #include <asm/setup.h> | ||
40 | 41 | ||
41 | /* Convenient for calling VMI functions indirectly in the ROM */ | 42 | /* Convenient for calling VMI functions indirectly in the ROM */ |
42 | typedef u32 __attribute__((regparm(1))) (VROMFUNC)(void); | 43 | typedef u32 __attribute__((regparm(1))) (VROMFUNC)(void); |
@@ -683,7 +684,7 @@ void vmi_bringup(void) | |||
683 | { | 684 | { |
684 | /* We must establish the lowmem mapping for MMU ops to work */ | 685 | /* We must establish the lowmem mapping for MMU ops to work */ |
685 | if (vmi_ops.set_linear_mapping) | 686 | if (vmi_ops.set_linear_mapping) |
686 | vmi_ops.set_linear_mapping(0, (void *)__PAGE_OFFSET, max_low_pfn, 0); | 687 | vmi_ops.set_linear_mapping(0, (void *)__PAGE_OFFSET, MAXMEM_PFN, 0); |
687 | } | 688 | } |
688 | 689 | ||
689 | /* | 690 | /* |
diff --git a/arch/x86/kernel/vmlinux_32.lds.S b/arch/x86/kernel/vmlinux_32.lds.S index cdb2363697d2..af5bdad84604 100644 --- a/arch/x86/kernel/vmlinux_32.lds.S +++ b/arch/x86/kernel/vmlinux_32.lds.S | |||
@@ -209,3 +209,11 @@ SECTIONS | |||
209 | 209 | ||
210 | DWARF_DEBUG | 210 | DWARF_DEBUG |
211 | } | 211 | } |
212 | |||
213 | #ifdef CONFIG_KEXEC | ||
214 | /* Link time checks */ | ||
215 | #include <asm/kexec.h> | ||
216 | |||
217 | ASSERT(kexec_control_code_size <= KEXEC_CONTROL_CODE_MAX_SIZE, | ||
218 | "kexec control code size is too big") | ||
219 | #endif | ||