Skip to content

Commit 5e3ddf9

Browse files
committed
Merge tag 'x86_urgent_for_v5.12-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Borislav Petkov: "The freshest pile of shiny x86 fixes for 5.12: - Add the arch-specific mapping between physical and logical CPUs to fix devicetree-node lookups - Restore the IRQ2 ignore logic - Fix get_nr_restart_syscall() to return the correct restart syscall number. Split in a 4-patches set to avoid kABI breakage when backporting to dead kernels" * tag 'x86_urgent_for_v5.12-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/apic/of: Fix CPU devicetree-node lookups x86/ioapic: Ignore IRQ2 again x86: Introduce restart_block->arch_data to remove TS_COMPAT_RESTART x86: Introduce TS_COMPAT_RESTART to fix get_nr_restart_syscall() x86: Move TS_COMPAT back to asm/thread_info.h kernel, fs: Introduce and use set_restart_fn() and arch_set_restart_data()
2 parents b35660a + dd92688 commit 5e3ddf9

File tree

12 files changed

+52
-44
lines changed

12 files changed

+52
-44
lines changed

arch/x86/include/asm/processor.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -551,15 +551,6 @@ static inline void arch_thread_struct_whitelist(unsigned long *offset,
551551
*size = fpu_kernel_xstate_size;
552552
}
553553

554-
/*
555-
* Thread-synchronous status.
556-
*
557-
* This is different from the flags in that nobody else
558-
* ever touches our thread-synchronous status, so we don't
559-
* have to worry about atomic accesses.
560-
*/
561-
#define TS_COMPAT 0x0002 /* 32bit syscall active (64BIT)*/
562-
563554
static inline void
564555
native_load_sp0(unsigned long sp0)
565556
{

arch/x86/include/asm/thread_info.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,10 +205,23 @@ static inline int arch_within_stack_frames(const void * const stack,
205205

206206
#endif
207207

208+
/*
209+
* Thread-synchronous status.
210+
*
211+
* This is different from the flags in that nobody else
212+
* ever touches our thread-synchronous status, so we don't
213+
* have to worry about atomic accesses.
214+
*/
215+
#define TS_COMPAT 0x0002 /* 32bit syscall active (64BIT)*/
216+
217+
#ifndef __ASSEMBLY__
208218
#ifdef CONFIG_COMPAT
209219
#define TS_I386_REGS_POKED 0x0004 /* regs poked by 32-bit ptracer */
220+
221+
#define arch_set_restart_data(restart) \
222+
do { restart->arch_data = current_thread_info()->status; } while (0)
223+
210224
#endif
211-
#ifndef __ASSEMBLY__
212225

213226
#ifdef CONFIG_X86_32
214227
#define in_ia32_syscall() true

arch/x86/kernel/apic/apic.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2342,6 +2342,11 @@ static int cpuid_to_apicid[] = {
23422342
[0 ... NR_CPUS - 1] = -1,
23432343
};
23442344

2345+
bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
2346+
{
2347+
return phys_id == cpuid_to_apicid[cpu];
2348+
}
2349+
23452350
#ifdef CONFIG_SMP
23462351
/**
23472352
* apic_id_is_primary_thread - Check whether APIC ID belongs to a primary thread

arch/x86/kernel/apic/io_apic.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,6 +1032,16 @@ static int mp_map_pin_to_irq(u32 gsi, int idx, int ioapic, int pin,
10321032
if (idx >= 0 && test_bit(mp_irqs[idx].srcbus, mp_bus_not_pci)) {
10331033
irq = mp_irqs[idx].srcbusirq;
10341034
legacy = mp_is_legacy_irq(irq);
1035+
/*
1036+
* IRQ2 is unusable for historical reasons on systems which
1037+
* have a legacy PIC. See the comment vs. IRQ2 further down.
1038+
*
1039+
* If this gets removed at some point then the related code
1040+
* in lapic_assign_system_vectors() needs to be adjusted as
1041+
* well.
1042+
*/
1043+
if (legacy && irq == PIC_CASCADE_IR)
1044+
return -EINVAL;
10351045
}
10361046

10371047
mutex_lock(&ioapic_mutex);

arch/x86/kernel/signal.c

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -766,30 +766,8 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs)
766766

