Skip to content

Commit

Permalink
Merge tag 'for-5.18/parisc-2' of git://git.kernel.org/pub/scm/linux/k…
Browse files Browse the repository at this point in the history
…ernel/git/deller/parisc-linux

Pull more parisc architecture updates from Helge Deller:

 - Revert a patch to the invalidate/flush vmap routines which broke
   kernel patching functions on older PA-RISC machines.

 - Fix the kernel patching code wrt locking and flushing. Works now on
   B160L machine as well.

 - Fix CPU IRQ affinity for LASI, WAX and Dino chips

 - Add CPU hotplug support

 - Detect the hppa-suse-linux-gcc compiler when cross-compiling

* tag 'for-5.18/parisc-2' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux:
  parisc: Fix patch code locking and flushing
  parisc: Find a new timesync master if current CPU is removed
  parisc: Move common_stext into .text section when CONFIG_HOTPLUG_CPU=y
  parisc: Rewrite arch_cpu_idle_dead() for CPU hotplugging
  parisc: Implement __cpu_die() and __cpu_disable() for CPU hotplugging
  parisc: Add PDC locking functions for rendezvous code
  parisc: Move disable_sr_hashing_asm() into .text section
  parisc: Move CPU startup-related functions into .text section
  parisc: Move store_cpu_topology() into text section
  parisc: Switch from GENERIC_CPU_DEVICES to GENERIC_ARCH_TOPOLOGY
  parisc: Ensure set_firmware_width() is called only once
  parisc: Add constants for control registers and clean up mfctl()
  parisc: Detect hppa-suse-linux-gcc compiler for cross-building
  parisc: Clean up cpu_check_affinity() and drop cpu_set_affinity_irq()
  parisc: Fix CPU affinity for Lasi, WAX and Dino chips
  Revert "parisc: Fix invalidate/flush vmap routines"
  • Loading branch information
Linus Torvalds committed Mar 30, 2022
2 parents 57c06b6 + a9fe7fa commit d5fd43b
Show file tree
Hide file tree
Showing 25 changed files with 312 additions and 206 deletions.
12 changes: 3 additions & 9 deletions arch/parisc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ config PARISC
select GENERIC_PCI_IOMAP
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select GENERIC_SMP_IDLE_THREAD
select GENERIC_CPU_DEVICES
select GENERIC_ARCH_TOPOLOGY if SMP
select GENERIC_LIB_DEVMEM_IS_ALLOWED
select SYSCTL_ARCH_UNALIGN_ALLOW
select SYSCTL_EXCEPTION_TRACE
Expand All @@ -56,6 +56,7 @@ config PARISC
select HAVE_ARCH_TRACEHOOK
select HAVE_REGS_AND_STACK_ACCESS_API
select GENERIC_SCHED_CLOCK
select GENERIC_IRQ_MIGRATION if SMP
select HAVE_UNSTABLE_SCHED_CLOCK if SMP
select LEGACY_TIMER_TICK
select CPU_NO_EFFICIENT_FFS
Expand Down Expand Up @@ -279,16 +280,9 @@ config SMP

If you don't know what to do here, say N.

config PARISC_CPU_TOPOLOGY
bool "Support cpu topology definition"
depends on SMP
default y
help
Support PARISC cpu topology definition.

config SCHED_MC
bool "Multi-core scheduler support"
depends on PARISC_CPU_TOPOLOGY && PA8X00
depends on GENERIC_ARCH_TOPOLOGY && PA8X00
help
Multi-core scheduler support improves the CPU scheduler's decision
making when dealing with multi-core CPU chips at a cost of slightly
Expand Down
4 changes: 2 additions & 2 deletions arch/parisc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export LD_BFD

# Set default 32 bits cross compilers for vdso
CC_ARCHES_32 = hppa hppa2.0 hppa1.1
CC_SUFFIXES = linux linux-gnu unknown-linux-gnu
CC_SUFFIXES = linux linux-gnu unknown-linux-gnu suse-linux
CROSS32_COMPILE := $(call cc-cross-prefix, \
$(foreach a,$(CC_ARCHES_32), \
$(foreach s,$(CC_SUFFIXES),$(a)-$(s)-)))
Expand All @@ -52,7 +52,7 @@ export CROSS32CC
# Set default cross compiler for kernel build
ifdef cross_compiling
ifeq ($(CROSS_COMPILE),)
CC_SUFFIXES = linux linux-gnu unknown-linux-gnu
CC_SUFFIXES = linux linux-gnu unknown-linux-gnu suse-linux
CROSS_COMPILE := $(call cc-cross-prefix, \
$(foreach a,$(CC_ARCHES), \
$(foreach s,$(CC_SUFFIXES),$(a)-$(s)-)))
Expand Down
3 changes: 3 additions & 0 deletions arch/parisc/include/asm/pdc.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ int pdc_sti_call(unsigned long func, unsigned long flags,
unsigned long glob_cfg);

