summaryrefslogtreecommitdiff
path: root/arch/parisc/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/parisc/kernel')
-rw-r--r--arch/parisc/kernel/Makefile6
-rw-r--r--arch/parisc/kernel/cache.c14
-rw-r--r--arch/parisc/kernel/drivers.c35
-rw-r--r--arch/parisc/kernel/firmware.c27
-rw-r--r--arch/parisc/kernel/head.S8
-rw-r--r--arch/parisc/kernel/inventory.c17
-rw-r--r--arch/parisc/kernel/pci.c17
-rw-r--r--arch/parisc/kernel/process.c3
-rw-r--r--arch/parisc/kernel/processor.c28
-rw-r--r--arch/parisc/kernel/ptrace.c12
-rw-r--r--arch/parisc/kernel/setup.c32
-rw-r--r--arch/parisc/kernel/signal.c18
-rw-r--r--arch/parisc/kernel/smp.c2
-rw-r--r--arch/parisc/kernel/sys_parisc.c8
-rw-r--r--arch/parisc/kernel/syscall.S11
-rw-r--r--arch/parisc/kernel/syscalls/syscall.tbl4
-rw-r--r--arch/parisc/kernel/time.c25
-rw-r--r--arch/parisc/kernel/unwind.c37
-rw-r--r--arch/parisc/kernel/vdso.c2
-rw-r--r--arch/parisc/kernel/vmlinux.lds.S1
20 files changed, 201 insertions, 106 deletions
diff --git a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile
index 9157bc8bdf41..49f937c2abbe 100644
--- a/arch/parisc/kernel/Makefile
+++ b/arch/parisc/kernel/Makefile
@@ -46,5 +46,9 @@ obj-$(CONFIG_KEXEC_FILE) += kexec_file.o
# vdso
obj-y += vdso.o
-obj-$(CONFIG_64BIT) += vdso64/
+ifdef CONFIG_64BIT
+obj-y += vdso64/
+obj-$(CONFIG_COMPAT) += vdso32/
+else
obj-y += vdso32/
+endif
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
index 4c5240d3a3c7..98200b6b5b82 100644
--- a/arch/parisc/kernel/cache.c
+++ b/arch/parisc/kernel/cache.c
@@ -503,7 +503,7 @@ void flush_dcache_folio(struct folio *folio)
* on machines that support equivalent aliasing
*/
flush_dcache_mmap_lock_irqsave(mapping, flags);
- vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff, pgoff + nr - 1) {
+ mapping_rmap_tree_foreach(vma, mapping, pgoff, pgoff + nr - 1) {
unsigned long offset = pgoff - vma->vm_pgoff;
unsigned long pfn = folio_pfn(folio);
@@ -781,18 +781,18 @@ void flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned lon
__flush_cache_page(vma, vmaddr, PFN_PHYS(page_to_pfn(page)));
}
-int ptep_clear_flush_young(struct vm_area_struct *vma, unsigned long addr,
- pte_t *ptep)
+bool ptep_clear_flush_young(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep)
{
pte_t pte = ptep_get(ptep);
if (!pte_young(pte))
- return 0;
+ return false;
set_pte(ptep, pte_mkold(pte));
#if CONFIG_FLUSH_PAGE_ACCESSED
__flush_cache_page(vma, addr, PFN_PHYS(pte_pfn(pte)));
#endif
- return 1;
+ return true;
}
/*
@@ -953,7 +953,7 @@ SYSCALL_DEFINE3(cacheflush, unsigned long, addr, unsigned long, bytes,
#else
"1: cmpb,<<,n %0,%2,1b\n"
#endif
- " fic,m %3(%4,%0)\n"
+ " fdc,m %3(%4,%0)\n"
"2: sync\n"
ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 2b, "%1")
: "+r" (start), "+r" (error)
@@ -968,7 +968,7 @@ SYSCALL_DEFINE3(cacheflush, unsigned long, addr, unsigned long, bytes,
#else
"1: cmpb,<<,n %0,%2,1b\n"
#endif
- " fdc,m %3(%4,%0)\n"
+ " fic,m %3(%4,%0)\n"
"2: sync\n"
ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 2b, "%1")
: "+r" (start), "+r" (error)
diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c
index 8d23fe42b0ce..b52ad704ec8a 100644
--- a/arch/parisc/kernel/drivers.c
+++ b/arch/parisc/kernel/drivers.c
@@ -41,9 +41,7 @@
const struct dma_map_ops *hppa_dma_ops __ro_after_init;
EXPORT_SYMBOL(hppa_dma_ops);
-static struct device root = {
- .init_name = "parisc",
-};
+static struct device *root;
static inline int check_dev(struct device *dev)
{
@@ -89,7 +87,7 @@ static int for_each_padev(int (*fn)(struct device *, void *), void * data)
.obj = data,
.fn = fn,
};
- return device_for_each_child(&root, &recurse_data, descend_children);
+ return device_for_each_child(root, &recurse_data, descend_children);
}
/**
@@ -290,7 +288,7 @@ const struct parisc_device *
find_pa_parent_type(const struct parisc_device *padev, int type)
{
const struct device *dev = &padev->dev;
- while (dev != &root) {
+ while (dev != root) {
struct parisc_device *candidate = to_parisc_device(dev);
if (candidate->id.hw_type == type)
return candidate;
@@ -319,7 +317,7 @@ static void get_node_path(struct device *dev, struct hardware_path *path)
dev = dev->parent;
}
- while (dev != &root) {
+ while (dev != root) {
if (dev_is_pci(dev)) {
unsigned int devfn = to_pci_dev(dev)->devfn;
path->bc[i--] = PCI_SLOT(devfn) | (PCI_FUNC(devfn)<< 5);
@@ -418,7 +416,7 @@ static void setup_bus_id(struct parisc_device *padev)
static struct parisc_device * __init create_tree_node(char id,
struct device *parent)
{
- struct parisc_device *dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ struct parisc_device *dev = kzalloc_obj(*dev);
if (!dev)
return NULL;
@@ -435,7 +433,7 @@ static struct parisc_device * __init create_tree_node(char id,
dev->dev.dma_mask = &dev->dma_mask;
dev->dev.coherent_dma_mask = dev->dma_mask;
if (device_register(&dev->dev)) {
- kfree(dev);
+ put_device(&dev->dev);
return NULL;
}
@@ -482,7 +480,7 @@ static struct parisc_device * __init alloc_tree_node(
static struct parisc_device *create_parisc_device(struct hardware_path *modpath)
{
int i;
- struct device *parent = &root;
+ struct device *parent = root;
for (i = 0; i < 6; i++) {
if (modpath->bc[i] == -1)
continue;
@@ -755,7 +753,7 @@ parse_tree_node(struct device *parent, int index, struct hardware_path *modpath)
struct device *hwpath_to_device(struct hardware_path *modpath)
{
int i;
- struct device *parent = &root;
+ struct device *parent = root;
for (i = 0; i < 6; i++) {
if (modpath->bc[i] == -1)
continue;
@@ -880,7 +878,7 @@ void __init walk_central_bus(void)
{
walk_native_bus(CENTRAL_BUS_ADDR,
CENTRAL_BUS_ADDR + (MAX_NATIVE_DEVICES * NATIVE_DEVICE_OFFSET),
- &root);
+ root);
}
static __init void print_parisc_device(struct parisc_device *dev)
@@ -907,23 +905,28 @@ void __init init_parisc_bus(void)
{
if (bus_register(&parisc_bus_type))
panic("Could not register PA-RISC bus type\n");
- if (device_register(&root))
+
+ root = root_device_register("parisc");
+ if (IS_ERR(root))
panic("Could not register PA-RISC root device\n");
- get_device(&root);
}
static __init void qemu_header(void)
{
int num;
unsigned long *p;
+ char name_mpe[80];
pr_info("--- cut here ---\n");
pr_info("/* AUTO-GENERATED HEADER FILE FOR SEABIOS FIRMWARE */\n");
pr_cont("/* generated with Linux kernel */\n");
pr_cont("/* search for PARISC_QEMU_MACHINE_HEADER in Linux */\n\n");
- pr_info("#define PARISC_MODEL \"%s\"\n\n",
+ pr_info("#define PARISC_MODEL \"%s\"\n",
boot_cpu_data.pdc.sys_model_name);
+ strcpy(name_mpe, boot_cpu_data.pdc.sys_model_name);
+ pdc_model_sysmodel(OS_ID_MPEXL, name_mpe);
+ pr_info("#define PARISC_MODEL_MPE \"%s\"\n\n", name_mpe);
#define p ((unsigned long *)&boot_cpu_data.pdc.model)
pr_info("#define PARISC_PDC_MODEL 0x%lx, 0x%lx, 0x%lx, "
@@ -1036,14 +1039,14 @@ static __init int qemu_print_iodc_data(struct device *lin_dev, void *data)
"mod_path_hpa_%08lx = {\n", hpa);
pr_cont("\t.path = { ");
pr_cont(".flags = 0x%x, ", mod_path.path.flags);
- pr_cont(".bc = { 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x }, ",
+ pr_cont(".bc = { 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x }, ",
(unsigned char)mod_path.path.bc[0],
(unsigned char)mod_path.path.bc[1],
(unsigned char)mod_path.path.bc[2],
(unsigned char)mod_path.path.bc[3],
(unsigned char)mod_path.path.bc[4],
(unsigned char)mod_path.path.bc[5]);
- pr_cont(".mod = 0x%x }\n", mod_path.path.mod);
+ pr_cont(".mod = 0x%02x }\n", (unsigned char)mod_path.path.mod);
pr_cont("};\n");
pr_info("static struct pdc_iodc iodc_data_hpa_%08lx = {\n", hpa);
diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c
index 042343492a28..c35a34809743 100644
--- a/arch/parisc/kernel/firmware.c
+++ b/arch/parisc/kernel/firmware.c
@@ -1643,11 +1643,36 @@ int pdc_pat_pd_get_pdc_revisions(unsigned long *legacy_rev,
return retval;
}
+/**
+ * pdc_pat_pd_get_platform_counter - Retrieve address of free-running 64-bit counter.
+ * @addr: The address of the 64-bit counter.
+ * @freq: The frequency of the counter, or -1 if unknown.
+ * @unique: Although monotonic growing, may it return the same number twice?
+ *
+ */
+int pdc_pat_pd_get_platform_counter(uint64_t **addr,
+ unsigned long *freq, unsigned long *unique)
+{
+ int retval;
+ unsigned long flags;
+
+ spin_lock_irqsave(&pdc_lock, flags);
+ retval = mem_pdc_call(PDC_PAT_PD, PDC_PAT_PD_GET_PLATFORM_COUNTER,
+ __pa(pdc_result));
+ if (retval == PDC_OK) {
+ *addr = (uint64_t *)pdc_result[0];
+ *freq = pdc_result[1];
+ *unique = pdc_result[2];
+ }
+ spin_unlock_irqrestore(&pdc_lock, flags);
+
+ return retval;
+}
/**
* pdc_pat_io_pci_cfg_read - Read PCI configuration space.
* @pci_addr: PCI configuration space address for which the read request is being made.
- * @pci_size: Size of read in bytes. Valid values are 1, 2, and 4.
+ * @pci_size: Size of read in bytes. Valid values are 1, 2, and 4.
* @mem_addr: Pointer to return memory buffer.
*
*/
diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S
index 96e0264ac961..e84d7d6e1eb9 100644
--- a/arch/parisc/kernel/head.S
+++ b/arch/parisc/kernel/head.S
@@ -56,6 +56,7 @@ ENTRY(parisc_kernel_start)
.import __bss_start,data
.import __bss_stop,data
+ .import __end,data
load32 PA(__bss_start),%r3
load32 PA(__bss_stop),%r4
@@ -104,6 +105,7 @@ $iodc_panic:
or %r10,%r10,%r10 /* qemu idle sleep */
msg1: .ascii "Can't boot kernel which was built for PA8x00 CPUs on this machine.\r\n"
msg1_end:
+ .align 4
$cpu_ok:
#endif
@@ -149,7 +151,11 @@ $cpu_ok:
* everything ... it will get remapped correctly later */
ldo 0+_PAGE_KERNEL_RWX(%r0),%r3 /* Hardwired 0 phys addr start */
load32 (1<<(KERNEL_INITIAL_ORDER-PAGE_SHIFT)),%r11 /* PFN count */
- load32 PA(pg0),%r1
+ load32 PA(_end),%r1
+ SHRREG %r1,PAGE_SHIFT,%r1 /* %r1 is PFN count for _end symbol */
+ cmpb,<<,n %r11,%r1,1f
+ copy %r1,%r11 /* %r1 PFN count smaller than %r11 */
+1: load32 PA(pg0),%r1
$pgt_fill_loop:
STREGM %r3,ASM_PTE_ENTRY_SIZE(%r1)
diff --git a/arch/parisc/kernel/inventory.c b/arch/parisc/kernel/inventory.c
index 7ab2f2a54400..103f58dac948 100644
--- a/arch/parisc/kernel/inventory.c
+++ b/arch/parisc/kernel/inventory.c
@@ -193,7 +193,7 @@ pat_query_module(ulong pcell_loc, ulong mod_index)
long status; /* PDC return value status */
struct parisc_device *dev;
- pa_pdc_cell = kmalloc(sizeof (*pa_pdc_cell), GFP_KERNEL);
+ pa_pdc_cell = kmalloc_obj(*pa_pdc_cell);
if (!pa_pdc_cell)
panic("couldn't allocate memory for PDC_PAT_CELL!");
@@ -207,6 +207,19 @@ pat_query_module(ulong pcell_loc, ulong mod_index)
return status;
}
+#ifdef DEBUG_PAT
+ pr_debug("PAT INDEX: %lu: cba 0x%lx, "
+ "mod_info 0x%lx, mod_location 0x%lx, "
+ "mod: 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx "
+ "0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n",
+ mod_index + 1, pa_pdc_cell->cba,
+ pa_pdc_cell->mod_info, pa_pdc_cell->mod_location,
+ pa_pdc_cell->mod[0], pa_pdc_cell->mod[1], pa_pdc_cell->mod[2],
+ pa_pdc_cell->mod[3], pa_pdc_cell->mod[4], pa_pdc_cell->mod[5],
+ pa_pdc_cell->mod[6], pa_pdc_cell->mod[7], pa_pdc_cell->mod[8],
+ pa_pdc_cell->mod[9], pa_pdc_cell->mod[10], pa_pdc_cell->mod[11]);
+#endif
+
temp = pa_pdc_cell->cba;
dev = alloc_pa_dev(PAT_GET_CBA(temp), &(pa_pdc_cell->mod_path));
if (!dev) {
@@ -523,7 +536,7 @@ add_system_map_addresses(struct parisc_device *dev, int num_addrs,
long status;
struct pdc_system_map_addr_info addr_result;
- dev->addr = kmalloc_array(num_addrs, sizeof(*dev->addr), GFP_KERNEL);
+ dev->addr = kmalloc_objs(*dev->addr, num_addrs);
if(!dev->addr) {
printk(KERN_ERR "%s %s(): memory allocation failure\n",
__FILE__, __func__);
diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c
index cf285b17a5ae..b8007c7400d4 100644
--- a/arch/parisc/kernel/pci.c
+++ b/arch/parisc/kernel/pci.c
@@ -8,6 +8,7 @@
* Copyright (C) 1999-2001 Hewlett-Packard Company
* Copyright (C) 1999-2001 Grant Grundler
*/
+#include <linux/align.h>
#include <linux/eisa.h>
#include <linux/init.h>
#include <linux/module.h>
@@ -196,9 +197,12 @@ void __ref pcibios_init_bridge(struct pci_dev *dev)
* than res->start.
*/
resource_size_t pcibios_align_resource(void *data, const struct resource *res,
- resource_size_t size, resource_size_t alignment)
+ const struct resource *empty_res,
+ resource_size_t size,
+ resource_size_t alignment)
{
- resource_size_t mask, align, start = res->start;
+ struct pci_dev *dev = data;
+ resource_size_t align, start = res->start;
DBG_RES("pcibios_align_resource(%s, (%p) [%lx,%lx]/%x, 0x%lx, 0x%lx)\n",
pci_name(((struct pci_dev *) data)),
@@ -207,11 +211,10 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
/* If it's not IO, then it's gotta be MEM */
align = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
-
- /* Align to largest of MIN or input size */
- mask = max(alignment, align) - 1;
- start += mask;
- start &= ~mask;
+ if (align > alignment)
+ start = ALIGN(start, align);
+ else
+ start = pci_align_resource(dev, res, empty_res, size, alignment);
return start;
}
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index e64ab5d2a40d..703644e5bfc4 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -85,6 +85,9 @@ void machine_restart(char *cmd)
#endif
/* set up a new led state on systems shipped with a LED State panel */
pdc_chassis_send_status(PDC_CHASSIS_DIRECT_SHUTDOWN);
+
+ /* prevent interrupts during reboot */
+ set_eiem(0);
/* "Normal" system reset */
pdc_do_reset();
diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c
index bf73562706b2..d09be22babdb 100644
--- a/arch/parisc/kernel/processor.c
+++ b/arch/parisc/kernel/processor.c
@@ -3,7 +3,7 @@
* Initial setup-routines for HP 9000 based hardware.
*
* Copyright (C) 1991, 1992, 1995 Linus Torvalds
- * Modifications for PA-RISC (C) 1999-2008 Helge Deller <deller@gmx.de>
+ * Modifications for PA-RISC (C) 1999-2026 Helge Deller <deller@gmx.de>
* Modifications copyright 1999 SuSE GmbH (Philipp Rumpf)
* Modifications copyright 2000 Martin K. Petersen <mkp@mkp.net>
* Modifications copyright 2000 Philipp Rumpf <prumpf@tux.org>
@@ -41,7 +41,7 @@ EXPORT_SYMBOL(_parisc_requires_coherency);
DEFINE_PER_CPU(struct cpuinfo_parisc, cpu_data);
/*
-** PARISC CPU driver - claim "device" and initialize CPU data structures.
+** PARISC CPU driver - claim "device" and initialize CPU data structures.
**
** Consolidate per CPU initialization into (mostly) one module.
** Monarch CPU will initialize boot_cpu_data which shouldn't
@@ -74,8 +74,8 @@ init_percpu_prof(unsigned long cpunum)
* processor_probe - Determine if processor driver should claim this device.
* @dev: The device which has been found.
*
- * Determine if processor driver should claim this chip (return 0) or not
- * (return 1). If so, initialize the chip and tell other partners in crime
+ * Determine if processor driver should claim this chip (return 0) or not
+ * (return 1). If so, initialize the chip and tell other partners in crime
* they have work to do.
*/
static int __init processor_probe(struct parisc_device *dev)
@@ -110,7 +110,7 @@ static int __init processor_probe(struct parisc_device *dev)
unsigned long bytecnt;
pdc_pat_cell_mod_maddr_block_t *pa_pdc_cell;
- pa_pdc_cell = kmalloc(sizeof (*pa_pdc_cell), GFP_KERNEL);
+ pa_pdc_cell = kmalloc_obj(*pa_pdc_cell);
if (!pa_pdc_cell)
panic("couldn't allocate memory for PDC_PAT_CELL!");
@@ -207,7 +207,7 @@ static int __init processor_probe(struct parisc_device *dev)
}
#endif
- /*
+ /*
* Bring this CPU up now! (ignore bootstrap cpuid == 0)
*/
#ifdef CONFIG_SMP
@@ -241,9 +241,10 @@ void __init collect_boot_cpu_data(void)
/* get CPU-Model Information... */
#define p ((unsigned long *)&boot_cpu_data.pdc.model)
if (pdc_model_info(&boot_cpu_data.pdc.model) == PDC_OK) {
- printk(KERN_INFO
- "model %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
- p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9]);
+ pr_info("model 0x%04lx 0x%04lx 0x%04lx 0x%04lx 0x%04lx "
+ "0x%04lx 0x%04lx 0x%04lx 0x%04lx 0x%04lx\n",
+ p[0], p[1], p[2], p[3], p[4],
+ p[5], p[6], p[7], p[8], p[9]);
add_device_randomness(&boot_cpu_data.pdc.model,
sizeof(boot_cpu_data.pdc.model));
@@ -251,15 +252,14 @@ void __init collect_boot_cpu_data(void)
#undef p
if (pdc_model_versions(&boot_cpu_data.pdc.versions, 0) == PDC_OK) {
- printk(KERN_INFO "vers %08lx\n",
- boot_cpu_data.pdc.versions);
+ pr_info("vers 0x%04lx\n", boot_cpu_data.pdc.versions);
add_device_randomness(&boot_cpu_data.pdc.versions,
sizeof(boot_cpu_data.pdc.versions));
}
if (pdc_model_cpuid(&boot_cpu_data.pdc.cpuid) == PDC_OK) {
- printk(KERN_INFO "CPUID vers %ld rev %ld (0x%08lx)\n",
+ pr_info("CPUID vers %ld rev %ld (0x%04lx)\n",
(boot_cpu_data.pdc.cpuid >> 5) & 127,
boot_cpu_data.pdc.cpuid & 31,
boot_cpu_data.pdc.cpuid);
@@ -437,8 +437,8 @@ show_cpuinfo (struct seq_file *m, void *v)
boot_cpu_data.pdc.sys_model_name,
cpu_name);
- seq_printf(m, "hversion\t: 0x%08x\n"
- "sversion\t: 0x%08x\n",
+ seq_printf(m, "hversion\t: 0x%04x\n"
+ "sversion\t: 0x%04x\n",
boot_cpu_data.hversion,
boot_cpu_data.sversion );
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
index 8a17ab7e6e0b..1d9e210702e1 100644
--- a/arch/parisc/kernel/ptrace.c
+++ b/arch/parisc/kernel/ptrace.c
@@ -326,7 +326,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
long do_syscall_trace_enter(struct pt_regs *regs)
{
if (test_thread_flag(TIF_SYSCALL_TRACE)) {
- int rc = ptrace_report_syscall_entry(regs);
+ bool permit = ptrace_report_syscall_permit_entry(regs);
/*
* As tracesys_next does not set %r28 to -ENOSYS
@@ -334,12 +334,10 @@ long do_syscall_trace_enter(struct pt_regs *regs)
*/
regs->gr[28] = -ENOSYS;
- if (rc) {
+ if (!permit) {
/*
- * A nonzero return code from
- * ptrace_report_syscall_entry() tells us
- * to prevent the syscall execution. Skip
- * the syscall call and the syscall restart handling.
+ * Skip the syscall call and the syscall restart
+ * handling.
*
* Note that the tracer may also just change
* regs->gr[20] to an invalid syscall number,
@@ -351,7 +349,7 @@ long do_syscall_trace_enter(struct pt_regs *regs)
}
/* Do the secure computing check after ptrace. */
- if (secure_computing() == -1)
+ if (!seccomp_permit_syscall())
return -1;
#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c
index ace483b6f19a..4d3015a411d6 100644
--- a/arch/parisc/kernel/setup.c
+++ b/arch/parisc/kernel/setup.c
@@ -120,14 +120,6 @@ void __init setup_arch(char **cmdline_p)
#endif
printk(KERN_CONT ".\n");
- /*
- * Check if initial kernel page mappings are sufficient.
- * panic early if not, else we may access kernel functions
- * and variables which can't be reached.
- */
- if (__pa((unsigned long) &_end) >= KERNEL_INITIAL_SIZE)
- panic("KERNEL_INITIAL_ORDER too small!");
-
#ifdef CONFIG_64BIT
if(parisc_narrow_firmware) {
printk(KERN_INFO "Kernel is using PDC in 32-bit mode.\n");
@@ -140,6 +132,18 @@ void __init setup_arch(char **cmdline_p)
parisc_cache_init();
paging_init();
+ /*
+ * Parse early parameters before mm_core_init_early() runs.
+ * Several early_param() handlers only record data that is consumed
+ * from there - for example hugepages=, hugepagesz=,
+ * default_hugepagesz=, hugetlb_cma= and hugetlb_free_vmemmap= - so
+ * the generic parse_early_param() call in start_kernel() is too late
+ * for them. jump_label_init() must come first, since early param
+ * handlers may enable or disable static keys.
+ */
+ jump_label_init();
+ parse_early_param();
+
#ifdef CONFIG_PA11
dma_ops_init();
#endif
@@ -279,6 +283,18 @@ void __init start_parisc(void)
int ret, cpunum;
struct pdc_coproc_cfg coproc_cfg;
+ /*
+ * Check if initial kernel page mapping is sufficient.
+ * Print warning if not, because we may access kernel functions and
+ * variables which can't be reached yet through the initial mappings.
+ * Note that the panic() and printk() functions are not functional
+ * yet, so we need to use direct iodc() firmware calls instead.
+ */
+ const char warn1[] = "CRITICAL: Kernel may crash because "
+ "KERNEL_INITIAL_ORDER is too small.\n";
+ if (__pa((unsigned long) &_end) >= KERNEL_INITIAL_SIZE)
+ pdc_iodc_print(warn1, sizeof(warn1) - 1);
+
/* check QEMU/SeaBIOS marker in PAGE0 */
running_on_qemu = (memcmp(&PAGE0->pad0, "SeaBIOS", 8) == 0);
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
index e8d27def6c52..64a62006bb15 100644
--- a/arch/parisc/kernel/signal.c
+++ b/arch/parisc/kernel/signal.c
@@ -80,7 +80,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
sigset_t set;
unsigned long usp = (regs->gr[30] & ~(0x01UL));
unsigned long sigframe_size = PARISC_RT_SIGFRAME_SIZE;
-#ifdef CONFIG_64BIT
+#ifdef CONFIG_COMPAT
struct compat_rt_sigframe __user * compat_frame;
if (is_compat_task())
@@ -96,7 +96,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
regs->orig_r28 = 1; /* no restarts for sigreturn */
-#ifdef CONFIG_64BIT
+#ifdef CONFIG_COMPAT
compat_frame = (struct compat_rt_sigframe __user *)frame;
if (is_compat_task()) {
@@ -112,7 +112,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
set_current_blocked(&set);
/* Good thing we saved the old gr[30], eh? */
-#ifdef CONFIG_64BIT
+#ifdef CONFIG_COMPAT
if (is_compat_task()) {
DBG(1, "%s: compat_frame->uc.uc_mcontext 0x%p\n",
__func__, &compat_frame->uc.uc_mcontext);
@@ -218,13 +218,13 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
unsigned long haddr, sigframe_size;
unsigned long start;
int err = 0;
-#ifdef CONFIG_64BIT
+#ifdef CONFIG_COMPAT
struct compat_rt_sigframe __user * compat_frame;
#endif
-
+
usp = (regs->gr[30] & ~(0x01UL));
sigframe_size = PARISC_RT_SIGFRAME_SIZE;
-#ifdef CONFIG_64BIT
+#ifdef CONFIG_COMPAT
if (is_compat_task()) {
/* The gcc alloca implementation leaves garbage in the upper 32 bits of sp */
usp = (compat_uint_t)usp;
@@ -239,7 +239,7 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
if (start >= TASK_SIZE_MAX - sigframe_size)
return -EFAULT;
-#ifdef CONFIG_64BIT
+#ifdef CONFIG_COMPAT
compat_frame = (struct compat_rt_sigframe __user *)frame;
@@ -349,8 +349,8 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
regs->gr[2] = rp; /* userland return pointer */
regs->gr[26] = ksig->sig; /* signal number */
-
-#ifdef CONFIG_64BIT
+
+#ifdef CONFIG_COMPAT
if (is_compat_task()) {
regs->gr[25] = A(&compat_frame->info); /* siginfo pointer */
regs->gr[24] = A(&compat_frame->uc); /* ucontext pointer */
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index b2d12ab728b1..36be17e32948 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -343,7 +343,7 @@ static int smp_boot_one_cpu(int cpuid, struct task_struct *idle)
for (i = 0; i < NR_IRQS; i++) {
struct irq_desc *desc = irq_to_desc(i);
- if (desc && desc->kstat_irqs)
+ if (desc)
*per_cpu_ptr(desc->kstat_irqs, cpuid) = (struct irqstat) { };
}
#endif
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
index b2cdbb8a12b1..1a676a9bf80c 100644
--- a/arch/parisc/kernel/sys_parisc.c
+++ b/arch/parisc/kernel/sys_parisc.c
@@ -50,9 +50,13 @@ static inline unsigned long COLOR_ALIGN(unsigned long addr,
}
+#ifdef CONFIG_COMPAT
#define STACK_SIZE_DEFAULT (USER_WIDE_MODE \
? (1 << 30) /* 1 GB */ \
: (CONFIG_STACK_MAX_DEFAULT_SIZE_MB*1024*1024))
+#else
+#define STACK_SIZE_DEFAULT (1 << 30)
+#endif
unsigned long calc_max_stack_size(unsigned long stack_max)
{
@@ -216,7 +220,7 @@ asmlinkage long parisc_truncate64(const char __user * path,
asmlinkage long parisc_ftruncate64(unsigned int fd,
unsigned int high, unsigned int low)
{
- return ksys_ftruncate(fd, (long)high << 32 | low);
+ return ksys_ftruncate(fd, (long)high << 32 | low, FTRUNCATE_LFS);
}
/* stubs for the benefit of the syscall_table since truncate64 and truncate
@@ -227,7 +231,7 @@ asmlinkage long sys_truncate64(const char __user * path, unsigned long length)
}
asmlinkage long sys_ftruncate64(unsigned int fd, unsigned long length)
{
- return ksys_ftruncate(fd, length);
+ return ksys_ftruncate(fd, length, FTRUNCATE_LFS);
}
asmlinkage long sys_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg)
{
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S
index f58c4bccfbce..e11c88c34eb2 100644
--- a/arch/parisc/kernel/syscall.S
+++ b/arch/parisc/kernel/syscall.S
@@ -241,7 +241,7 @@ linux_gateway_entry:
/* Note! We cannot use the syscall table that is mapped
nearby since the gateway page is mapped execute-only. */
-#ifdef CONFIG_64BIT
+#ifdef CONFIG_COMPAT
ldil L%sys_call_table, %r1
or,ev %r2,%r2,%r2
ldil L%sys_call_table64, %r1
@@ -250,7 +250,7 @@ linux_gateway_entry:
ldo R%sys_call_table64(%r1), %r19
#else
load32 sys_call_table, %r19
-#endif
+#endif
comiclr,>> __NR_Linux_syscalls, %r20, %r0
b,n .Lsyscall_nosys
@@ -374,7 +374,7 @@ tracesys_next:
/* Note! We cannot use the syscall table that is mapped
nearby since the gateway page is mapped execute-only. */
-#ifdef CONFIG_64BIT
+#ifdef CONFIG_COMPAT
LDREG TASK_PT_GR30(%r1), %r19 /* get users sp back */
extrd,u %r19,63,1,%r2 /* W hidden in bottom bit */
@@ -1326,16 +1326,19 @@ ENTRY(lws_table)
END(lws_table)
/* End of lws table */
-#ifdef CONFIG_64BIT
+#ifdef CONFIG_COMPAT
#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, compat)
#else
#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native)
#endif
#define __SYSCALL(nr, entry) ASM_ULONG_INSN entry
+
.align 8
ENTRY(sys_call_table)
.export sys_call_table,data
+#if defined(CONFIG_COMPAT) || !defined(CONFIG_64BIT)
#include <asm/syscall_table_32.h> /* 32-bit syscalls */
+#endif
END(sys_call_table)
#ifdef CONFIG_64BIT
diff --git a/arch/parisc/kernel/syscalls/syscall.tbl b/arch/parisc/kernel/syscalls/syscall.tbl
index 39bdacaa530b..88adc4016cce 100644
--- a/arch/parisc/kernel/syscalls/syscall.tbl
+++ b/arch/parisc/kernel/syscalls/syscall.tbl
@@ -154,7 +154,7 @@
# 137 was afs_syscall
138 common setfsuid sys_setfsuid
139 common setfsgid sys_setfsgid
-140 common _llseek sys_llseek
+140 32 _llseek sys_llseek
141 common getdents sys_getdents compat_sys_getdents
142 common _newselect sys_select compat_sys_select
143 common flock sys_flock
@@ -469,3 +469,5 @@
468 common file_getattr sys_file_getattr
469 common file_setattr sys_file_setattr
470 common listns sys_listns
+471 common rseq_slice_yield sys_rseq_slice_yield
+472 common fchroot sys_fchroot
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
index c17e2249115f..71c9d5426995 100644
--- a/arch/parisc/kernel/time.c
+++ b/arch/parisc/kernel/time.c
@@ -16,6 +16,7 @@
#include <linux/rtc.h>
#include <linux/platform_device.h>
#include <asm/processor.h>
+#include <asm/pdcpat.h>
static u64 cr16_clock_freq;
static unsigned long clocktick;
@@ -99,6 +100,22 @@ void parisc_clockevent_init(void)
clockevents_config_and_register(cd, cr16_clock_freq, min_delta, max_delta);
}
+static void parisc_find_64bit_counter(void)
+{
+#ifdef CONFIG_64BIT
+ uint64_t *pclock;
+ unsigned long freq, unique;
+ int ret;
+
+ ret = pdc_pat_pd_get_platform_counter(&pclock, &freq, &unique);
+ if (ret == PDC_OK)
+ pr_info("64-bit counter found at %px, freq: %lu, unique: %lu\n",
+ pclock, freq, unique);
+ else
+ pr_info("64-bit counter not found.\n");
+#endif
+}
+
unsigned long notrace profile_pc(struct pt_regs *regs)
{
unsigned long pc = instruction_pointer(regs);
@@ -193,12 +210,9 @@ static struct clocksource clocksource_cr16 = {
.read = read_cr16,
.mask = CLOCKSOURCE_MASK(BITS_PER_LONG),
.flags = CLOCK_SOURCE_IS_CONTINUOUS |
- CLOCK_SOURCE_VALID_FOR_HRES |
- CLOCK_SOURCE_MUST_VERIFY |
- CLOCK_SOURCE_VERIFY_PERCPU,
+ CLOCK_SOURCE_VALID_FOR_HRES,
};
-
/*
* timer interrupt and sched_clock() initialization
*/
@@ -213,6 +227,9 @@ void __init time_init(void)
parisc_clockevent_init();
+ /* check for free-running 64-bit platform counter */
+ parisc_find_64bit_counter();
+
/* register at clocksource framework */
clocksource_register_hz(&clocksource_cr16, cr16_clock_freq);
}
diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c
index 7ac88ff13d3c..fab9ae22191a 100644
--- a/arch/parisc/kernel/unwind.c
+++ b/arch/parisc/kernel/unwind.c
@@ -14,6 +14,7 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/sort.h>
+#include <linux/bsearch.h>
#include <linux/sched/task_stack.h>
#include <linux/uaccess.h>
@@ -49,27 +50,23 @@ static DEFINE_SPINLOCK(unwind_lock);
static struct unwind_table kernel_unwind_table __ro_after_init;
static LIST_HEAD(unwind_tables);
-static inline const struct unwind_table_entry *
-find_unwind_entry_in_table(const struct unwind_table *table, unsigned long addr)
+static int cmp_unwind_entry(const void *key, const void *elt)
{
- const struct unwind_table_entry *e = NULL;
- unsigned long lo, hi, mid;
+ unsigned long addr = (unsigned long)key;
+ const struct unwind_table_entry *e = elt;
- lo = 0;
- hi = table->length - 1;
-
- while (lo <= hi) {
- mid = (hi - lo) / 2 + lo;
- e = &table->table[mid];
- if (addr < e->region_start)
- hi = mid - 1;
- else if (addr > e->region_end)
- lo = mid + 1;
- else
- return e;
- }
+ if (addr < e->region_start)
+ return -1;
+ if (addr > e->region_end)
+ return 1;
+ return 0;
+}
- return NULL;
+static inline const struct unwind_table_entry *
+find_unwind_entry_in_table(const struct unwind_table *table, unsigned long addr)
+{
+ return bsearch((void *)addr, table->table, table->length,
+ sizeof(*table->table), cmp_unwind_entry);
}
static const struct unwind_table_entry *
@@ -157,7 +154,7 @@ unwind_table_add(const char *name, unsigned long base_addr,
unwind_table_sort(s, e);
- table = kmalloc(sizeof(struct unwind_table), GFP_USER);
+ table = kmalloc_obj(struct unwind_table, GFP_USER);
if (table == NULL)
return NULL;
unwind_table_init(table, name, base_addr, gp, start, end);
@@ -408,7 +405,7 @@ void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info, struct
struct pt_regs *r = &t->thread.regs;
struct pt_regs *r2;
- r2 = kmalloc(sizeof(struct pt_regs), GFP_ATOMIC);
+ r2 = kmalloc_obj(struct pt_regs, GFP_ATOMIC);
if (!r2)
return;
*r2 = *r;
diff --git a/arch/parisc/kernel/vdso.c b/arch/parisc/kernel/vdso.c
index c5cbfce7a84c..54c18574424a 100644
--- a/arch/parisc/kernel/vdso.c
+++ b/arch/parisc/kernel/vdso.c
@@ -102,7 +102,7 @@ static struct page ** __init vdso_setup_pages(void *start, void *end)
struct page **pagelist;
int i;
- pagelist = kcalloc(pages + 1, sizeof(struct page *), GFP_KERNEL);
+ pagelist = kzalloc_objs(struct page *, pages + 1);
if (!pagelist)
panic("%s: Cannot allocate page list for VDSO", __func__);
for (i = 0; i < pages; i++)
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
index b445e47903cf..0ca93d6d7235 100644
--- a/arch/parisc/kernel/vmlinux.lds.S
+++ b/arch/parisc/kernel/vmlinux.lds.S
@@ -165,6 +165,7 @@ SECTIONS
_end = . ;
STABS_DEBUG
+ MODINFO
ELF_DETAILS
.note 0 : { *(.note) }