Commit a5f2bd47 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'parisc-4.21-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux

Pull parisc updates from Helge Deller:
 "The major change in this patchset is the new system call table
  generation support from Firoz Khan"

* 'parisc-4.21-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux:
  parisc: syscalls: ignore nfsservctl for other architectures
  parisc: generate uapi header and system call table files
  parisc: add system call table generation support
  parisc: remove __NR_Linux from uapi header file.
  parisc: add __NR_syscalls along with __NR_Linux_syscalls
  parisc: move __IGNORE* entries to non uapi header
  parisc: Fix HP SDC hpa address output
  parisc: Fix serio address output
  parisc: Split out alternative live patching code
parents 89261c57 930e1299
......@@ -163,3 +163,6 @@ define archhelp
@echo ' copy to $$(INSTALL_PATH)'
@echo ' zinstall - Install compressed vmlinuz kernel'
endef
archheaders:
$(Q)$(MAKE) $(build)=arch/parisc/kernel/syscalls all
generated-y += syscall_table_32.h
generated-y += syscall_table_64.h
generated-y += syscall_table_c32.h
generic-y += barrier.h
generic-y += current.h
generic-y += device.h
......
......@@ -2,6 +2,7 @@
#ifndef __ASM_PARISC_ALTERNATIVE_H
#define __ASM_PARISC_ALTERNATIVE_H
#define ALT_COND_ALWAYS 0x80 /* always replace instruction */
#define ALT_COND_NO_SMP 0x01 /* when running UP instead of SMP */
#define ALT_COND_NO_DCACHE 0x02 /* if system has no d-cache */
#define ALT_COND_NO_ICACHE 0x04 /* if system has no i-cache */
......@@ -26,6 +27,9 @@ struct alt_instr {
};
void set_kernel_text_rw(int enable_read_write);
void apply_alternatives_all(void);
void apply_alternatives(struct alt_instr *start, struct alt_instr *end,
const char *module_name);
/* Alternative SMP implementation. */
#define ALTERNATIVE(cond, replacement) "!0:" \
......
......@@ -4,10 +4,18 @@
#include <uapi/asm/unistd.h>
#define __NR_Linux_syscalls __NR_syscalls
#ifndef __ASSEMBLY__
#define SYS_ify(syscall_name) __NR_##syscall_name
#define __IGNORE_select /* newselect */
#define __IGNORE_fadvise64 /* fadvise64_64 */
#define __IGNORE_pkey_mprotect
#define __IGNORE_pkey_alloc
#define __IGNORE_pkey_free
#ifndef ASM_LINE_SEP
# define ASM_LINE_SEP ;
#endif
......
# UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm
generated-y += unistd_32.h
generated-y += unistd_64.h
generic-y += auxvec.h
generic-y += bpf_perf_event.h
generic-y += kvm_para.h
......
This diff is collapsed.
......@@ -7,7 +7,7 @@ extra-y := head.o vmlinux.lds
obj-y := cache.o pacache.o setup.o pdt.o traps.o time.o irq.o \
pa7300lc.o syscall.o entry.o sys_parisc.o firmware.o \
ptrace.o hardware.o inventory.o drivers.o \
ptrace.o hardware.o inventory.o drivers.o alternative.o \
signal.o hpmc.o real2.o parisc_ksyms.o unaligned.o \
process.o processor.o pdc_cons.o pdc_chassis.o unwind.o
......
// SPDX-License-Identifier: GPL-2.0
/*
* Alternative live-patching for parisc.
* Copyright (C) 2018 Helge Deller <deller@gmx.de>
*
*/
#include <asm/processor.h>
#include <asm/sections.h>
#include <asm/alternative.h>
#include <linux/module.h>
static int no_alternatives;
static int __init setup_no_alternatives(char *str)
{
no_alternatives = 1;
return 1;
}
__setup("no-alternatives", setup_no_alternatives);
void __init_or_module apply_alternatives(struct alt_instr *start,
struct alt_instr *end, const char *module_name)
{
struct alt_instr *entry;
int index = 0, applied = 0;
int num_cpus = num_online_cpus();
for (entry = start; entry < end; entry++, index++) {
u32 *from, len, cond, replacement;
from = (u32 *)((ulong)&entry->orig_offset + entry->orig_offset);
len = entry->len;
cond = entry->cond;
replacement = entry->replacement;
WARN_ON(!cond);
if (cond != ALT_COND_ALWAYS && no_alternatives)
continue;
pr_debug("Check %d: Cond 0x%x, Replace %02d instructions @ 0x%px with 0x%08x\n",
index, cond, len, from, replacement);
if ((cond & ALT_COND_NO_SMP) && (num_cpus != 1))
continue;
if ((cond & ALT_COND_NO_DCACHE) && (cache_info.dc_size != 0))
continue;
if ((cond & ALT_COND_NO_ICACHE) && (cache_info.ic_size != 0))
continue;
/*
* If the PDC_MODEL capabilities has Non-coherent IO-PDIR bit
* set (bit #61, big endian), we have to flush and sync every
* time IO-PDIR is changed in Ike/Astro.
*/
if ((cond & ALT_COND_NO_IOC_FDC) &&
(boot_cpu_data.pdc.capabilities & PDC_MODEL_IOPDIR_FDC))
continue;
/* Want to replace pdtlb by a pdtlb,l instruction? */
if (replacement == INSN_PxTLB) {
replacement = *from;
if (boot_cpu_data.cpu_type >= pcxu) /* >= pa2.0 ? */
replacement |= (1 << 10); /* set el bit */
}
/*
* Replace instruction with NOPs?
* For long distance insert a branch instruction instead.
*/
if (replacement == INSN_NOP && len > 1)
replacement = 0xe8000002 + (len-2)*8; /* "b,n .+8" */
pr_debug("Do %d: Cond 0x%x, Replace %02d instructions @ 0x%px with 0x%08x\n",
index, cond, len, from, replacement);
/* Replace instruction */
*from = replacement;
applied++;
}
pr_info("%s%salternatives: applied %d out of %d patches\n",
module_name ? : "", module_name ? " " : "",
applied, index);
}
void __init apply_alternatives_all(void)
{
set_kernel_text_rw(1);
apply_alternatives((struct alt_instr *) &__alt_instructions,
(struct alt_instr *) &__alt_instructions_end, NULL);
set_kernel_text_rw(0);
}
......@@ -877,6 +877,8 @@ int module_finalize(const Elf_Ehdr *hdr,
int i;
unsigned long nsyms;
const char *strtab = NULL;
const Elf_Shdr *s;
char *secstrings;
Elf_Sym *newptr, *oldptr;
Elf_Shdr *symhdr = NULL;
#ifdef DEBUG
......@@ -948,6 +950,18 @@ int module_finalize(const Elf_Ehdr *hdr,
nsyms = newptr - (Elf_Sym *)symhdr->sh_addr;
DEBUGP("NEW num_symtab %lu\n", nsyms);
symhdr->sh_size = nsyms * sizeof(Elf_Sym);
/* find .altinstructions section */
secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
void *aseg = (void *) s->sh_addr;
char *secname = secstrings + s->sh_name;
if (!strcmp(".altinstructions", secname))
/* patch .altinstructions */
apply_alternatives(aseg, aseg + s->sh_size, me->name);
}
return 0;
}
......
......@@ -305,86 +305,6 @@ static int __init parisc_init_resources(void)
return 0;
}
static int no_alternatives __initdata;
static int __init setup_no_alternatives(char *str)
{
no_alternatives = 1;
return 1;
}
__setup("no-alternatives", setup_no_alternatives);
static void __init apply_alternatives_all(void)
{
struct alt_instr *entry;
int index = 0, applied = 0;
pr_info("alternatives: %spatching kernel code\n",
no_alternatives ? "NOT " : "");
if (no_alternatives)
return;
set_kernel_text_rw(1);
for (entry = (struct alt_instr *) &__alt_instructions;
entry < (struct alt_instr *) &__alt_instructions_end;
entry++, index++) {
u32 *from, len, cond, replacement;
from = (u32 *)((ulong)&entry->orig_offset + entry->orig_offset);
len = entry->len;
cond = entry->cond;
replacement = entry->replacement;
WARN_ON(!cond);
pr_debug("Check %d: Cond 0x%x, Replace %02d instructions @ 0x%px with 0x%08x\n",
index, cond, len, from, replacement);
if ((cond & ALT_COND_NO_SMP) && (num_online_cpus() != 1))
continue;
if ((cond & ALT_COND_NO_DCACHE) && (cache_info.dc_size != 0))
continue;
if ((cond & ALT_COND_NO_ICACHE) && (cache_info.ic_size != 0))
continue;
/*
* If the PDC_MODEL capabilities has Non-coherent IO-PDIR bit
* set (bit #61, big endian), we have to flush and sync every
* time IO-PDIR is changed in Ike/Astro.
*/
if ((cond & ALT_COND_NO_IOC_FDC) &&
(boot_cpu_data.pdc.capabilities & PDC_MODEL_IOPDIR_FDC))
continue;
/* Want to replace pdtlb by a pdtlb,l instruction? */
if (replacement == INSN_PxTLB) {
replacement = *from;
if (boot_cpu_data.cpu_type >= pcxu) /* >= pa2.0 ? */
replacement |= (1 << 10); /* set el bit */
}
/*
* Replace instruction with NOPs?
* For long distance insert a branch instruction instead.
*/
if (replacement == INSN_NOP && len > 1)
replacement = 0xe8000002 + (len-2)*8; /* "b,n .+8" */
pr_debug("Do %d: Cond 0x%x, Replace %02d instructions @ 0x%px with 0x%08x\n",
index, cond, len, from, replacement);
/* Replace instruction */
*from = replacement;
applied++;
}
pr_info("alternatives: applied %d out of %d patches\n", applied, index);
set_kernel_text_rw(0);
}
extern void gsc_init(void);
extern void processor_init(void);
extern void ccio_init(void);
......
......@@ -923,19 +923,24 @@ ENTRY(lws_table)
END(lws_table)
/* End of lws table */
#define __SYSCALL(nr, entry, nargs) ASM_ULONG_INSN entry
.align 8
ENTRY(sys_call_table)
.export sys_call_table,data
#include "syscall_table.S"
#ifdef CONFIG_64BIT
#include <asm/syscall_table_c32.h> /* Compat syscalls */
#else
#include <asm/syscall_table_32.h> /* 32-bit native syscalls */
#endif
END(sys_call_table)
#ifdef CONFIG_64BIT
.align 8
ENTRY(sys_call_table64)
#define SYSCALL_TABLE_64BIT
#include "syscall_table.S"
#include <asm/syscall_table_64.h> /* 64-bit native syscalls */
END(sys_call_table64)
#endif
#undef __SYSCALL
/*
All light-weight-syscall atomic operations
......
This diff is collapsed.
# SPDX-License-Identifier: GPL-2.0
kapi := arch/$(SRCARCH)/include/generated/asm
uapi := arch/$(SRCARCH)/include/generated/uapi/asm
_dummy := $(shell [ -d '$(uapi)' ] || mkdir -p '$(uapi)') \
$(shell [ -d '$(kapi)' ] || mkdir -p '$(kapi)')
syscall := $(srctree)/$(src)/syscall.tbl
syshdr := $(srctree)/$(src)/syscallhdr.sh
systbl := $(srctree)/$(src)/syscalltbl.sh
quiet_cmd_syshdr = SYSHDR $@
cmd_syshdr = $(CONFIG_SHELL) '$(syshdr)' '$<' '$@' \
'$(syshdr_abis_$(basetarget))' \
'$(syshdr_pfx_$(basetarget))' \
'$(syshdr_offset_$(basetarget))'
quiet_cmd_systbl = SYSTBL $@
cmd_systbl = $(CONFIG_SHELL) '$(systbl)' '$<' '$@' \
'$(systbl_abis_$(basetarget))' \
'$(systbl_abi_$(basetarget))' \
'$(systbl_offset_$(basetarget))'
syshdr_abis_unistd_32 := common,32
$(uapi)/unistd_32.h: $(syscall) $(syshdr)
$(call if_changed,syshdr)
syshdr_abis_unistd_64 := common,64
$(uapi)/unistd_64.h: $(syscall) $(syshdr)
$(call if_changed,syshdr)
systbl_abis_syscall_table_32 := common,32
$(kapi)/syscall_table_32.h: $(syscall) $(systbl)
$(call if_changed,systbl)
systbl_abis_syscall_table_64 := common,64
$(kapi)/syscall_table_64.h: $(syscall) $(systbl)
$(call if_changed,systbl)
systbl_abis_syscall_table_c32 := common,32
systbl_abi_syscall_table_c32 := c32
$(kapi)/syscall_table_c32.h: $(syscall) $(systbl)
$(call if_changed,systbl)
uapisyshdr-y += unistd_32.h unistd_64.h
kapisyshdr-y += syscall_table_32.h \
syscall_table_64.h \
syscall_table_c32.h
targets += $(uapisyshdr-y) $(kapisyshdr-y)
PHONY += all
all: $(addprefix $(uapi)/,$(uapisyshdr-y))
all: $(addprefix $(kapi)/,$(kapisyshdr-y))
@:
This diff is collapsed.
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
in="$1"
out="$2"
my_abis=`echo "($3)" | tr ',' '|'`
prefix="$4"
offset="$5"
fileguard=_UAPI_ASM_PARISC_`basename "$out" | sed \
-e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \
-e 's/[^A-Z0-9_]/_/g' -e 's/__/_/g'`
grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | (
printf "#ifndef %s\n" "${fileguard}"
printf "#define %s\n" "${fileguard}"
printf "\n"
nxt=0
while read nr abi name entry compat ; do
if [ -z "$offset" ]; then
printf "#define __NR_%s%s\t%s\n" \
"${prefix}" "${name}" "${nr}"
else
printf "#define __NR_%s%s\t(%s + %s)\n" \
"${prefix}" "${name}" "${offset}" "${nr}"
fi
nxt=$((nr+1))
done
printf "\n"
printf "#ifdef __KERNEL__\n"
printf "#define __NR_syscalls\t%s\n" "${nxt}"
printf "#endif\n"
printf "\n"
printf "#endif /* %s */" "${fileguard}"
) > "$out"
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
in="$1"
out="$2"
my_abis=`echo "($3)" | tr ',' '|'`
my_abi="$4"
offset="$5"
emit() {
t_nxt="$1"
t_nr="$2"
t_entry="$3"
while [ $t_nxt -lt $t_nr ]; do
printf "__SYSCALL(%s, sys_ni_syscall, )\n" "${t_nxt}"
t_nxt=$((t_nxt+1))
done
printf "__SYSCALL(%s, %s, )\n" "${t_nxt}" "${t_entry}"
}
grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | (
nxt=0
if [ -z "$offset" ]; then
offset=0
fi
while read nr abi name entry compat ; do
if [ "$my_abi" = "c32" ] && [ ! -z "$compat" ]; then
emit $((nxt+offset)) $((nr+offset)) $compat
else
emit $((nxt+offset)) $((nr+offset)) $entry
fi
nxt=$((nr+1))
done
) > "$out"
......@@ -381,9 +381,9 @@ static int __init gscps2_probe(struct parisc_device *dev)
goto fail;
#endif
printk(KERN_INFO "serio: %s port at 0x%p irq %d @ %s\n",
pr_info("serio: %s port at 0x%08lx irq %d @ %s\n",
ps2port->port->name,
ps2port->addr,
hpa,
ps2port->padev->irq,
ps2port->port->phys);
......
......@@ -884,8 +884,8 @@ static int __init hp_sdc_init(void)
"HP SDC NMI", &hp_sdc))
goto err2;
printk(KERN_INFO PREFIX "HP SDC at 0x%p, IRQ %d (NMI IRQ %d)\n",
(void *)hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi);
pr_info(PREFIX "HP SDC at 0x%08lx, IRQ %d (NMI IRQ %d)\n",
hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi);
hp_sdc_status_in8();
hp_sdc_data_in8();
......
......@@ -150,6 +150,7 @@ cat << EOF
#define __IGNORE_uselib
#define __IGNORE__sysctl
#define __IGNORE_arch_prctl
#define __IGNORE_nfsservctl
/* ... including the "new" 32-bit uid syscalls */
#define __IGNORE_lchown32
......
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