Commit c1e2e035 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-5.16/parisc-2' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux

Pull more parisc architecture fixes and updates from Helge Deller:
 "One build error fix and two optimizations:

   - Fix build error by moving the CPU field back into thread_info
     struct (Ard Biesheuvel)

   - Do not enable IRQs unconditionally at start of interrupt handler if
     they were disabled before (Sven Schnelle)

   - Keep interrupts enabled during cmpxchg and futex operations (Dave
     Anglin)"

* tag 'for-5.16/parisc-2' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux:
  parisc: move CPU field back into thread_info
  parisc: Don't disable interrupts in cmpxchg and futex operations
  parisc: don't enable irqs unconditionally in handle_interruption()
parents 7e113d01 2a2e8202
...@@ -11,35 +11,34 @@ ...@@ -11,35 +11,34 @@
sixteen four-word locks. */ sixteen four-word locks. */
static inline void static inline void
_futex_spin_lock_irqsave(u32 __user *uaddr, unsigned long int *flags) _futex_spin_lock(u32 __user *uaddr)
{ {
extern u32 lws_lock_start[]; extern u32 lws_lock_start[];
long index = ((long)uaddr & 0x3f8) >> 1; long index = ((long)uaddr & 0x3f8) >> 1;
arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index]; arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index];
local_irq_save(*flags); preempt_disable();
arch_spin_lock(s); arch_spin_lock(s);
} }
static inline void static inline void
_futex_spin_unlock_irqrestore(u32 __user *uaddr, unsigned long int *flags) _futex_spin_unlock(u32 __user *uaddr)
{ {
extern u32 lws_lock_start[]; extern u32 lws_lock_start[];
long index = ((long)uaddr & 0x3f8) >> 1; long index = ((long)uaddr & 0x3f8) >> 1;
arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index]; arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index];
arch_spin_unlock(s); arch_spin_unlock(s);
local_irq_restore(*flags); preempt_enable();
} }
static inline int static inline int
arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
{ {
unsigned long int flags;
int oldval, ret; int oldval, ret;
u32 tmp; u32 tmp;
_futex_spin_lock_irqsave(uaddr, &flags);
ret = -EFAULT; ret = -EFAULT;
_futex_spin_lock(uaddr);
if (unlikely(get_user(oldval, uaddr) != 0)) if (unlikely(get_user(oldval, uaddr) != 0))
goto out_pagefault_enable; goto out_pagefault_enable;
...@@ -70,7 +69,7 @@ arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) ...@@ -70,7 +69,7 @@ arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
ret = -EFAULT; ret = -EFAULT;
out_pagefault_enable: out_pagefault_enable:
_futex_spin_unlock_irqrestore(uaddr, &flags); _futex_spin_unlock(uaddr);
if (!ret) if (!ret)
*oval = oldval; *oval = oldval;
...@@ -83,7 +82,6 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, ...@@ -83,7 +82,6 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
u32 oldval, u32 newval) u32 oldval, u32 newval)
{ {
u32 val; u32 val;
unsigned long flags;
/* futex.c wants to do a cmpxchg_inatomic on kernel NULL, which is /* futex.c wants to do a cmpxchg_inatomic on kernel NULL, which is
* our gateway page, and causes no end of trouble... * our gateway page, and causes no end of trouble...
...@@ -100,19 +98,19 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, ...@@ -100,19 +98,19 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
* address. This should scale to a couple of CPUs. * address. This should scale to a couple of CPUs.
*/ */
_futex_spin_lock_irqsave(uaddr, &flags); _futex_spin_lock(uaddr);
if (unlikely(get_user(val, uaddr) != 0)) { if (unlikely(get_user(val, uaddr) != 0)) {
_futex_spin_unlock_irqrestore(uaddr, &flags); _futex_spin_unlock(uaddr);
return -EFAULT; return -EFAULT;
} }
if (val == oldval && unlikely(put_user(newval, uaddr) != 0)) { if (val == oldval && unlikely(put_user(newval, uaddr) != 0)) {
_futex_spin_unlock_irqrestore(uaddr, &flags); _futex_spin_unlock(uaddr);
return -EFAULT; return -EFAULT;
} }
*uval = val; *uval = val;
_futex_spin_unlock_irqrestore(uaddr, &flags); _futex_spin_unlock(uaddr);
return 0; return 0;
} }
......
...@@ -32,25 +32,10 @@ extern void smp_send_all_nop(void); ...@@ -32,25 +32,10 @@ extern void smp_send_all_nop(void);
extern void arch_send_call_function_single_ipi(int cpu); extern void arch_send_call_function_single_ipi(int cpu);
extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
#define raw_smp_processor_id() (current_thread_info()->cpu)
#endif /* !ASSEMBLY */ #endif /* !ASSEMBLY */
/*
* This is particularly ugly: it appears we can't actually get the definition
* of task_struct here, but we need access to the CPU this task is running on.
* Instead of using task_struct we're using TASK_CPU which is extracted from
* asm-offsets.h by kbuild to get the current processor ID.
*
* This also needs to be safeguarded when building asm-offsets.s because at
* that time TASK_CPU is not defined yet. It could have been guarded by
* TASK_CPU itself, but we want the build to fail if TASK_CPU is missing
* when building something else than asm-offsets.s
*/
#ifdef GENERATING_ASM_OFFSETS
#define raw_smp_processor_id() (0)
#else
#include <asm/asm-offsets.h>
#define raw_smp_processor_id() (*(unsigned int *)((void *)current + TASK_CPU))
#endif
#else /* CONFIG_SMP */ #else /* CONFIG_SMP */
static inline void smp_send_all_nop(void) { return; } static inline void smp_send_all_nop(void) { return; }
......
...@@ -9,6 +9,9 @@ ...@@ -9,6 +9,9 @@
struct thread_info { struct thread_info {
unsigned long flags; /* thread_info flags (see TIF_*) */ unsigned long flags; /* thread_info flags (see TIF_*) */
int preempt_count; /* 0=premptable, <0=BUG; will also serve as bh-counter */ int preempt_count; /* 0=premptable, <0=BUG; will also serve as bh-counter */
#ifdef CONFIG_SMP
unsigned int cpu;
#endif
}; };
#define INIT_THREAD_INFO(tsk) \ #define INIT_THREAD_INFO(tsk) \
......
...@@ -14,8 +14,6 @@ ...@@ -14,8 +14,6 @@
* Copyright (C) 2003 James Bottomley <jejb at parisc-linux.org> * Copyright (C) 2003 James Bottomley <jejb at parisc-linux.org>
*/ */
#define GENERATING_ASM_OFFSETS /* asm/smp.h */
#include <linux/types.h> #include <linux/types.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/thread_info.h> #include <linux/thread_info.h>
...@@ -39,9 +37,6 @@ int main(void) ...@@ -39,9 +37,6 @@ int main(void)
{ {
DEFINE(TASK_TI_FLAGS, offsetof(struct task_struct, thread_info.flags)); DEFINE(TASK_TI_FLAGS, offsetof(struct task_struct, thread_info.flags));
DEFINE(TASK_STACK, offsetof(struct task_struct, stack)); DEFINE(TASK_STACK, offsetof(struct task_struct, stack));
#ifdef CONFIG_SMP
DEFINE(TASK_CPU, offsetof(struct task_struct, cpu));
#endif
BLANK(); BLANK();
DEFINE(TASK_REGS, offsetof(struct task_struct, thread.regs)); DEFINE(TASK_REGS, offsetof(struct task_struct, thread.regs));
DEFINE(TASK_PT_PSW, offsetof(struct task_struct, thread.regs.gr[ 0])); DEFINE(TASK_PT_PSW, offsetof(struct task_struct, thread.regs.gr[ 0]));
......
...@@ -339,8 +339,6 @@ int smp_boot_one_cpu(int cpuid, struct task_struct *idle) ...@@ -339,8 +339,6 @@ int smp_boot_one_cpu(int cpuid, struct task_struct *idle)
const struct cpuinfo_parisc *p = &per_cpu(cpu_data, cpuid); const struct cpuinfo_parisc *p = &per_cpu(cpu_data, cpuid);
long timeout; long timeout;
idle->cpu = cpuid;
/* Let _start know what logical CPU we're booting /* Let _start know what logical CPU we're booting
** (offset into init_tasks[],cpu_data[]) ** (offset into init_tasks[],cpu_data[])
*/ */
......
...@@ -597,13 +597,11 @@ cas_nocontend: ...@@ -597,13 +597,11 @@ cas_nocontend:
# endif # endif
/* ENABLE_LWS_DEBUG */ /* ENABLE_LWS_DEBUG */
rsm PSW_SM_I, %r0 /* Disable interrupts */
/* COW breaks can cause contention on UP systems */ /* COW breaks can cause contention on UP systems */
LDCW 0(%sr2,%r20), %r28 /* Try to acquire the lock */ LDCW 0(%sr2,%r20), %r28 /* Try to acquire the lock */
cmpb,<>,n %r0, %r28, cas_action /* Did we get it? */ cmpb,<>,n %r0, %r28, cas_action /* Did we get it? */
cas_wouldblock: cas_wouldblock:
ldo 2(%r0), %r28 /* 2nd case */ ldo 2(%r0), %r28 /* 2nd case */
ssm PSW_SM_I, %r0
b lws_exit /* Contended... */ b lws_exit /* Contended... */
ldo -EAGAIN(%r0), %r21 /* Spin in userspace */ ldo -EAGAIN(%r0), %r21 /* Spin in userspace */
...@@ -639,8 +637,6 @@ cas_action: ...@@ -639,8 +637,6 @@ cas_action:
/* Clear thread register indicator */ /* Clear thread register indicator */
stw %r0, 4(%sr2,%r20) stw %r0, 4(%sr2,%r20)
#endif #endif
/* Enable interrupts */
ssm PSW_SM_I, %r0
/* Return to userspace, set no error */ /* Return to userspace, set no error */
b lws_exit b lws_exit
copy %r0, %r21 copy %r0, %r21
...@@ -652,7 +648,6 @@ cas_action: ...@@ -652,7 +648,6 @@ cas_action:
#if ENABLE_LWS_DEBUG #if ENABLE_LWS_DEBUG
stw %r0, 4(%sr2,%r20) stw %r0, 4(%sr2,%r20)
#endif #endif
ssm PSW_SM_I, %r0
b lws_exit b lws_exit
ldo -EFAULT(%r0),%r21 /* set errno */ ldo -EFAULT(%r0),%r21 /* set errno */
nop nop
...@@ -764,13 +759,11 @@ cas2_lock_start: ...@@ -764,13 +759,11 @@ cas2_lock_start:
shlw %r20, 4, %r20 shlw %r20, 4, %r20
add %r20, %r28, %r20 add %r20, %r28, %r20
rsm PSW_SM_I, %r0 /* Disable interrupts */
/* COW breaks can cause contention on UP systems */ /* COW breaks can cause contention on UP systems */
LDCW 0(%sr2,%r20), %r28 /* Try to acquire the lock */ LDCW 0(%sr2,%r20), %r28 /* Try to acquire the lock */
cmpb,<>,n %r0, %r28, cas2_action /* Did we get it? */ cmpb,<>,n %r0, %r28, cas2_action /* Did we get it? */
cas2_wouldblock: cas2_wouldblock:
ldo 2(%r0), %r28 /* 2nd case */ ldo 2(%r0), %r28 /* 2nd case */
ssm PSW_SM_I, %r0
b lws_exit /* Contended... */ b lws_exit /* Contended... */
ldo -EAGAIN(%r0), %r21 /* Spin in userspace */ ldo -EAGAIN(%r0), %r21 /* Spin in userspace */
...@@ -850,8 +843,6 @@ cas2_action: ...@@ -850,8 +843,6 @@ cas2_action:
cas2_end: cas2_end:
/* Free lock */ /* Free lock */
stw,ma %r20, 0(%sr2,%r20) stw,ma %r20, 0(%sr2,%r20)
/* Enable interrupts */
ssm PSW_SM_I, %r0
/* Return to userspace, set no error */ /* Return to userspace, set no error */
b lws_exit b lws_exit
copy %r0, %r21 copy %r0, %r21
...@@ -860,7 +851,6 @@ cas2_end: ...@@ -860,7 +851,6 @@ cas2_end:
/* Error occurred on load or store */ /* Error occurred on load or store */
/* Free lock */ /* Free lock */
stw,ma %r20, 0(%sr2,%r20) stw,ma %r20, 0(%sr2,%r20)
ssm PSW_SM_I, %r0
ldo 1(%r0),%r28 ldo 1(%r0),%r28
b lws_exit b lws_exit
ldo -EFAULT(%r0),%r21 /* set errno */ ldo -EFAULT(%r0),%r21 /* set errno */
......
...@@ -481,7 +481,7 @@ void notrace handle_interruption(int code, struct pt_regs *regs) ...@@ -481,7 +481,7 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
if (code == 1) if (code == 1)
pdc_console_restart(); /* switch back to pdc if HPMC */ pdc_console_restart(); /* switch back to pdc if HPMC */
else else if (!irqs_disabled_flags(regs->gr[0]))
local_irq_enable(); local_irq_enable();
/* Security check: /* Security check:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment