diff options
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 3 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/perf_event.c | 10 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/perf_event_intel_uncore.c | 48 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/perf_event_knc.c | 93 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/perf_event_p6.c | 127 | ||||
-rw-r--r-- | arch/x86/kernel/e820.c | 3 | ||||
-rw-r--r-- | arch/x86/kernel/entry_32.S | 8 | ||||
-rw-r--r-- | arch/x86/kernel/entry_64.S | 2 | ||||
-rw-r--r-- | arch/x86/kernel/kvm.c | 3 | ||||
-rw-r--r-- | arch/x86/kernel/setup.c | 27 | ||||
-rw-r--r-- | arch/x86/kernel/signal.c | 4 | ||||
-rw-r--r-- | arch/x86/kernel/uprobes.c | 16 |
12 files changed, 269 insertions, 75 deletions
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index c265593ec2cd..1817fa911024 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -2257,6 +2257,9 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void) | |||
2257 | continue; | 2257 | continue; |
2258 | 2258 | ||
2259 | cfg = irq_cfg(irq); | 2259 | cfg = irq_cfg(irq); |
2260 | if (!cfg) | ||
2261 | continue; | ||
2262 | |||
2260 | raw_spin_lock(&desc->lock); | 2263 | raw_spin_lock(&desc->lock); |
2261 | 2264 | ||
2262 | /* | 2265 | /* |
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 3373f84d1397..4a3374e61a93 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
@@ -208,12 +208,14 @@ static bool check_hw_exists(void) | |||
208 | } | 208 | } |
209 | 209 | ||
210 | /* | 210 | /* |
211 | * Now write a value and read it back to see if it matches, | 211 | * Read the current value, change it and read it back to see if it |
212 | * this is needed to detect certain hardware emulators (qemu/kvm) | 212 | * matches, this is needed to detect certain hardware emulators |
213 | * that don't trap on the MSR access and always return 0s. | 213 | * (qemu/kvm) that don't trap on the MSR access and always return 0s. |
214 | */ | 214 | */ |
215 | val = 0xabcdUL; | ||
216 | reg = x86_pmu_event_addr(0); | 215 | reg = x86_pmu_event_addr(0); |
216 | if (rdmsrl_safe(reg, &val)) | ||
217 | goto msr_fail; | ||
218 | val ^= 0xffffUL; | ||
217 | ret = wrmsrl_safe(reg, val); | 219 | ret = wrmsrl_safe(reg, val); |
218 | ret |= rdmsrl_safe(reg, &val_new); | 220 | ret |= rdmsrl_safe(reg, &val_new); |
219 | if (ret || val != val_new) | 221 | if (ret || val != val_new) |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index 99d96a4978b5..3cf3d97cce3a 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c | |||
@@ -118,22 +118,24 @@ static void snbep_uncore_pci_disable_box(struct intel_uncore_box *box) | |||
118 | { | 118 | { |
119 | struct pci_dev *pdev = box->pci_dev; | 119 | struct pci_dev *pdev = box->pci_dev; |
120 | int box_ctl = uncore_pci_box_ctl(box); | 120 | int box_ctl = uncore_pci_box_ctl(box); |
121 | u32 config; | 121 | u32 config = 0; |
122 | 122 | ||
123 | pci_read_config_dword(pdev, box_ctl, &config); | 123 | if (!pci_read_config_dword(pdev, box_ctl, &config)) { |
124 | config |= SNBEP_PMON_BOX_CTL_FRZ; | 124 | config |= SNBEP_PMON_BOX_CTL_FRZ; |
125 | pci_write_config_dword(pdev, box_ctl, config); | 125 | pci_write_config_dword(pdev, box_ctl, config); |
126 | } | ||
126 | } | 127 | } |
127 | 128 | ||
128 | static void snbep_uncore_pci_enable_box(struct intel_uncore_box *box) | 129 | static void snbep_uncore_pci_enable_box(struct intel_uncore_box *box) |
129 | { | 130 | { |
130 | struct pci_dev *pdev = box->pci_dev; | 131 | struct pci_dev *pdev = box->pci_dev; |
131 | int box_ctl = uncore_pci_box_ctl(box); | 132 | int box_ctl = uncore_pci_box_ctl(box); |
132 | u32 config; | 133 | u32 config = 0; |
133 | 134 | ||
134 | pci_read_config_dword(pdev, box_ctl, &config); | 135 | if (!pci_read_config_dword(pdev, box_ctl, &config)) { |
135 | config &= ~SNBEP_PMON_BOX_CTL_FRZ; | 136 | config &= ~SNBEP_PMON_BOX_CTL_FRZ; |
136 | pci_write_config_dword(pdev, box_ctl, config); | 137 | pci_write_config_dword(pdev, box_ctl, config); |
138 | } | ||
137 | } | 139 | } |
138 | 140 | ||
139 | static void snbep_uncore_pci_enable_event(struct intel_uncore_box *box, struct perf_event *event) | 141 | static void snbep_uncore_pci_enable_event(struct intel_uncore_box *box, struct perf_event *event) |
@@ -156,7 +158,7 @@ static u64 snbep_uncore_pci_read_counter(struct intel_uncore_box *box, struct pe | |||
156 | { | 158 | { |
157 | struct pci_dev *pdev = box->pci_dev; | 159 | struct pci_dev *pdev = box->pci_dev; |
158 | struct hw_perf_event *hwc = &event->hw; | 160 | struct hw_perf_event *hwc = &event->hw; |
159 | u64 count; | 161 | u64 count = 0; |
160 | 162 | ||
161 | pci_read_config_dword(pdev, hwc->event_base, (u32 *)&count); | 163 | pci_read_config_dword(pdev, hwc->event_base, (u32 *)&count); |
162 | pci_read_config_dword(pdev, hwc->event_base + 4, (u32 *)&count + 1); | 164 | pci_read_config_dword(pdev, hwc->event_base + 4, (u32 *)&count + 1); |
@@ -603,11 +605,12 @@ static struct pci_driver snbep_uncore_pci_driver = { | |||
603 | /* | 605 | /* |
604 | * build pci bus to socket mapping | 606 | * build pci bus to socket mapping |
605 | */ | 607 | */ |
606 | static void snbep_pci2phy_map_init(void) | 608 | static int snbep_pci2phy_map_init(void) |
607 | { | 609 | { |
608 | struct pci_dev *ubox_dev = NULL; | 610 | struct pci_dev *ubox_dev = NULL; |
609 | int i, bus, nodeid; | 611 | int i, bus, nodeid; |
610 | u32 config; | 612 | int err = 0; |
613 | u32 config = 0; | ||
611 | 614 | ||
612 | while (1) { | 615 | while (1) { |
613 | /* find the UBOX device */ | 616 | /* find the UBOX device */ |
@@ -618,10 +621,14 @@ static void snbep_pci2phy_map_init(void) | |||
618 | break; | 621 | break; |
619 | bus = ubox_dev->bus->number; | 622 | bus = ubox_dev->bus->number; |
620 | /* get the Node ID of the local register */ | 623 | /* get the Node ID of the local register */ |
621 | pci_read_config_dword(ubox_dev, 0x40, &config); | 624 | err = pci_read_config_dword(ubox_dev, 0x40, &config); |
625 | if (err) | ||
626 | break; | ||
622 | nodeid = config; | 627 | nodeid = config; |
623 | /* get the Node ID mapping */ | 628 | /* get the Node ID mapping */ |
624 | pci_read_config_dword(ubox_dev, 0x54, &config); | 629 | err = pci_read_config_dword(ubox_dev, 0x54, &config); |
630 | if (err) | ||
631 | break; | ||
625 | /* | 632 | /* |
626 | * every three bits in the Node ID mapping register maps | 633 | * every three bits in the Node ID mapping register maps |
627 | * to a particular node. | 634 | * to a particular node. |
@@ -633,7 +640,11 @@ static void snbep_pci2phy_map_init(void) | |||
633 | } | 640 | } |
634 | } | 641 | } |
635 | }; | 642 | }; |
636 | return; | 643 | |
644 | if (ubox_dev) | ||
645 | pci_dev_put(ubox_dev); | ||
646 | |||
647 | return err ? pcibios_err_to_errno(err) : 0; | ||
637 | } | 648 | } |
638 | /* end of Sandy Bridge-EP uncore support */ | 649 | /* end of Sandy Bridge-EP uncore support */ |
639 | 650 | ||
@@ -1547,7 +1558,6 @@ void nhmex_rbox_alter_er(struct intel_uncore_box *box, struct perf_event *event) | |||
1547 | { | 1558 | { |
1548 | struct hw_perf_event *hwc = &event->hw; | 1559 | struct hw_perf_event *hwc = &event->hw; |
1549 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | 1560 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; |
1550 | int port; | ||
1551 | 1561 | ||
1552 | /* adjust the main event selector and extra register index */ | 1562 | /* adjust the main event selector and extra register index */ |
1553 | if (reg1->idx % 2) { | 1563 | if (reg1->idx % 2) { |
@@ -1559,7 +1569,6 @@ void nhmex_rbox_alter_er(struct intel_uncore_box *box, struct perf_event *event) | |||
1559 | } | 1569 | } |
1560 | 1570 | ||
1561 | /* adjust extra register config */ | 1571 | /* adjust extra register config */ |
1562 | port = reg1->idx / 6 + box->pmu->pmu_idx * 4; | ||
1563 | switch (reg1->idx % 6) { | 1572 | switch (reg1->idx % 6) { |
1564 | case 2: | 1573 | case 2: |
1565 | /* shift the 8~15 bits to the 0~7 bits */ | 1574 | /* shift the 8~15 bits to the 0~7 bits */ |
@@ -2578,9 +2587,11 @@ static int __init uncore_pci_init(void) | |||
2578 | 2587 | ||
2579 | switch (boot_cpu_data.x86_model) { | 2588 | switch (boot_cpu_data.x86_model) { |
2580 | case 45: /* Sandy Bridge-EP */ | 2589 | case 45: /* Sandy Bridge-EP */ |
2590 | ret = snbep_pci2phy_map_init(); | ||
2591 | if (ret) | ||
2592 | return ret; | ||
2581 | pci_uncores = snbep_pci_uncores; | 2593 | pci_uncores = snbep_pci_uncores; |
2582 | uncore_pci_driver = &snbep_uncore_pci_driver; | 2594 | uncore_pci_driver = &snbep_uncore_pci_driver; |
2583 | snbep_pci2phy_map_init(); | ||
2584 | break; | 2595 | break; |
2585 | default: | 2596 | default: |
2586 | return 0; | 2597 | return 0; |
@@ -2926,6 +2937,9 @@ static int __init intel_uncore_init(void) | |||
2926 | if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) | 2937 | if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) |
2927 | return -ENODEV; | 2938 | return -ENODEV; |
2928 | 2939 | ||
2940 | if (cpu_has_hypervisor) | ||
2941 | return -ENODEV; | ||
2942 | |||
2929 | ret = uncore_pci_init(); | 2943 | ret = uncore_pci_init(); |
2930 | if (ret) | 2944 | if (ret) |
2931 | goto fail; | 2945 | goto fail; |
diff --git a/arch/x86/kernel/cpu/perf_event_knc.c b/arch/x86/kernel/cpu/perf_event_knc.c index 7c46bfdbc373..4b7731bf23a8 100644 --- a/arch/x86/kernel/cpu/perf_event_knc.c +++ b/arch/x86/kernel/cpu/perf_event_knc.c | |||
@@ -3,6 +3,8 @@ | |||
3 | #include <linux/perf_event.h> | 3 | #include <linux/perf_event.h> |
4 | #include <linux/types.h> | 4 | #include <linux/types.h> |
5 | 5 | ||
6 | #include <asm/hardirq.h> | ||
7 | |||
6 | #include "perf_event.h" | 8 | #include "perf_event.h" |
7 | 9 | ||
8 | static const u64 knc_perfmon_event_map[] = | 10 | static const u64 knc_perfmon_event_map[] = |
@@ -173,30 +175,100 @@ static void knc_pmu_enable_all(int added) | |||
173 | static inline void | 175 | static inline void |
174 | knc_pmu_disable_event(struct perf_event *event) | 176 | knc_pmu_disable_event(struct perf_event *event) |
175 | { | 177 | { |
176 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | ||
177 | struct hw_perf_event *hwc = &event->hw; | 178 | struct hw_perf_event *hwc = &event->hw; |
178 | u64 val; | 179 | u64 val; |
179 | 180 | ||
180 | val = hwc->config; | 181 | val = hwc->config; |
181 | if (cpuc->enabled) | 182 | val &= ~ARCH_PERFMON_EVENTSEL_ENABLE; |
182 | val &= ~ARCH_PERFMON_EVENTSEL_ENABLE; | ||
183 | 183 | ||
184 | (void)wrmsrl_safe(hwc->config_base + hwc->idx, val); | 184 | (void)wrmsrl_safe(hwc->config_base + hwc->idx, val); |
185 | } | 185 | } |
186 | 186 | ||
187 | static void knc_pmu_enable_event(struct perf_event *event) | 187 | static void knc_pmu_enable_event(struct perf_event *event) |
188 | { | 188 | { |
189 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | ||
190 | struct hw_perf_event *hwc = &event->hw; | 189 | struct hw_perf_event *hwc = &event->hw; |
191 | u64 val; | 190 | u64 val; |
192 | 191 | ||
193 | val = hwc->config; | 192 | val = hwc->config; |
194 | if (cpuc->enabled) | 193 | val |= ARCH_PERFMON_EVENTSEL_ENABLE; |
195 | val |= ARCH_PERFMON_EVENTSEL_ENABLE; | ||
196 | 194 | ||
197 | (void)wrmsrl_safe(hwc->config_base + hwc->idx, val); | 195 | (void)wrmsrl_safe(hwc->config_base + hwc->idx, val); |
198 | } | 196 | } |
199 | 197 | ||
198 | static inline u64 knc_pmu_get_status(void) | ||
199 | { | ||
200 | u64 status; | ||
201 | |||
202 | rdmsrl(MSR_KNC_IA32_PERF_GLOBAL_STATUS, status); | ||
203 | |||
204 | return status; | ||
205 | } | ||
206 | |||
207 | static inline void knc_pmu_ack_status(u64 ack) | ||
208 | { | ||
209 | wrmsrl(MSR_KNC_IA32_PERF_GLOBAL_OVF_CONTROL, ack); | ||
210 | } | ||
211 | |||
212 | static int knc_pmu_handle_irq(struct pt_regs *regs) | ||
213 | { | ||
214 | struct perf_sample_data data; | ||
215 | struct cpu_hw_events *cpuc; | ||
216 | int handled = 0; | ||
217 | int bit, loops; | ||
218 | u64 status; | ||
219 | |||
220 | cpuc = &__get_cpu_var(cpu_hw_events); | ||
221 | |||
222 | knc_pmu_disable_all(); | ||
223 | |||
224 | status = knc_pmu_get_status(); | ||
225 | if (!status) { | ||
226 | knc_pmu_enable_all(0); | ||
227 | return handled; | ||
228 | } | ||
229 | |||
230 | loops = 0; | ||
231 | again: | ||
232 | knc_pmu_ack_status(status); | ||
233 | if (++loops > 100) { | ||
234 | WARN_ONCE(1, "perf: irq loop stuck!\n"); | ||
235 | perf_event_print_debug(); | ||
236 | goto done; | ||
237 | } | ||
238 | |||
239 | inc_irq_stat(apic_perf_irqs); | ||
240 | |||
241 | for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) { | ||
242 | struct perf_event *event = cpuc->events[bit]; | ||
243 | |||
244 | handled++; | ||
245 | |||
246 | if (!test_bit(bit, cpuc->active_mask)) | ||
247 | continue; | ||
248 | |||
249 | if (!intel_pmu_save_and_restart(event)) | ||
250 | continue; | ||
251 | |||
252 | perf_sample_data_init(&data, 0, event->hw.last_period); | ||
253 | |||
254 | if (perf_event_overflow(event, &data, regs)) | ||
255 | x86_pmu_stop(event, 0); | ||
256 | } | ||
257 | |||
258 | /* | ||
259 | * Repeat if there is more work to be done: | ||
260 | */ | ||
261 | status = knc_pmu_get_status(); | ||
262 | if (status) | ||
263 | goto again; | ||
264 | |||
265 | done: | ||
266 | knc_pmu_enable_all(0); | ||
267 | |||
268 | return handled; | ||
269 | } | ||
270 | |||
271 | |||
200 | PMU_FORMAT_ATTR(event, "config:0-7" ); | 272 | PMU_FORMAT_ATTR(event, "config:0-7" ); |
201 | PMU_FORMAT_ATTR(umask, "config:8-15" ); | 273 | PMU_FORMAT_ATTR(umask, "config:8-15" ); |
202 | PMU_FORMAT_ATTR(edge, "config:18" ); | 274 | PMU_FORMAT_ATTR(edge, "config:18" ); |
@@ -214,7 +286,7 @@ static struct attribute *intel_knc_formats_attr[] = { | |||
214 | 286 | ||
215 | static __initconst struct x86_pmu knc_pmu = { | 287 | static __initconst struct x86_pmu knc_pmu = { |
216 | .name = "knc", | 288 | .name = "knc", |
217 | .handle_irq = x86_pmu_handle_irq, | 289 | .handle_irq = knc_pmu_handle_irq, |
218 | .disable_all = knc_pmu_disable_all, | 290 | .disable_all = knc_pmu_disable_all, |
219 | .enable_all = knc_pmu_enable_all, | 291 | .enable_all = knc_pmu_enable_all, |
220 | .enable = knc_pmu_enable_event, | 292 | .enable = knc_pmu_enable_event, |
@@ -226,12 +298,11 @@ static __initconst struct x86_pmu knc_pmu = { | |||
226 | .event_map = knc_pmu_event_map, | 298 | .event_map = knc_pmu_event_map, |
227 | .max_events = ARRAY_SIZE(knc_perfmon_event_map), | 299 | .max_events = ARRAY_SIZE(knc_perfmon_event_map), |
228 | .apic = 1, | 300 | .apic = 1, |
229 | .max_period = (1ULL << 31) - 1, | 301 | .max_period = (1ULL << 39) - 1, |
230 | .version = 0, | 302 | .version = 0, |
231 | .num_counters = 2, | 303 | .num_counters = 2, |
232 | /* in theory 40 bits, early silicon is buggy though */ | 304 | .cntval_bits = 40, |
233 | .cntval_bits = 32, | 305 | .cntval_mask = (1ULL << 40) - 1, |
234 | .cntval_mask = (1ULL << 32) - 1, | ||
235 | .get_event_constraints = x86_get_event_constraints, | 306 | .get_event_constraints = x86_get_event_constraints, |
236 | .event_constraints = knc_event_constraints, | 307 | .event_constraints = knc_event_constraints, |
237 | .format_attrs = intel_knc_formats_attr, | 308 | .format_attrs = intel_knc_formats_attr, |
diff --git a/arch/x86/kernel/cpu/perf_event_p6.c b/arch/x86/kernel/cpu/perf_event_p6.c index e4dd0f7a0453..7d0270bd793e 100644 --- a/arch/x86/kernel/cpu/perf_event_p6.c +++ b/arch/x86/kernel/cpu/perf_event_p6.c | |||
@@ -8,13 +8,106 @@ | |||
8 | */ | 8 | */ |
9 | static const u64 p6_perfmon_event_map[] = | 9 | static const u64 p6_perfmon_event_map[] = |
10 | { | 10 | { |
11 | [PERF_COUNT_HW_CPU_CYCLES] = 0x0079, | 11 | [PERF_COUNT_HW_CPU_CYCLES] = 0x0079, /* CPU_CLK_UNHALTED */ |
12 | [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, | 12 | [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, /* INST_RETIRED */ |
13 | [PERF_COUNT_HW_CACHE_REFERENCES] = 0x0f2e, | 13 | [PERF_COUNT_HW_CACHE_REFERENCES] = 0x0f2e, /* L2_RQSTS:M:E:S:I */ |
14 | [PERF_COUNT_HW_CACHE_MISSES] = 0x012e, | 14 | [PERF_COUNT_HW_CACHE_MISSES] = 0x012e, /* L2_RQSTS:I */ |
15 | [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c4, | 15 | [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c4, /* BR_INST_RETIRED */ |
16 | [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c5, | 16 | [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c5, /* BR_MISS_PRED_RETIRED */ |
17 | [PERF_COUNT_HW_BUS_CYCLES] = 0x0062, | 17 | [PERF_COUNT_HW_BUS_CYCLES] = 0x0062, /* BUS_DRDY_CLOCKS */ |
18 | [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x00a2, /* RESOURCE_STALLS */ | ||
19 | |||
20 | }; | ||
21 | |||
22 | static __initconst u64 p6_hw_cache_event_ids | ||
23 | [PERF_COUNT_HW_CACHE_MAX] | ||
24 | [PERF_COUNT_HW_CACHE_OP_MAX] | ||
25 | [PERF_COUNT_HW_CACHE_RESULT_MAX] = | ||
26 | { | ||
27 | [ C(L1D) ] = { | ||
28 | [ C(OP_READ) ] = { | ||
29 | [ C(RESULT_ACCESS) ] = 0x0043, /* DATA_MEM_REFS */ | ||
30 | [ C(RESULT_MISS) ] = 0x0045, /* DCU_LINES_IN */ | ||
31 | }, | ||
32 | [ C(OP_WRITE) ] = { | ||
33 | [ C(RESULT_ACCESS) ] = 0, | ||
34 | [ C(RESULT_MISS) ] = 0x0f29, /* L2_LD:M:E:S:I */ | ||
35 | }, | ||
36 | [ C(OP_PREFETCH) ] = { | ||
37 | [ C(RESULT_ACCESS) ] = 0, | ||
38 | [ C(RESULT_MISS) ] = 0, | ||
39 | }, | ||
40 | }, | ||
41 | [ C(L1I ) ] = { | ||
42 | [ C(OP_READ) ] = { | ||
43 | [ C(RESULT_ACCESS) ] = 0x0080, /* IFU_IFETCH */ | ||
44 | [ C(RESULT_MISS) ] = 0x0f28, /* L2_IFETCH:M:E:S:I */ | ||
45 | }, | ||
46 | [ C(OP_WRITE) ] = { | ||
47 | [ C(RESULT_ACCESS) ] = -1, | ||
48 | [ C(RESULT_MISS) ] = -1, | ||
49 | }, | ||
50 | [ C(OP_PREFETCH) ] = { | ||
51 | [ C(RESULT_ACCESS) ] = 0, | ||
52 | [ C(RESULT_MISS) ] = 0, | ||
53 | }, | ||
54 | }, | ||
55 | [ C(LL ) ] = { | ||
56 | [ C(OP_READ) ] = { | ||
57 | [ C(RESULT_ACCESS) ] = 0, | ||
58 | [ C(RESULT_MISS) ] = 0, | ||
59 | }, | ||
60 | [ C(OP_WRITE) ] = { | ||
61 | [ C(RESULT_ACCESS) ] = 0, | ||
62 | [ C(RESULT_MISS) ] = 0x0025, /* L2_M_LINES_INM */ | ||
63 | }, | ||
64 | [ C(OP_PREFETCH) ] = { | ||
65 | [ C(RESULT_ACCESS) ] = 0, | ||
66 | [ C(RESULT_MISS) ] = 0, | ||
67 | }, | ||
68 | }, | ||
69 | [ C(DTLB) ] = { | ||
70 | [ C(OP_READ) ] = { | ||
71 | [ C(RESULT_ACCESS) ] = 0x0043, /* DATA_MEM_REFS */ | ||
72 | [ C(RESULT_MISS) ] = 0, | ||
73 | }, | ||
74 | [ C(OP_WRITE) ] = { | ||
75 | [ C(RESULT_ACCESS) ] = 0, | ||
76 | [ C(RESULT_MISS) ] = 0, | ||
77 | }, | ||
78 | [ C(OP_PREFETCH) ] = { | ||
79 | [ C(RESULT_ACCESS) ] = 0, | ||
80 | [ C(RESULT_MISS) ] = 0, | ||
81 | }, | ||
82 | }, | ||
83 | [ C(ITLB) ] = { | ||
84 | [ C(OP_READ) ] = { | ||
85 | [ C(RESULT_ACCESS) ] = 0x0080, /* IFU_IFETCH */ | ||
86 | [ C(RESULT_MISS) ] = 0x0085, /* ITLB_MISS */ | ||
87 | }, | ||
88 | [ C(OP_WRITE) ] = { | ||
89 | [ C(RESULT_ACCESS) ] = -1, | ||
90 | [ C(RESULT_MISS) ] = -1, | ||
91 | }, | ||
92 | [ C(OP_PREFETCH) ] = { | ||
93 | [ C(RESULT_ACCESS) ] = -1, | ||
94 | [ C(RESULT_MISS) ] = -1, | ||
95 | }, | ||
96 | }, | ||
97 | [ C(BPU ) ] = { | ||
98 | [ C(OP_READ) ] = { | ||
99 | [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED */ | ||
100 | [ C(RESULT_MISS) ] = 0x00c5, /* BR_MISS_PRED_RETIRED */ | ||
101 | }, | ||
102 | [ C(OP_WRITE) ] = { | ||
103 | [ C(RESULT_ACCESS) ] = -1, | ||
104 | [ C(RESULT_MISS) ] = -1, | ||
105 | }, | ||
106 | [ C(OP_PREFETCH) ] = { | ||
107 | [ C(RESULT_ACCESS) ] = -1, | ||
108 | [ C(RESULT_MISS) ] = -1, | ||
109 | }, | ||
110 | }, | ||
18 | }; | 111 | }; |
19 | 112 | ||
20 | static u64 p6_pmu_event_map(int hw_event) | 113 | static u64 p6_pmu_event_map(int hw_event) |
@@ -34,7 +127,7 @@ static struct event_constraint p6_event_constraints[] = | |||
34 | { | 127 | { |
35 | INTEL_EVENT_CONSTRAINT(0xc1, 0x1), /* FLOPS */ | 128 | INTEL_EVENT_CONSTRAINT(0xc1, 0x1), /* FLOPS */ |
36 | INTEL_EVENT_CONSTRAINT(0x10, 0x1), /* FP_COMP_OPS_EXE */ | 129 | INTEL_EVENT_CONSTRAINT(0x10, 0x1), /* FP_COMP_OPS_EXE */ |
37 | INTEL_EVENT_CONSTRAINT(0x11, 0x1), /* FP_ASSIST */ | 130 | INTEL_EVENT_CONSTRAINT(0x11, 0x2), /* FP_ASSIST */ |
38 | INTEL_EVENT_CONSTRAINT(0x12, 0x2), /* MUL */ | 131 | INTEL_EVENT_CONSTRAINT(0x12, 0x2), /* MUL */ |
39 | INTEL_EVENT_CONSTRAINT(0x13, 0x2), /* DIV */ | 132 | INTEL_EVENT_CONSTRAINT(0x13, 0x2), /* DIV */ |
40 | INTEL_EVENT_CONSTRAINT(0x14, 0x1), /* CYCLES_DIV_BUSY */ | 133 | INTEL_EVENT_CONSTRAINT(0x14, 0x1), /* CYCLES_DIV_BUSY */ |
@@ -64,25 +157,25 @@ static void p6_pmu_enable_all(int added) | |||
64 | static inline void | 157 | static inline void |
65 | p6_pmu_disable_event(struct perf_event *event) | 158 | p6_pmu_disable_event(struct perf_event *event) |
66 | { | 159 | { |
67 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | ||
68 | struct hw_perf_event *hwc = &event->hw; | 160 | struct hw_perf_event *hwc = &event->hw; |
69 | u64 val = P6_NOP_EVENT; | 161 | u64 val = P6_NOP_EVENT; |
70 | 162 | ||
71 | if (cpuc->enabled) | ||
72 | val |= ARCH_PERFMON_EVENTSEL_ENABLE; | ||
73 | |||
74 | (void)wrmsrl_safe(hwc->config_base, val); | 163 | (void)wrmsrl_safe(hwc->config_base, val); |
75 | } | 164 | } |
76 | 165 | ||
77 | static void p6_pmu_enable_event(struct perf_event *event) | 166 | static void p6_pmu_enable_event(struct perf_event *event) |
78 | { | 167 | { |
79 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | ||
80 | struct hw_perf_event *hwc = &event->hw; | 168 | struct hw_perf_event *hwc = &event->hw; |
81 | u64 val; | 169 | u64 val; |
82 | 170 | ||
83 | val = hwc->config; | 171 | val = hwc->config; |
84 | if (cpuc->enabled) | 172 | |
85 | val |= ARCH_PERFMON_EVENTSEL_ENABLE; | 173 | /* |
174 | * p6 only has a global event enable, set on PerfEvtSel0 | ||
175 | * We "disable" events by programming P6_NOP_EVENT | ||
176 | * and we rely on p6_pmu_enable_all() being called | ||
177 | * to actually enable the events. | ||
178 | */ | ||
86 | 179 | ||
87 | (void)wrmsrl_safe(hwc->config_base, val); | 180 | (void)wrmsrl_safe(hwc->config_base, val); |
88 | } | 181 | } |
@@ -158,5 +251,9 @@ __init int p6_pmu_init(void) | |||
158 | 251 | ||
159 | x86_pmu = p6_pmu; | 252 | x86_pmu = p6_pmu; |
160 | 253 | ||
254 | memcpy(hw_cache_event_ids, p6_hw_cache_event_ids, | ||
255 | sizeof(hw_cache_event_ids)); | ||
256 | |||
257 | |||
161 | return 0; | 258 | return 0; |
162 | } | 259 | } |
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index ed858e9e9a74..df06ade26bef 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c | |||
@@ -1077,6 +1077,9 @@ void __init memblock_x86_fill(void) | |||
1077 | memblock_add(ei->addr, ei->size); | 1077 | memblock_add(ei->addr, ei->size); |
1078 | } | 1078 | } |
1079 | 1079 | ||
1080 | /* throw away partial pages */ | ||
1081 | memblock_trim_memory(PAGE_SIZE); | ||
1082 | |||
1080 | memblock_dump_all(); | 1083 | memblock_dump_all(); |
1081 | } | 1084 | } |
1082 | 1085 | ||
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index a1193aef6d7d..88b725aa1d52 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S | |||
@@ -1035,7 +1035,7 @@ ENTRY(xen_sysenter_target) | |||
1035 | 1035 | ||
1036 | ENTRY(xen_hypervisor_callback) | 1036 | ENTRY(xen_hypervisor_callback) |
1037 | CFI_STARTPROC | 1037 | CFI_STARTPROC |
1038 | pushl_cfi $0 | 1038 | pushl_cfi $-1 /* orig_ax = -1 => not a system call */ |
1039 | SAVE_ALL | 1039 | SAVE_ALL |
1040 | TRACE_IRQS_OFF | 1040 | TRACE_IRQS_OFF |
1041 | 1041 | ||
@@ -1077,14 +1077,16 @@ ENTRY(xen_failsafe_callback) | |||
1077 | 2: mov 8(%esp),%es | 1077 | 2: mov 8(%esp),%es |
1078 | 3: mov 12(%esp),%fs | 1078 | 3: mov 12(%esp),%fs |
1079 | 4: mov 16(%esp),%gs | 1079 | 4: mov 16(%esp),%gs |
1080 | /* EAX == 0 => Category 1 (Bad segment) | ||
1081 | EAX != 0 => Category 2 (Bad IRET) */ | ||
1080 | testl %eax,%eax | 1082 | testl %eax,%eax |
1081 | popl_cfi %eax | 1083 | popl_cfi %eax |
1082 | lea 16(%esp),%esp | 1084 | lea 16(%esp),%esp |
1083 | CFI_ADJUST_CFA_OFFSET -16 | 1085 | CFI_ADJUST_CFA_OFFSET -16 |
1084 | jz 5f | 1086 | jz 5f |
1085 | addl $16,%esp | 1087 | addl $16,%esp |
1086 | jmp iret_exc # EAX != 0 => Category 2 (Bad IRET) | 1088 | jmp iret_exc |
1087 | 5: pushl_cfi $0 # EAX == 0 => Category 1 (Bad segment) | 1089 | 5: pushl_cfi $-1 /* orig_ax = -1 => not a system call */ |
1088 | SAVE_ALL | 1090 | SAVE_ALL |
1089 | jmp ret_from_exception | 1091 | jmp ret_from_exception |
1090 | CFI_ENDPROC | 1092 | CFI_ENDPROC |
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 0c58952d64e8..b51b2c7ee51f 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
@@ -1435,7 +1435,7 @@ ENTRY(xen_failsafe_callback) | |||
1435 | CFI_RESTORE r11 | 1435 | CFI_RESTORE r11 |
1436 | addq $0x30,%rsp | 1436 | addq $0x30,%rsp |
1437 | CFI_ADJUST_CFA_OFFSET -0x30 | 1437 | CFI_ADJUST_CFA_OFFSET -0x30 |
1438 | pushq_cfi $0 | 1438 | pushq_cfi $-1 /* orig_ax = -1 => not a system call */ |
1439 | SAVE_ALL | 1439 | SAVE_ALL |
1440 | jmp error_exit | 1440 | jmp error_exit |
1441 | CFI_ENDPROC | 1441 | CFI_ENDPROC |
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index b3e5e51bc907..4180a874c764 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c | |||
@@ -247,7 +247,10 @@ do_async_page_fault(struct pt_regs *regs, unsigned long error_code) | |||
247 | break; | 247 | break; |
248 | case KVM_PV_REASON_PAGE_NOT_PRESENT: | 248 | case KVM_PV_REASON_PAGE_NOT_PRESENT: |
249 | /* page is swapped out by the host. */ | 249 | /* page is swapped out by the host. */ |
250 | rcu_irq_enter(); | ||
251 | exit_idle(); | ||
250 | kvm_async_pf_task_wait((u32)read_cr2()); | 252 | kvm_async_pf_task_wait((u32)read_cr2()); |
253 | rcu_irq_exit(); | ||
251 | break; | 254 | break; |
252 | case KVM_PV_REASON_PAGE_READY: | 255 | case KVM_PV_REASON_PAGE_READY: |
253 | rcu_irq_enter(); | 256 | rcu_irq_enter(); |
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 468e98dfd44e..ca45696f30fb 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -921,18 +921,19 @@ void __init setup_arch(char **cmdline_p) | |||
921 | #ifdef CONFIG_X86_64 | 921 | #ifdef CONFIG_X86_64 |
922 | if (max_pfn > max_low_pfn) { | 922 | if (max_pfn > max_low_pfn) { |
923 | int i; | 923 | int i; |
924 | for (i = 0; i < e820.nr_map; i++) { | 924 | unsigned long start, end; |
925 | struct e820entry *ei = &e820.map[i]; | 925 | unsigned long start_pfn, end_pfn; |
926 | 926 | ||
927 | if (ei->addr + ei->size <= 1UL << 32) | 927 | for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, |
928 | continue; | 928 | NULL) { |
929 | 929 | ||
930 | if (ei->type == E820_RESERVED) | 930 | end = PFN_PHYS(end_pfn); |
931 | if (end <= (1UL<<32)) | ||
931 | continue; | 932 | continue; |
932 | 933 | ||
934 | start = PFN_PHYS(start_pfn); | ||
933 | max_pfn_mapped = init_memory_mapping( | 935 | max_pfn_mapped = init_memory_mapping( |
934 | ei->addr < 1UL << 32 ? 1UL << 32 : ei->addr, | 936 | max((1UL<<32), start), end); |
935 | ei->addr + ei->size); | ||
936 | } | 937 | } |
937 | 938 | ||
938 | /* can we preseve max_low_pfn ?*/ | 939 | /* can we preseve max_low_pfn ?*/ |
@@ -1048,6 +1049,18 @@ void __init setup_arch(char **cmdline_p) | |||
1048 | arch_init_ideal_nops(); | 1049 | arch_init_ideal_nops(); |
1049 | 1050 | ||
1050 | register_refined_jiffies(CLOCK_TICK_RATE); | 1051 | register_refined_jiffies(CLOCK_TICK_RATE); |
1052 | |||
1053 | #ifdef CONFIG_EFI | ||
1054 | /* Once setup is done above, disable efi_enabled on mismatched | ||
1055 | * firmware/kernel archtectures since there is no support for | ||
1056 | * runtime services. | ||
1057 | */ | ||
1058 | if (efi_enabled && IS_ENABLED(CONFIG_X86_64) != efi_64bit) { | ||
1059 | pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n"); | ||
1060 | efi_unmap_memmap(); | ||
1061 | efi_enabled = 0; | ||
1062 | } | ||
1063 | #endif | ||
1051 | } | 1064 | } |
1052 | 1065 | ||
1053 | #ifdef CONFIG_X86_32 | 1066 | #ifdef CONFIG_X86_32 |
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index 29ad351804e9..70b27ee6118e 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c | |||
@@ -824,10 +824,8 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) | |||
824 | mce_notify_process(); | 824 | mce_notify_process(); |
825 | #endif /* CONFIG_X86_64 && CONFIG_X86_MCE */ | 825 | #endif /* CONFIG_X86_64 && CONFIG_X86_MCE */ |
826 | 826 | ||
827 | if (thread_info_flags & _TIF_UPROBE) { | 827 | if (thread_info_flags & _TIF_UPROBE) |
828 | clear_thread_flag(TIF_UPROBE); | ||
829 | uprobe_notify_resume(regs); | 828 | uprobe_notify_resume(regs); |
830 | } | ||
831 | 829 | ||
832 | /* deal with pending signal delivery */ | 830 | /* deal with pending signal delivery */ |
833 | if (thread_info_flags & _TIF_SIGPENDING) | 831 | if (thread_info_flags & _TIF_SIGPENDING) |
diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c index 9538f00827a9..aafa5557b396 100644 --- a/arch/x86/kernel/uprobes.c +++ b/arch/x86/kernel/uprobes.c | |||
@@ -651,31 +651,19 @@ void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) | |||
651 | 651 | ||
652 | /* | 652 | /* |
653 | * Skip these instructions as per the currently known x86 ISA. | 653 | * Skip these instructions as per the currently known x86 ISA. |
654 | * 0x66* { 0x90 | 0x0f 0x1f | 0x0f 0x19 | 0x87 0xc0 } | 654 | * rep=0x66*; nop=0x90 |
655 | */ | 655 | */ |
656 | static bool __skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs) | 656 | static bool __skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs) |
657 | { | 657 | { |
658 | int i; | 658 | int i; |
659 | 659 | ||
660 | for (i = 0; i < MAX_UINSN_BYTES; i++) { | 660 | for (i = 0; i < MAX_UINSN_BYTES; i++) { |
661 | if ((auprobe->insn[i] == 0x66)) | 661 | if (auprobe->insn[i] == 0x66) |
662 | continue; | 662 | continue; |
663 | 663 | ||
664 | if (auprobe->insn[i] == 0x90) | 664 | if (auprobe->insn[i] == 0x90) |
665 | return true; | 665 | return true; |
666 | 666 | ||
667 | if (i == (MAX_UINSN_BYTES - 1)) | ||
668 | break; | ||
669 | |||
670 | if ((auprobe->insn[i] == 0x0f) && (auprobe->insn[i+1] == 0x1f)) | ||
671 | return true; | ||
672 | |||
673 | if ((auprobe->insn[i] == 0x0f) && (auprobe->insn[i+1] == 0x19)) | ||
674 | return true; | ||
675 | |||
676 | if ((auprobe->insn[i] == 0x87) && (auprobe->insn[i+1] == 0xc0)) | ||
677 | return true; | ||
678 | |||
679 | break; | 667 | break; |
680 | } | 668 | } |
681 | return false; | 669 | return false; |