767767
static inline unsigned long get_nr_restart_syscall(const struct pt_regs *regs)
768768
{
769-
/*
770-
* This function is fundamentally broken as currently
771-
* implemented.
772-
*
773-
* The idea is that we want to trigger a call to the
774-
* restart_block() syscall and that we want in_ia32_syscall(),
775-
* in_x32_syscall(), etc. to match whatever they were in the
776-
* syscall being restarted. We assume that the syscall
777-
* instruction at (regs->ip - 2) matches whatever syscall
778-
* instruction we used to enter in the first place.
779-
*
780-
* The problem is that we can get here when ptrace pokes
781-
* syscall-like values into regs even if we're not in a syscall
782-
* at all.
783-
*
784-
* For now, we maintain historical behavior and guess based on
785-
* stored state. We could do better by saving the actual
786-
* syscall arch in restart_block or (with caveats on x32) by
787-
* checking if regs->ip points to 'int $0x80'. The current
788-
* behavior is incorrect if a tracer has a different bitness
789-
* than the tracee.
790-
*/
791769
#ifdef CONFIG_IA32_EMULATION
792-
if (current_thread_info()->status & (TS_COMPAT|TS_I386_REGS_POKED))
770+
if (current->restart_block.arch_data & TS_COMPAT)
793771
return __NR_ia32_restart_syscall;
794772
#endif
795773
#ifdef CONFIG_X86_X32_ABI

fs/select.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,10 +1055,9 @@ static long do_restart_poll(struct restart_block *restart_block)
10551055

10561056
ret = do_sys_poll(ufds, nfds, to);
10571057

1058-
if (ret == -ERESTARTNOHAND) {
1059-
restart_block->fn = do_restart_poll;
1060-
ret = -ERESTART_RESTARTBLOCK;
1061-
}
1058+
if (ret == -ERESTARTNOHAND)
1059+
ret = set_restart_fn(restart_block, do_restart_poll);
1060+
10621061
return ret;
10631062
}
10641063

@@ -1080,7 +1079,6 @@ SYSCALL_DEFINE3(poll, struct pollfd __user *, ufds, unsigned int, nfds,
10801079
struct restart_block *restart_block;
10811080

10821081
restart_block = &current->restart_block;
1083-
restart_block->fn = do_restart_poll;
10841082
restart_block->poll.ufds = ufds;
10851083
restart_block->poll.nfds = nfds;
10861084

@@ -1091,7 +1089,7 @@ SYSCALL_DEFINE3(poll, struct pollfd __user *, ufds, unsigned int, nfds,
10911089
} else
10921090
restart_block->poll.has_timeout = 0;
10931091

1094-
ret = -ERESTART_RESTARTBLOCK;
1092+
ret = set_restart_fn(restart_block, do_restart_poll);
10951093
}
10961094
return ret;
10971095
}

include/linux/restart_block.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ enum timespec_type {
2323
* System call restart block.
2424
*/
2525
struct restart_block {
26+
unsigned long arch_data;
2627
long (*fn)(struct restart_block *);
2728
union {
2829
/* For futex_wait and futex_wait_requeue_pi */

include/linux/thread_info.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <linux/types.h>
1212
#include <linux/bug.h>
1313
#include <linux/restart_block.h>
14+
#include <linux/errno.h>
1415

1516
#ifdef CONFIG_THREAD_INFO_IN_TASK
1617
/*
@@ -59,6 +60,18 @@ enum syscall_work_bit {
5960

6061
#ifdef __KERNEL__
6162

63+
#ifndef arch_set_restart_data
64+
#define arch_set_restart_data(restart) do { } while (0)
65+
#endif
66+
67+
static inline long set_restart_fn(struct restart_block *restart,
68+
long (*fn)(struct restart_block *))
69+
{
70+
restart->fn = fn;
71+
arch_set_restart_data(restart);
72+
return -ERESTART_RESTARTBLOCK;
73+
}
74+
6275
#ifndef THREAD_ALIGN
6376
#define THREAD_ALIGN THREAD_SIZE
6477
#endif

kernel/futex.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2728,14 +2728,13 @@ static int futex_wait(u32 __user *uaddr, unsigned int flags, u32 val,
27282728
goto out;
27292729

27302730
restart = &current->restart_block;
2731-
restart->fn = futex_wait_restart;
27322731
restart->futex.uaddr = uaddr;
27332732
restart->futex.val = val;
27342733
restart->futex.time = *abs_time;
27352734
restart->futex.bitset = bitset;
27362735
restart->futex.flags = flags | FLAGS_HAS_TIMEOUT;
27372736

2738-
ret = -ERESTART_RESTARTBLOCK;
2737+
ret = set_restart_fn(restart, futex_wait_restart);
27392738

27402739
out:
27412740
if (to) {

kernel/time/alarmtimer.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -854,9 +854,9 @@ static int alarm_timer_nsleep(const clockid_t which_clock, int flags,
854854
if (flags == TIMER_ABSTIME)
855855
return -ERESTARTNOHAND;
856856

857-
restart->fn = alarm_timer_nsleep_restart;
858857
restart->nanosleep.clockid = type;
859858
restart->nanosleep.expires = exp;
859+
set_restart_fn(restart, alarm_timer_nsleep_restart);
860860
return ret;
861861
}
862862

0 commit comments

Comments
 (0)