int __pdc_cpu_rendezvous(void);
void pdc_cpu_rendezvous_lock(void);
void pdc_cpu_rendezvous_unlock(void);

static inline char * os_id_to_string(u16 os_id) {
switch(os_id) {
case OS_ID_NONE: return "No OS";
Expand Down
3 changes: 2 additions & 1 deletion arch/parisc/include/asm/pdcpat.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
#define PDC_PAT_CPU_RENDEZVOUS 6L /* Rendezvous CPU */
#define PDC_PAT_CPU_GET_CLOCK_INFO 7L /* Return CPU Clock info */
#define PDC_PAT_CPU_GET_RENDEZVOUS_STATE 8L /* Return Rendezvous State */
#define PDC_PAT_CPU_GET_PDC_ENTRYPOINT 11L /* Return PDC Entry point */
#define PDC_PAT_CPU_PLUNGE_FABRIC 128L /* Plunge Fabric */
#define PDC_PAT_CPU_UPDATE_CACHE_CLEANSING 129L /* Manipulate Cache
* Cleansing Mode */
Expand Down Expand Up @@ -356,7 +357,7 @@ struct pdc_pat_cell_mod_maddr_block { /* PDC_PAT_CELL_MODULE */

typedef struct pdc_pat_cell_mod_maddr_block pdc_pat_cell_mod_maddr_block_t;


extern int pdc_pat_get_PDC_entrypoint(unsigned long *pdc_entry);
extern int pdc_pat_chassis_send_log(unsigned long status, unsigned long data);
extern int pdc_pat_cell_get_number(struct pdc_pat_cell_num *cell_info);
extern int pdc_pat_cell_info(struct pdc_pat_cell_info_rtn_block *info,
Expand Down
1 change: 1 addition & 0 deletions arch/parisc/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ struct cpuinfo_parisc {

extern struct system_cpuinfo_parisc boot_cpu_data;
DECLARE_PER_CPU(struct cpuinfo_parisc, cpu_data);
extern int time_keeper_id; /* CPU used for timekeeping */

#define CPU_HVERSION ((boot_cpu_data.hversion >> 4) & 0x0FFF)

Expand Down
9 changes: 2 additions & 7 deletions arch/parisc/include/asm/smp.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,7 @@ static inline void smp_send_all_nop(void) { return; }

#define NO_PROC_ID 0xFF /* No processor magic marker */
#define ANY_PROC_ID 0xFF /* Any processor magic marker */
static inline int __cpu_disable (void) {
return 0;
}
static inline void __cpu_die (unsigned int cpu) {
while(1)
;
}
int __cpu_disable(void);
void __cpu_die(unsigned int cpu);

#endif /* __ASM_SMP_H */
17 changes: 8 additions & 9 deletions arch/parisc/include/asm/special_insns.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,15 @@
pa; \
})

#define CR_EIEM 15 /* External Interrupt Enable Mask */
#define CR_CR16 16 /* CR16 Interval Timer */
#define CR_EIRR 23 /* External Interrupt Request Register */

#define mfctl(reg) ({ \
unsigned long cr; \
__asm__ __volatile__( \
"mfctl " #reg ",%0" : \
"=r" (cr) \
"mfctl %1,%0" : \
"=r" (cr) : "i" (reg) \
); \
cr; \
})
Expand All @@ -44,13 +48,8 @@
: /* no outputs */ \
: "r" (gr), "i" (cr) : "memory")

/* these are here to de-mystefy the calling code, and to provide hooks */
/* which I needed for debugging EIEM problems -PB */
#define get_eiem() mfctl(15)
static inline void set_eiem(unsigned long val)
{
mtctl(val, 15);
}
#define get_eiem() mfctl(CR_EIEM)
#define set_eiem(val) mtctl(val, CR_EIEM)

#define mfsp(reg) ({ \
unsigned long cr; \
Expand Down
23 changes: 3 additions & 20 deletions arch/parisc/include/asm/topology.h
Original file line number Diff line number Diff line change
@@ -1,33 +1,16 @@
#ifndef _ASM_PARISC_TOPOLOGY_H
#define _ASM_PARISC_TOPOLOGY_H

