diff options
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/Makefile | 1 | ||||
-rw-r--r-- | arch/x86/kernel/acpi/boot.c | 35 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/aperfmperf.c | 9 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/bugs.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/common.c | 9 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/resctrl/monitor.c | 49 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/resctrl/rdtgroup.c | 12 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/vmware.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/fpu/context.h | 2 | ||||
-rw-r--r-- | arch/x86/kernel/fpu/core.c | 6 | ||||
-rw-r--r-- | arch/x86/kernel/i8259.c | 1 | ||||
-rw-r--r-- | arch/x86/kernel/irqinit.c | 4 | ||||
-rw-r--r-- | arch/x86/kernel/kprobes/core.c | 36 | ||||
-rw-r--r-- | arch/x86/kernel/kvmclock.c | 6 | ||||
-rw-r--r-- | arch/x86/kernel/paravirt.c | 14 | ||||
-rw-r--r-- | arch/x86/kernel/process.c | 65 | ||||
-rw-r--r-- | arch/x86/kernel/pvclock.c | 22 | ||||
-rw-r--r-- | arch/x86/kernel/signal_32.c | 127 | ||||
-rw-r--r-- | arch/x86/kernel/signal_64.c | 127 | ||||
-rw-r--r-- | arch/x86/kernel/signal_compat.c | 191 | ||||
-rw-r--r-- | arch/x86/kernel/tsc.c | 7 | ||||
-rw-r--r-- | arch/x86/kernel/vmlinux.lds.S | 1 |
22 files changed, 426 insertions, 302 deletions
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 96d51bbc2bd4..dd61752f4c96 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -45,7 +45,6 @@ obj-y += head$(BITS).o obj-y += ebda.o obj-y += platform-quirks.o obj-y += process_$(BITS).o signal.o signal_$(BITS).o -obj-$(CONFIG_COMPAT) += signal_compat.o obj-y += traps.o idt.o irq.o irq_$(BITS).o dumpstack_$(BITS).o obj-y += time.o ioport.o dumpstack.o nmi.o obj-$(CONFIG_MODIFY_LDT_SYSCALL) += ldt.o diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 907cc98b1938..1c38174b5f01 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -188,6 +188,17 @@ static int acpi_register_lapic(int id, u32 acpiid, u8 enabled) return cpu; } +static bool __init acpi_is_processor_usable(u32 lapic_flags) +{ + if (lapic_flags & ACPI_MADT_ENABLED) + return true; + + if (acpi_support_online_capable && (lapic_flags & ACPI_MADT_ONLINE_CAPABLE)) + return true; + + return false; +} + static int __init acpi_parse_x2apic(union acpi_subtable_headers *header, const unsigned long end) { @@ -212,6 +223,10 @@ acpi_parse_x2apic(union acpi_subtable_headers *header, const unsigned long end) if (apic_id == 0xffffffff) return 0; + /* don't register processors that cannot be onlined */ + if (!acpi_is_processor_usable(processor->lapic_flags)) + return 0; + /* * We need to register disabled CPU as well to permit * counting disabled CPUs. This allows us to size @@ -250,9 +265,7 @@ acpi_parse_lapic(union acpi_subtable_headers * header, const unsigned long end) return 0; /* don't register processors that can not be onlined */ - if (acpi_support_online_capable && - !(processor->lapic_flags & ACPI_MADT_ENABLED) && - !(processor->lapic_flags & ACPI_MADT_ONLINE_CAPABLE)) + if (!acpi_is_processor_usable(processor->lapic_flags)) return 0; /* @@ -1840,23 +1853,23 @@ early_param("acpi_sci", setup_acpi_sci); int __acpi_acquire_global_lock(unsigned int *lock) { - unsigned int old, new, val; + unsigned int old, new; + + old = READ_ONCE(*lock); do { - old = *lock; new = (((old & ~0x3) + 2) + ((old >> 1) & 0x1)); - val = cmpxchg(lock, old, new); - } while (unlikely (val != old)); + } while (!try_cmpxchg(lock, &old, new)); return ((new & 0x3) < 3) ? -1 : 0; } int __acpi_release_global_lock(unsigned int *lock) { - unsigned int old, new, val; + unsigned int old, new; + + old = READ_ONCE(*lock); do { - old = *lock; new = old & ~0x3; - val = cmpxchg(lock, old, new); - } while (unlikely (val != old)); + } while (!try_cmpxchg(lock, &old, new)); return old & 0x1; } diff --git a/arch/x86/kernel/cpu/aperfmperf.c b/arch/x86/kernel/cpu/aperfmperf.c index 1f60a2b27936..fdbb5f07448f 100644 --- a/arch/x86/kernel/cpu/aperfmperf.c +++ b/arch/x86/kernel/cpu/aperfmperf.c @@ -330,7 +330,16 @@ static void __init bp_init_freq_invariance(void) static void disable_freq_invariance_workfn(struct work_struct *work) { + int cpu; + static_branch_disable(&arch_scale_freq_key); + + /* + * Set arch_freq_scale to a default value on all cpus + * This negates the effect of scaling + */ + for_each_possible_cpu(cpu) + per_cpu(arch_freq_scale, cpu) = SCHED_CAPACITY_SCALE; } static DECLARE_WORK(disable_freq_invariance_work, diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index bca0bd8f4846..85168740f76a 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -86,7 +86,7 @@ void update_spec_ctrl_cond(u64 val) wrmsrl(MSR_IA32_SPEC_CTRL, val); } -u64 spec_ctrl_current(void) +noinstr u64 spec_ctrl_current(void) { return this_cpu_read(x86_spec_ctrl_current); } diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 9cfca3d7d0e2..f3cc7699e1e1 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -1256,6 +1256,8 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = { #define MMIO_SBDS BIT(2) /* CPU is affected by RETbleed, speculating where you would not expect it */ #define RETBLEED BIT(3) +/* CPU is affected by SMT (cross-thread) return predictions */ +#define SMT_RSB BIT(4) static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = { VULNBL_INTEL_STEPPINGS(IVYBRIDGE, X86_STEPPING_ANY, SRBDS), @@ -1287,8 +1289,8 @@ static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = { VULNBL_AMD(0x15, RETBLEED), VULNBL_AMD(0x16, RETBLEED), - VULNBL_AMD(0x17, RETBLEED), - VULNBL_HYGON(0x18, RETBLEED), + VULNBL_AMD(0x17, RETBLEED | SMT_RSB), + VULNBL_HYGON(0x18, RETBLEED | SMT_RSB), {} }; @@ -1406,6 +1408,9 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) !(ia32_cap & ARCH_CAP_PBRSB_NO)) setup_force_cpu_bug(X86_BUG_EIBRS_PBRSB); + if (cpu_matches(cpu_vuln_blacklist, SMT_RSB)) + setup_force_cpu_bug(X86_BUG_SMT_RSB); + if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN)) return; diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c index efe0c30d3a12..77538abeb72a 100644 --- a/arch/x86/kernel/cpu/resctrl/monitor.c +++ b/arch/x86/kernel/cpu/resctrl/monitor.c @@ -146,6 +146,30 @@ static inline struct rmid_entry *__rmid_entry(u32 rmid) return entry; } +static int __rmid_read(u32 rmid, enum resctrl_event_id eventid, u64 *val) +{ + u64 msr_val; + + /* + * As per the SDM, when IA32_QM_EVTSEL.EvtID (bits 7:0) is configured + * with a valid event code for supported resource type and the bits + * IA32_QM_EVTSEL.RMID (bits 41:32) are configured with valid RMID, + * IA32_QM_CTR.data (bits 61:0) reports the monitored data. + * IA32_QM_CTR.Error (bit 63) and IA32_QM_CTR.Unavailable (bit 62) + * are error bits. + */ + wrmsr(MSR_IA32_QM_EVTSEL, eventid, rmid); + rdmsrl(MSR_IA32_QM_CTR, msr_val); + + if (msr_val & RMID_VAL_ERROR) + return -EIO; + if (msr_val & RMID_VAL_UNAVAIL) + return -EINVAL; + + *val = msr_val; + return 0; +} + static struct arch_mbm_state *get_arch_mbm_state(struct rdt_hw_domain *hw_dom, u32 rmid, enum resctrl_event_id eventid) @@ -172,8 +196,12 @@ void resctrl_arch_reset_rmid(struct rdt_resource *r, struct rdt_domain *d, struct arch_mbm_state *am; am = get_arch_mbm_state(hw_dom, rmid, eventid); - if (am) + if (am) { memset(am, 0, sizeof(*am)); + + /* Record any initial, non-zero count value. */ + __rmid_read(rmid, eventid, &am->prev_msr); + } } static u64 mbm_overflow_count(u64 prev_msr, u64 cur_msr, unsigned int width) @@ -191,25 +219,14 @@ int resctrl_arch_rmid_read(struct rdt_resource *r, struct rdt_domain *d, struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d); struct arch_mbm_state *am; u64 msr_val, chunks; + int ret; if (!cpumask_test_cpu(smp_processor_id(), &d->cpu_mask)) return -EINVAL; - /* - * As per the SDM, when IA32_QM_EVTSEL.EvtID (bits 7:0) is configured - * with a valid event code for supported resource type and the bits - * IA32_QM_EVTSEL.RMID (bits 41:32) are configured with valid RMID, - * IA32_QM_CTR.data (bits 61:0) reports the monitored data. - * IA32_QM_CTR.Error (bit 63) and IA32_QM_CTR.Unavailable (bit 62) - * are error bits. - */ - wrmsr(MSR_IA32_QM_EVTSEL, eventid, rmid); - rdmsrl(MSR_IA32_QM_CTR, msr_val); - - if (msr_val & RMID_VAL_ERROR) - return -EIO; - if (msr_val & RMID_VAL_UNAVAIL) - return -EINVAL; + ret = __rmid_read(rmid, eventid, &msr_val); + if (ret) + return ret; am = get_arch_mbm_state(hw_dom, rmid, eventid); if (am) { diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/resctrl/rdtgroup.c index e5a48f05e787..5993da21d822 100644 --- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c +++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c @@ -580,8 +580,10 @@ static int __rdtgroup_move_task(struct task_struct *tsk, /* * Ensure the task's closid and rmid are written before determining if * the task is current that will decide if it will be interrupted. + * This pairs with the full barrier between the rq->curr update and + * resctrl_sched_in() during context switch. */ - barrier(); + smp_mb(); /* * By now, the task's closid and rmid are set. If the task is current @@ -2402,6 +2404,14 @@ static void rdt_move_group_tasks(struct rdtgroup *from, struct rdtgroup *to, WRITE_ONCE(t->rmid, to->mon.rmid); /* + * Order the closid/rmid stores above before the loads + * in task_curr(). This pairs with the full barrier + * between the rq->curr update and resctrl_sched_in() + * during context switch. + */ + smp_mb(); + + /* * If the task is on a CPU, set the CPU in the mask. * The detection is inaccurate as tasks might move or * schedule before the smp function call takes place. diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c index 02039ec3597d..11f83d07925e 100644 --- a/arch/x86/kernel/cpu/vmware.c +++ b/arch/x86/kernel/cpu/vmware.c @@ -143,7 +143,7 @@ static __init int parse_no_stealacc(char *arg) } early_param("no-steal-acc", parse_no_stealacc); -static unsigned long long notrace vmware_sched_clock(void) +static noinstr u64 vmware_sched_clock(void) { unsigned long long ns; diff --git a/arch/x86/kernel/fpu/context.h b/arch/x86/kernel/fpu/context.h index 958accf2ccf0..9fcfa5c4dad7 100644 --- a/arch/x86/kernel/fpu/context.h +++ b/arch/x86/kernel/fpu/context.h @@ -57,7 +57,7 @@ static inline void fpregs_restore_userregs(void) struct fpu *fpu = ¤t->thread.fpu; int cpu = smp_processor_id(); - if (WARN_ON_ONCE(current->flags & PF_KTHREAD)) + if (WARN_ON_ONCE(current->flags & (PF_KTHREAD | PF_IO_WORKER))) return; if (!fpregs_state_valid(fpu, cpu)) { diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c index 9baa89a8877d..caf33486dc5e 100644 --- a/arch/x86/kernel/fpu/core.c +++ b/arch/x86/kernel/fpu/core.c @@ -426,7 +426,7 @@ void kernel_fpu_begin_mask(unsigned int kfpu_mask) this_cpu_write(in_kernel_fpu, true); - if (!(current->flags & PF_KTHREAD) && + if (!(current->flags & (PF_KTHREAD | PF_IO_WORKER)) && !test_thread_flag(TIF_NEED_FPU_LOAD)) { set_thread_flag(TIF_NEED_FPU_LOAD); save_fpregs_to_fpstate(¤t->thread.fpu); @@ -853,12 +853,12 @@ int fpu__exception_code(struct fpu *fpu, int trap_nr) * Initialize register state that may prevent from entering low-power idle. * This function will be invoked from the cpuidle driver only when needed. */ -void fpu_idle_fpregs(void) +noinstr void fpu_idle_fpregs(void) { /* Note: AMX_TILE being enabled implies XGETBV1 support */ if (cpu_feature_enabled(X86_FEATURE_AMX_TILE) && (xfeatures_in_use() & XFEATURE_MASK_XTILE)) { tile_release(); - fpregs_deactivate(¤t->thread.fpu); + __this_cpu_write(fpu_fpregs_owner_ctx, NULL); } } diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c index 3aa5304200c5..4d8aff05a509 100644 --- a/arch/x86/kernel/i8259.c +++ b/arch/x86/kernel/i8259.c @@ -114,6 +114,7 @@ static void make_8259A_irq(unsigned int irq) disable_irq_nosync(irq); io_apic_irqs &= ~(1<<irq); irq_set_chip_and_handler(irq, &i8259A_chip, handle_level_irq); + irq_set_status_flags(irq, IRQ_LEVEL); enable_irq(irq); lapic_assign_legacy_vector(irq, true); } diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c index beb1bada1b0a..c683666876f1 100644 --- a/arch/x86/kernel/irqinit.c +++ b/arch/x86/kernel/irqinit.c @@ -65,8 +65,10 @@ void __init init_ISA_irqs(void) legacy_pic->init(0); - for (i = 0; i < nr_legacy_irqs(); i++) + for (i = 0; i < nr_legacy_irqs(); i++) { irq_set_chip_and_handler(i, chip, handle_level_irq); + irq_set_status_flags(i, IRQ_LEVEL); + } } void __init init_IRQ(void) diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index b36f3c367cb2..754da3b226f9 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c @@ -625,7 +625,7 @@ static int prepare_emulation(struct kprobe *p, struct insn *insn) /* 1 byte conditional jump */ p->ainsn.emulate_op = kprobe_emulate_jcc; p->ainsn.jcc.type = opcode & 0xf; - p->ainsn.rel32 = *(char *)insn->immediate.bytes; + p->ainsn.rel32 = insn->immediate.value; break; case 0x0f: opcode = insn->opcode.bytes[1]; @@ -659,17 +659,19 @@ static int prepare_emulation(struct kprobe *p, struct insn *insn) * is determined by the MOD/RM byte. */ opcode = insn->modrm.bytes[0]; - if ((opcode & 0x30) == 0x10) { - if ((opcode & 0x8) == 0x8) - return -EOPNOTSUPP; /* far call */ - /* call absolute, indirect */ + switch (X86_MODRM_REG(opcode)) { + case 0b010: /* FF /2, call near, absolute indirect */ p->ainsn.emulate_op = kprobe_emulate_call_indirect; - } else if ((opcode & 0x30) == 0x20) { - if ((opcode & 0x8) == 0x8) - return -EOPNOTSUPP; /* far jmp */ - /* jmp near absolute indirect */ + break; + case 0b100: /* FF /4, jmp near, absolute indirect */ p->ainsn.emulate_op = kprobe_emulate_jmp_indirect; - } else + break; + case 0b011: /* FF /3, call far, absolute indirect */ + case 0b101: /* FF /5, jmp far, absolute indirect */ + return -EOPNOTSUPP; + } + + if (!p->ainsn.emulate_op) break; if (insn->addr_bytes != sizeof(unsigned long)) @@ -990,20 +992,6 @@ int kprobe_int3_handler(struct pt_regs *regs) kprobe_post_process(p, regs, kcb); return 1; } - } - - if (*addr != INT3_INSN_OPCODE) { - /* - * The breakpoint instruction was removed right - * after we hit it. Another cpu has removed - * either a probepoint or a debugger breakpoint - * at this address. In either case, no further - * handling of this interrupt is appropriate. - * Back up over the (now missing) int3 and run - * the original instruction. - */ - regs->ip = (unsigned long)addr; - return 1; } /* else: not a kprobe fault; let the kernel handle it */ return 0; diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c index 16333ba1904b..0f35d44c56fe 100644 --- a/arch/x86/kernel/kvmclock.c +++ b/arch/x86/kernel/kvmclock.c @@ -71,12 +71,12 @@ static int kvm_set_wallclock(const struct timespec64 *now) return -ENODEV; } -static u64 kvm_clock_read(void) +static noinstr u64 kvm_clock_read(void) { u64 ret; preempt_disable_notrace(); - ret = pvclock_clocksource_read(this_cpu_pvti()); + ret = pvclock_clocksource_read_nowd(this_cpu_pvti()); preempt_enable_notrace(); return ret; } @@ -86,7 +86,7 @@ static u64 kvm_clock_get_cycles(struct clocksource *cs) return kvm_clock_read(); } -static u64 kvm_sched_clock_read(void) +static noinstr u64 kvm_sched_clock_read(void) { return kvm_clock_read() - kvm_sched_clock_offset; } diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index 327757afb027..5bf4f0b2f35d 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c @@ -216,6 +216,11 @@ static noinstr void pv_native_set_debugreg(int regno, unsigned long val) native_set_debugreg(regno, val); } +noinstr void pv_native_wbinvd(void) +{ + native_wbinvd(); +} + static noinstr void pv_native_irq_enable(void) { native_irq_enable(); @@ -225,6 +230,11 @@ static noinstr void pv_native_irq_disable(void) { native_irq_disable(); } + +static noinstr void pv_native_safe_halt(void) +{ + native_safe_halt(); +} #endif enum paravirt_lazy_mode paravirt_get_lazy_mode(void) @@ -256,7 +266,7 @@ struct paravirt_patch_template pv_ops = { .cpu.read_cr0 = native_read_cr0, .cpu.write_cr0 = native_write_cr0, .cpu.write_cr4 = native_write_cr4, - .cpu.wbinvd = native_wbinvd, + .cpu.wbinvd = pv_native_wbinvd, .cpu.read_msr = native_read_msr, .cpu.write_msr = native_write_msr, .cpu.read_msr_safe = native_read_msr_safe, @@ -290,7 +300,7 @@ struct paravirt_patch_template pv_ops = { .irq.save_fl = __PV_IS_CALLEE_SAVE(native_save_fl), .irq.irq_disable = __PV_IS_CALLEE_SAVE(pv_native_irq_disable), .irq.irq_enable = __PV_IS_CALLEE_SAVE(pv_native_irq_enable), - .irq.safe_halt = native_safe_halt, + .irq.safe_halt = pv_native_safe_halt, .irq.halt = native_halt, #endif /* CONFIG_PARAVIRT_XXL */ diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 40d156a31676..e57cd31bfec4 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -24,6 +24,7 @@ #include <linux/cpuidle.h> #include <linux/acpi.h> #include <linux/elf-randomize.h> +#include <linux/static_call.h> #include <trace/events/power.h> #include <linux/hw_breakpoint.h> #include <asm/cpu.h> @@ -694,7 +695,24 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p) unsigned long boot_option_idle_override = IDLE_NO_OVERRIDE; EXPORT_SYMBOL(boot_option_idle_override); -static void (*x86_idle)(void); +/* + * We use this if we don't have any better idle routine.. + */ +void __cpuidle default_idle(void) +{ + raw_safe_halt(); + raw_local_irq_disable(); +} +#if defined(CONFIG_APM_MODULE) || defined(CONFIG_HALTPOLL_CPUIDLE_MODULE) +EXPORT_SYMBOL(default_idle); +#endif + +DEFINE_STATIC_CALL_NULL(x86_idle, default_idle); + +static bool x86_idle_set(void) +{ + return !!static_call_query(x86_idle); +} #ifndef CONFIG_SMP static inline void play_dead(void) @@ -717,28 +735,17 @@ void arch_cpu_idle_dead(void) /* * Called from the generic idle code. */ -void arch_cpu_idle(void) -{ - x86_idle(); -} - -/* - * We use this if we don't have any better idle routine.. - */ -void __cpuidle default_idle(void) +void __cpuidle arch_cpu_idle(void) { - raw_safe_halt(); + static_call(x86_idle)(); } -#if defined(CONFIG_APM_MODULE) || defined(CONFIG_HALTPOLL_CPUIDLE_MODULE) -EXPORT_SYMBOL(default_idle); -#endif #ifdef CONFIG_XEN bool xen_set_default_idle(void) { - bool ret = !!x86_idle; + bool ret = x86_idle_set(); - x86_idle = default_idle; + static_call_update(x86_idle, default_idle); return ret; } @@ -800,13 +807,7 @@ static void amd_e400_idle(void) default_idle(); - /* - * The switch back from broadcast mode needs to be called with - * interrupts disabled. - */ - raw_local_irq_disable(); tick_broadcast_exit(); - raw_local_irq_enable(); } /* @@ -864,12 +865,10 @@ static __cpuidle void mwait_idle(void) } __monitor((void *)¤t_thread_info()->flags, 0, 0); - if (!need_resched()) + if (!need_resched()) { __sti_mwait(0, 0); - else - raw_local_irq_enable(); - } else { - raw_local_irq_enable(); + raw_local_irq_disable(); + } } __current_clr_polling(); } @@ -880,20 +879,20 @@ void select_idle_routine(const struct cpuinfo_x86 *c) if (boot_option_idle_override == IDLE_POLL && smp_num_siblings > 1) pr_warn_once("WARNING: polling idle and HT enabled, performance may degrade\n"); #endif - if (x86_idle || boot_option_idle_override == IDLE_POLL) + if (x86_idle_set() || boot_option_idle_override == IDLE_POLL) return; if (boot_cpu_has_bug(X86_BUG_AMD_E400)) { pr_info("using AMD E400 aware idle routine\n"); - x86_idle = amd_e400_idle; + static_call_update(x86_idle, amd_e400_idle); } else if (prefer_mwait_c1_over_halt(c)) { pr_info("using mwait in idle threads\n"); - x86_idle = mwait_idle; + static_call_update(x86_idle, mwait_idle); } else if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST)) { pr_info("using TDX aware idle routine\n"); - x86_idle = tdx_safe_halt; + static_call_update(x86_idle, tdx_safe_halt); } else - x86_idle = default_idle; + static_call_update(x86_idle, default_idle); } void amd_e400_c1e_apic_setup(void) @@ -946,7 +945,7 @@ static int __init idle_setup(char *str) * To continue to load the CPU idle driver, don't touch * the boot_option_idle_override. */ - x86_idle = default_idle; + static_call_update(x86_idle, default_idle); boot_option_idle_override = IDLE_HALT; } else if (!strcmp(str, "nomwait")) { /* diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c index eda37df016f0..56acf53a782a 100644 --- a/arch/x86/kernel/pvclock.c +++ b/arch/x86/kernel/pvclock.c @@ -64,7 +64,8 @@ u8 pvclock_read_flags(struct pvclock_vcpu_time_info *src) return flags & valid_flags; } -u64 pvclock_clocksource_read(struct pvclock_vcpu_time_info *src) +static __always_inline +u64 __pvclock_clocksource_read(struct pvclock_vcpu_time_info *src, bool dowd) { unsigned version; u64 ret; @@ -77,7 +78,7 @@ u64 pvclock_clocksource_read(struct pvclock_vcpu_time_info *src) flags = src->flags; } while (pvclock_read_retry(src, version)); - if (unlikely((flags & PVCLOCK_GUEST_STOPPED) != 0)) { + if (dowd && unlikely((flags & PVCLOCK_GUEST_STOPPED) != 0)) { src->flags &= ~PVCLOCK_GUEST_STOPPED; pvclock_touch_watchdogs(); } @@ -100,16 +101,25 @@ u64 pvclock_clocksource_read(struct pvclock_vcpu_time_info *src) * updating at the same time, and one of them could be slightly behind, * making the assumption that last_value always go forward fail to hold. */ - last = atomic64_read(&last_value); + last = arch_atomic64_read(&last_value); do { - if (ret < last) + if (ret <= last) return last; - last = atomic64_cmpxchg(&last_value, last, ret); - } while (unlikely(last != ret)); + } while (!arch_atomic64_try_cmpxchg(&last_value, &last, ret)); return ret; } +u64 pvclock_clocksource_read(struct pvclock_vcpu_time_info *src) +{ + return __pvclock_clocksource_read(src, true); +} + +noinstr u64 pvclock_clocksource_read_nowd(struct pvclock_vcpu_time_info *src) +{ + return __pvclock_clocksource_read(src, false); +} + void pvclock_read_wallclock(struct pvclock_wall_clock *wall_clock, struct pvclock_vcpu_time_info *vcpu_time, struct timespec64 *ts) diff --git a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c index 2553136cf39b..f042dcdf1f16 100644 --- a/arch/x86/kernel/signal_32.c +++ b/arch/x86/kernel/signal_32.c @@ -54,12 +54,14 @@ static inline void reload_segments(struct sigcontext_32 *sc) } #define sigset32_t compat_sigset_t +#define siginfo32_t compat_siginfo_t #define restore_altstack32 compat_restore_altstack #define unsafe_save_altstack32 unsafe_compat_save_altstack #else #define sigset32_t sigset_t +#define siginfo32_t siginfo_t #define __NR_ia32_sigreturn __NR_sigreturn #define __NR_ia32_rt_sigreturn __NR_rt_sigreturn #define restore_altstack32 restore_altstack @@ -377,3 +379,128 @@ Efault: user_access_end(); return -EFAULT; } + +/* + * The siginfo_t structure and handing code is very easy + * to break in several ways. It must always be updated when new + * updates are made to the main siginfo_t, and + * copy_siginfo_to_user32() must be updated when the + * (arch-independent) copy_siginfo_to_user() is updated. + * + * It is also easy to put a new member in the siginfo_t + * which has implicit alignment which can move internal structure + * alignment around breaking the ABI. This can happen if you, + * for instance, put a plain 64-bit value in there. + */ + +/* +* If adding a new si_code, there is probably new data in +* the siginfo. Make sure folks bumping the si_code +* limits also have to look at this code. Make sure any +* new fields are handled in copy_siginfo_to_user32()! +*/ +static_assert(NSIGILL == 11); +static_assert(NSIGFPE == 15); +static_assert(NSIGSEGV == 9); +static_assert(NSIGBUS == 5); +static_assert(NSIGTRAP == 6); +static_assert(NSIGCHLD == 6); +static_assert(NSIGSYS == 2); + +/* This is part of the ABI and can never change in size: */ +static_assert(sizeof(siginfo32_t) == 128); + +/* This is a part of the ABI and can never change in alignment */ +static_assert(__alignof__(siginfo32_t) == 4); + +/* +* The offsets of all the (unioned) si_fields are fixed +* in the ABI, of course. Make sure none of them ever +* move and are always at the beginning: +*/ +static_assert(offsetof(siginfo32_t, _sifields) == 3 * sizeof(int)); + +static_assert(offsetof(siginfo32_t, si_signo) == 0); +static_assert(offsetof(siginfo32_t, si_errno) == 4); +static_assert(offsetof(siginfo32_t, si_code) == 8); + +/* +* Ensure that the size of each si_field never changes. +* If it does, it is a sign that the +* copy_siginfo_to_user32() code below needs to updated +* along with the size in the CHECK_SI_SIZE(). +* +* We repeat this check for both the generic and compat +* siginfos. +* +* Note: it is OK for these to grow as long as the whole +* structure stays within the padding size (checked +* above). +*/ + +#define CHECK_SI_OFFSET(name) \ + static_assert(offsetof(siginfo32_t, _sifields) == \ + offsetof(siginfo32_t, _sifields.name)) + +#define CHECK_SI_SIZE(name, size) \ + static_assert(sizeof_field(siginfo32_t, _sifields.name) == size) + +CHECK_SI_OFFSET(_kill); +CHECK_SI_SIZE (_kill, 2*sizeof(int)); +static_assert(offsetof(siginfo32_t, si_pid) == 0xC); +static_assert(offsetof(siginfo32_t, si_uid) == 0x10); + +CHECK_SI_OFFSET(_timer); +#ifdef CONFIG_COMPAT +/* compat_siginfo_t doesn't have si_sys_private */ +CHECK_SI_SIZE (_timer, 3*sizeof(int)); +#else +CHECK_SI_SIZE (_timer, 4*sizeof(int)); +#endif +static_assert(offsetof(siginfo32_t, si_tid) == 0x0C); +static_assert(offsetof(siginfo32_t, si_overrun) == 0x10); +static_assert(offsetof(siginfo32_t, si_value) == 0x14); + +CHECK_SI_OFFSET(_rt); +CHECK_SI_SIZE (_rt, 3*sizeof(int)); +static_assert(offsetof(siginfo32_t, si_pid) == 0x0C); +static_assert(offsetof(siginfo32_t, si_uid) == 0x10); +static_assert(offsetof(siginfo32_t, si_value) == 0x14); + +CHECK_SI_OFFSET(_sigchld); +CHECK_SI_SIZE (_sigchld, 5*sizeof(int)); +static_assert(offsetof(siginfo32_t, si_pid) == 0x0C); +static_assert(offsetof(siginfo32_t, si_uid) == 0x10); +static_assert(offsetof(siginfo32_t, si_status) == 0x14); +static_assert(offsetof(siginfo32_t, si_utime) == 0x18); +static_assert(offsetof(siginfo32_t, si_stime) == 0x1C); + +CHECK_SI_OFFSET(_sigfault); +CHECK_SI_SIZE (_sigfault, 4*sizeof(int)); +static_assert(offsetof(siginfo32_t, si_addr) == 0x0C); + +static_assert(offsetof(siginfo32_t, si_trapno) == 0x10); + +static_assert(offsetof(siginfo32_t, si_addr_lsb) == 0x10); + +static_assert(offsetof(siginfo32_t, si_lower) == 0x14); +static_assert(offsetof(siginfo32_t, si_upper) == 0x18); + +static_assert(offsetof(siginfo32_t, si_pkey) == 0x14); + +static_assert(offsetof(siginfo32_t, si_perf_data) == 0x10); +static_assert(offsetof(siginfo32_t, si_perf_type) == 0x14); +static_assert(offsetof(siginfo32_t, si_perf_flags) == 0x18); + +CHECK_SI_OFFSET(_sigpoll); +CHECK_SI_SIZE (_sigpoll, 2*sizeof(int)); +static_assert(offsetof(siginfo32_t, si_band) == 0x0C); +static_assert(offsetof(siginfo32_t, si_fd) == 0x10); + +CHECK_SI_OFFSET(_sigsys); +CHECK_SI_SIZE (_sigsys, 3*sizeof(int)); +static_assert(offsetof(siginfo32_t, si_call_addr) == 0x0C); +static_assert(offsetof(siginfo32_t, si_syscall) == 0x10); +static_assert(offsetof(siginfo32_t, si_arch) == 0x14); + +/* any new si_fields should be added here */ diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c index ff9c55064223..13a1e6083837 100644 --- a/arch/x86/kernel/signal_64.c +++ b/arch/x86/kernel/signal_64.c @@ -381,3 +381,130 @@ badframe: return 0; } #endif /* CONFIG_X86_X32_ABI */ + +#ifdef CONFIG_COMPAT +void sigaction_compat_abi(struct k_sigaction *act, struct k_sigaction *oact) +{ + if (!act) + return; + + if (in_ia32_syscall()) + act->sa.sa_flags |= SA_IA32_ABI; + if (in_x32_syscall()) + act->sa.sa_flags |= SA_X32_ABI; +} +#endif /* CONFIG_COMPAT */ + +/* +* If adding a new si_code, there is probably new data in +* the siginfo. Make sure folks bumping the si_code +* limits also have to look at this code. Make sure any +* new fields are handled in copy_siginfo_to_user32()! +*/ +static_assert(NSIGILL == 11); +static_assert(NSIGFPE == 15); +static_assert(NSIGSEGV == 9); +static_assert(NSIGBUS == 5); +static_assert(NSIGTRAP == 6); +static_assert(NSIGCHLD == 6); +static_assert(NSIGSYS == 2); + +/* This is part of the ABI and can never change in size: */ +static_assert(sizeof(siginfo_t) == 128); + +/* This is a part of the ABI and can never change in alignment */ +static_assert(__alignof__(siginfo_t) == 8); + +/* +* The offsets of all the (unioned) si_fields are fixed +* in the ABI, of course. Make sure none of them ever +* move and are always at the beginning: +*/ +static_assert(offsetof(siginfo_t, si_signo) == 0); +static_assert(offsetof(siginfo_t, si_errno) == 4); +static_assert(offsetof(siginfo_t, si_code) == 8); + +/* +* Ensure that the size of each si_field never changes. +* If it does, it is a sign that the +* copy_siginfo_to_user32() code below needs to updated +* along with the size in the CHECK_SI_SIZE(). +* +* We repeat this check for both the generic and compat +* siginfos. +* +* Note: it is OK for these to grow as long as the whole +* structure stays within the padding size (checked +* above). +*/ + +#define CHECK_SI_OFFSET(name) \ + static_assert(offsetof(siginfo_t, _sifields) == \ + offsetof(siginfo_t, _sifields.name)) +#define CHECK_SI_SIZE(name, size) \ + static_assert(sizeof_field(siginfo_t, _sifields.name) == size) + +CHECK_SI_OFFSET(_kill); +CHECK_SI_SIZE (_kill, 2*sizeof(int)); +static_assert(offsetof(siginfo_t, si_pid) == 0x10); +static_assert(offsetof(siginfo_t, si_uid) == 0x14); + +CHECK_SI_OFFSET(_timer); +CHECK_SI_SIZE (_timer, 6*sizeof(int)); +static_assert(offsetof(siginfo_t, si_tid) == 0x10); +static_assert(offsetof(siginfo_t, si_overrun) == 0x14); +static_assert(offsetof(siginfo_t, si_value) == 0x18); + +CHECK_SI_OFFSET(_rt); +CHECK_SI_SIZE (_rt, 4*sizeof(int)); +static_assert(offsetof(siginfo_t, si_pid) == 0x10); +static_assert(offsetof(siginfo_t, si_uid) == 0x14); +static_assert(offsetof(siginfo_t, si_value) == 0x18); + +CHECK_SI_OFFSET(_sigchld); +CHECK_SI_SIZE (_sigchld, 8*sizeof(int)); +static_assert(offsetof(siginfo_t, si_pid) == 0x10); +static_assert(offsetof(siginfo_t, si_uid) == 0x14); +static_assert(offsetof(siginfo_t, si_status) == 0x18); +static_assert(offsetof(siginfo_t, si_utime) == 0x20); +static_assert(offsetof(siginfo_t, si_stime) == 0x28); + +#ifdef CONFIG_X86_X32_ABI +/* no _sigchld_x32 in the generic siginfo_t */ +static_assert(sizeof_field(compat_siginfo_t, _sifields._sigchld_x32) == + 7*sizeof(int)); +static_assert(offsetof(compat_siginfo_t, _sifields) == + offsetof(compat_siginfo_t, _sifields._sigchld_x32)); +static_assert(offsetof(compat_siginfo_t, _sifields._sigchld_x32._utime) == 0x18); +static_assert(offsetof(compat_siginfo_t, _sifields._sigchld_x32._stime) == 0x20); +#endif + +CHECK_SI_OFFSET(_sigfault); +CHECK_SI_SIZE (_sigfault, 8*sizeof(int)); +static_assert(offsetof(siginfo_t, si_addr) == 0x10); + +static_assert(offsetof(siginfo_t, si_trapno) == 0x18); + +static_assert(offsetof(siginfo_t, si_addr_lsb) == 0x18); + +static_assert(offsetof(siginfo_t, si_lower) == 0x20); +static_assert(offsetof(siginfo_t, si_upper) == 0x28); + +static_assert(offsetof(siginfo_t, si_pkey) == 0x20); + +static_assert(offsetof(siginfo_t, si_perf_data) == 0x18); +static_assert(offsetof(siginfo_t, si_perf_type) == 0x20); +static_assert(offsetof(siginfo_t, si_perf_flags) == 0x24); + +CHECK_SI_OFFSET(_sigpoll); +CHECK_SI_SIZE (_sigpoll, 4*sizeof(int)); +static_assert(offsetof(siginfo_t, si_band) == 0x10); +static_assert(offsetof(siginfo_t, si_fd) == 0x18); + +CHECK_SI_OFFSET(_sigsys); +CHECK_SI_SIZE (_sigsys, 4*sizeof(int)); +static_assert(offsetof(siginfo_t, si_call_addr) == 0x10); +static_assert(offsetof(siginfo_t, si_syscall) == 0x18); +static_assert(offsetof(siginfo_t, si_arch) == 0x1C); + +/* any new si_fields should be added here */ diff --git a/arch/x86/kernel/signal_compat.c b/arch/x86/kernel/signal_compat.c deleted file mode 100644 index 879ef8c72f5c..000000000000 --- a/arch/x86/kernel/signal_compat.c +++ /dev/null @@ -1,191 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include <linux/compat.h> -#include <linux/uaccess.h> -#include <linux/ptrace.h> - -/* - * The compat_siginfo_t structure and handing code is very easy - * to break in several ways. It must always be updated when new - * updates are made to the main siginfo_t, and - * copy_siginfo_to_user32() must be updated when the - * (arch-independent) copy_siginfo_to_user() is updated. - * - * It is also easy to put a new member in the compat_siginfo_t - * which has implicit alignment which can move internal structure - * alignment around breaking the ABI. This can happen if you, - * for instance, put a plain 64-bit value in there. - */ -static inline void signal_compat_build_tests(void) -{ - int _sifields_offset = offsetof(compat_siginfo_t, _sifields); - - /* - * If adding a new si_code, there is probably new data in - * the siginfo. Make sure folks bumping the si_code - * limits also have to look at this code. Make sure any - * new fields are handled in copy_siginfo_to_user32()! - */ - BUILD_BUG_ON(NSIGILL != 11); - BUILD_BUG_ON(NSIGFPE != 15); - BUILD_BUG_ON(NSIGSEGV != 9); - BUILD_BUG_ON(NSIGBUS != 5); - BUILD_BUG_ON(NSIGTRAP != 6); - BUILD_BUG_ON(NSIGCHLD != 6); - BUILD_BUG_ON(NSIGSYS != 2); - - /* This is part of the ABI and can never change in size: */ - BUILD_BUG_ON(sizeof(siginfo_t) != 128); - BUILD_BUG_ON(sizeof(compat_siginfo_t) != 128); - - /* This is a part of the ABI and can never change in alignment */ - BUILD_BUG_ON(__alignof__(siginfo_t) != 8); - BUILD_BUG_ON(__alignof__(compat_siginfo_t) != 4); - - /* - * The offsets of all the (unioned) si_fields are fixed - * in the ABI, of course. Make sure none of them ever - * move and are always at the beginning: - */ - BUILD_BUG_ON(offsetof(compat_siginfo_t, _sifields) != 3 * sizeof(int)); -#define CHECK_CSI_OFFSET(name) BUILD_BUG_ON(_sifields_offset != offsetof(compat_siginfo_t, _sifields.name)) - - BUILD_BUG_ON(offsetof(siginfo_t, si_signo) != 0); - BUILD_BUG_ON(offsetof(siginfo_t, si_errno) != 4); - BUILD_BUG_ON(offsetof(siginfo_t, si_code) != 8); - - BUILD_BUG_ON(offsetof(compat_siginfo_t, si_signo) != 0); - BUILD_BUG_ON(offsetof(compat_siginfo_t, si_errno) != 4); - BUILD_BUG_ON(offsetof(compat_siginfo_t, si_code) != 8); - /* - * Ensure that the size of each si_field never changes. - * If it does, it is a sign that the - * copy_siginfo_to_user32() code below needs to updated - * along with the size in the CHECK_SI_SIZE(). - * - * We repeat this check for both the generic and compat - * siginfos. - * - * Note: it is OK for these to grow as long as the whole - * structure stays within the padding size (checked - * above). - */ -#define CHECK_CSI_SIZE(name, size) BUILD_BUG_ON(size != sizeof(((compat_siginfo_t *)0)->_sifields.name)) -#define CHECK_SI_SIZE(name, size) BUILD_BUG_ON(size != sizeof(((siginfo_t *)0)->_sifields.name)) - - CHECK_CSI_OFFSET(_kill); - CHECK_CSI_SIZE (_kill, 2*sizeof(int)); - CHECK_SI_SIZE (_kill, 2*sizeof(int)); - - BUILD_BUG_ON(offsetof(siginfo_t, si_pid) != 0x10); - BUILD_BUG_ON(offsetof(siginfo_t, si_uid) != 0x14); - BUILD_BUG_ON(offsetof(compat_siginfo_t, si_pid) != 0xC); - BUILD_BUG_ON(offsetof(compat_siginfo_t, si_uid) != 0x10); - - CHECK_CSI_OFFSET(_timer); - CHECK_CSI_SIZE (_timer, 3*sizeof(int)); - CHECK_SI_SIZE (_timer, 6*sizeof(int)); - - BUILD_BUG_ON(offsetof(siginfo_t, si_tid) != 0x10); - BUILD_BUG_ON(offsetof(siginfo_t, si_overrun) != 0x14); - BUILD_BUG_ON(offsetof(siginfo_t, si_value) != 0x18); - BUILD_BUG_ON(offsetof(compat_siginfo_t, si_tid) != 0x0C); - BUILD_BUG_ON(offsetof(compat_siginfo_t, si_overrun) != 0x10); - BUILD_BUG_ON(offsetof(compat_siginfo_t, si_value) != 0x14); - - CHECK_CSI_OFFSET(_rt); - CHECK_CSI_SIZE (_rt, 3*sizeof(int)); - CHECK_SI_SIZE (_rt, 4*sizeof(int)); - - BUILD_BUG_ON(offsetof(siginfo_t, si_pid) != 0x10); - BUILD_BUG_ON(offsetof(siginfo_t, si_uid) != 0x14); - BUILD_BUG_ON(offsetof(siginfo_t, si_value) != 0x18); - BUILD_BUG_ON(offsetof(compat_siginfo_t, si_pid) != 0x0C); - BUILD_BUG_ON(offsetof(compat_siginfo_t, si_uid) != 0x10); - BUILD_BUG_ON(offsetof(compat_siginfo_t, si_value) != 0x14); - - CHECK_CSI_OFFSET(_sigchld); - CHECK_CSI_SIZE (_sigchld, 5*sizeof(int)); - CHECK_SI_SIZE (_sigchld, 8*sizeof(int)); - - BUILD_BUG_ON(offsetof(siginfo_t, si_pid) != 0x10); - BUILD_BUG_ON(offsetof(siginfo_t, si_uid) != 0x14); - BUILD_BUG_ON(offsetof(siginfo_t, si_status) != 0x18); - BUILD_BUG_ON(offsetof(siginfo_t, si_utime) != 0x20); - BUILD_BUG_ON(offsetof(siginfo_t, si_stime) != 0x28); - BUILD_BUG_ON(offsetof(compat_siginfo_t, si_pid) != 0x0C); - BUILD_BUG_ON(offsetof(compat_siginfo_t, si_uid) != 0x10); - BUILD_BUG_ON(offsetof(compat_siginfo_t, si_status) != 0x14); - BUILD_BUG_ON(offsetof(compat_siginfo_t, si_utime) != 0x18); - BUILD_BUG_ON(offsetof(compat_siginfo_t, si_stime) != 0x1C); - -#ifdef CONFIG_X86_X32_ABI - CHECK_CSI_OFFSET(_sigchld_x32); - CHECK_CSI_SIZE (_sigchld_x32, 7*sizeof(int)); - /* no _sigchld_x32 in the generic siginfo_t */ - BUILD_BUG_ON(offsetof(compat_siginfo_t, _sifields._sigchld_x32._utime) != 0x18); - BUILD_BUG_ON(offsetof(compat_siginfo_t, _sifields._sigchld_x32._stime) != 0x20); -#endif - - CHECK_CSI_OFFSET(_sigfault); - CHECK_CSI_SIZE (_sigfault, 4*sizeof(int)); - CHECK_SI_SIZE (_sigfault, 8*sizeof(int)); - - BUILD_BUG_ON(offsetof(siginfo_t, si_addr) != 0x10); - BUILD_BUG_ON(offsetof(compat_siginfo_t, si_addr) != 0x0C); - - BUILD_BUG_ON(offsetof(siginfo_t, si_trapno) != 0x18); - BUILD_BUG_ON(offsetof(compat_siginfo_t, si_trapno) != 0x10); - - BUILD_BUG_ON(offsetof(siginfo_t, si_addr_lsb) != 0x18); - BUILD_BUG_ON(offsetof(compat_siginfo_t, si_addr_lsb) != 0x10); - - BUILD_BUG_ON(offsetof(siginfo_t, si_lower) != 0x20); - BUILD_BUG_ON(offsetof(siginfo_t, si_upper) != 0x28); - BUILD_BUG_ON(offsetof(compat_siginfo_t, si_lower) != 0x14); - BUILD_BUG_ON(offsetof(compat_siginfo_t, si_upper) != 0x18); - - BUILD_BUG_ON(offsetof(siginfo_t, si_pkey) != 0x20); - BUILD_BUG_ON(offsetof(compat_siginfo_t, si_pkey) != 0x14); - - BUILD_BUG_ON(offsetof(siginfo_t, si_perf_data) != 0x18); - BUILD_BUG_ON(offsetof(siginfo_t, si_perf_type) != 0x20); - BUILD_BUG_ON(offsetof(siginfo_t, si_perf_flags) != 0x24); - BUILD_BUG_ON(offsetof(compat_siginfo_t, si_perf_data) != 0x10); - BUILD_BUG_ON(offsetof(compat_siginfo_t, si_perf_type) != 0x14); - BUILD_BUG_ON(offsetof(compat_siginfo_t, si_perf_flags) != 0x18); - - CHECK_CSI_OFFSET(_sigpoll); - CHECK_CSI_SIZE (_sigpoll, 2*sizeof(int)); - CHECK_SI_SIZE (_sigpoll, 4*sizeof(int)); - - BUILD_BUG_ON(offsetof(siginfo_t, si_band) != 0x10); - BUILD_BUG_ON(offsetof(siginfo_t, si_fd) != 0x18); - BUILD_BUG_ON(offsetof(compat_siginfo_t, si_band) != 0x0C); - BUILD_BUG_ON(offsetof(compat_siginfo_t, si_fd) != 0x10); - - CHECK_CSI_OFFSET(_sigsys); - CHECK_CSI_SIZE (_sigsys, 3*sizeof(int)); - CHECK_SI_SIZE (_sigsys, 4*sizeof(int)); - - BUILD_BUG_ON(offsetof(siginfo_t, si_call_addr) != 0x10); - BUILD_BUG_ON(offsetof(siginfo_t, si_syscall) != 0x18); - BUILD_BUG_ON(offsetof(siginfo_t, si_arch) != 0x1C); - BUILD_BUG_ON(offsetof(compat_siginfo_t, si_call_addr) != 0x0C); - BUILD_BUG_ON(offsetof(compat_siginfo_t, si_syscall) != 0x10); - BUILD_BUG_ON(offsetof(compat_siginfo_t, si_arch) != 0x14); - - /* any new si_fields should be added here */ -} - -void sigaction_compat_abi(struct k_sigaction *act, struct k_sigaction *oact) -{ - signal_compat_build_tests(); - - if (!act) - return; - - if (in_ia32_syscall()) - act->sa.sa_flags |= SA_IA32_ABI; - if (in_x32_syscall()) - act->sa.sa_flags |= SA_X32_ABI; -} diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index a78e73da4a74..8c33936b017d 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -215,7 +215,7 @@ static void __init cyc2ns_init_secondary_cpus(void) /* * Scheduler clock - returns current time in nanosec units. */ -u64 native_sched_clock(void) +noinstr u64 native_sched_clock(void) { if (static_branch_likely(&__use_tsc)) { u64 tsc_now = rdtsc(); @@ -248,7 +248,7 @@ u64 native_sched_clock_from_tsc(u64 tsc) /* We need to define a real function for sched_clock, to override the weak default version */ #ifdef CONFIG_PARAVIRT -unsigned long long sched_clock(void) +noinstr u64 sched_clock(void) { return paravirt_sched_clock(); } @@ -258,8 +258,7 @@ bool using_native_sched_clock(void) return static_call_query(pv_sched_clock) == native_sched_clock; } #else -unsigned long long -sched_clock(void) __attribute__((alias("native_sched_clock"))); +u64 sched_clock(void) __attribute__((alias("native_sched_clock"))); bool using_native_sched_clock(void) { return true; } #endif diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index 2e0ee14229bf..25f155205770 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S @@ -129,7 +129,6 @@ SECTIONS HEAD_TEXT TEXT_TEXT SCHED_TEXT - CPUIDLE_TEXT LOCK_TEXT KPROBES_TEXT SOFTIRQENTRY_TEXT |