diff options
Diffstat (limited to 'arch/x86/kernel')
| -rw-r--r-- | arch/x86/kernel/acpi/boot.c | 26 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/mshyperv.c | 1 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event_intel_ds.c | 4 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event_intel_rapl.c | 44 | ||||
| -rw-r--r-- | arch/x86/kernel/irq.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/kprobes/core.c | 20 | ||||
| -rw-r--r-- | arch/x86/kernel/tls.c | 25 |
7 files changed, 87 insertions, 35 deletions
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index d1626364a28a..b9e30daa0881 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
| @@ -611,20 +611,20 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger) | |||
| 611 | 611 | ||
| 612 | int acpi_gsi_to_irq(u32 gsi, unsigned int *irqp) | 612 | int acpi_gsi_to_irq(u32 gsi, unsigned int *irqp) |
| 613 | { | 613 | { |
| 614 | int irq; | 614 | int rc, irq, trigger, polarity; |
| 615 | 615 | ||
| 616 | if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) { | 616 | rc = acpi_get_override_irq(gsi, &trigger, &polarity); |
| 617 | *irqp = gsi; | 617 | if (rc == 0) { |
| 618 | } else { | 618 | trigger = trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE; |
| 619 | mutex_lock(&acpi_ioapic_lock); | 619 | polarity = polarity ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH; |
| 620 | irq = mp_map_gsi_to_irq(gsi, | 620 | irq = acpi_register_gsi(NULL, gsi, trigger, polarity); |
| 621 | IOAPIC_MAP_ALLOC | IOAPIC_MAP_CHECK); | 621 | if (irq >= 0) { |
| 622 | mutex_unlock(&acpi_ioapic_lock); | 622 | *irqp = irq; |
| 623 | if (irq < 0) | 623 | return 0; |
| 624 | return -1; | 624 | } |
| 625 | *irqp = irq; | ||
| 626 | } | 625 | } |
| 627 | return 0; | 626 | |
| 627 | return -1; | ||
| 628 | } | 628 | } |
| 629 | EXPORT_SYMBOL_GPL(acpi_gsi_to_irq); | 629 | EXPORT_SYMBOL_GPL(acpi_gsi_to_irq); |
| 630 | 630 | ||
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index a450373e8e91..939155ffdece 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c | |||
| @@ -107,6 +107,7 @@ static struct clocksource hyperv_cs = { | |||
| 107 | .rating = 400, /* use this when running on Hyperv*/ | 107 | .rating = 400, /* use this when running on Hyperv*/ |
| 108 | .read = read_hv_clock, | 108 | .read = read_hv_clock, |
| 109 | .mask = CLOCKSOURCE_MASK(64), | 109 | .mask = CLOCKSOURCE_MASK(64), |
| 110 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
| 110 | }; | 111 | }; |
| 111 | 112 | ||
| 112 | static void __init ms_hyperv_init_platform(void) | 113 | static void __init ms_hyperv_init_platform(void) |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index 3c895d480cd7..073983398364 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c | |||
| @@ -568,8 +568,8 @@ struct event_constraint intel_atom_pebs_event_constraints[] = { | |||
| 568 | }; | 568 | }; |
| 569 | 569 | ||
| 570 | struct event_constraint intel_slm_pebs_event_constraints[] = { | 570 | struct event_constraint intel_slm_pebs_event_constraints[] = { |
| 571 | /* UOPS_RETIRED.ALL, inv=1, cmask=16 (cycles:p). */ | 571 | /* INST_RETIRED.ANY_P, inv=1, cmask=16 (cycles:p). */ |
| 572 | INTEL_FLAGS_EVENT_CONSTRAINT(0x108001c2, 0xf), | 572 | INTEL_FLAGS_EVENT_CONSTRAINT(0x108000c0, 0x1), |
| 573 | /* Allow all events as PEBS with no flags */ | 573 | /* Allow all events as PEBS with no flags */ |
| 574 | INTEL_ALL_EVENT_CONSTRAINT(0, 0x1), | 574 | INTEL_ALL_EVENT_CONSTRAINT(0, 0x1), |
| 575 | EVENT_CONSTRAINT_END | 575 | EVENT_CONSTRAINT_END |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_rapl.c b/arch/x86/kernel/cpu/perf_event_intel_rapl.c index 673f930c700f..6e434f8e5fc8 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_rapl.c +++ b/arch/x86/kernel/cpu/perf_event_intel_rapl.c | |||
| @@ -103,6 +103,13 @@ static struct kobj_attribute format_attr_##_var = \ | |||
| 103 | 103 | ||
| 104 | #define RAPL_CNTR_WIDTH 32 /* 32-bit rapl counters */ | 104 | #define RAPL_CNTR_WIDTH 32 /* 32-bit rapl counters */ |
| 105 | 105 | ||
| 106 | #define RAPL_EVENT_ATTR_STR(_name, v, str) \ | ||
| 107 | static struct perf_pmu_events_attr event_attr_##v = { \ | ||
| 108 | .attr = __ATTR(_name, 0444, rapl_sysfs_show, NULL), \ | ||
| 109 | .id = 0, \ | ||
| 110 | .event_str = str, \ | ||
| 111 | }; | ||
| 112 | |||
| 106 | struct rapl_pmu { | 113 | struct rapl_pmu { |
| 107 | spinlock_t lock; | 114 | spinlock_t lock; |
| 108 | int hw_unit; /* 1/2^hw_unit Joule */ | 115 | int hw_unit; /* 1/2^hw_unit Joule */ |
| @@ -379,23 +386,36 @@ static struct attribute_group rapl_pmu_attr_group = { | |||
| 379 | .attrs = rapl_pmu_attrs, | 386 | .attrs = rapl_pmu_attrs, |
| 380 | }; | 387 | }; |
| 381 | 388 | ||
| 382 | EVENT_ATTR_STR(energy-cores, rapl_cores, "event=0x01"); | 389 | static ssize_t rapl_sysfs_show(struct device *dev, |
| 383 | EVENT_ATTR_STR(energy-pkg , rapl_pkg, "event=0x02"); | 390 | struct device_attribute *attr, |
| 384 | EVENT_ATTR_STR(energy-ram , rapl_ram, "event=0x03"); | 391 | char *page) |
| 385 | EVENT_ATTR_STR(energy-gpu , rapl_gpu, "event=0x04"); | 392 | { |
| 393 | struct perf_pmu_events_attr *pmu_attr = \ | ||
| 394 | container_of(attr, struct perf_pmu_events_attr, attr); | ||
| 395 | |||
| 396 | if (pmu_attr->event_str) | ||
| 397 | return sprintf(page, "%s", pmu_attr->event_str); | ||
| 398 | |||
| 399 | return 0; | ||
| 400 | } | ||
| 401 | |||
| 402 | RAPL_EVENT_ATTR_STR(energy-cores, rapl_cores, "event=0x01"); | ||
| 403 | RAPL_EVENT_ATTR_STR(energy-pkg , rapl_pkg, "event=0x02"); | ||
| 404 | RAPL_EVENT_ATTR_STR(energy-ram , rapl_ram, "event=0x03"); | ||
| 405 | RAPL_EVENT_ATTR_STR(energy-gpu , rapl_gpu, "event=0x04"); | ||
| 386 | 406 | ||
| 387 | EVENT_ATTR_STR(energy-cores.unit, rapl_cores_unit, "Joules"); | 407 | RAPL_EVENT_ATTR_STR(energy-cores.unit, rapl_cores_unit, "Joules"); |
| 388 | EVENT_ATTR_STR(energy-pkg.unit , rapl_pkg_unit, "Joules"); | 408 | RAPL_EVENT_ATTR_STR(energy-pkg.unit , rapl_pkg_unit, "Joules"); |
| 389 | EVENT_ATTR_STR(energy-ram.unit , rapl_ram_unit, "Joules"); | 409 | RAPL_EVENT_ATTR_STR(energy-ram.unit , rapl_ram_unit, "Joules"); |
| 390 | EVENT_ATTR_STR(energy-gpu.unit , rapl_gpu_unit, "Joules"); | 410 | RAPL_EVENT_ATTR_STR(energy-gpu.unit , rapl_gpu_unit, "Joules"); |
| 391 | 411 | ||
| 392 | /* | 412 | /* |
| 393 | * we compute in 0.23 nJ increments regardless of MSR | 413 | * we compute in 0.23 nJ increments regardless of MSR |
| 394 | */ | 414 | */ |
| 395 | EVENT_ATTR_STR(energy-cores.scale, rapl_cores_scale, "2.3283064365386962890625e-10"); | 415 | RAPL_EVENT_ATTR_STR(energy-cores.scale, rapl_cores_scale, "2.3283064365386962890625e-10"); |
| 396 | EVENT_ATTR_STR(energy-pkg.scale, rapl_pkg_scale, "2.3283064365386962890625e-10"); | 416 | RAPL_EVENT_ATTR_STR(energy-pkg.scale, rapl_pkg_scale, "2.3283064365386962890625e-10"); |
| 397 | EVENT_ATTR_STR(energy-ram.scale, rapl_ram_scale, "2.3283064365386962890625e-10"); | 417 | RAPL_EVENT_ATTR_STR(energy-ram.scale, rapl_ram_scale, "2.3283064365386962890625e-10"); |
| 398 | EVENT_ATTR_STR(energy-gpu.scale, rapl_gpu_scale, "2.3283064365386962890625e-10"); | 418 | RAPL_EVENT_ATTR_STR(energy-gpu.scale, rapl_gpu_scale, "2.3283064365386962890625e-10"); |
| 399 | 419 | ||
| 400 | static struct attribute *rapl_events_srv_attr[] = { | 420 | static struct attribute *rapl_events_srv_attr[] = { |
| 401 | EVENT_PTR(rapl_cores), | 421 | EVENT_PTR(rapl_cores), |
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 6307a0f0cf17..705ef8d48e2d 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c | |||
| @@ -127,7 +127,7 @@ int arch_show_interrupts(struct seq_file *p, int prec) | |||
| 127 | seq_puts(p, " Machine check polls\n"); | 127 | seq_puts(p, " Machine check polls\n"); |
| 128 | #endif | 128 | #endif |
| 129 | #if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN) | 129 | #if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN) |
| 130 | seq_printf(p, "%*s: ", prec, "THR"); | 130 | seq_printf(p, "%*s: ", prec, "HYP"); |
| 131 | for_each_online_cpu(j) | 131 | for_each_online_cpu(j) |
| 132 | seq_printf(p, "%10u ", irq_stats(j)->irq_hv_callback_count); | 132 | seq_printf(p, "%10u ", irq_stats(j)->irq_hv_callback_count); |
| 133 | seq_puts(p, " Hypervisor callback interrupts\n"); | 133 | seq_puts(p, " Hypervisor callback interrupts\n"); |
diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index f7e3cd50ece0..98f654d466e5 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c | |||
| @@ -1020,6 +1020,15 @@ int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) | |||
| 1020 | regs->flags &= ~X86_EFLAGS_IF; | 1020 | regs->flags &= ~X86_EFLAGS_IF; |
| 1021 | trace_hardirqs_off(); | 1021 | trace_hardirqs_off(); |
| 1022 | regs->ip = (unsigned long)(jp->entry); | 1022 | regs->ip = (unsigned long)(jp->entry); |
| 1023 | |||
| 1024 | /* | ||
| 1025 | * jprobes use jprobe_return() which skips the normal return | ||
| 1026 | * path of the function, and this messes up the accounting of the | ||
| 1027 | * function graph tracer to get messed up. | ||
| 1028 | * | ||
| 1029 | * Pause function graph tracing while performing the jprobe function. | ||
| 1030 | */ | ||
| 1031 | pause_graph_tracing(); | ||
| 1023 | return 1; | 1032 | return 1; |
| 1024 | } | 1033 | } |
| 1025 | NOKPROBE_SYMBOL(setjmp_pre_handler); | 1034 | NOKPROBE_SYMBOL(setjmp_pre_handler); |
| @@ -1048,24 +1057,25 @@ int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) | |||
| 1048 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 1057 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
| 1049 | u8 *addr = (u8 *) (regs->ip - 1); | 1058 | u8 *addr = (u8 *) (regs->ip - 1); |
| 1050 | struct jprobe *jp = container_of(p, struct jprobe, kp); | 1059 | struct jprobe *jp = container_of(p, struct jprobe, kp); |
| 1060 | void *saved_sp = kcb->jprobe_saved_sp; | ||
| 1051 | 1061 | ||
| 1052 | if ((addr > (u8 *) jprobe_return) && | 1062 | if ((addr > (u8 *) jprobe_return) && |
| 1053 | (addr < (u8 *) jprobe_return_end)) { | 1063 | (addr < (u8 *) jprobe_return_end)) { |
| 1054 | if (stack_addr(regs) != kcb->jprobe_saved_sp) { | 1064 | if (stack_addr(regs) != saved_sp) { |
| 1055 | struct pt_regs *saved_regs = &kcb->jprobe_saved_regs; | 1065 | struct pt_regs *saved_regs = &kcb->jprobe_saved_regs; |
| 1056 | printk(KERN_ERR | 1066 | printk(KERN_ERR |
| 1057 | "current sp %p does not match saved sp %p\n", | 1067 | "current sp %p does not match saved sp %p\n", |
| 1058 | stack_addr(regs), kcb->jprobe_saved_sp); | 1068 | stack_addr(regs), saved_sp); |
| 1059 | printk(KERN_ERR "Saved registers for jprobe %p\n", jp); | 1069 | printk(KERN_ERR "Saved registers for jprobe %p\n", jp); |
| 1060 | show_regs(saved_regs); | 1070 | show_regs(saved_regs); |
| 1061 | printk(KERN_ERR "Current registers\n"); | 1071 | printk(KERN_ERR "Current registers\n"); |
| 1062 | show_regs(regs); | 1072 | show_regs(regs); |
| 1063 | BUG(); | 1073 | BUG(); |
| 1064 | } | 1074 | } |
| 1075 | /* It's OK to start function graph tracing again */ | ||
| 1076 | unpause_graph_tracing(); | ||
| 1065 | *regs = kcb->jprobe_saved_regs; | 1077 | *regs = kcb->jprobe_saved_regs; |
| 1066 | memcpy((kprobe_opcode_t *)(kcb->jprobe_saved_sp), | 1078 | memcpy(saved_sp, kcb->jprobes_stack, MIN_STACK_SIZE(saved_sp)); |
| 1067 | kcb->jprobes_stack, | ||
| 1068 | MIN_STACK_SIZE(kcb->jprobe_saved_sp)); | ||
| 1069 | preempt_enable_no_resched(); | 1079 | preempt_enable_no_resched(); |
| 1070 | return 1; | 1080 | return 1; |
| 1071 | } | 1081 | } |
diff --git a/arch/x86/kernel/tls.c b/arch/x86/kernel/tls.c index 4e942f31b1a7..7fc5e843f247 100644 --- a/arch/x86/kernel/tls.c +++ b/arch/x86/kernel/tls.c | |||
| @@ -29,7 +29,28 @@ static int get_free_idx(void) | |||
| 29 | 29 | ||
| 30 | static bool tls_desc_okay(const struct user_desc *info) | 30 | static bool tls_desc_okay(const struct user_desc *info) |
| 31 | { | 31 | { |
| 32 | if (LDT_empty(info)) | 32 | /* |
| 33 | * For historical reasons (i.e. no one ever documented how any | ||
| 34 | * of the segmentation APIs work), user programs can and do | ||
| 35 | * assume that a struct user_desc that's all zeros except for | ||
| 36 | * entry_number means "no segment at all". This never actually | ||
| 37 | * worked. In fact, up to Linux 3.19, a struct user_desc like | ||
| 38 | * this would create a 16-bit read-write segment with base and | ||
| 39 | * limit both equal to zero. | ||
| 40 | * | ||
| 41 | * That was close enough to "no segment at all" until we | ||
| 42 | * hardened this function to disallow 16-bit TLS segments. Fix | ||
| 43 | * it up by interpreting these zeroed segments the way that they | ||
| 44 | * were almost certainly intended to be interpreted. | ||
| 45 | * | ||
| 46 | * The correct way to ask for "no segment at all" is to specify | ||
| 47 | * a user_desc that satisfies LDT_empty. To keep everything | ||
| 48 | * working, we accept both. | ||
| 49 | * | ||
| 50 | * Note that there's a similar kludge in modify_ldt -- look at | ||
| 51 | * the distinction between modes 1 and 0x11. | ||
| 52 | */ | ||
| 53 | if (LDT_empty(info) || LDT_zero(info)) | ||
| 33 | return true; | 54 | return true; |
| 34 | 55 | ||
| 35 | /* | 56 | /* |
| @@ -71,7 +92,7 @@ static void set_tls_desc(struct task_struct *p, int idx, | |||
| 71 | cpu = get_cpu(); | 92 | cpu = get_cpu(); |
| 72 | 93 | ||
| 73 | while (n-- > 0) { | 94 | while (n-- > 0) { |
| 74 | if (LDT_empty(info)) | 95 | if (LDT_empty(info) || LDT_zero(info)) |
| 75 | desc->a = desc->b = 0; | 96 | desc->a = desc->b = 0; |
| 76 | else | 97 | else |
| 77 | fill_ldt(desc, info); | 98 | fill_ldt(desc, info); |