#ifdef CONFIG_PARISC_CPU_TOPOLOGY
#ifdef CONFIG_GENERIC_ARCH_TOPOLOGY

#include <linux/cpumask.h>

struct cputopo_parisc {
int thread_id;
int core_id;
int socket_id;
cpumask_t thread_sibling;
cpumask_t core_sibling;
};

extern struct cputopo_parisc cpu_topology[NR_CPUS];

#define topology_physical_package_id(cpu) (cpu_topology[cpu].socket_id)
#define topology_core_id(cpu) (cpu_topology[cpu].core_id)
#define topology_core_cpumask(cpu) (&cpu_topology[cpu].core_sibling)
#define topology_sibling_cpumask(cpu) (&cpu_topology[cpu].thread_sibling)

void init_cpu_topology(void);
void store_cpu_topology(unsigned int cpuid);
const struct cpumask *cpu_coregroup_mask(int cpu);
#include <linux/arch_topology.h>

#else

static inline void init_cpu_topology(void) { }
static inline void store_cpu_topology(unsigned int cpuid) { }
static inline void reset_cpu_topology(void) { }

#endif

Expand Down
2 changes: 1 addition & 1 deletion arch/parisc/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ obj-$(CONFIG_AUDIT) += audit.o
obj64-$(CONFIG_AUDIT) += compat_audit.o
# only supported for PCX-W/U in 64-bit mode at the moment
obj-$(CONFIG_64BIT) += perf.o perf_asm.o $(obj64-y)
obj-$(CONFIG_PARISC_CPU_TOPOLOGY) += topology.o
obj-$(CONFIG_GENERIC_ARCH_TOPOLOGY) += topology.o
obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o
obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
obj-$(CONFIG_JUMP_LABEL) += jump_label.o
Expand Down
26 changes: 6 additions & 20 deletions arch/parisc/kernel/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ parisc_cache_init(void)
}
}

void __init disable_sr_hashing(void)
void disable_sr_hashing(void)
{
int srhash_type, retval;
unsigned long space_bits;
Expand Down Expand Up @@ -611,8 +611,8 @@ void
flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long pfn)
{
if (pfn_valid(pfn)) {
flush_tlb_page(vma, vmaddr);
if (likely(vma->vm_mm->context.space_id)) {
flush_tlb_page(vma, vmaddr);
__flush_cache_page(vma, vmaddr, PFN_PHYS(pfn));
} else {
__purge_cache_page(vma, vmaddr, PFN_PHYS(pfn));
Expand All @@ -624,7 +624,6 @@ void flush_kernel_vmap_range(void *vaddr, int size)
{
unsigned long start = (unsigned long)vaddr;
unsigned long end = start + size;
unsigned long flags, physaddr;

if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
(unsigned long)size >= parisc_cache_flush_threshold) {
Expand All @@ -633,22 +632,15 @@ void flush_kernel_vmap_range(void *vaddr, int size)
return;
}

while (start < end) {
physaddr = lpa(start);
purge_tlb_start(flags);
pdtlb(SR_KERNEL, start);
purge_tlb_end(flags);
flush_dcache_page_asm(physaddr, start);
start += PAGE_SIZE;
}
flush_kernel_dcache_range_asm(start, end);
flush_tlb_kernel_range(start, end);
}
EXPORT_SYMBOL(flush_kernel_vmap_range);

void invalidate_kernel_vmap_range(void *vaddr, int size)
{
unsigned long start = (unsigned long)vaddr;
unsigned long end = start + size;
unsigned long flags, physaddr;

if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
(unsigned long)size >= parisc_cache_flush_threshold) {
Expand All @@ -657,13 +649,7 @@ void invalidate_kernel_vmap_range(void *vaddr, int size)
return;
}

while (start < end) {
physaddr = lpa(start);
purge_tlb_start(flags);
pdtlb(SR_KERNEL, start);
purge_tlb_end(flags);
purge_dcache_page_asm(physaddr, start);
start += PAGE_SIZE;
}
purge_kernel_dcache_range_asm(start, end);
flush_tlb_kernel_range(start, end);
}
EXPORT_SYMBOL(invalidate_kernel_vmap_range);
44 changes: 43 additions & 1 deletion arch/parisc/kernel/firmware.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ extern unsigned long pdc_result2[NUM_PDC_RESULT];

/* Firmware needs to be initially set to narrow to determine the
* actual firmware width. */
int parisc_narrow_firmware __ro_after_init = 1;
int parisc_narrow_firmware __ro_after_init = 2;
#endif

/* On most currently-supported platforms, IODC I/O calls are 32-bit calls
Expand Down Expand Up @@ -174,6 +174,11 @@ void set_firmware_width_unlocked(void)
void set_firmware_width(void)
{
unsigned long flags;

/* already initialized? */
if (parisc_narrow_firmware != 2)
return;

spin_lock_irqsave(&pdc_lock, flags);
set_firmware_width_unlocked();
spin_unlock_irqrestore(&pdc_lock, flags);
Expand Down Expand Up @@ -324,7 +329,44 @@ int __pdc_cpu_rendezvous(void)
return mem_pdc_call(PDC_PROC, 1, 0);
}

