diff options
Diffstat (limited to 'arch/um/include')
| -rw-r--r-- | arch/um/include/asm/current.h | 5 | ||||
| -rw-r--r-- | arch/um/include/asm/hardirq.h | 24 | ||||
| -rw-r--r-- | arch/um/include/asm/irqflags.h | 4 | ||||
| -rw-r--r-- | arch/um/include/asm/kasan.h | 4 | ||||
| -rw-r--r-- | arch/um/include/asm/mmu.h | 10 | ||||
| -rw-r--r-- | arch/um/include/asm/page.h | 4 | ||||
| -rw-r--r-- | arch/um/include/asm/pgtable.h | 8 | ||||
| -rw-r--r-- | arch/um/include/asm/smp.h | 15 | ||||
| -rw-r--r-- | arch/um/include/asm/uaccess.h | 9 | ||||
| -rw-r--r-- | arch/um/include/linux/smp-internal.h | 17 | ||||
| -rw-r--r-- | arch/um/include/linux/time-internal.h | 3 | ||||
| -rw-r--r-- | arch/um/include/shared/as-layout.h | 1 | ||||
| -rw-r--r-- | arch/um/include/shared/common-offsets.h | 20 | ||||
| -rw-r--r-- | arch/um/include/shared/kern_util.h | 5 | ||||
| -rw-r--r-- | arch/um/include/shared/longjmp.h | 3 | ||||
| -rw-r--r-- | arch/um/include/shared/mem_user.h | 13 | ||||
| -rw-r--r-- | arch/um/include/shared/os.h | 24 | ||||
| -rw-r--r-- | arch/um/include/shared/skas/mm_id.h | 5 | ||||
| -rw-r--r-- | arch/um/include/shared/skas/skas.h | 2 | ||||
| -rw-r--r-- | arch/um/include/shared/smp.h | 20 |
20 files changed, 129 insertions, 67 deletions
diff --git a/arch/um/include/asm/current.h b/arch/um/include/asm/current.h index 8accc6d6f502..159a29b3d4cc 100644 --- a/arch/um/include/asm/current.h +++ b/arch/um/include/asm/current.h @@ -7,15 +7,16 @@ #ifndef __ASSEMBLER__ +#include <shared/smp.h> + struct task_struct; extern struct task_struct *cpu_tasks[NR_CPUS]; static __always_inline struct task_struct *get_current(void) { - return cpu_tasks[0]; + return cpu_tasks[uml_curr_cpu()]; } - #define current get_current() #endif /* __ASSEMBLER__ */ diff --git a/arch/um/include/asm/hardirq.h b/arch/um/include/asm/hardirq.h index 52e2c36267a9..8de71752a9b8 100644 --- a/arch/um/include/asm/hardirq.h +++ b/arch/um/include/asm/hardirq.h @@ -2,8 +2,30 @@ #ifndef __ASM_UM_HARDIRQ_H #define __ASM_UM_HARDIRQ_H -#include <asm-generic/hardirq.h> +#include <linux/cache.h> +#include <linux/threads.h> #define __ARCH_IRQ_EXIT_IRQS_DISABLED 1 +typedef struct { + unsigned int __softirq_pending; +#if IS_ENABLED(CONFIG_SMP) + unsigned int irq_resched_count; + unsigned int irq_call_count; +#endif +} ____cacheline_aligned irq_cpustat_t; + +DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); + +#define __ARCH_IRQ_STAT + +#define inc_irq_stat(member) this_cpu_inc(irq_stat.member) + +#include <linux/irq.h> + +static inline void ack_bad_irq(unsigned int irq) +{ + pr_crit("unexpected IRQ trap at vector %02x\n", irq); +} + #endif /* __ASM_UM_HARDIRQ_H */ diff --git a/arch/um/include/asm/irqflags.h b/arch/um/include/asm/irqflags.h index 1e69ef5bc35e..31e49e0894c5 100644 --- a/arch/um/include/asm/irqflags.h +++ b/arch/um/include/asm/irqflags.h @@ -2,7 +2,7 @@ #ifndef __UM_IRQFLAGS_H #define __UM_IRQFLAGS_H -extern int signals_enabled; +int um_get_signals(void); int um_set_signals(int enable); void block_signals(void); void unblock_signals(void); @@ -10,7 +10,7 @@ void unblock_signals(void); #define arch_local_save_flags arch_local_save_flags static inline unsigned long arch_local_save_flags(void) { - return signals_enabled; + return um_get_signals(); } #define arch_local_irq_restore arch_local_irq_restore diff --git a/arch/um/include/asm/kasan.h b/arch/um/include/asm/kasan.h index b54a4e937fd1..81bcdc0f962e 100644 --- a/arch/um/include/asm/kasan.h +++ b/arch/um/include/asm/kasan.h @@ -24,10 +24,6 @@ #ifdef CONFIG_KASAN void kasan_init(void); - -#if defined(CONFIG_STATIC_LINK) && defined(CONFIG_KASAN_INLINE) -#error UML does not work in KASAN_INLINE mode with STATIC_LINK enabled! -#endif #else static inline void kasan_init(void) { } #endif /* CONFIG_KASAN */ diff --git a/arch/um/include/asm/mmu.h b/arch/um/include/asm/mmu.h index 4d0e4239f3cc..07d48738b402 100644 --- a/arch/um/include/asm/mmu.h +++ b/arch/um/include/asm/mmu.h @@ -7,16 +7,26 @@ #define __ARCH_UM_MMU_H #include "linux/types.h" +#include <linux/mutex.h> +#include <linux/spinlock.h> #include <mm_id.h> typedef struct mm_context { struct mm_id id; + struct mutex turnstile; struct list_head list; /* Address range in need of a TLB sync */ + spinlock_t sync_tlb_lock; unsigned long sync_tlb_range_from; unsigned long sync_tlb_range_to; } mm_context_t; +#define INIT_MM_CONTEXT(mm) \ + .context = { \ + .turnstile = __MUTEX_INITIALIZER(mm.context.turnstile), \ + .sync_tlb_lock = __SPIN_LOCK_INITIALIZER(mm.context.sync_tlb_lock), \ + } + #endif diff --git a/arch/um/include/asm/page.h b/arch/um/include/asm/page.h index 6f54254aaf44..2d363460d896 100644 --- a/arch/um/include/asm/page.h +++ b/arch/um/include/asm/page.h @@ -96,8 +96,4 @@ extern unsigned long uml_physmem; #endif /* __ASSEMBLER__ */ -#ifdef CONFIG_X86_32 -#define __HAVE_ARCH_GATE_AREA 1 -#endif - #endif /* __UM_PAGE_H */ diff --git a/arch/um/include/asm/pgtable.h b/arch/um/include/asm/pgtable.h index 24fdea6f88c3..3b42b0f45bf6 100644 --- a/arch/um/include/asm/pgtable.h +++ b/arch/um/include/asm/pgtable.h @@ -45,10 +45,12 @@ extern unsigned long *empty_zero_page; * area for the same reason. ;) */ -extern unsigned long end_iomem; +#ifndef COMPILE_OFFSETS +#include <as-layout.h> /* for high_physmem */ +#endif #define VMALLOC_OFFSET (__va_space) -#define VMALLOC_START ((end_iomem + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) +#define VMALLOC_START ((high_physmem + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) #define VMALLOC_END (TASK_SIZE-2*PAGE_SIZE) #define MODULES_VADDR VMALLOC_START #define MODULES_END VMALLOC_END @@ -225,6 +227,8 @@ static inline void set_pte(pte_t *pteptr, pte_t pteval) static inline void um_tlb_mark_sync(struct mm_struct *mm, unsigned long start, unsigned long end) { + guard(spinlock_irqsave)(&mm->context.sync_tlb_lock); + if (!mm->context.sync_tlb_range_to) { mm->context.sync_tlb_range_from = start; mm->context.sync_tlb_range_to = end; diff --git a/arch/um/include/asm/smp.h b/arch/um/include/asm/smp.h index a8cc1d46ddcb..be1743a6ff3c 100644 --- a/arch/um/include/asm/smp.h +++ b/arch/um/include/asm/smp.h @@ -2,6 +2,19 @@ #ifndef __UM_SMP_H #define __UM_SMP_H -#define hard_smp_processor_id() 0 +#if IS_ENABLED(CONFIG_SMP) + +#include <linux/cpumask.h> +#include <shared/smp.h> + +#define raw_smp_processor_id() uml_curr_cpu() + +void arch_smp_send_reschedule(int cpu); + +void arch_send_call_function_single_ipi(int cpu); + +void arch_send_call_function_ipi_mask(const struct cpumask *mask); + +#endif /* CONFIG_SMP */ #endif diff --git a/arch/um/include/asm/uaccess.h b/arch/um/include/asm/uaccess.h index 1c6e0ae41b0c..0df9ea4abda8 100644 --- a/arch/um/include/asm/uaccess.h +++ b/arch/um/include/asm/uaccess.h @@ -15,11 +15,6 @@ (((unsigned long) (addr) < TASK_SIZE) && \ (((unsigned long) (addr) + (size)) < TASK_SIZE)) -#define __access_ok_vsyscall(addr, size) \ - (((unsigned long) (addr) >= FIXADDR_USER_START) && \ - ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \ - ((unsigned long) (addr) + (size) >= (unsigned long)(addr))) - #define __addr_range_nowrap(addr, size) \ ((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) @@ -40,9 +35,7 @@ static inline int __access_ok(const void __user *ptr, unsigned long size); static inline int __access_ok(const void __user *ptr, unsigned long size) { unsigned long addr = (unsigned long)ptr; - return __addr_range_nowrap(addr, size) && - (__under_task_size(addr, size) || - __access_ok_vsyscall(addr, size)); + return __addr_range_nowrap(addr, size) && __under_task_size(addr, size); } #define __get_kernel_nofault(dst, src, type, err_label) \ diff --git a/arch/um/include/linux/smp-internal.h b/arch/um/include/linux/smp-internal.h new file mode 100644 index 000000000000..1dbcbc23f9c9 --- /dev/null +++ b/arch/um/include/linux/smp-internal.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __UM_SMP_INTERNAL_H +#define __UM_SMP_INTERNAL_H + +#if IS_ENABLED(CONFIG_SMP) + +void prefill_possible_map(void); + +#else /* !CONFIG_SMP */ + +static inline void prefill_possible_map(void) { } + +#endif /* CONFIG_SMP */ + +extern char cpu_irqstacks[NR_CPUS][THREAD_SIZE] __aligned(THREAD_SIZE); + +#endif /* __UM_SMP_INTERNAL_H */ diff --git a/arch/um/include/linux/time-internal.h b/arch/um/include/linux/time-internal.h index 138908b999d7..c274eb5ad55e 100644 --- a/arch/um/include/linux/time-internal.h +++ b/arch/um/include/linux/time-internal.h @@ -90,4 +90,7 @@ extern unsigned long tt_extra_sched_jiffies; * which is intentional since we really shouldn't link it in that case. */ void time_travel_ndelay(unsigned long nsec); + +int um_setup_timer(void); + #endif /* __TIMER_INTERNAL_H__ */ diff --git a/arch/um/include/shared/as-layout.h b/arch/um/include/shared/as-layout.h index 7c7e17bce403..02ef258e3395 100644 --- a/arch/um/include/shared/as-layout.h +++ b/arch/um/include/shared/as-layout.h @@ -44,7 +44,6 @@ extern unsigned long start_vm; extern unsigned long brk_start; -extern unsigned long host_task_size; extern unsigned long stub_start; extern int linux_main(int argc, char **argv, char **envp); diff --git a/arch/um/include/shared/common-offsets.h b/arch/um/include/shared/common-offsets.h deleted file mode 100644 index 8ca66a1918c3..000000000000 --- a/arch/um/include/shared/common-offsets.h +++ /dev/null @@ -1,20 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* for use by sys-$SUBARCH/kernel-offsets.c */ - -DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE); - -DEFINE(UM_KERN_PAGE_SIZE, PAGE_SIZE); -DEFINE(UM_KERN_PAGE_MASK, PAGE_MASK); -DEFINE(UM_KERN_PAGE_SHIFT, PAGE_SHIFT); - -DEFINE(UM_GFP_KERNEL, GFP_KERNEL); -DEFINE(UM_GFP_ATOMIC, GFP_ATOMIC); - -DEFINE(UM_THREAD_SIZE, THREAD_SIZE); - -DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC); -DEFINE(UM_NSEC_PER_USEC, NSEC_PER_USEC); - -DEFINE(UM_KERN_GDT_ENTRY_TLS_ENTRIES, GDT_ENTRY_TLS_ENTRIES); - -DEFINE(UM_SECCOMP_ARCH_NATIVE, SECCOMP_ARCH_NATIVE); diff --git a/arch/um/include/shared/kern_util.h b/arch/um/include/shared/kern_util.h index 00ca3e12fd9a..38321188c04c 100644 --- a/arch/um/include/shared/kern_util.h +++ b/arch/um/include/shared/kern_util.h @@ -15,9 +15,6 @@ extern int uml_exitcode; extern int kmalloc_ok; -#define UML_ROUND_UP(addr) \ - ((((unsigned long) addr) + PAGE_SIZE - 1) & PAGE_MASK) - extern unsigned long alloc_stack(int order, int atomic); extern void free_stack(unsigned long stack, int order); @@ -42,7 +39,6 @@ extern void uml_pm_wake(void); extern int start_uml(void); extern void paging_init(void); -extern int parse_iomem(char *str, int *add); extern void uml_cleanup(void); extern void do_uml_exitcalls(void); @@ -55,6 +51,7 @@ extern int __uml_cant_sleep(void); extern int get_current_pid(void); extern int copy_from_user_proc(void *to, void *from, int size); extern char *uml_strdup(const char *string); +int uml_need_resched(void); extern unsigned long to_irq_stack(unsigned long *mask_out); extern unsigned long from_irq_stack(int nested); diff --git a/arch/um/include/shared/longjmp.h b/arch/um/include/shared/longjmp.h index 8863319039f3..c53e43d980c8 100644 --- a/arch/um/include/shared/longjmp.h +++ b/arch/um/include/shared/longjmp.h @@ -5,7 +5,6 @@ #include <sysdep/archsetjmp.h> #include <os.h> -extern int signals_enabled; extern int setjmp(jmp_buf); extern void longjmp(jmp_buf, int); @@ -15,7 +14,7 @@ extern void longjmp(jmp_buf, int); #define UML_SETJMP(buf) ({ \ int n, enable; \ - enable = *(volatile int *)&signals_enabled; \ + enable = um_get_signals(); \ n = setjmp(*buf); \ if(n != 0) \ um_set_signals_trace(enable); \ diff --git a/arch/um/include/shared/mem_user.h b/arch/um/include/shared/mem_user.h index d4727efcf23d..8a5b72872ff8 100644 --- a/arch/um/include/shared/mem_user.h +++ b/arch/um/include/shared/mem_user.h @@ -32,21 +32,8 @@ #ifndef _MEM_USER_H #define _MEM_USER_H -struct iomem_region { - struct iomem_region *next; - char *driver; - int fd; - int size; - unsigned long phys; - unsigned long virt; -}; - -extern struct iomem_region *iomem_regions; -extern int iomem_size; - #define ROUND_4M(n) ((((unsigned long) (n)) + (1 << 22)) & ~((1 << 22) - 1)) -extern unsigned long find_iomem(char *driver, unsigned long *len_out); extern void setup_physmem(unsigned long start, unsigned long usable, unsigned long len); extern void map_memory(unsigned long virt, unsigned long phys, diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h index b35cc8ce333b..b26e94292fc1 100644 --- a/arch/um/include/shared/os.h +++ b/arch/um/include/shared/os.h @@ -216,6 +216,9 @@ extern int can_drop_memory(void); void os_set_pdeathsig(void); +int os_futex_wait(void *uaddr, unsigned int val); +int os_futex_wake(void *uaddr); + /* execvp.c */ extern int execvp_noalloc(char *buf, const char *file, char *const argv[]); /* helper.c */ @@ -243,6 +246,7 @@ extern void send_sigio_to_self(void); extern int change_sig(int signal, int on); extern void block_signals(void); extern void unblock_signals(void); +extern int um_get_signals(void); extern int um_set_signals(int enable); extern int um_set_signals_trace(int enable); extern void deliver_alarm(void); @@ -266,11 +270,12 @@ extern void os_warn(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); /* time.c */ +void os_idle_prepare(void); extern void os_idle_sleep(void); extern int os_timer_create(void); -extern int os_timer_set_interval(unsigned long long nsecs); -extern int os_timer_one_shot(unsigned long long nsecs); -extern void os_timer_disable(void); +extern int os_timer_set_interval(int cpu, unsigned long long nsecs); +extern int os_timer_one_shot(int cpu, unsigned long long nsecs); +extern void os_timer_disable(int cpu); extern long long os_persistent_clock_emulation(void); extern long long os_nsecs(void); @@ -338,4 +343,17 @@ extern void um_trace_signals_off(void); /* time-travel */ extern void deliver_time_travel_irqs(void); +/* smp.c */ +#if IS_ENABLED(CONFIG_SMP) +void os_init_smp(void); +int os_start_cpu_thread(int cpu); +void os_start_secondary(void *arg, jmp_buf *switch_buf); +int os_send_ipi(int cpu, int vector); +void os_local_ipi_enable(void); +void os_local_ipi_disable(void); +#else /* !CONFIG_SMP */ +static inline void os_local_ipi_enable(void) { } +static inline void os_local_ipi_disable(void) { } +#endif /* CONFIG_SMP */ + #endif diff --git a/arch/um/include/shared/skas/mm_id.h b/arch/um/include/shared/skas/mm_id.h index 4f977ef5dda5..fb96c0bd8222 100644 --- a/arch/um/include/shared/skas/mm_id.h +++ b/arch/um/include/shared/skas/mm_id.h @@ -6,6 +6,8 @@ #ifndef __MM_ID_H #define __MM_ID_H +#include <linux/compiler_types.h> + #define STUB_MAX_FDS 4 struct mm_id { @@ -19,6 +21,9 @@ struct mm_id { int syscall_fd_map[STUB_MAX_FDS]; }; +void enter_turnstile(struct mm_id *mm_id) __acquires(turnstile); +void exit_turnstile(struct mm_id *mm_id) __releases(turnstile); + void notify_mm_kill(int pid); #endif diff --git a/arch/um/include/shared/skas/skas.h b/arch/um/include/shared/skas/skas.h index 807514e10538..2237ffedec75 100644 --- a/arch/um/include/shared/skas/skas.h +++ b/arch/um/include/shared/skas/skas.h @@ -15,5 +15,7 @@ extern void handle_syscall(struct uml_pt_regs *regs); extern unsigned long current_stub_stack(void); extern struct mm_id *current_mm_id(void); extern void current_mm_sync(void); +void initial_jmpbuf_lock(void); +void initial_jmpbuf_unlock(void); #endif diff --git a/arch/um/include/shared/smp.h b/arch/um/include/shared/smp.h new file mode 100644 index 000000000000..06e3faa95091 --- /dev/null +++ b/arch/um/include/shared/smp.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __UM_SHARED_SMP_H +#define __UM_SHARED_SMP_H + +#if IS_ENABLED(CONFIG_SMP) + +extern int uml_ncpus; + +int uml_curr_cpu(void); +void uml_start_secondary(void *opaque); +void uml_ipi_handler(int vector); + +#else /* !CONFIG_SMP */ + +#define uml_ncpus 1 +#define uml_curr_cpu() 0 + +#endif /* CONFIG_SMP */ + +#endif /* __UM_SHARED_SMP_H */ |
