parisc architecture fixes for kernel v6.6-rc5:

* fix random faults in mmap'd memory on pre PA8800 processors
 * fix boot crash with nr_cpus=1 on kernel command line
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQS86RI+GtKfB8BJu973ErUQojoPXwUCZSGn1wAKCRD3ErUQojoP
 X2FbAP0clw0VUZZQuu9Z1jLXj1lVjb+2HOzK3t+PjQgIRMIlAgD8DCRGj5cTYcNi
 t+6s1+S/iamXQBPKv+SdJv99PVnN5QU=
 =sPnd
 -----END PGP SIGNATURE-----

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

Pull parisc fixes from Helge Deller:

 - fix random faults in mmap'd memory on pre PA8800 processors

 - fix boot crash with nr_cpus=1 on kernel command line

* tag 'parisc-for-6.6-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux:
  parisc: Restore __ldcw_align for PA-RISC 2.0 processors
  parisc: Fix crash with nr_cpus=1 option
This commit is contained in:
Linus Torvalds 2023-10-07 13:05:43 -07:00
commit b9ddbb0cde
3 changed files with 23 additions and 23 deletions

View File

@ -2,39 +2,42 @@
#ifndef __PARISC_LDCW_H #ifndef __PARISC_LDCW_H
#define __PARISC_LDCW_H #define __PARISC_LDCW_H
#ifndef CONFIG_PA20
/* Because kmalloc only guarantees 8-byte alignment for kmalloc'd data, /* Because kmalloc only guarantees 8-byte alignment for kmalloc'd data,
and GCC only guarantees 8-byte alignment for stack locals, we can't and GCC only guarantees 8-byte alignment for stack locals, we can't
be assured of 16-byte alignment for atomic lock data even if we be assured of 16-byte alignment for atomic lock data even if we
specify "__attribute ((aligned(16)))" in the type declaration. So, specify "__attribute ((aligned(16)))" in the type declaration. So,
we use a struct containing an array of four ints for the atomic lock we use a struct containing an array of four ints for the atomic lock
type and dynamically select the 16-byte aligned int from the array type and dynamically select the 16-byte aligned int from the array
for the semaphore. */ for the semaphore. */
/* From: "Jim Hull" <jim.hull of hp.com>
I've attached a summary of the change, but basically, for PA 2.0, as
long as the ",CO" (coherent operation) completer is implemented, then the
16-byte alignment requirement for ldcw and ldcd is relaxed, and instead
they only require "natural" alignment (4-byte for ldcw, 8-byte for
ldcd).
Although the cache control hint is accepted by all PA 2.0 processors,
it is only implemented on PA8800/PA8900 CPUs. Prior PA8X00 CPUs still
require 16-byte alignment. If the address is unaligned, the operation
of the instruction is undefined. The ldcw instruction does not generate
unaligned data reference traps so misaligned accesses are not detected.
This hid the problem for years. So, restore the 16-byte alignment dropped
by Kyle McMartin in "Remove __ldcw_align for PA-RISC 2.0 processors". */
#define __PA_LDCW_ALIGNMENT 16 #define __PA_LDCW_ALIGNMENT 16
#define __PA_LDCW_ALIGN_ORDER 4
#define __ldcw_align(a) ({ \ #define __ldcw_align(a) ({ \
unsigned long __ret = (unsigned long) &(a)->lock[0]; \ unsigned long __ret = (unsigned long) &(a)->lock[0]; \
__ret = (__ret + __PA_LDCW_ALIGNMENT - 1) \ __ret = (__ret + __PA_LDCW_ALIGNMENT - 1) \
& ~(__PA_LDCW_ALIGNMENT - 1); \ & ~(__PA_LDCW_ALIGNMENT - 1); \
(volatile unsigned int *) __ret; \ (volatile unsigned int *) __ret; \
}) })
#define __LDCW "ldcw"
#else /*CONFIG_PA20*/ #ifdef CONFIG_PA20
/* From: "Jim Hull" <jim.hull of hp.com>
I've attached a summary of the change, but basically, for PA 2.0, as
long as the ",CO" (coherent operation) completer is specified, then the
16-byte alignment requirement for ldcw and ldcd is relaxed, and instead
they only require "natural" alignment (4-byte for ldcw, 8-byte for
ldcd). */
#define __PA_LDCW_ALIGNMENT 4
#define __PA_LDCW_ALIGN_ORDER 2
#define __ldcw_align(a) (&(a)->slock)
#define __LDCW "ldcw,co" #define __LDCW "ldcw,co"
#else
#endif /*!CONFIG_PA20*/ #define __LDCW "ldcw"
#endif
/* LDCW, the only atomic read-write operation PA-RISC has. *sigh*. /* LDCW, the only atomic read-write operation PA-RISC has. *sigh*.
We don't explicitly expose that "*a" may be written as reload We don't explicitly expose that "*a" may be written as reload

View File

@ -9,15 +9,10 @@
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
typedef struct { typedef struct {
#ifdef CONFIG_PA20
volatile unsigned int slock;
# define __ARCH_SPIN_LOCK_UNLOCKED { __ARCH_SPIN_LOCK_UNLOCKED_VAL }
#else
volatile unsigned int lock[4]; volatile unsigned int lock[4];
# define __ARCH_SPIN_LOCK_UNLOCKED \ # define __ARCH_SPIN_LOCK_UNLOCKED \
{ { __ARCH_SPIN_LOCK_UNLOCKED_VAL, __ARCH_SPIN_LOCK_UNLOCKED_VAL, \ { { __ARCH_SPIN_LOCK_UNLOCKED_VAL, __ARCH_SPIN_LOCK_UNLOCKED_VAL, \
__ARCH_SPIN_LOCK_UNLOCKED_VAL, __ARCH_SPIN_LOCK_UNLOCKED_VAL } } __ARCH_SPIN_LOCK_UNLOCKED_VAL, __ARCH_SPIN_LOCK_UNLOCKED_VAL } }
#endif
} arch_spinlock_t; } arch_spinlock_t;

View File

@ -440,7 +440,9 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle)
if (cpu_online(cpu)) if (cpu_online(cpu))
return 0; return 0;
if (num_online_cpus() < setup_max_cpus && smp_boot_one_cpu(cpu, tidle)) if (num_online_cpus() < nr_cpu_ids &&
num_online_cpus() < setup_max_cpus &&
smp_boot_one_cpu(cpu, tidle))
return -EIO; return -EIO;
return cpu_online(cpu) ? 0 : -EIO; return cpu_online(cpu) ? 0 : -EIO;