/**
* pdc_cpu_rendezvous_lock - Lock PDC while transitioning to rendezvous state
*/
void pdc_cpu_rendezvous_lock(void)
{
spin_lock(&pdc_lock);
}

/**
* pdc_cpu_rendezvous_unlock - Unlock PDC after reaching rendezvous state
*/
void pdc_cpu_rendezvous_unlock(void)
{
spin_unlock(&pdc_lock);
}

/**
* pdc_pat_get_PDC_entrypoint - Get PDC entry point for current CPU
* @retval: -1 on error, 0 on success
*/
int pdc_pat_get_PDC_entrypoint(unsigned long *pdc_entry)
{
int retval = 0;
unsigned long flags;

if (!IS_ENABLED(CONFIG_SMP) || !is_pdc_pat()) {
*pdc_entry = MEM_PDC;
return 0;
}

spin_lock_irqsave(&pdc_lock, flags);
retval = mem_pdc_call(PDC_PAT_CPU, PDC_PAT_CPU_GET_PDC_ENTRYPOINT,
__pa(pdc_result));
*pdc_entry = pdc_result[0];
spin_unlock_irqrestore(&pdc_lock, flags);

return retval;
}
/**
* pdc_chassis_warn - Fetches chassis warnings
* @retval: -1 on error, 0 on success
Expand Down
11 changes: 9 additions & 2 deletions arch/parisc/kernel/head.S
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,15 @@ $pgt_fill_loop:
/* FALLTHROUGH */
.procend

#ifdef CONFIG_HOTPLUG_CPU
/* common_stext is far away in another section... jump there */
load32 PA(common_stext), %rp
bv,n (%rp)

/* common_stext and smp_slave_stext needs to be in text section */
.text
#endif

/*
** Code Common to both Monarch and Slave processors.
** Entry:
Expand Down Expand Up @@ -371,8 +380,6 @@ smp_slave_stext:
.procend
#endif /* CONFIG_SMP */

ENDPROC(parisc_kernel_start)

#ifndef CONFIG_64BIT
.section .data..ro_after_init

Expand Down
25 changes: 3 additions & 22 deletions arch/parisc/kernel/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,28 +105,12 @@ int cpu_check_affinity(struct irq_data *d, const struct cpumask *dest)
if (irqd_is_per_cpu(d))
return -EINVAL;

/* whatever mask they set, we just allow one CPU */
cpu_dest = cpumask_next_and(d->irq & (num_online_cpus()-1),
dest, cpu_online_mask);
cpu_dest = cpumask_first_and(dest, cpu_online_mask);
if (cpu_dest >= nr_cpu_ids)
cpu_dest = cpumask_first_and(dest, cpu_online_mask);
cpu_dest = cpumask_first(cpu_online_mask);

return cpu_dest;
}

static int cpu_set_affinity_irq(struct irq_data *d, const struct cpumask *dest,
bool force)
{
int cpu_dest;

cpu_dest = cpu_check_affinity(d, dest);
if (cpu_dest < 0)
return -1;

cpumask_copy(irq_data_get_affinity_mask(d), dest);

return 0;
}
#endif

static struct irq_chip cpu_interrupt_type = {
Expand All @@ -135,9 +119,6 @@ static struct irq_chip cpu_interrupt_type = {
.irq_unmask = cpu_unmask_irq,
.irq_ack = cpu_ack_irq,
.irq_eoi = cpu_eoi_irq,
#ifdef CONFIG_SMP
.irq_set_affinity = cpu_set_affinity_irq,
#endif
/* XXX: Needs to be written. We managed without it so far, but
* we really ought to write it.
*/
Expand Down Expand Up @@ -582,7 +563,7 @@ static void claim_cpu_irqs(void)
#endif
}

void __init init_IRQ(void)
void init_IRQ(void)
{
local_irq_disable(); /* PARANOID - should already be disabled */
mtctl(~0UL, 23); /* EIRR : clear all pending external intr */
Expand Down
Loading

0 comments on commit d5fd43b

Please sign in to comment.