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/intel_cacheinfo.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce.c | 6 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce_amd.c | 10 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event.c | 16 | ||||
| -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/reboot.c | 8 | ||||
| -rw-r--r-- | arch/x86/kernel/setup.c | 30 | ||||
| -rw-r--r-- | arch/x86/kernel/signal.c | 4 | ||||
| -rw-r--r-- | arch/x86/kernel/uprobes.c | 16 |
16 files changed, 289 insertions, 90 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/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index 9a7c90d80bc4..93c5451bdd52 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c | |||
| @@ -991,7 +991,7 @@ static struct attribute ** __cpuinit amd_l3_attrs(void) | |||
| 991 | if (attrs) | 991 | if (attrs) |
| 992 | return attrs; | 992 | return attrs; |
| 993 | 993 | ||
| 994 | n = sizeof (default_attrs) / sizeof (struct attribute *); | 994 | n = ARRAY_SIZE(default_attrs); |
| 995 | 995 | ||
| 996 | if (amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) | 996 | if (amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) |
| 997 | n += 2; | 997 | n += 2; |
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 29e87d3b2843..46cbf8689692 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
| @@ -2209,11 +2209,6 @@ static struct dev_ext_attribute dev_attr_cmci_disabled = { | |||
| 2209 | &mce_cmci_disabled | 2209 | &mce_cmci_disabled |
| 2210 | }; | 2210 | }; |
| 2211 | 2211 | ||
| 2212 | static struct dev_ext_attribute dev_attr_bios_cmci_threshold = { | ||
| 2213 | __ATTR(bios_cmci_threshold, 0444, device_show_int, NULL), | ||
| 2214 | &mce_bios_cmci_threshold | ||
| 2215 | }; | ||
| 2216 | |||
| 2217 | static struct device_attribute *mce_device_attrs[] = { | 2212 | static struct device_attribute *mce_device_attrs[] = { |
| 2218 | &dev_attr_tolerant.attr, | 2213 | &dev_attr_tolerant.attr, |
| 2219 | &dev_attr_check_interval.attr, | 2214 | &dev_attr_check_interval.attr, |
| @@ -2222,7 +2217,6 @@ static struct device_attribute *mce_device_attrs[] = { | |||
| 2222 | &dev_attr_dont_log_ce.attr, | 2217 | &dev_attr_dont_log_ce.attr, |
| 2223 | &dev_attr_ignore_ce.attr, | 2218 | &dev_attr_ignore_ce.attr, |
| 2224 | &dev_attr_cmci_disabled.attr, | 2219 | &dev_attr_cmci_disabled.attr, |
| 2225 | &dev_attr_bios_cmci_threshold.attr, | ||
| 2226 | NULL | 2220 | NULL |
| 2227 | }; | 2221 | }; |
| 2228 | 2222 | ||
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index c4e916d77378..698b6ec12e0f 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c | |||
| @@ -576,12 +576,10 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank) | |||
| 576 | int err = 0; | 576 | int err = 0; |
| 577 | 577 | ||
| 578 | if (shared_bank[bank]) { | 578 | if (shared_bank[bank]) { |
| 579 | |||
| 580 | nb = node_to_amd_nb(amd_get_nb_id(cpu)); | 579 | nb = node_to_amd_nb(amd_get_nb_id(cpu)); |
| 581 | WARN_ON(!nb); | ||
| 582 | 580 | ||
| 583 | /* threshold descriptor already initialized on this node? */ | 581 | /* threshold descriptor already initialized on this node? */ |
| 584 | if (nb->bank4) { | 582 | if (nb && nb->bank4) { |
| 585 | /* yes, use it */ | 583 | /* yes, use it */ |
| 586 | b = nb->bank4; | 584 | b = nb->bank4; |
| 587 | err = kobject_add(b->kobj, &dev->kobj, name); | 585 | err = kobject_add(b->kobj, &dev->kobj, name); |
| @@ -615,8 +613,10 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank) | |||
| 615 | atomic_set(&b->cpus, 1); | 613 | atomic_set(&b->cpus, 1); |
| 616 | 614 | ||
| 617 | /* nb is already initialized, see above */ | 615 | /* nb is already initialized, see above */ |
| 618 | WARN_ON(nb->bank4); | 616 | if (nb) { |
| 619 | nb->bank4 = b; | 617 | WARN_ON(nb->bank4); |
| 618 | nb->bank4 = b; | ||
| 619 | } | ||
| 620 | } | 620 | } |
| 621 | 621 | ||
| 622 | err = allocate_threshold_blocks(cpu, bank, 0, | 622 | err = allocate_threshold_blocks(cpu, bank, 0, |
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 915b876edd1e..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) |
| @@ -338,6 +340,9 @@ int x86_setup_perfctr(struct perf_event *event) | |||
| 338 | /* BTS is currently only allowed for user-mode. */ | 340 | /* BTS is currently only allowed for user-mode. */ |
| 339 | if (!attr->exclude_kernel) | 341 | if (!attr->exclude_kernel) |
| 340 | return -EOPNOTSUPP; | 342 | return -EOPNOTSUPP; |
| 343 | |||
| 344 | if (!attr->exclude_guest) | ||
| 345 | return -EOPNOTSUPP; | ||
| 341 | } | 346 | } |
| 342 | 347 | ||
| 343 | hwc->config |= config; | 348 | hwc->config |= config; |
| @@ -380,6 +385,9 @@ int x86_pmu_hw_config(struct perf_event *event) | |||
| 380 | if (event->attr.precise_ip) { | 385 | if (event->attr.precise_ip) { |
| 381 | int precise = 0; | 386 | int precise = 0; |
| 382 | 387 | ||
| 388 | if (!event->attr.exclude_guest) | ||
| 389 | return -EOPNOTSUPP; | ||
| 390 | |||
| 383 | /* Support for constant skid */ | 391 | /* Support for constant skid */ |
| 384 | if (x86_pmu.pebs_active && !x86_pmu.pebs_broken) { | 392 | if (x86_pmu.pebs_active && !x86_pmu.pebs_broken) { |
| 385 | precise++; | 393 | precise++; |
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/reboot.c b/arch/x86/kernel/reboot.c index 52190a938b4a..4e8ba39eaf0f 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c | |||
| @@ -358,14 +358,6 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { | |||
| 358 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-Z540N"), | 358 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-Z540N"), |
| 359 | }, | 359 | }, |
| 360 | }, | 360 | }, |
| 361 | { /* Handle problems with rebooting on CompuLab SBC-FITPC2 */ | ||
| 362 | .callback = set_bios_reboot, | ||
| 363 | .ident = "CompuLab SBC-FITPC2", | ||
| 364 | .matches = { | ||
| 365 | DMI_MATCH(DMI_SYS_VENDOR, "CompuLab"), | ||
| 366 | DMI_MATCH(DMI_PRODUCT_NAME, "SBC-FITPC2"), | ||
| 367 | }, | ||
| 368 | }, | ||
| 369 | { /* Handle problems with rebooting on ASUS P4S800 */ | 361 | { /* Handle problems with rebooting on ASUS P4S800 */ |
| 370 | .callback = set_bios_reboot, | 362 | .callback = set_bios_reboot, |
| 371 | .ident = "ASUS P4S800", | 363 | .ident = "ASUS P4S800", |
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index a2bb18e02839..ca45696f30fb 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
| @@ -920,8 +920,22 @@ void __init setup_arch(char **cmdline_p) | |||
| 920 | 920 | ||
| 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 | max_pfn_mapped = init_memory_mapping(1UL<<32, | 923 | int i; |
| 924 | max_pfn<<PAGE_SHIFT); | 924 | unsigned long start, end; |
| 925 | unsigned long start_pfn, end_pfn; | ||
| 926 | |||
| 927 | for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, | ||
| 928 | NULL) { | ||
| 929 | |||
| 930 | end = PFN_PHYS(end_pfn); | ||
| 931 | if (end <= (1UL<<32)) | ||
| 932 | continue; | ||
| 933 | |||
| 934 | start = PFN_PHYS(start_pfn); | ||
| 935 | max_pfn_mapped = init_memory_mapping( | ||
| 936 | max((1UL<<32), start), end); | ||
| 937 | } | ||
| 938 | |||
| 925 | /* can we preseve max_low_pfn ?*/ | 939 | /* can we preseve max_low_pfn ?*/ |
| 926 | max_low_pfn = max_pfn; | 940 | max_low_pfn = max_pfn; |
| 927 | } | 941 | } |
| @@ -1035,6 +1049,18 @@ void __init setup_arch(char **cmdline_p) | |||
| 1035 | arch_init_ideal_nops(); | 1049 | arch_init_ideal_nops(); |
| 1036 | 1050 | ||
| 1037 | 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 | ||
| 1038 | } | 1064 | } |
| 1039 | 1065 | ||
| 1040 | #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; |
