mirror of
https://github.com/torvalds/linux.git
synced 2024-12-25 12:21:37 +00:00
Xtensa updates for v5.9:
- add syscall audit support - add seccomp filter support - clean up make rules under arch/xtensa/boot - fix state management for exclusive access opcodes - fix build with PMU enabled -----BEGIN PGP SIGNATURE----- iQJHBAABCgAxFiEEK2eFS5jlMn3N6xfYUfnMkfg/oEQFAl8q2YsTHGpjbXZia2Jj QGdtYWlsLmNvbQAKCRBR+cyR+D+gRPbID/9G6Ck59fsl62MGyqNeEmZV3Wro+tx7 7OlqN7KF20MgZMpure+NY2gTG+n3DwDdmEiiJ4aBzSY0Bg/R6SGubvAn6d+cBZG8 Wfd/bFTW390/FVaPNtveef8cJ9qlfqnGTQgTJ97LVoopnbIWm+aDHfyyb+2Td/c8 eIbhBmKOY1mZD8prnLZoVfXt7kuRrDDumBrRUwpIG/6O5sa+Q5xCj6KxNDlYqMMq /gi7BEVnDKz6cjXswmJYVkoPFdpJQ6dYEdfqkp+uoEb3i66qOcqB8JKppLdhjZy0 MayL4t7xT+0PxDRQ7eU+TONVHdZxIgu9BKDpREC+xhKLBx2q0U0i/KMWOHnRdJry AWJtDgiQmPzYuNEAlSDndxPmpDQptFIExJ6aKu0vWafv2XwTw5ukcksDh9bP6r8e XnxQasiDooAcnW+ByILXyi8a2kOUGTyaM1JMKNtevLVmp4h36I7K9F++Xr9a/R/R W+as2D4Tp0XX2yutDh5BvjSs5+BokGKj2CdlKpVA1CsrDeTXkjncNgyL84LXId/l v7hm2mjsNwrtOvr8SiMiV7I/1k+5MhYfxxNrqMsUpXvvzR2TGJZzN4dLdW/IbvY4 mkBoVcGeaa7KODRIXYbnh9sjAx2fJDgkQHjbo9S4RB2csxXdWcgbeXKt6ijkMOwz YzLhnJ/Bb7UqlQ== =nN46 -----END PGP SIGNATURE----- Merge tag 'xtensa-20200805' of git://github.com/jcmvbkbc/linux-xtensa Pull Xtensa updates from Max Filippov: - add syscall audit support - add seccomp filter support - clean up make rules under arch/xtensa/boot - fix state management for exclusive access opcodes - fix build with PMU enabled * tag 'xtensa-20200805' of git://github.com/jcmvbkbc/linux-xtensa: xtensa: add missing exclusive access state management xtensa: fix xtensa_pmu_setup prototype xtensa: add boot subdirectories build artifacts to 'targets' xtensa: add uImage and xipImage to targets xtensa: move vmlinux.bin[.gz] to boot subdirectory xtensa: initialize_mmu.h: fix a duplicated word selftests/seccomp: add xtensa support xtensa: add seccomp support xtensa: expose syscall through user_pt_regs xtensa: add audit support
This commit is contained in:
commit
bbcf9cd157
@ -29,5 +29,5 @@
|
||||
| sparc: | TODO |
|
||||
| um: | ok |
|
||||
| x86: | ok |
|
||||
| xtensa: | TODO |
|
||||
| xtensa: | ok |
|
||||
-----------------------
|
||||
|
@ -21,8 +21,10 @@ config XTENSA
|
||||
select GENERIC_PCI_IOMAP
|
||||
select GENERIC_SCHED_CLOCK
|
||||
select GENERIC_STRNCPY_FROM_USER if KASAN
|
||||
select HAVE_ARCH_AUDITSYSCALL
|
||||
select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
|
||||
select HAVE_ARCH_KASAN if MMU && !XIP_KERNEL
|
||||
select HAVE_ARCH_SECCOMP_FILTER
|
||||
select HAVE_ARCH_TRACEHOOK
|
||||
select HAVE_DEBUG_KMEMLEAK
|
||||
select HAVE_DMA_CONTIGUOUS
|
||||
@ -215,6 +217,20 @@ config HOTPLUG_CPU
|
||||
|
||||
Say N if you want to disable CPU hotplug.
|
||||
|
||||
config SECCOMP
|
||||
bool
|
||||
prompt "Enable seccomp to safely compute untrusted bytecode"
|
||||
help
|
||||
This kernel feature is useful for number crunching applications
|
||||
that may need to compute untrusted bytecode during their
|
||||
execution. By using pipes or other transports made available to
|
||||
the process as file descriptors supporting the read/write
|
||||
syscalls, it's possible to isolate those applications in
|
||||
their own address space using seccomp. Once seccomp is
|
||||
enabled via prctl(PR_SET_SECCOMP), it cannot be disabled
|
||||
and the task is only allowed to execute a few safe syscalls
|
||||
defined by each seccomp mode.
|
||||
|
||||
config FAST_SYSCALL_XTENSA
|
||||
bool "Enable fast atomic syscalls"
|
||||
default n
|
||||
|
@ -17,6 +17,8 @@ BIG_ENDIAN := $(shell echo __XTENSA_EB__ | $(CC) -E - | grep -v "\#")
|
||||
export BIG_ENDIAN
|
||||
|
||||
subdir-y := lib
|
||||
targets += vmlinux.bin vmlinux.bin.gz
|
||||
targets += uImage xipImage
|
||||
|
||||
# Subdirs for the boot loader(s)
|
||||
|
||||
@ -35,19 +37,19 @@ boot-elf boot-redboot: $(addprefix $(obj)/,$(subdir-y))
|
||||
|
||||
OBJCOPYFLAGS = --strip-all -R .comment -R .notes -O binary
|
||||
|
||||
vmlinux.bin: vmlinux FORCE
|
||||
$(obj)/vmlinux.bin: vmlinux FORCE
|
||||
$(call if_changed,objcopy)
|
||||
|
||||
vmlinux.bin.gz: vmlinux.bin FORCE
|
||||
$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
|
||||
$(call if_changed,gzip)
|
||||
|
||||
boot-elf: vmlinux.bin
|
||||
boot-redboot: vmlinux.bin.gz
|
||||
boot-elf: $(obj)/vmlinux.bin
|
||||
boot-redboot: $(obj)/vmlinux.bin.gz
|
||||
|
||||
UIMAGE_LOADADDR = $(CONFIG_KERNEL_LOAD_ADDRESS)
|
||||
UIMAGE_COMPRESSION = gzip
|
||||
|
||||
$(obj)/uImage: vmlinux.bin.gz FORCE
|
||||
$(obj)/uImage: $(obj)/vmlinux.bin.gz FORCE
|
||||
$(call if_changed,uimage)
|
||||
$(Q)$(kecho) ' Kernel: $@ is ready'
|
||||
|
||||
|
@ -15,12 +15,13 @@ export CPPFLAGS_boot.lds += -P -C
|
||||
export KBUILD_AFLAGS += -mtext-section-literals
|
||||
|
||||
boot-y := bootstrap.o
|
||||
targets += $(boot-y) boot.lds
|
||||
|
||||
OBJS := $(addprefix $(obj)/,$(boot-y))
|
||||
|
||||
$(obj)/Image.o: vmlinux.bin $(OBJS)
|
||||
$(obj)/Image.o: $(obj)/../vmlinux.bin $(OBJS)
|
||||
$(Q)$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
|
||||
--add-section image=vmlinux.bin \
|
||||
--add-section image=$< \
|
||||
--set-section-flags image=contents,alloc,load,load,data \
|
||||
$(OBJS) $@
|
||||
|
||||
|
@ -13,15 +13,16 @@ endif
|
||||
LD_ARGS = -T $(srctree)/$(obj)/boot.ld
|
||||
|
||||
boot-y := bootstrap.o
|
||||
targets += $(boot-y)
|
||||
|
||||
OBJS := $(addprefix $(obj)/,$(boot-y))
|
||||
LIBS := arch/xtensa/boot/lib/lib.a arch/xtensa/lib/lib.a
|
||||
|
||||
LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
|
||||
|
||||
$(obj)/zImage.o: vmlinux.bin.gz $(OBJS)
|
||||
$(obj)/zImage.o: $(obj)/../vmlinux.bin.gz $(OBJS)
|
||||
$(Q)$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
|
||||
--add-section image=vmlinux.bin.gz \
|
||||
--add-section image=$< \
|
||||
--set-section-flags image=contents,alloc,load,load,data \
|
||||
$(OBJS) $@
|
||||
|
||||
|
@ -7,4 +7,5 @@ generic-y += mcs_spinlock.h
|
||||
generic-y += param.h
|
||||
generic-y += qrwlock.h
|
||||
generic-y += qspinlock.h
|
||||
generic-y += seccomp.h
|
||||
generic-y += user.h
|
||||
|
@ -6,7 +6,7 @@
|
||||
* For the new V3 MMU we remap the TLB from virtual == physical
|
||||
* to the standard Linux mapping used in earlier MMU's.
|
||||
*
|
||||
* The the MMU we also support a new configuration register that
|
||||
* For the MMU we also support a new configuration register that
|
||||
* specifies how the S32C1I instruction operates with the cache
|
||||
* controller.
|
||||
*
|
||||
|
@ -55,6 +55,10 @@ struct thread_info {
|
||||
mm_segment_t addr_limit; /* thread address space */
|
||||
|
||||
unsigned long cpenable;
|
||||
#if XCHAL_HAVE_EXCLUSIVE
|
||||
/* result of the most recent exclusive store */
|
||||
unsigned long atomctl8;
|
||||
#endif
|
||||
|
||||
/* Allocate storage for extra user states and coprocessor states. */
|
||||
#if XTENSA_HAVE_COPROCESSORS
|
||||
@ -111,15 +115,20 @@ static inline struct thread_info *current_thread_info(void)
|
||||
#define TIF_RESTORE_SIGMASK 6 /* restore signal mask in do_signal() */
|
||||
#define TIF_NOTIFY_RESUME 7 /* callback before returning to user */
|
||||
#define TIF_DB_DISABLED 8 /* debug trap disabled for syscall */
|
||||
#define TIF_SYSCALL_AUDIT 9 /* syscall auditing active */
|
||||
#define TIF_SECCOMP 10 /* secure computing */
|
||||
|
||||
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
|
||||
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
|
||||
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
|
||||
#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
|
||||
#define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT)
|
||||
#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
|
||||
#define _TIF_SECCOMP (1<<TIF_SECCOMP)
|
||||
|
||||
#define _TIF_WORK_MASK (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | \
|
||||
_TIF_SYSCALL_TRACEPOINT)
|
||||
_TIF_SYSCALL_TRACEPOINT | \
|
||||
_TIF_SYSCALL_AUDIT | _TIF_SECCOMP)
|
||||
|
||||
#define THREAD_SIZE KERNEL_STACK_SIZE
|
||||
#define THREAD_SIZE_ORDER (KERNEL_STACK_SHIFT - PAGE_SHIFT)
|
||||
|
@ -50,7 +50,8 @@ struct user_pt_regs {
|
||||
__u32 windowstart;
|
||||
__u32 windowbase;
|
||||
__u32 threadptr;
|
||||
__u32 reserved[7 + 48];
|
||||
__u32 syscall;
|
||||
__u32 reserved[6 + 48];
|
||||
__u32 a[64];
|
||||
};
|
||||
|
||||
|
@ -93,6 +93,9 @@ int main(void)
|
||||
DEFINE(THREAD_RA, offsetof (struct task_struct, thread.ra));
|
||||
DEFINE(THREAD_SP, offsetof (struct task_struct, thread.sp));
|
||||
DEFINE(THREAD_CPENABLE, offsetof (struct thread_info, cpenable));
|
||||
#if XCHAL_HAVE_EXCLUSIVE
|
||||
DEFINE(THREAD_ATOMCTL8, offsetof (struct thread_info, atomctl8));
|
||||
#endif
|
||||
#if XTENSA_HAVE_COPROCESSORS
|
||||
DEFINE(THREAD_XTREGS_CP0, offsetof(struct thread_info, xtregs_cp.cp0));
|
||||
DEFINE(THREAD_XTREGS_CP1, offsetof(struct thread_info, xtregs_cp.cp1));
|
||||
|
@ -374,6 +374,11 @@ common_exception:
|
||||
s32i a2, a1, PT_LCOUNT
|
||||
#endif
|
||||
|
||||
#if XCHAL_HAVE_EXCLUSIVE
|
||||
/* Clear exclusive access monitor set by interrupted code */
|
||||
clrex
|
||||
#endif
|
||||
|
||||
/* It is now save to restore the EXC_TABLE_FIXUP variable. */
|
||||
|
||||
rsr a2, exccause
|
||||
@ -2020,6 +2025,12 @@ ENTRY(_switch_to)
|
||||
s32i a3, a4, THREAD_CPENABLE
|
||||
#endif
|
||||
|
||||
#if XCHAL_HAVE_EXCLUSIVE
|
||||
l32i a3, a5, THREAD_ATOMCTL8
|
||||
getex a3
|
||||
s32i a3, a4, THREAD_ATOMCTL8
|
||||
#endif
|
||||
|
||||
/* Flush register file. */
|
||||
|
||||
spill_registers_kernel
|
||||
|
@ -399,7 +399,7 @@ static struct pmu xtensa_pmu = {
|
||||
.read = xtensa_pmu_read,
|
||||
};
|
||||
|
||||
static int xtensa_pmu_setup(int cpu)
|
||||
static int xtensa_pmu_setup(unsigned int cpu)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
* Marc Gauthier<marc@tensilica.com> <marc@alumni.uwaterloo.ca>
|
||||
*/
|
||||
|
||||
#include <linux/audit.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/hw_breakpoint.h>
|
||||
#include <linux/kernel.h>
|
||||
@ -21,6 +22,7 @@
|
||||
#include <linux/regset.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/sched/task_stack.h>
|
||||
#include <linux/seccomp.h>
|
||||
#include <linux/security.h>
|
||||
#include <linux/signal.h>
|
||||
#include <linux/smp.h>
|
||||
@ -51,6 +53,7 @@ static int gpr_get(struct task_struct *target,
|
||||
.threadptr = regs->threadptr,
|
||||
.windowbase = regs->windowbase,
|
||||
.windowstart = regs->windowstart,
|
||||
.syscall = regs->syscall,
|
||||
};
|
||||
|
||||
memcpy(newregs.a,
|
||||
@ -90,6 +93,9 @@ static int gpr_set(struct task_struct *target,
|
||||
regs->sar = newregs.sar;
|
||||
regs->threadptr = newregs.threadptr;
|
||||
|
||||
if (newregs.syscall)
|
||||
regs->syscall = newregs.syscall;
|
||||
|
||||
if (newregs.windowbase != regs->windowbase ||
|
||||
newregs.windowstart != regs->windowstart) {
|
||||
u32 rotws, wmask;
|
||||
@ -554,7 +560,8 @@ int do_syscall_trace_enter(struct pt_regs *regs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (regs->syscall == NO_SYSCALL) {
|
||||
if (regs->syscall == NO_SYSCALL ||
|
||||
secure_computing() == -1) {
|
||||
do_syscall_trace_leave(regs);
|
||||
return 0;
|
||||
}
|
||||
@ -562,6 +569,9 @@ int do_syscall_trace_enter(struct pt_regs *regs)
|
||||
if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
|
||||
trace_sys_enter(regs, syscall_get_nr(current, regs));
|
||||
|
||||
audit_syscall_entry(regs->syscall, regs->areg[6],
|
||||
regs->areg[3], regs->areg[4],
|
||||
regs->areg[5]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -569,6 +579,8 @@ void do_syscall_trace_leave(struct pt_regs *regs)
|
||||
{
|
||||
int step;
|
||||
|
||||
audit_syscall_exit(regs);
|
||||
|
||||
if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
|
||||
trace_sys_exit(regs, regs_return_value(regs));
|
||||
|
||||
|
@ -129,6 +129,8 @@ struct seccomp_data {
|
||||
# define __NR_seccomp 358
|
||||
# elif defined(__s390__)
|
||||
# define __NR_seccomp 348
|
||||
# elif defined(__xtensa__)
|
||||
# define __NR_seccomp 337
|
||||
# else
|
||||
# warning "seccomp syscall number unknown for this architecture"
|
||||
# define __NR_seccomp 0xffff
|
||||
@ -1699,6 +1701,14 @@ TEST_F(TRACE_poke, getpid_runs_normally)
|
||||
# define SYSCALL_SYSCALL_NUM regs[4]
|
||||
# define SYSCALL_RET regs[2]
|
||||
# define SYSCALL_NUM_RET_SHARE_REG
|
||||
#elif defined(__xtensa__)
|
||||
# define ARCH_REGS struct user_pt_regs
|
||||
# define SYSCALL_NUM syscall
|
||||
/*
|
||||
* On xtensa syscall return value is in the register
|
||||
* a2 of the current window which is not fixed.
|
||||
*/
|
||||
#define SYSCALL_RET(reg) a[(reg).windowbase * 4 + 2]
|
||||
#else
|
||||
# error "Do not know how to find your architecture's registers and syscalls"
|
||||
#endif
|
||||
@ -1770,7 +1780,8 @@ void change_syscall(struct __test_metadata *_metadata,
|
||||
EXPECT_EQ(0, ret) {}
|
||||
|
||||
#if defined(__x86_64__) || defined(__i386__) || defined(__powerpc__) || \
|
||||
defined(__s390__) || defined(__hppa__) || defined(__riscv)
|
||||
defined(__s390__) || defined(__hppa__) || defined(__riscv) || \
|
||||
defined(__xtensa__)
|
||||
{
|
||||
regs.SYSCALL_NUM = syscall;
|
||||
}
|
||||
@ -1813,6 +1824,9 @@ void change_syscall(struct __test_metadata *_metadata,
|
||||
if (syscall == -1)
|
||||
#ifdef SYSCALL_NUM_RET_SHARE_REG
|
||||
TH_LOG("Can't modify syscall return on this architecture");
|
||||
|
||||
#elif defined(__xtensa__)
|
||||
regs.SYSCALL_RET(regs) = result;
|
||||
#else
|
||||
regs.SYSCALL_RET = result;
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user