Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
+30
View File
@@ -0,0 +1,30 @@
# SPDX-License-Identifier: GPL-2.0
generic-y += bug.h
generic-y += compat.h
generic-y += device.h
generic-y += dma-mapping.h
generic-y += emergency-restart.h
generic-y += exec.h
generic-y += ftrace.h
generic-y += hw_irq.h
generic-y += irq_regs.h
generic-y += irq_work.h
generic-y += kdebug.h
generic-y += mcs_spinlock.h
generic-y += mmiowb.h
generic-y += module.h
generic-y += module.lds.h
generic-y += parport.h
generic-y += percpu.h
generic-y += percpu_types.h
generic-y += preempt.h
generic-y += ring_buffer.h
generic-y += runtime-const.h
generic-y += softirq_stack.h
generic-y += switch_to.h
generic-y += topology.h
generic-y += trace_clock.h
generic-y += kprobes.h
generic-y += mm_hooks.h
generic-y += vga.h
generic-y += video.h
@@ -0,0 +1,25 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_UM_ARCHRANDOM_H__
#define __ASM_UM_ARCHRANDOM_H__
#include <linux/types.h>
/* This is from <os.h>, but better not to #include that in a global header here. */
ssize_t os_getrandom(void *buf, size_t len, unsigned int flags);
static inline size_t __must_check arch_get_random_longs(unsigned long *v, size_t max_longs)
{
ssize_t ret;
ret = os_getrandom(v, max_longs * sizeof(*v), 0);
if (ret < 0)
return 0;
return ret / sizeof(*v);
}
static inline size_t __must_check arch_get_random_seed_longs(unsigned long *v, size_t max_longs)
{
return 0;
}
#endif
@@ -0,0 +1,6 @@
#include <asm-generic/asm-prototypes.h>
#include <asm/checksum.h>
#ifdef CONFIG_UML_X86
extern void cmpxchg8b_emu(void);
#endif
@@ -0,0 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* asm-generic/bpf_perf_event.h is part of the uapi headers, but since
* arch/um has no uapi of its on, we can't use the "generic-y"
* Kbuild rule to generate the wrapper
*/
#include <asm-generic/bpf_perf_event.h>
+18
View File
@@ -0,0 +1,18 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __UM_CACHE_H
#define __UM_CACHE_H
#if defined(CONFIG_UML_X86) && !defined(CONFIG_64BIT)
# define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT)
#elif defined(CONFIG_UML_X86) /* 64-bit */
# define L1_CACHE_SHIFT 6 /* Should be 7 on Intel */
#else
/* XXX: this was taken from x86, now it's completely random. Luckily only
* affects SMP padding. */
# define L1_CACHE_SHIFT 5
#endif
#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
#endif
@@ -0,0 +1,9 @@
#ifndef __UM_ASM_CACHEFLUSH_H
#define __UM_ASM_CACHEFLUSH_H
#include <asm/tlbflush.h>
#define flush_cache_vmap flush_tlb_kernel_range
#define flush_cache_vunmap flush_tlb_kernel_range
#include <asm-generic/cacheflush.h>
#endif /* __UM_ASM_CACHEFLUSH_H */
@@ -0,0 +1,101 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include <asm-generic/vmlinux.lds.h>
.fini : { *(.fini) } =0x9090
_etext = .;
PROVIDE (etext = .);
. = ALIGN(4096);
_sdata = .;
PROVIDE (sdata = .);
RO_DATA(4096)
.unprotected : { *(.unprotected) }
. = ALIGN(4096);
PROVIDE (_unprotected_end = .);
. = ALIGN(4096);
EXCEPTION_TABLE(0)
BUG_TABLE
.uml.setup.init : {
__uml_setup_start = .;
*(.uml.setup.init)
__uml_setup_end = .;
}
.uml.help.init : {
__uml_help_start = .;
*(.uml.help.init)
__uml_help_end = .;
}
.uml.postsetup.init : {
__uml_postsetup_start = .;
*(.uml.postsetup.init)
__uml_postsetup_end = .;
}
.init.setup : {
INIT_SETUP(0)
}
PERCPU_SECTION(32)
.initcall.init : {
INIT_CALLS
}
.con_initcall.init : {
CON_INITCALL
}
.exitcall : {
__exitcall_begin = .;
*(.exitcall.exit)
__exitcall_end = .;
}
.uml.exitcall : {
__uml_exitcall_begin = .;
*(.uml.exitcall.exit)
__uml_exitcall_end = .;
}
. = ALIGN(4);
.altinstructions : {
__alt_instructions = .;
*(.altinstructions)
__alt_instructions_end = .;
}
.altinstr_replacement : { *(.altinstr_replacement) }
/* .exit.text is discard at runtime, not link time, to deal with references
from .altinstructions and .eh_frame */
.exit.text : { EXIT_TEXT }
.exit.data : { *(.exit.data) }
.preinit_array : {
__preinit_array_start = .;
*(.preinit_array)
__preinit_array_end = .;
}
.init_array : {
__init_array_start = .;
*(.kasan_init)
*(.init_array.*)
*(.init_array)
__init_array_end = .;
}
.fini_array : {
__fini_array_start = .;
*(.fini_array)
__fini_array_end = .;
}
. = ALIGN(4096);
.init.ramfs : {
INIT_RAM_FS
}
@@ -0,0 +1,141 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_UM_CPUFEATURE_H
#define _ASM_UM_CPUFEATURE_H
#include <asm/processor.h>
#if defined(__KERNEL__) && !defined(__ASSEMBLER__)
#include <asm/asm.h>
#include <linux/bitops.h>
extern const char * const x86_cap_flags[NCAPINTS*32];
extern const char * const x86_power_flags[32];
#define X86_CAP_FMT "%s"
#define x86_cap_flag(flag) x86_cap_flags[flag]
/*
* In order to save room, we index into this array by doing
* X86_BUG_<name> - NCAPINTS*32.
*/
extern const char * const x86_bug_flags[NBUGINTS*32];
#define test_cpu_cap(c, bit) \
test_bit(bit, (unsigned long *)((c)->x86_capability))
/*
* There are 32 bits/features in each mask word. The high bits
* (selected with (bit>>5) give us the word number and the low 5
* bits give us the bit/feature number inside the word.
* (1UL<<((bit)&31) gives us a mask for the feature_bit so we can
* see if it is set in the mask word.
*/
#define CHECK_BIT_IN_MASK_WORD(maskname, word, bit) \
(((bit)>>5)==(word) && (1UL<<((bit)&31) & maskname##word ))
#define cpu_has(c, bit) \
test_cpu_cap(c, bit)
#define this_cpu_has(bit) \
(__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \
x86_this_cpu_test_bit(bit, cpu_info.x86_capability))
/*
* This macro is for detection of features which need kernel
* infrastructure to be used. It may *not* directly test the CPU
* itself. Use the cpu_has() family if you want true runtime
* testing of CPU features, like in hypervisor code where you are
* supporting a possible guest feature where host support for it
* is not relevant.
*/
#define cpu_feature_enabled(bit) \
(__builtin_constant_p(bit) && DISABLED_MASK_BIT_SET(bit) ? 0 : static_cpu_has(bit))
#define boot_cpu_has(bit) cpu_has(&boot_cpu_data, bit)
#define set_cpu_cap(c, bit) set_bit(bit, (unsigned long *)((c)->x86_capability))
extern void setup_clear_cpu_cap(unsigned int bit);
#define setup_force_cpu_cap(bit) do { \
set_cpu_cap(&boot_cpu_data, bit); \
set_bit(bit, (unsigned long *)cpu_caps_set); \
} while (0)
#define setup_force_cpu_bug(bit) setup_force_cpu_cap(bit)
/*
* Static testing of CPU features. Used the same as boot_cpu_has(). It
* statically patches the target code for additional performance. Use
* static_cpu_has() only in fast paths, where every cycle counts. Which
* means that the boot_cpu_has() variant is already fast enough for the
* majority of cases and you should stick to using it as it is generally
* only two instructions: a RIP-relative MOV and a TEST.
*/
static __always_inline bool _static_cpu_has(u16 bit)
{
asm goto("1: jmp 6f\n"
"2:\n"
".skip -(((5f-4f) - (2b-1b)) > 0) * "
"((5f-4f) - (2b-1b)),0x90\n"
"3:\n"
".section .altinstructions,\"a\"\n"
" .long 1b - .\n" /* src offset */
" .long 4f - .\n" /* repl offset */
" .word %P[always]\n" /* always replace */
" .byte 3b - 1b\n" /* src len */
" .byte 5f - 4f\n" /* repl len */
" .byte 3b - 2b\n" /* pad len */
".previous\n"
".section .altinstr_replacement,\"ax\"\n"
"4: jmp %l[t_no]\n"
"5:\n"
".previous\n"
".section .altinstructions,\"a\"\n"
" .long 1b - .\n" /* src offset */
" .long 0\n" /* no replacement */
" .word %P[feature]\n" /* feature bit */
" .byte 3b - 1b\n" /* src len */
" .byte 0\n" /* repl len */
" .byte 0\n" /* pad len */
".previous\n"
".section .altinstr_aux,\"ax\"\n"
"6:\n"
" testb %[bitnum],%[cap_byte]\n"
" jnz %l[t_yes]\n"
" jmp %l[t_no]\n"
".previous\n"
: : [feature] "i" (bit),
[always] "i" (X86_FEATURE_ALWAYS),
[bitnum] "i" (1 << (bit & 7)),
[cap_byte] "m" (((const char *)boot_cpu_data.x86_capability)[bit >> 3])
: : t_yes, t_no);
t_yes:
return true;
t_no:
return false;
}
#define static_cpu_has(bit) \
( \
__builtin_constant_p(boot_cpu_has(bit)) ? \
boot_cpu_has(bit) : \
_static_cpu_has(bit) \
)
#define cpu_has_bug(c, bit) cpu_has(c, (bit))
#define set_cpu_bug(c, bit) set_cpu_cap(c, (bit))
#define static_cpu_has_bug(bit) static_cpu_has((bit))
#define boot_cpu_has_bug(bit) cpu_has_bug(&boot_cpu_data, (bit))
#define boot_cpu_set_bug(bit) set_cpu_cap(&boot_cpu_data, (bit))
#define MAX_CPU_FEATURES (NCAPINTS * 32)
#define cpu_have_feature boot_cpu_has
#define CPU_FEATURE_TYPEFMT "x86,ven%04Xfam%04Xmod%04X"
#define CPU_FEATURE_TYPEVAL boot_cpu_data.x86_vendor, boot_cpu_data.x86, \
boot_cpu_data.x86_model
#endif /* defined(__KERNEL__) && !defined(__ASSEMBLER__) */
#endif /* _ASM_UM_CPUFEATURE_H */
+24
View File
@@ -0,0 +1,24 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_CURRENT_H
#define __ASM_CURRENT_H
#include <linux/compiler.h>
#include <linux/threads.h>
#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[uml_curr_cpu()];
}
#define current get_current()
#endif /* __ASSEMBLER__ */
#endif /* __ASM_CURRENT_H */
+30
View File
@@ -0,0 +1,30 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __UM_DELAY_H
#define __UM_DELAY_H
#include <asm-generic/delay.h>
#include <linux/time-internal.h>
static inline void um_ndelay(unsigned long nsecs)
{
if (time_travel_mode == TT_MODE_INFCPU ||
time_travel_mode == TT_MODE_EXTERNAL) {
time_travel_ndelay(nsecs);
return;
}
ndelay(nsecs);
}
#undef ndelay
#define ndelay(n) um_ndelay(n)
static inline void um_udelay(unsigned long usecs)
{
if (time_travel_mode == TT_MODE_INFCPU ||
time_travel_mode == TT_MODE_EXTERNAL) {
time_travel_ndelay(1000 * usecs);
return;
}
udelay(usecs);
}
#undef udelay
#define udelay(n) um_udelay(n)
#endif /* __UM_DELAY_H */
+11
View File
@@ -0,0 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __UM_DMA_H
#define __UM_DMA_H
#include <asm/io.h>
extern unsigned long uml_physmem;
#define MAX_DMA_ADDRESS (uml_physmem)
#endif
+22
View File
@@ -0,0 +1,22 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef _ASM_UM_FPU_API_H
#define _ASM_UM_FPU_API_H
#include <linux/types.h>
/* Copyright (c) 2020 Cambridge Greys Ltd
* Copyright (c) 2020 Red Hat Inc.
* A set of "dummy" defines to allow the direct inclusion
* of x86 optimized copy, xor, etc routines into the
* UML code tree. */
#define kernel_fpu_begin() (void)0
#define kernel_fpu_end() (void)0
static inline bool irq_fpu_usable(void)
{
return true;
}
#endif
+14
View File
@@ -0,0 +1,14 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_UM_FUTEX_H
#define _ASM_UM_FUTEX_H
#include <linux/futex.h>
#include <linux/uaccess.h>
#include <asm/errno.h>
int arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval, u32 __user *uaddr);
int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
u32 oldval, u32 newval);
#endif
+31
View File
@@ -0,0 +1,31 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_UM_HARDIRQ_H
#define __ASM_UM_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 */
+26
View File
@@ -0,0 +1,26 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_UM_IO_H
#define _ASM_UM_IO_H
#include <linux/types.h>
/* get emulated iomem (if desired) */
#include <asm-generic/logic_io.h>
#ifndef ioremap
#define ioremap ioremap
static inline void __iomem *ioremap(phys_addr_t offset, size_t size)
{
return NULL;
}
#endif /* ioremap */
#ifndef iounmap
#define iounmap iounmap
static inline void iounmap(void __iomem *addr)
{
}
#endif /* iounmap */
#include <asm-generic/io.h>
#endif
+40
View File
@@ -0,0 +1,40 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __UM_IRQ_H
#define __UM_IRQ_H
#define TIMER_IRQ 0
#define UMN_IRQ 1
#define UBD_IRQ 2
#define UM_ETH_IRQ 3
#define ACCEPT_IRQ 4
#define MCONSOLE_IRQ 5
#define WINCH_IRQ 6
#define SIGIO_WRITE_IRQ 7
#define TELNETD_IRQ 8
#define XTERM_IRQ 9
#define RANDOM_IRQ 10
#define SIGCHLD_IRQ 11
#ifdef CONFIG_UML_NET_VECTOR
#define VECTOR_BASE_IRQ (SIGCHLD_IRQ + 1)
#define VECTOR_IRQ_SPACE 8
#define UM_FIRST_DYN_IRQ (VECTOR_IRQ_SPACE + VECTOR_BASE_IRQ)
#else
#define UM_FIRST_DYN_IRQ (SIGCHLD_IRQ + 1)
#endif
#define UM_LAST_SIGNAL_IRQ 64
/* If we have (simulated) PCI MSI, allow 64 more interrupt numbers for it */
#ifdef CONFIG_PCI_MSI
#define NR_IRQS (UM_LAST_SIGNAL_IRQ + 64)
#else
#define NR_IRQS UM_LAST_SIGNAL_IRQ
#endif /* CONFIG_PCI_MSI */
#include <asm-generic/irq.h>
#endif
@@ -0,0 +1,38 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __UM_IRQFLAGS_H
#define __UM_IRQFLAGS_H
int um_get_signals(void);
int um_set_signals(int enable);
void block_signals(void);
void unblock_signals(void);
#define arch_local_save_flags arch_local_save_flags
static inline unsigned long arch_local_save_flags(void)
{
return um_get_signals();
}
#define arch_local_irq_restore arch_local_irq_restore
static inline void arch_local_irq_restore(unsigned long flags)
{
um_set_signals(flags);
}
#define arch_local_irq_enable arch_local_irq_enable
static inline void arch_local_irq_enable(void)
{
unblock_signals();
}
#define arch_local_irq_disable arch_local_irq_disable
static inline void arch_local_irq_disable(void)
{
block_signals();
}
#define ARCH_IRQ_DISABLED 0
#include <asm-generic/irqflags.h>
#endif
+31
View File
@@ -0,0 +1,31 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_UM_KASAN_H
#define __ASM_UM_KASAN_H
#include <linux/init.h>
#include <linux/const.h>
#define KASAN_SHADOW_OFFSET _AC(CONFIG_KASAN_SHADOW_OFFSET, UL)
/* used in kasan_mem_to_shadow to divide by 8 */
#define KASAN_SHADOW_SCALE_SHIFT 3
#ifdef CONFIG_X86_64
#define KASAN_HOST_USER_SPACE_END_ADDR 0x00007fffffffffffUL
/* KASAN_SHADOW_SIZE is the size of total address space divided by 8 */
#define KASAN_SHADOW_SIZE ((KASAN_HOST_USER_SPACE_END_ADDR + 1) >> \
KASAN_SHADOW_SCALE_SHIFT)
#else
#error "KASAN_SHADOW_SIZE is not defined for this sub-architecture"
#endif /* CONFIG_X86_64 */
#define KASAN_SHADOW_START (KASAN_SHADOW_OFFSET)
#define KASAN_SHADOW_END (KASAN_SHADOW_START + KASAN_SHADOW_SIZE)
#ifdef CONFIG_KASAN
void kasan_init(void);
#else
static inline void kasan_init(void) { }
#endif /* CONFIG_KASAN */
#endif /* __ASM_UM_KASAN_H */
@@ -0,0 +1 @@
#include <asm-generic/kvm_para.h>
+32
View File
@@ -0,0 +1,32 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
*/
#ifndef __ARCH_UM_MMU_H
#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
@@ -0,0 +1,29 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
*/
#ifndef __UM_MMU_CONTEXT_H
#define __UM_MMU_CONTEXT_H
#include <linux/sched.h>
#include <linux/mm_types.h>
#include <linux/mmap_lock.h>
#include <asm/mm_hooks.h>
#include <asm/mmu.h>
static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
struct task_struct *tsk)
{
}
#define init_new_context init_new_context
extern int init_new_context(struct task_struct *task, struct mm_struct *mm);
#define destroy_context destroy_context
extern void destroy_context(struct mm_struct *mm);
#include <asm-generic/mmu_context.h>
#endif
+1
View File
@@ -0,0 +1 @@
#include <asm-generic/msi.h>
+98
View File
@@ -0,0 +1,98 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
* Copyright 2003 PathScale, Inc.
*/
#ifndef __UM_PAGE_H
#define __UM_PAGE_H
#include <linux/const.h>
#include <vdso/page.h>
#ifndef __ASSEMBLER__
struct page;
#include <linux/pfn.h>
#include <linux/types.h>
#include <asm/vm-flags.h>
/*
* These are used to make use of C type-checking..
*/
#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
#define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE)
#define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
typedef struct { unsigned long pte; } pte_t;
typedef struct { unsigned long pgd; } pgd_t;
#if CONFIG_PGTABLE_LEVELS > 2
typedef struct { unsigned long pmd; } pmd_t;
#define pmd_val(x) ((x).pmd)
#define __pmd(x) ((pmd_t) { (x) } )
#if CONFIG_PGTABLE_LEVELS > 3
typedef struct { unsigned long pud; } pud_t;
#define pud_val(x) ((x).pud)
#define __pud(x) ((pud_t) { (x) } )
#endif /* CONFIG_PGTABLE_LEVELS > 3 */
#endif /* CONFIG_PGTABLE_LEVELS > 2 */
#define pte_val(x) ((x).pte)
#define pte_get_bits(p, bits) ((p).pte & (bits))
#define pte_set_bits(p, bits) ((p).pte |= (bits))
#define pte_clear_bits(p, bits) ((p).pte &= ~(bits))
#define pte_copy(to, from) ((to).pte = (from).pte)
#define pte_is_zero(p) (!((p).pte & ~_PAGE_NEEDSYNC))
#define pte_set_val(p, phys, prot) (p).pte = (phys | pgprot_val(prot))
typedef unsigned long phys_t;
typedef struct { unsigned long pgprot; } pgprot_t;
typedef struct page *pgtable_t;
#define pgd_val(x) ((x).pgd)
#define pgprot_val(x) ((x).pgprot)
#define __pte(x) ((pte_t) { (x) } )
#define __pgd(x) ((pgd_t) { (x) } )
#define __pgprot(x) ((pgprot_t) { (x) } )
extern unsigned long uml_physmem;
#define PAGE_OFFSET (uml_physmem)
#define KERNELBASE PAGE_OFFSET
#define __va_space (8*1024*1024)
#include <mem.h>
/* Cast to unsigned long before casting to void * to avoid a warning from
* mmap_kmem about cutting a long long down to a void *. Not sure that
* casting is the right thing, but 32-bit UML can't have 64-bit virtual
* addresses
*/
#define __pa(virt) uml_to_phys((void *) (unsigned long) (virt))
#define __va(phys) uml_to_virt((unsigned long) (phys))
#define phys_to_pfn(p) ((p) >> PAGE_SHIFT)
#define pfn_to_phys(pfn) PFN_PHYS(pfn)
#define virt_addr_valid(v) pfn_valid(phys_to_pfn(__pa(v)))
#include <asm-generic/memory_model.h>
#include <asm-generic/getorder.h>
#endif /* __ASSEMBLER__ */
#endif /* __UM_PAGE_H */
+19
View File
@@ -0,0 +1,19 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef __ASM_UM_PCI_H
#define __ASM_UM_PCI_H
#include <linux/types.h>
#include <asm/io.h>
/* Generic PCI */
#include <asm-generic/pci.h>
#ifdef CONFIG_PCI_MSI
/*
* This is a bit of an annoying hack, and it assumes we only have
* the virt-pci (if anything). Which is true, but still.
*/
void *pci_root_bus_fwnode(struct pci_bus *bus);
#define pci_root_bus_fwnode pci_root_bus_fwnode
#endif
#endif /* __ASM_UM_PCI_H */
+45
View File
@@ -0,0 +1,45 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
* Copyright 2003 PathScale, Inc.
* Derived from include/asm-i386/pgalloc.h and include/asm-i386/pgtable.h
*/
#ifndef __UM_PGALLOC_H
#define __UM_PGALLOC_H
#include <linux/mm.h>
#include <asm-generic/pgalloc.h>
#define pmd_populate_kernel(mm, pmd, pte) \
set_pmd(pmd, __pmd(_PAGE_TABLE + (unsigned long) __pa(pte)))
#define pmd_populate(mm, pmd, pte) \
set_pmd(pmd, __pmd(_PAGE_TABLE + \
((unsigned long long)page_to_pfn(pte) << \
(unsigned long long) PAGE_SHIFT)))
/*
* Allocate and free page tables.
*/
extern pgd_t *pgd_alloc(struct mm_struct *);
#define __pte_free_tlb(tlb, pte, address) \
tlb_remove_ptdesc((tlb), page_ptdesc(pte))
#if CONFIG_PGTABLE_LEVELS > 2
#define __pmd_free_tlb(tlb, pmd, address) \
tlb_remove_ptdesc((tlb), virt_to_ptdesc(pmd))
#if CONFIG_PGTABLE_LEVELS > 3
#define __pud_free_tlb(tlb, pud, address) \
tlb_remove_ptdesc((tlb), virt_to_ptdesc(pud))
#endif
#endif
#endif
@@ -0,0 +1,42 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
* Copyright 2003 PathScale, Inc.
* Derived from include/asm-i386/pgtable.h
*/
#ifndef __UM_PGTABLE_2LEVEL_H
#define __UM_PGTABLE_2LEVEL_H
#include <asm-generic/pgtable-nopmd.h>
/* PGDIR_SHIFT determines what a third-level page table entry can map */
#define PGDIR_SHIFT 22
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
#define PGDIR_MASK (~(PGDIR_SIZE-1))
/*
* entries per page directory level: the i386 is two-level, so
* we don't really have any PMD directory physically.
*/
#define PTRS_PER_PTE 1024
#define USER_PTRS_PER_PGD ((TASK_SIZE + (PGDIR_SIZE - 1)) / PGDIR_SIZE)
#define PTRS_PER_PGD 1024
#define pte_ERROR(e) \
printk("%s:%d: bad pte %p(%08lx).\n", __FILE__, __LINE__, &(e), \
pte_val(e))
#define pgd_ERROR(e) \
printk("%s:%d: bad pgd %p(%08lx).\n", __FILE__, __LINE__, &(e), \
pgd_val(e))
static inline int pgd_needsync(pgd_t pgd) { return 0; }
static inline void pgd_mkuptodate(pgd_t pgd) { }
#define set_pmd(pmdptr, pmdval) (*(pmdptr) = (pmdval))
#define pte_pfn(x) phys_to_pfn(pte_val(x))
#define pfn_pmd(pfn, prot) __pmd(pfn_to_phys(pfn) | pgprot_val(prot))
#endif
@@ -0,0 +1,110 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright 2003 PathScale Inc
* Derived from include/asm-i386/pgtable.h
*/
#ifndef __UM_PGTABLE_4LEVEL_H
#define __UM_PGTABLE_4LEVEL_H
#include <asm-generic/pgtable-nop4d.h>
/* PGDIR_SHIFT determines what a fourth-level page table entry can map */
#define PGDIR_SHIFT 39
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
#define PGDIR_MASK (~(PGDIR_SIZE-1))
/* PUD_SHIFT determines the size of the area a third-level page table can
* map
*/
#define PUD_SHIFT 30
#define PUD_SIZE (1UL << PUD_SHIFT)
#define PUD_MASK (~(PUD_SIZE-1))
/* PMD_SHIFT determines the size of the area a second-level page table can
* map
*/
#define PMD_SHIFT 21
#define PMD_SIZE (1UL << PMD_SHIFT)
#define PMD_MASK (~(PMD_SIZE-1))
/*
* entries per page directory level
*/
#define PTRS_PER_PTE 512
#define PTRS_PER_PMD 512
#define PTRS_PER_PUD 512
#define PTRS_PER_PGD 512
#define USER_PTRS_PER_PGD ((TASK_SIZE + (PGDIR_SIZE - 1)) / PGDIR_SIZE)
#define pte_ERROR(e) \
printk("%s:%d: bad pte %p(%016lx).\n", __FILE__, __LINE__, &(e), \
pte_val(e))
#define pmd_ERROR(e) \
printk("%s:%d: bad pmd %p(%016lx).\n", __FILE__, __LINE__, &(e), \
pmd_val(e))
#define pud_ERROR(e) \
printk("%s:%d: bad pud %p(%016lx).\n", __FILE__, __LINE__, &(e), \
pud_val(e))
#define pgd_ERROR(e) \
printk("%s:%d: bad pgd %p(%016lx).\n", __FILE__, __LINE__, &(e), \
pgd_val(e))
#define pud_none(x) (!(pud_val(x) & ~_PAGE_NEEDSYNC))
#define pud_bad(x) ((pud_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
#define pud_present(x) (pud_val(x) & _PAGE_PRESENT)
#define pud_populate(mm, pud, pmd) \
set_pud(pud, __pud(_PAGE_TABLE + __pa(pmd)))
#define set_pud(pudptr, pudval) (*(pudptr) = (pudval))
#define p4d_none(x) (!(p4d_val(x) & ~_PAGE_NEEDSYNC))
#define p4d_bad(x) ((p4d_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
#define p4d_present(x) (p4d_val(x) & _PAGE_PRESENT)
#define p4d_populate(mm, p4d, pud) \
set_p4d(p4d, __p4d(_PAGE_TABLE + __pa(pud)))
#define set_p4d(p4dptr, p4dval) (*(p4dptr) = (p4dval))
static inline int pgd_needsync(pgd_t pgd)
{
return pgd_val(pgd) & _PAGE_NEEDSYNC;
}
static inline void pgd_mkuptodate(pgd_t pgd) { pgd_val(pgd) &= ~_PAGE_NEEDSYNC; }
#define set_pmd(pmdptr, pmdval) (*(pmdptr) = (pmdval))
static inline void pud_clear (pud_t *pud)
{
set_pud(pud, __pud(_PAGE_NEEDSYNC));
}
static inline void p4d_clear (p4d_t *p4d)
{
set_p4d(p4d, __p4d(_PAGE_NEEDSYNC));
}
#define pud_page(pud) phys_to_page(pud_val(pud) & PAGE_MASK)
#define pud_pgtable(pud) ((pmd_t *) __va(pud_val(pud) & PAGE_MASK))
#define p4d_page(p4d) phys_to_page(p4d_val(p4d) & PAGE_MASK)
#define p4d_pgtable(p4d) ((pud_t *) __va(p4d_val(p4d) & PAGE_MASK))
static inline unsigned long pte_pfn(pte_t pte)
{
return phys_to_pfn(pte_val(pte));
}
static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot)
{
return __pmd((page_nr << PAGE_SHIFT) | pgprot_val(pgprot));
}
#endif
+328
View File
@@ -0,0 +1,328 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Copyright 2003 PathScale, Inc.
* Derived from include/asm-i386/pgtable.h
*/
#ifndef __UM_PGTABLE_H
#define __UM_PGTABLE_H
#include <asm/page.h>
#include <linux/mm_types.h>
#define _PAGE_PRESENT 0x001
#define _PAGE_NEEDSYNC 0x002
#define _PAGE_RW 0x020
#define _PAGE_USER 0x040
#define _PAGE_ACCESSED 0x080
#define _PAGE_DIRTY 0x100
/* If _PAGE_PRESENT is clear, we use these: */
#define _PAGE_PROTNONE 0x010 /* if the user mapped it with PROT_NONE;
pte_present gives true */
/* We borrow bit 10 to store the exclusive marker in swap PTEs. */
#define _PAGE_SWP_EXCLUSIVE 0x400
#if CONFIG_PGTABLE_LEVELS == 4
#include <asm/pgtable-4level.h>
#elif CONFIG_PGTABLE_LEVELS == 2
#include <asm/pgtable-2level.h>
#else
#error "Unsupported number of page table levels"
#endif
extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
/* Just any arbitrary offset to the start of the vmalloc VM area: the
* current 8MB value just means that there will be a 8MB "hole" after the
* physical memory until the kernel virtual memory starts. That means that
* any out-of-bounds memory accesses will hopefully be caught.
* The vmalloc() routines leaves a hole of 4kB between each vmalloced
* area for the same reason. ;)
*/
#ifndef COMPILE_OFFSETS
#include <as-layout.h> /* for high_physmem */
#endif
#define VMALLOC_OFFSET (__va_space)
#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
#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
#define __PAGE_KERNEL_EXEC \
(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
#define PAGE_KERNEL_EXEC __pgprot(__PAGE_KERNEL_EXEC)
/*
* The i386 can't do page protection for execute, and considers that the same
* are read.
* Also, write permissions imply read permissions. This is the closest we can
* get..
*/
#define pte_clear(mm, addr, xp) pte_set_val(*(xp), (phys_t) 0, __pgprot(_PAGE_NEEDSYNC))
#define pmd_none(x) (!((unsigned long)pmd_val(x) & ~_PAGE_NEEDSYNC))
#define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT)
#define pmd_clear(xp) do { pmd_val(*(xp)) = _PAGE_NEEDSYNC; } while (0)
#define pmd_needsync(x) (pmd_val(x) & _PAGE_NEEDSYNC)
#define pmd_mkuptodate(x) (pmd_val(x) &= ~_PAGE_NEEDSYNC)
#define pud_needsync(x) (pud_val(x) & _PAGE_NEEDSYNC)
#define pud_mkuptodate(x) (pud_val(x) &= ~_PAGE_NEEDSYNC)
#define p4d_needsync(x) (p4d_val(x) & _PAGE_NEEDSYNC)
#define p4d_mkuptodate(x) (p4d_val(x) &= ~_PAGE_NEEDSYNC)
#define pmd_pfn(pmd) (pmd_val(pmd) >> PAGE_SHIFT)
#define pmd_page(pmd) phys_to_page(pmd_val(pmd) & PAGE_MASK)
#define pte_page(x) pfn_to_page(pte_pfn(x))
#define pte_present(x) pte_get_bits(x, (_PAGE_PRESENT | _PAGE_PROTNONE))
/*
* =================================
* Flags checking section.
* =================================
*/
static inline int pte_none(pte_t pte)
{
return pte_is_zero(pte);
}
/*
* The following only work if pte_present() is true.
* Undefined behaviour if not..
*/
static inline int pte_read(pte_t pte)
{
return !pte_get_bits(pte, _PAGE_PROTNONE);
}
static inline int pte_exec(pte_t pte)
{
return !pte_get_bits(pte, _PAGE_PROTNONE);
}
static inline int pte_write(pte_t pte)
{
return((pte_get_bits(pte, _PAGE_RW)) &&
!(pte_get_bits(pte, _PAGE_PROTNONE)));
}
static inline int pte_dirty(pte_t pte)
{
return pte_get_bits(pte, _PAGE_DIRTY);
}
static inline int pte_young(pte_t pte)
{
return pte_get_bits(pte, _PAGE_ACCESSED);
}
static inline int pte_needsync(pte_t pte)
{
return pte_get_bits(pte, _PAGE_NEEDSYNC);
}
/*
* =================================
* Flags setting section.
* =================================
*/
static inline pte_t pte_mkclean(pte_t pte)
{
pte_clear_bits(pte, _PAGE_DIRTY);
return(pte);
}
static inline pte_t pte_mkold(pte_t pte)
{
pte_clear_bits(pte, _PAGE_ACCESSED);
return(pte);
}
static inline pte_t pte_wrprotect(pte_t pte)
{
pte_clear_bits(pte, _PAGE_RW);
return pte;
}
static inline pte_t pte_mkread(pte_t pte)
{
pte_set_bits(pte, _PAGE_USER);
return pte;
}
static inline pte_t pte_mkdirty(pte_t pte)
{
pte_set_bits(pte, _PAGE_DIRTY);
return(pte);
}
static inline pte_t pte_mkyoung(pte_t pte)
{
pte_set_bits(pte, _PAGE_ACCESSED);
return(pte);
}
static inline pte_t pte_mkwrite_novma(pte_t pte)
{
pte_set_bits(pte, _PAGE_RW);
return pte;
}
static inline pte_t pte_mkuptodate(pte_t pte)
{
pte_clear_bits(pte, _PAGE_NEEDSYNC);
return pte;
}
static inline pte_t pte_mkneedsync(pte_t pte)
{
pte_set_bits(pte, _PAGE_NEEDSYNC);
return(pte);
}
static inline void set_pte(pte_t *pteptr, pte_t pteval)
{
pte_copy(*pteptr, pteval);
/* If it's a swap entry, it needs to be marked _PAGE_NEEDSYNC so
* update_pte_range knows to unmap it.
*/
*pteptr = pte_mkneedsync(*pteptr);
}
#define PFN_PTE_SHIFT PAGE_SHIFT
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;
} else {
if (start < mm->context.sync_tlb_range_from)
mm->context.sync_tlb_range_from = start;
if (end > mm->context.sync_tlb_range_to)
mm->context.sync_tlb_range_to = end;
}
}
#define set_ptes set_ptes
static inline void set_ptes(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pte, int nr)
{
/* Basically the default implementation */
size_t length = nr * PAGE_SIZE;
for (;;) {
set_pte(ptep, pte);
if (--nr == 0)
break;
ptep++;
pte = __pte(pte_val(pte) + (nr << PFN_PTE_SHIFT));
}
um_tlb_mark_sync(mm, addr, addr + length);
}
#define __HAVE_ARCH_PTE_SAME
static inline int pte_same(pte_t pte_a, pte_t pte_b)
{
return !((pte_val(pte_a) ^ pte_val(pte_b)) & ~_PAGE_NEEDSYNC);
}
#define __virt_to_page(virt) phys_to_page(__pa(virt))
#define virt_to_page(addr) __virt_to_page((const unsigned long) addr)
static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot)
{
pte_t pte;
pte_set_val(pte, pfn_to_phys(pfn), pgprot);
return pte;
}
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{
pte_set_val(pte, (pte_val(pte) & _PAGE_CHG_MASK), newprot);
return pte;
}
/*
* the pmd page can be thought of an array like this: pmd_t[PTRS_PER_PMD]
*
* this macro returns the index of the entry in the pmd page which would
* control the given virtual address
*/
#define pmd_page_vaddr(pmd) ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
struct mm_struct;
extern pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr);
#define update_mmu_cache(vma,address,ptep) do {} while (0)
#define update_mmu_cache_range(vmf, vma, address, ptep, nr) do {} while (0)
/*
* Encode/decode swap entries and swap PTEs. Swap PTEs are all PTEs that
* are !pte_none() && !pte_present().
*
* Format of swap PTEs:
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* <--------------- offset ----------------> E < type -> 0 0 0 1 0
*
* E is the exclusive marker that is not stored in swap entries.
* _PAGE_NEEDSYNC (bit 1) is always set to 1 in set_pte().
*/
#define __swp_type(x) (((x).val >> 5) & 0x1f)
#define __swp_offset(x) ((x).val >> 11)
#define __swp_entry(type, offset) \
((swp_entry_t) { (((type) & 0x1f) << 5) | ((offset) << 11) })
#define __pte_to_swp_entry(pte) \
((swp_entry_t) { pte_val(pte_mkuptodate(pte)) })
#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
static inline bool pte_swp_exclusive(pte_t pte)
{
return pte_get_bits(pte, _PAGE_SWP_EXCLUSIVE);
}
static inline pte_t pte_swp_mkexclusive(pte_t pte)
{
pte_set_bits(pte, _PAGE_SWP_EXCLUSIVE);
return pte;
}
static inline pte_t pte_swp_clear_exclusive(pte_t pte)
{
pte_clear_bits(pte, _PAGE_SWP_EXCLUSIVE);
return pte;
}
#endif
@@ -0,0 +1,88 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
*/
#ifndef __UM_PROCESSOR_GENERIC_H
#define __UM_PROCESSOR_GENERIC_H
struct pt_regs;
struct task_struct;
#include <asm/ptrace.h>
#include <sysdep/archsetjmp.h>
#include <linux/prefetch.h>
#include <asm/cpufeatures.h>
struct mm_struct;
struct thread_struct {
struct pt_regs *segv_regs;
struct task_struct *prev_sched;
struct arch_thread arch;
jmp_buf switch_buf;
struct {
struct {
int (*proc)(void *);
void *arg;
} thread;
} request;
void *segv_continue;
/* Contains variable sized FP registers */
struct pt_regs regs;
};
#define INIT_THREAD \
{ \
.regs = EMPTY_REGS, \
.prev_sched = NULL, \
.arch = INIT_ARCH_THREAD, \
.request = { } \
}
/*
* User space process size: 3GB (default).
*/
extern unsigned long task_size;
#define TASK_SIZE (task_size)
#undef STACK_TOP
#undef STACK_TOP_MAX
extern unsigned long stacksizelim;
#define STACK_ROOM (stacksizelim)
#define STACK_TOP (TASK_SIZE - 2 * PAGE_SIZE)
#define STACK_TOP_MAX STACK_TOP
/* This decides where the kernel will search for a free chunk of vm
* space during mmap's.
*/
#define TASK_UNMAPPED_BASE (0x40000000)
extern void start_thread(struct pt_regs *regs, unsigned long entry,
unsigned long stack);
struct cpuinfo_um {
unsigned long loops_per_jiffy;
int cache_alignment;
union {
__u32 x86_capability[NCAPINTS + NBUGINTS];
unsigned long x86_capability_alignment;
};
};
extern struct cpuinfo_um boot_cpu_data;
#define cache_line_size() (boot_cpu_data.cache_alignment)
#define KSTK_REG(tsk, reg) get_thread_reg(reg, &tsk->thread.switch_buf)
extern unsigned long __get_wchan(struct task_struct *p);
#endif
@@ -0,0 +1,49 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
*/
#ifndef __UM_PTRACE_GENERIC_H
#define __UM_PTRACE_GENERIC_H
#ifndef __ASSEMBLER__
#include <sysdep/ptrace.h>
struct pt_regs {
struct uml_pt_regs regs;
};
#define arch_has_single_step() (1)
#define EMPTY_REGS { .regs = EMPTY_UML_PT_REGS }
#define PT_REGS_IP(r) UPT_IP(&(r)->regs)
#define PT_REGS_SP(r) UPT_SP(&(r)->regs)
#define PT_REGS_RESTART_SYSCALL(r) UPT_RESTART_SYSCALL(&(r)->regs)
#define PT_REGS_SYSCALL_NR(r) UPT_SYSCALL_NR(&(r)->regs)
#define instruction_pointer(regs) PT_REGS_IP(regs)
#define PTRACE_OLDSETOPTIONS 21
struct task_struct;
extern long subarch_ptrace(struct task_struct *child, long request,
unsigned long addr, unsigned long data);
extern unsigned long getreg(struct task_struct *child, int regno);
extern int putreg(struct task_struct *child, int regno, unsigned long value);
extern int poke_user(struct task_struct *child, long addr, long data);
extern int peek_user(struct task_struct *child, long addr, long data);
extern int arch_set_tls(struct task_struct *new, unsigned long tls);
extern void clear_flushed_tls(struct task_struct *task);
extern int syscall_trace_enter(struct pt_regs *regs);
extern void syscall_trace_leave(struct pt_regs *regs);
#endif
#endif
@@ -0,0 +1,10 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __UM_SECTIONS_H
#define __UM_SECTIONS_H
#include <asm-generic/sections.h>
extern char __binary_start[];
extern char __syscall_stub_start[], __syscall_stub_end[];
#endif
+11
View File
@@ -0,0 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef SETUP_H_INCLUDED
#define SETUP_H_INCLUDED
/* POSIX mandated with _POSIX_ARG_MAX that we can rely on 4096 chars in the
* command line, so this choice is ok.
*/
#define COMMAND_LINE_SIZE 4096
#endif /* SETUP_H_INCLUDED */
+20
View File
@@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __UM_SMP_H
#define __UM_SMP_H
#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
@@ -0,0 +1,43 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_UML_STACKTRACE_H
#define _ASM_UML_STACKTRACE_H
#include <linux/uaccess.h>
#include <linux/ptrace.h>
struct stack_frame {
struct stack_frame *next_frame;
unsigned long return_address;
};
struct stacktrace_ops {
void (*address)(void *data, unsigned long address, int reliable);
};
#ifdef CONFIG_FRAME_POINTER
static inline unsigned long
get_frame_pointer(struct task_struct *task, struct pt_regs *segv_regs)
{
if (!task || task == current)
return segv_regs ? PT_REGS_BP(segv_regs) : current_bp();
return KSTK_EBP(task);
}
#else
static inline unsigned long
get_frame_pointer(struct task_struct *task, struct pt_regs *segv_regs)
{
return 0;
}
#endif
static inline unsigned long
*get_stack_pointer(struct task_struct *task, struct pt_regs *segv_regs)
{
if (!task || task == current)
return segv_regs ? (unsigned long *)PT_REGS_SP(segv_regs) : current_sp();
return (unsigned long *)KSTK_ESP(task);
}
void dump_trace(struct task_struct *tsk, const struct stacktrace_ops *ops, void *data);
#endif /* _ASM_UML_STACKTRACE_H */
@@ -0,0 +1,86 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Access to user system call parameters and results
*
* See asm-generic/syscall.h for function descriptions.
*
* Copyright (C) 2015 Mickaël Salaün <mic@digikod.net>
*/
#ifndef __UM_SYSCALL_GENERIC_H
#define __UM_SYSCALL_GENERIC_H
#include <asm/ptrace.h>
#include <linux/err.h>
#include <linux/sched.h>
#include <sysdep/ptrace.h>
static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
{
return PT_REGS_SYSCALL_NR(regs);
}
static inline void syscall_set_nr(struct task_struct *task, struct pt_regs *regs, int nr)
{
PT_REGS_SYSCALL_NR(regs) = nr;
}
static inline void syscall_rollback(struct task_struct *task,
struct pt_regs *regs)
{
/* do nothing */
}
static inline long syscall_get_error(struct task_struct *task,
struct pt_regs *regs)
{
const long error = regs_return_value(regs);
return IS_ERR_VALUE(error) ? error : 0;
}
static inline long syscall_get_return_value(struct task_struct *task,
struct pt_regs *regs)
{
return regs_return_value(regs);
}
static inline void syscall_set_return_value(struct task_struct *task,
struct pt_regs *regs,
int error, long val)
{
PT_REGS_SET_SYSCALL_RETURN(regs, (long) error ?: val);
}
static inline void syscall_get_arguments(struct task_struct *task,
struct pt_regs *regs,
unsigned long *args)
{
const struct uml_pt_regs *r = &regs->regs;
*args++ = UPT_SYSCALL_ARG1(r);
*args++ = UPT_SYSCALL_ARG2(r);
*args++ = UPT_SYSCALL_ARG3(r);
*args++ = UPT_SYSCALL_ARG4(r);
*args++ = UPT_SYSCALL_ARG5(r);
*args = UPT_SYSCALL_ARG6(r);
}
static inline void syscall_set_arguments(struct task_struct *task,
struct pt_regs *regs,
const unsigned long *args)
{
struct uml_pt_regs *r = &regs->regs;
UPT_SYSCALL_ARG1(r) = *args++;
UPT_SYSCALL_ARG2(r) = *args++;
UPT_SYSCALL_ARG3(r) = *args++;
UPT_SYSCALL_ARG4(r) = *args++;
UPT_SYSCALL_ARG5(r) = *args++;
UPT_SYSCALL_ARG6(r) = *args;
}
/* See arch/x86/um/asm/syscall.h for syscall_get_arch() definition. */
#endif /* __UM_SYSCALL_GENERIC_H */
@@ -0,0 +1,62 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
*/
#ifndef __UM_THREAD_INFO_H
#define __UM_THREAD_INFO_H
#define THREAD_SIZE_ORDER CONFIG_KERNEL_STACK_ORDER
#define THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
#ifndef __ASSEMBLER__
#include <asm/types.h>
#include <asm/page.h>
#include <asm/segment.h>
#include <sysdep/ptrace_user.h>
struct thread_info {
unsigned long flags; /* low level flags */
__u32 cpu; /* current CPU */
int preempt_count; /* 0 => preemptable,
<0 => BUG */
};
#define INIT_THREAD_INFO(tsk) \
{ \
.flags = 0, \
.cpu = 0, \
.preempt_count = INIT_PREEMPT_COUNT, \
}
#endif
#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
#define TIF_SIGPENDING 1 /* signal pending */
#define TIF_NEED_RESCHED 2 /* rescheduling necessary */
#define TIF_NOTIFY_SIGNAL 3 /* signal notifications exist */
#define TIF_RESTART_BLOCK 4
#define TIF_MEMDIE 5 /* is terminating due to OOM killer */
#define TIF_SYSCALL_AUDIT 6
#define TIF_RESTORE_SIGMASK 7
#define TIF_NOTIFY_RESUME 8
#define TIF_SECCOMP 9 /* secure computing */
#define TIF_SINGLESTEP 10 /* single stepping userspace */
#define TIF_SYSCALL_TRACEPOINT 11 /* syscall tracepoint instrumentation */
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL)
#define _TIF_MEMDIE (1 << TIF_MEMDIE)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
#define _TIF_SECCOMP (1 << TIF_SECCOMP)
#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
#define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL | \
_TIF_NOTIFY_RESUME)
#endif
+9
View File
@@ -0,0 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __UM_TIMEX_H
#define __UM_TIMEX_H
#define CLOCK_TICK_RATE (HZ)
#include <asm-generic/timex.h>
#endif
+11
View File
@@ -0,0 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __UM_TLB_H
#define __UM_TLB_H
#include <linux/mm.h>
#include <asm/tlbflush.h>
#include <asm/cacheflush.h>
#include <asm-generic/tlb.h>
#endif
@@ -0,0 +1,59 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
*/
#ifndef __UM_TLBFLUSH_H
#define __UM_TLBFLUSH_H
#include <linux/mm.h>
/*
* In UML, we need to sync the TLB over by using mmap/munmap syscalls from
* the process handling the MM (which can be the kernel itself).
*
* To track updates, we can hook into set_ptes and flush_tlb_*. With set_ptes
* we catch all PTE transitions where memory that was unusable becomes usable.
* While with flush_tlb_* we can track any memory that becomes unusable and
* even if a higher layer of the page table was modified.
*
* So, we simply track updates using both methods and mark the memory area to
* be synced later on. The only special case is that flush_tlb_kern_* needs to
* be executed immediately as there is no good synchronization point in that
* case. In contrast, in the set_ptes case we can wait for the next kernel
* segfault before we do the synchornization.
*
* - flush_tlb_all() flushes all processes TLBs
* - flush_tlb_mm(mm) flushes the specified mm context TLB's
* - flush_tlb_page(vma, vmaddr) flushes one page
* - flush_tlb_range(vma, start, end) flushes a range of pages
* - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
*/
extern int um_tlb_sync(struct mm_struct *mm);
extern void flush_tlb_all(void);
extern void flush_tlb_mm(struct mm_struct *mm);
static inline void flush_tlb_page(struct vm_area_struct *vma,
unsigned long address)
{
um_tlb_mark_sync(vma->vm_mm, address, address + PAGE_SIZE);
}
static inline void flush_tlb_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end)
{
um_tlb_mark_sync(vma->vm_mm, start, end);
}
static inline void flush_tlb_kernel_range(unsigned long start,
unsigned long end)
{
um_tlb_mark_sync(&init_mm, start, end);
/* Kernel needs to be synced immediately */
um_tlb_sync(&init_mm);
}
#endif
+66
View File
@@ -0,0 +1,66 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
* Copyright (C) 2015 Richard Weinberger (richard@nod.at)
*/
#ifndef __UM_UACCESS_H
#define __UM_UACCESS_H
#include <asm/elf.h>
#include <linux/unaligned.h>
#include <sysdep/faultinfo.h>
#define __under_task_size(addr, size) \
(((unsigned long) (addr) < TASK_SIZE) && \
(((unsigned long) (addr) + (size)) < TASK_SIZE))
#define __addr_range_nowrap(addr, size) \
((unsigned long) (addr) <= ((unsigned long) (addr) + (size)))
extern unsigned long raw_copy_from_user(void *to, const void __user *from, unsigned long n);
extern unsigned long raw_copy_to_user(void __user *to, const void *from, unsigned long n);
extern unsigned long __clear_user(void __user *mem, unsigned long len);
static inline int __access_ok(const void __user *ptr, unsigned long size);
/* Teach asm-generic/uaccess.h that we have C functions for these. */
#define __access_ok __access_ok
#define __clear_user __clear_user
#define INLINE_COPY_USER
#include <asm-generic/uaccess.h>
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);
}
#define __get_kernel_nofault(dst, src, type, err_label) \
do { \
int __faulted; \
\
___backtrack_faulted(__faulted); \
if (__faulted) { \
*((type *)dst) = (type) 0; \
goto err_label; \
} \
*((type *)dst) = get_unaligned((type *)(src)); \
barrier(); \
current->thread.segv_continue = NULL; \
} while (0)
#define __put_kernel_nofault(dst, src, type, err_label) \
do { \
int __faulted; \
\
___backtrack_faulted(__faulted); \
if (__faulted) \
goto err_label; \
put_unaligned(*((type *)src), (type *)(dst)); \
barrier(); \
current->thread.segv_continue = NULL; \
} while (0)
#endif
+8
View File
@@ -0,0 +1,8 @@
#ifndef _ASM_UML_UNWIND_H
#define _ASM_UML_UNWIND_H
static inline void
unwind_module_init(struct module *mod, void *orc_ip, size_t orc_ip_size,
void *orc, size_t orc_size) {}
#endif /* _ASM_UML_UNWIND_H */
@@ -0,0 +1,4 @@
#ifndef _ASM_UM_VMALLOC_H
#define _ASM_UM_VMALLOC_H
#endif /* _ASM_UM_VMALLOC_H */
@@ -0,0 +1,2 @@
#include <asm/thread_info.h>
#include <asm-generic/vmlinux.lds.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 */
@@ -0,0 +1,96 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2012 - 2014 Cisco Systems
* Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
*/
#ifndef __TIMER_INTERNAL_H__
#define __TIMER_INTERNAL_H__
#include <linux/list.h>
#include <asm/bug.h>
#include <shared/timetravel.h>
#define TIMER_MULTIPLIER 256
#define TIMER_MIN_DELTA 500
#ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT
struct time_travel_event {
unsigned long long time;
void (*fn)(struct time_travel_event *d);
struct list_head list;
bool pending, onstack;
};
void time_travel_sleep(void);
static inline void
time_travel_set_event_fn(struct time_travel_event *e,
void (*fn)(struct time_travel_event *d))
{
e->fn = fn;
}
void __time_travel_propagate_time(void);
static inline void time_travel_propagate_time(void)
{
if (time_travel_mode == TT_MODE_EXTERNAL)
__time_travel_propagate_time();
}
void __time_travel_wait_readable(int fd);
static inline void time_travel_wait_readable(int fd)
{
if (time_travel_mode == TT_MODE_EXTERNAL)
__time_travel_wait_readable(fd);
}
void time_travel_add_irq_event(struct time_travel_event *e);
void time_travel_add_event_rel(struct time_travel_event *e,
unsigned long long delay_ns);
bool time_travel_del_event(struct time_travel_event *e);
#else
struct time_travel_event {
};
static inline void time_travel_sleep(void)
{
}
/* this is a macro so the event/function need not exist */
#define time_travel_set_event_fn(e, fn) do {} while (0)
static inline void time_travel_propagate_time(void)
{
}
static inline void time_travel_wait_readable(int fd)
{
}
static inline void time_travel_add_irq_event(struct time_travel_event *e)
{
WARN_ON(1);
}
/*
* not inlines so the data structure need not exist,
* cause linker failures
*/
extern void time_travel_not_configured(void);
#define time_travel_add_event_rel(...) time_travel_not_configured()
#define time_travel_del_event(...) time_travel_not_configured()
#endif /* CONFIG_UML_TIME_TRAVEL_SUPPORT */
extern unsigned long tt_extra_sched_jiffies;
/*
* Without CONFIG_UML_TIME_TRAVEL_SUPPORT this is a linker error if used,
* 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__ */
@@ -0,0 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2021 Intel Corporation
* Author: Johannes Berg <johannes@sipsolutions.net>
*/
#ifndef __VIRTIO_UML_H__
#define __VIRTIO_UML_H__
void virtio_uml_set_no_vq_suspend(struct virtio_device *vdev,
bool no_vq_suspend);
#endif /* __VIRTIO_UML_H__ */
+17
View File
@@ -0,0 +1,17 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
*/
#ifndef __ARCH_H__
#define __ARCH_H__
#include <sysdep/ptrace.h>
extern void arch_check_bugs(void);
extern int arch_fixup(unsigned long address, struct uml_pt_regs *regs);
extern void arch_examine_signal(int sig, struct uml_pt_regs *regs);
void mc_set_rip(void *_mc, void *target);
#endif
@@ -0,0 +1,57 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
*/
#ifndef __START_H__
#define __START_H__
#include <generated/asm-offsets.h>
/*
* Stolen from linux/const.h, which can't be directly included since
* this is used in userspace code, which has no access to the kernel
* headers. Changed to be suitable for adding casts to the start,
* rather than "UL" to the end.
*/
/* Some constant macros are used in both assembler and
* C code. Therefore we cannot annotate them always with
* 'UL' and other type specifiers unilaterally. We
* use the following macros to deal with this.
*/
#define STUB_START stub_start
#define STUB_CODE STUB_START
#define STUB_DATA (STUB_CODE + UM_KERN_PAGE_SIZE)
#define STUB_DATA_PAGES 2
#define STUB_SIZE ((1 + STUB_DATA_PAGES) * UM_KERN_PAGE_SIZE)
#define STUB_END (STUB_START + STUB_SIZE)
#ifndef __ASSEMBLER__
#include <sysdep/ptrace.h>
struct task_struct;
extern struct task_struct *cpu_tasks[];
extern unsigned long long physmem_size;
extern unsigned long high_physmem;
extern unsigned long uml_physmem;
extern unsigned long uml_reserved;
extern unsigned long end_vm;
extern unsigned long start_vm;
extern unsigned long brk_start;
extern unsigned long stub_start;
extern int linux_main(int argc, char **argv, char **envp);
extern void uml_finishsetup(void);
struct siginfo;
extern void (*sig_info[])(int, struct siginfo *si, struct uml_pt_regs *, void *);
#endif
#endif
@@ -0,0 +1,19 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2004 Fujitsu Siemens Computers GmbH
* Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
*/
#ifndef __ELF_USER_H__
#define __ELF_USER_H__
/* For compilation on a host that doesn't support AT_SYSINFO (Linux 2.4) */
#ifndef AT_SYSINFO
#define AT_SYSINFO 32
#endif
#ifndef AT_SYSINFO_EHDR
#define AT_SYSINFO_EHDR 33
#endif
#endif
@@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
*/
#ifndef __FRAME_KERN_H_
#define __FRAME_KERN_H_
extern int setup_signal_stack_sc(unsigned long stack_top, struct ksignal *ksig,
struct pt_regs *regs, sigset_t *mask);
extern int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig,
struct pt_regs *regs, sigset_t *mask);
#endif
+127
View File
@@ -0,0 +1,127 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_UML_INIT_H
#define _LINUX_UML_INIT_H
/* These macros are used to mark some functions or
* initialized data (doesn't apply to uninitialized data)
* as `initialization' functions. The kernel can take this
* as hint that the function is used only during the initialization
* phase and free up used memory resources after
*
* Usage:
* For functions:
*
* You should add __init immediately before the function name, like:
*
* static void __init initme(int x, int y)
* {
* extern int z; z = x * y;
* }
*
* If the function has a prototype somewhere, you can also add
* __init between closing brace of the prototype and semicolon:
*
* extern int initialize_foobar_device(int, int, int) __init;
*
* For initialized data:
* You should insert __initdata between the variable name and equal
* sign followed by value, e.g.:
*
* static int init_variable __initdata = 0;
* static const char linux_logo[] __initconst = { 0x32, 0x36, ... };
*
* Don't forget to initialize data not at file scope, i.e. within a function,
* as gcc otherwise puts the data into the bss section and not into the init
* section.
*
* Also note, that this data cannot be "const".
*/
#ifndef _LINUX_INIT_H
typedef int (*initcall_t)(void);
typedef void (*exitcall_t)(void);
#include <linux/compiler_types.h>
/* These are for everybody (although not all archs will actually
discard it in modules) */
#define __init __section(".init.text")
#define __initdata __section(".init.data")
#define __exitdata __section(".exit.data")
#define __exit_call __used __section(".exitcall.exit")
#ifdef MODULE
#define __exit __section(".exit.text")
#else
#define __exit __used __section(".exit.text")
#endif
#endif
#ifndef MODULE
struct uml_param {
const char *str;
int (*setup_func)(char *, int *);
};
extern initcall_t __uml_postsetup_start, __uml_postsetup_end;
extern const char *__uml_help_start, *__uml_help_end;
#endif
#define __uml_exitcall(fn) \
static exitcall_t __uml_exitcall_##fn __uml_exit_call = fn
extern struct uml_param __uml_setup_start, __uml_setup_end;
#define __uml_postsetup(fn) \
static initcall_t __uml_postsetup_##fn __uml_postsetup_call = fn
#define __non_empty_string(dummyname,string) \
struct __uml_non_empty_string_struct_##dummyname \
{ \
char _string[sizeof(string)-2]; \
}
#ifndef MODULE
#define __uml_setup(str, fn, help...) \
__non_empty_string(fn ##_setup, str); \
__uml_help(fn, help); \
static char __uml_setup_str_##fn[] __initdata = str; \
static struct uml_param __uml_setup_##fn __uml_init_setup = { __uml_setup_str_##fn, fn }
#else
#define __uml_setup(str, fn, help...) \
#endif
#define __uml_help(fn, help...) \
__non_empty_string(fn ##__help, help); \
static char __uml_help_str_##fn[] __initdata = help; \
static const char *__uml_help_##fn __uml_setup_help = __uml_help_str_##fn
/*
* Mark functions and data as being only used at initialization
* or exit time.
*/
#define __uml_init_setup __used __section(".uml.setup.init")
#define __uml_setup_help __used __section(".uml.help.init")
#define __uml_postsetup_call __used __section(".uml.postsetup.init")
#define __uml_exit_call __used __section(".uml.exitcall.exit")
#ifdef __UM_HOST__
#define __define_initcall(level,fn) \
static initcall_t __initcall_##fn __used \
__attribute__((__section__(".initcall" level ".init"))) = fn
/* Userspace initcalls shouldn't depend on anything in the kernel, so we'll
* make them run first.
*/
#define __initcall(fn) __define_initcall("1", fn)
#define __exitcall(fn) static exitcall_t __exitcall_##fn __exit_call = fn
#define __init_call __used __section(".initcall.init")
#endif
#endif /* _LINUX_UML_INIT_H */
@@ -0,0 +1,80 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
*/
#ifndef __IRQ_KERN_H__
#define __IRQ_KERN_H__
#include <linux/interrupt.h>
#include <linux/time-internal.h>
#include <asm/ptrace.h>
#include "irq_user.h"
#define UM_IRQ_ALLOC -1
int um_request_irq(int irq, int fd, enum um_irq_type type,
irq_handler_t handler, unsigned long irqflags,
const char *devname, void *dev_id);
#ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT
/**
* um_request_irq_tt - request an IRQ with timetravel handler
*
* @irq: the IRQ number, or %UM_IRQ_ALLOC
* @fd: The file descriptor to request an IRQ for
* @type: read or write
* @handler: the (generic style) IRQ handler
* @irqflags: Linux IRQ flags
* @devname: name for this to show
* @dev_id: data pointer to pass to the IRQ handler
* @timetravel_handler: the timetravel interrupt handler, invoked with the IRQ
* number, fd, dev_id and time-travel event pointer.
*
* Returns: The interrupt number assigned or a negative error.
*
* Note that the timetravel handler is invoked only if the time_travel_mode is
* %TT_MODE_EXTERNAL, and then it is invoked even while the system is suspended!
* This function must call time_travel_add_irq_event() for the event passed with
* an appropriate delay, before sending an ACK on the socket it was invoked for.
*
* If this was called while the system is suspended, then adding the event will
* cause the system to resume.
*
* Since this function will almost certainly have to handle the FD's condition,
* a read will consume the message, and after that it is up to the code using
* it to pass such a message to the @handler in whichever way it can.
*
* If time_travel_mode is not %TT_MODE_EXTERNAL the @timetravel_handler will
* not be invoked at all and the @handler must handle the FD becoming
* readable (or writable) instead. Use um_irq_timetravel_handler_used() to
* distinguish these cases.
*
* See virtio_uml.c for an example.
*/
int um_request_irq_tt(int irq, int fd, enum um_irq_type type,
irq_handler_t handler, unsigned long irqflags,
const char *devname, void *dev_id,
void (*timetravel_handler)(int, int, void *,
struct time_travel_event *));
#else
static inline
int um_request_irq_tt(int irq, int fd, enum um_irq_type type,
irq_handler_t handler, unsigned long irqflags,
const char *devname, void *dev_id,
void (*timetravel_handler)(int, int, void *,
struct time_travel_event *))
{
return um_request_irq(irq, fd, type, handler, irqflags,
devname, dev_id);
}
#endif
static inline bool um_irq_timetravel_handler_used(void)
{
return time_travel_mode == TT_MODE_EXTERNAL;
}
void um_free_irq(int irq, void *dev_id);
void free_irqs(void);
#endif
@@ -0,0 +1,27 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
*/
#ifndef __IRQ_USER_H__
#define __IRQ_USER_H__
#include <sysdep/ptrace.h>
enum um_irq_type {
IRQ_READ,
IRQ_WRITE,
NUM_IRQ_TYPES,
};
struct siginfo;
extern void sigio_handler(int sig, struct siginfo *unused_si,
struct uml_pt_regs *regs, void *mc);
extern void sigchld_handler(int sig, struct siginfo *unused_si,
struct uml_pt_regs *regs, void *mc);
void sigio_run_timetravel_handlers(void);
extern void free_irq_by_fd(int fd);
extern void deactivate_fd(int fd, int irqnum);
extern int deactivate_all_fds(void);
#endif
+22
View File
@@ -0,0 +1,22 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
*/
#ifndef __KERN_H__
#define __KERN_H__
/* These are all user-mode things which are convenient to call directly
* from kernel code and for which writing a wrapper is too much of a pain.
* The regular include files can't be included because this file is included
* only into kernel code, and user-space includes conflict with kernel
* includes.
*/
extern int printf(const char *fmt, ...);
extern void *sbrk(int increment);
extern int pause(void);
extern void exit(int);
#endif
@@ -0,0 +1,70 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
*/
#ifndef __KERN_UTIL_H__
#define __KERN_UTIL_H__
#include <sysdep/ptrace.h>
#include <sysdep/faultinfo.h>
struct siginfo;
extern int uml_exitcode;
extern int kmalloc_ok;
extern unsigned long alloc_stack(int order, int atomic);
extern void free_stack(unsigned long stack, int order);
struct pt_regs;
extern void do_signal(struct pt_regs *regs);
extern void interrupt_end(void);
extern void relay_signal(int sig, struct siginfo *si, struct uml_pt_regs *regs,
void *mc);
extern unsigned long segv(struct faultinfo fi, unsigned long ip,
int is_user, struct uml_pt_regs *regs,
void *mc);
extern int handle_page_fault(unsigned long address, unsigned long ip,
int is_write, int is_user, int *code_out);
extern unsigned int do_IRQ(int irq, struct uml_pt_regs *regs);
extern void initial_thread_cb(void (*proc)(void *), void *arg);
extern void timer_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs);
extern void uml_pm_wake(void);
extern int start_uml(void);
extern void uml_cleanup(void);
extern void do_uml_exitcalls(void);
/*
* Are we disallowed to sleep? Used to choose between GFP_KERNEL and
* GFP_ATOMIC.
*/
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);
extern int singlestepping(void);
extern void segv_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs,
void *mc);
extern void winch(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs,
void *mc);
extern void fatal_sigsegv(void) __attribute__ ((noreturn));
void um_idle_sleep(void);
void kasan_map_memory(void *start, size_t len);
#endif
@@ -0,0 +1,23 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __UML_LONGJMP_H
#define __UML_LONGJMP_H
#include <sysdep/archsetjmp.h>
#include <os.h>
extern int setjmp(jmp_buf);
extern void longjmp(jmp_buf, int);
#define UML_LONGJMP(buf, val) do { \
longjmp(*buf, val); \
} while(0)
#define UML_SETJMP(buf) ({ \
int n, enable; \
enable = um_get_signals(); \
n = setjmp(*buf); \
if(n != 0) \
um_set_signals_trace(enable); \
n; })
#endif
+22
View File
@@ -0,0 +1,22 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
*/
#ifndef __MEM_H__
#define __MEM_H__
extern int phys_mapping(unsigned long phys, unsigned long long *offset_out);
extern unsigned long uml_physmem;
static inline unsigned long uml_to_phys(void *virt)
{
return(((unsigned long) virt) - uml_physmem);
}
static inline void *uml_to_virt(unsigned long phys)
{
return((void *) uml_physmem + phys);
}
#endif
@@ -0,0 +1,42 @@
/*
* arch/um/include/mem_user.h
*
* BRIEF MODULE DESCRIPTION
* user side memory interface for support IO memory inside user mode linux
*
* Copyright (C) 2001 RidgeRun, Inc.
* Author: RidgeRun, Inc.
* Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _MEM_USER_H
#define _MEM_USER_H
#define ROUND_4M(n) ((((unsigned long) (n)) + (1 << 22)) & ~((1 << 22) - 1))
extern void setup_physmem(unsigned long start, unsigned long usable,
unsigned long len);
extern void map_memory(unsigned long virt, unsigned long phys,
unsigned long len, int r, int w, int x);
#endif
+359
View File
@@ -0,0 +1,359 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2015 Anton Ivanov (aivanov@{brocade.com,kot-begemot.co.uk})
* Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de)
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
*/
#ifndef __OS_H__
#define __OS_H__
#include <irq_user.h>
#include <longjmp.h>
#include <mm_id.h>
/* This is to get size_t */
#ifndef __UM_HOST__
#include <linux/types.h>
#else
#include <sys/types.h>
#endif
#define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR))
#define OS_TYPE_FILE 1
#define OS_TYPE_DIR 2
#define OS_TYPE_SYMLINK 3
#define OS_TYPE_CHARDEV 4
#define OS_TYPE_BLOCKDEV 5
#define OS_TYPE_FIFO 6
#define OS_TYPE_SOCK 7
/* os_access() flags */
#define OS_ACC_F_OK 0 /* Test for existence. */
#define OS_ACC_X_OK 1 /* Test for execute permission. */
#define OS_ACC_W_OK 2 /* Test for write permission. */
#define OS_ACC_R_OK 4 /* Test for read permission. */
#define OS_ACC_RW_OK (OS_ACC_W_OK | OS_ACC_R_OK) /* Test for RW permission */
#ifdef CONFIG_64BIT
#define OS_LIB_PATH "/usr/lib64/"
#else
#define OS_LIB_PATH "/usr/lib/"
#endif
#define OS_SENDMSG_MAX_FDS 8
/*
* types taken from stat_file() in hostfs_user.c
* (if they are wrong here, they are wrong there...).
*/
struct uml_stat {
int ust_dev; /* device */
unsigned long long ust_ino; /* inode */
int ust_mode; /* protection */
int ust_nlink; /* number of hard links */
int ust_uid; /* user ID of owner */
int ust_gid; /* group ID of owner */
unsigned long long ust_size; /* total size, in bytes */
int ust_blksize; /* blocksize for filesystem I/O */
unsigned long long ust_blocks; /* number of blocks allocated */
unsigned long ust_atime; /* time of last access */
unsigned long ust_mtime; /* time of last modification */
unsigned long ust_ctime; /* time of last change */
};
struct openflags {
unsigned int r : 1;
unsigned int w : 1;
unsigned int s : 1; /* O_SYNC */
unsigned int c : 1; /* O_CREAT */
unsigned int t : 1; /* O_TRUNC */
unsigned int a : 1; /* O_APPEND */
unsigned int e : 1; /* O_EXCL */
unsigned int cl : 1; /* FD_CLOEXEC */
};
#define OPENFLAGS() ((struct openflags) { .r = 0, .w = 0, .s = 0, .c = 0, \
.t = 0, .a = 0, .e = 0, .cl = 0 })
static inline struct openflags of_read(struct openflags flags)
{
flags.r = 1;
return flags;
}
static inline struct openflags of_write(struct openflags flags)
{
flags.w = 1;
return flags;
}
static inline struct openflags of_rdwr(struct openflags flags)
{
return of_read(of_write(flags));
}
static inline struct openflags of_set_rw(struct openflags flags, int r, int w)
{
flags.r = r;
flags.w = w;
return flags;
}
static inline struct openflags of_sync(struct openflags flags)
{
flags.s = 1;
return flags;
}
static inline struct openflags of_create(struct openflags flags)
{
flags.c = 1;
return flags;
}
static inline struct openflags of_trunc(struct openflags flags)
{
flags.t = 1;
return flags;
}
static inline struct openflags of_append(struct openflags flags)
{
flags.a = 1;
return flags;
}
static inline struct openflags of_excl(struct openflags flags)
{
flags.e = 1;
return flags;
}
static inline struct openflags of_cloexec(struct openflags flags)
{
flags.cl = 1;
return flags;
}
/* file.c */
extern int os_stat_file(const char *file_name, struct uml_stat *buf);
extern int os_stat_fd(const int fd, struct uml_stat *buf);
extern int os_access(const char *file, int mode);
extern int os_set_exec_close(int fd);
extern int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg);
extern int os_get_ifname(int fd, char *namebuf);
extern int os_mode_fd(int fd, int mode);
extern int os_seek_file(int fd, unsigned long long offset);
extern int os_open_file(const char *file, struct openflags flags, int mode);
extern int os_read_file(int fd, void *buf, int len);
extern int os_write_file(int fd, const void *buf, int count);
extern int os_sync_file(int fd);
extern int os_file_size(const char *file, unsigned long long *size_out);
extern int os_pread_file(int fd, void *buf, int len, unsigned long long offset);
extern int os_pwrite_file(int fd, const void *buf, int count, unsigned long long offset);
extern int os_file_modtime(const char *file, long long *modtime);
extern int os_pipe(int *fd, int stream, int close_on_exec);
extern int os_set_fd_async(int fd);
extern int os_clear_fd_async(int fd);
extern int os_set_fd_block(int fd, int blocking);
extern int os_accept_connection(int fd);
extern int os_create_unix_socket(const char *file, int len, int close_on_exec);
extern int os_shutdown_socket(int fd, int r, int w);
extern int os_dup_file(int fd);
extern void os_close_file(int fd);
ssize_t os_rcv_fd_msg(int fd, int *fds, unsigned int n_fds,
void *data, size_t data_len);
extern int os_connect_socket(const char *name);
extern int os_file_type(char *file);
extern int os_file_mode(const char *file, struct openflags *mode_out);
extern int os_lock_file(int fd, int excl);
extern void os_flush_stdout(void);
extern unsigned os_major(unsigned long long dev);
extern unsigned os_minor(unsigned long long dev);
extern unsigned long long os_makedev(unsigned major, unsigned minor);
extern int os_falloc_punch(int fd, unsigned long long offset, int count);
extern int os_falloc_zeroes(int fd, unsigned long long offset, int count);
extern int os_eventfd(unsigned int initval, int flags);
extern int os_sendmsg_fds(int fd, const void *buf, unsigned int len,
const int *fds, unsigned int fds_num);
int os_poll(unsigned int n, const int *fds);
void *os_mmap_rw_shared(int fd, size_t size);
void *os_mremap_rw_shared(void *old_addr, size_t old_size, size_t new_size);
/* start_up.c */
extern void os_early_checks(void);
extern void os_check_bugs(void);
extern void check_host_supports_tls(int *supports_tls, int *tls_min);
extern void get_host_cpu_features(
void (*flags_helper_func)(char *line),
void (*cache_helper_func)(char *line));
/* mem.c */
extern int create_mem_file(unsigned long long len);
/* tlb.c */
extern void report_enomem(void);
/* process.c */
pid_t os_reap_child(void);
extern void os_alarm_process(int pid);
extern void os_kill_process(int pid, int reap_child);
extern void os_kill_ptraced_process(int pid, int reap_child);
extern int os_getpid(void);
extern void init_new_thread_signals(void);
extern int os_map_memory(void *virt, int fd, unsigned long long off,
unsigned long len, int r, int w, int x);
extern int os_protect_memory(void *addr, unsigned long len,
int r, int w, int x);
extern int os_unmap_memory(void *addr, int len);
extern int os_drop_memory(void *addr, int length);
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 */
extern int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv);
extern int run_helper_thread(int (*proc)(void *), void *arg,
unsigned int flags, unsigned long *stack_out);
extern int helper_wait(int pid);
struct os_helper_thread;
int os_run_helper_thread(struct os_helper_thread **td_out,
void *(*routine)(void *), void *arg);
void os_kill_helper_thread(struct os_helper_thread *td);
void os_fix_helper_thread_signals(void);
/* umid.c */
extern int umid_file_name(char *name, char *buf, int len);
extern int set_umid(char *name);
extern char *get_umid(void);
/* signal.c */
extern void timer_set_signal_handler(void);
extern void set_sigstack(void *sig_stack, int size);
extern void set_handler(int sig);
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);
extern void register_pm_wake_signal(void);
extern void block_signals_hard(void);
extern void unblock_signals_hard(void);
extern void mark_sigio_pending(void);
/* util.c */
extern void stack_protections(unsigned long address);
extern int raw(int fd);
extern void setup_machinename(char *machine_out);
extern void setup_hostinfo(char *buf, int len);
extern ssize_t os_getrandom(void *buf, size_t len, unsigned int flags);
extern void os_dump_core(void) __attribute__ ((noreturn));
extern void um_early_printk(const char *s, unsigned int n);
extern void os_fix_helper_signals(void);
extern void os_info(const char *fmt, ...)
__attribute__ ((format (printf, 1, 2)));
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(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);
/* skas/mem.c */
int syscall_stub_flush(struct mm_id *mm_idp);
struct stub_syscall *syscall_stub_alloc(struct mm_id *mm_idp);
void syscall_stub_dump_error(struct mm_id *mm_idp);
int map(struct mm_id *mm_idp, unsigned long virt,
unsigned long len, int prot, int phys_fd,
unsigned long long offset);
int unmap(struct mm_id *mm_idp, unsigned long addr, unsigned long len);
/* skas/process.c */
extern int is_skas_winch(int pid, int fd, void *data);
extern int start_userspace(struct mm_id *mm_id);
extern void userspace(struct uml_pt_regs *regs);
extern void new_thread(void *stack, jmp_buf *buf, void (*handler)(void));
extern void switch_threads(jmp_buf *me, jmp_buf *you);
extern int start_idle_thread(void *stack, jmp_buf *switch_buf);
extern void initial_thread_cb_skas(void (*proc)(void *),
void *arg);
extern void halt_skas(void);
extern void reboot_skas(void);
/* irq.c */
extern int os_waiting_for_events_epoll(void);
extern void *os_epoll_get_data_pointer(int index);
extern int os_epoll_triggered(int index, int events);
extern int os_event_mask(enum um_irq_type irq_type);
extern int os_setup_epoll(void);
extern int os_add_epoll_fd(int events, int fd, void *data);
extern int os_mod_epoll_fd(int events, int fd, void *data);
extern int os_del_epoll_fd(int fd);
extern void os_set_ioignore(void);
extern void os_close_epoll_fd(void);
extern void um_irqs_suspend(void);
extern void um_irqs_resume(void);
/* sigio.c */
extern int add_sigio_fd(int fd);
extern int ignore_sigio_fd(int fd);
extern void maybe_sigio_broken(int fd);
extern void sigio_broken(void);
/*
* unlocked versions for IRQ controller code.
*
* This is safe because it's used at suspend/resume and nothing
* else is running.
*/
extern int __add_sigio_fd(int fd);
extern int __ignore_sigio_fd(int fd);
/* tty.c */
extern int get_pty(void);
long syscall(long number, ...);
/* irqflags tracing */
extern void block_signals_trace(void);
extern void unblock_signals_trace(void);
extern void um_trace_signals_on(void);
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
@@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
*/
#ifndef __PTRACE_USER_H__
#define __PTRACE_USER_H__
#include <sys/ptrace.h>
#include <sysdep/ptrace_user.h>
extern int ptrace_getregs(long pid, unsigned long *regs_out);
extern int ptrace_setregs(long pid, unsigned long *regs_in);
#endif
@@ -0,0 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2004 PathScale, Inc
*/
#ifndef __REGISTERS_H
#define __REGISTERS_H
#include <sysdep/ptrace.h>
extern int init_pid_registers(int pid);
extern void get_safe_registers(unsigned long *regs, unsigned long *fp_regs);
extern int get_fp_registers(int pid, unsigned long *regs);
extern int put_fp_registers(int pid, unsigned long *regs);
#endif
@@ -0,0 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
*/
#ifndef __SIGIO_H__
#define __SIGIO_H__
extern void sigio_lock(void);
extern void sigio_unlock(void);
#endif
@@ -0,0 +1,30 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2005 Jeff Dike (jdike@karaya.com)
*/
#ifndef __MM_ID_H
#define __MM_ID_H
#include <linux/compiler_types.h>
#define STUB_MAX_FDS 4
struct mm_id {
int pid;
unsigned long stack;
int syscall_data_len;
/* Only used with SECCOMP mode */
int sock;
int syscall_fd_num;
int syscall_fd_map[STUB_MAX_FDS];
};
struct mutex *__get_turnstile(struct mm_id *mm_id);
void enter_turnstile(struct mm_id *mm_id) __acquires(__get_turnstile(mm_id));
void exit_turnstile(struct mm_id *mm_id) __releases(__get_turnstile(mm_id));
void notify_mm_kill(int pid);
#endif
@@ -0,0 +1,21 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
*/
#ifndef __SKAS_H
#define __SKAS_H
#include <sysdep/ptrace.h>
extern int using_seccomp;
extern void new_thread_handler(void);
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
@@ -0,0 +1,76 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de)
* Copyright (C) 2005 Jeff Dike (jdike@karaya.com)
*/
#ifndef __STUB_DATA_H
#define __STUB_DATA_H
#include <linux/compiler_types.h>
#include <as-layout.h>
#include <sysdep/tls.h>
#include <sysdep/stub-data.h>
#include <mm_id.h>
#define FUTEX_IN_CHILD 0
#define FUTEX_IN_KERN 1
struct stub_init_data {
int seccomp;
unsigned long stub_start;
int stub_code_fd;
unsigned long stub_code_offset;
int stub_data_fd;
unsigned long stub_data_offset;
unsigned long signal_handler;
unsigned long signal_restorer;
};
#define STUB_NEXT_SYSCALL(s) \
((struct stub_syscall *) (((unsigned long) s) + (s)->cmd_len))
enum stub_syscall_type {
STUB_SYSCALL_UNSET = 0,
STUB_SYSCALL_MMAP,
STUB_SYSCALL_MUNMAP,
};
struct stub_syscall {
struct {
unsigned long addr;
unsigned long length;
unsigned long offset;
int fd;
int prot;
} mem;
enum stub_syscall_type syscall;
};
struct stub_data {
long err;
int syscall_data_len;
/* 128 leaves enough room for additional fields in the struct */
struct stub_syscall syscall_data[(UM_KERN_PAGE_SIZE - 128) / sizeof(struct stub_syscall)] __aligned(16);
/* data shared with signal handler (only used in seccomp mode) */
short restart_wait;
unsigned int futex;
int signal;
unsigned short si_offset;
unsigned short mctx_offset;
/* seccomp architecture specific state restore */
struct stub_data_arch arch_data;
/* Stack for our signal handlers and for calling into . */
unsigned char sigstack[UM_KERN_PAGE_SIZE] __aligned(UM_KERN_PAGE_SIZE);
};
#endif
+20
View File
@@ -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 */
@@ -0,0 +1,30 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2019-2021 Intel Corporation
*/
#ifndef _UM_TIME_TRAVEL_H_
#define _UM_TIME_TRAVEL_H_
enum time_travel_mode {
TT_MODE_OFF,
TT_MODE_BASIC,
TT_MODE_INFCPU,
TT_MODE_EXTERNAL,
};
#if IS_ENABLED(CONFIG_UML_TIME_TRAVEL_SUPPORT)
extern enum time_travel_mode time_travel_mode;
extern int time_travel_should_print_bc_msg;
#else
#define time_travel_mode TT_MODE_OFF
#define time_travel_should_print_bc_msg 0
#endif /* CONFIG_UML_TIME_TRAVEL_SUPPORT */
void _time_travel_print_bc_msg(void);
static inline void time_travel_print_bc_msg(void)
{
if (time_travel_should_print_bc_msg)
_time_travel_print_bc_msg();
}
#endif /* _UM_TIME_TRAVEL_H_ */
@@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2005 Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
*/
#ifndef __UM_MALLOC_H__
#define __UM_MALLOC_H__
#include <generated/asm-offsets.h>
extern void *uml_kmalloc(int size, int flags);
extern void kfree(const void *ptr);
extern void *vmalloc_noprof(unsigned long size);
#define vmalloc(...) vmalloc_noprof(__VA_ARGS__)
extern void vfree(const void *ptr);
#endif /* __UM_MALLOC_H__ */
+68
View File
@@ -0,0 +1,68 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
*/
#ifndef __USER_H__
#define __USER_H__
#include <generated/asm-offsets.h>
/*
* The usual definition - copied here because the kernel provides its own,
* fancier, type-safe, definition. Using that one would require
* copying too much infrastructure for my taste, so userspace files
* get less checking than kernel files.
*/
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
/* This is to get size_t and NULL */
#ifndef __UM_HOST__
#include <linux/types.h>
#else
#include <stddef.h>
#include <sys/types.h>
#endif
extern void panic(const char *fmt, ...)
__attribute__ ((format (printf, 1, 2)));
/* Requires preincluding include/linux/kern_levels.h */
#define UM_KERN_EMERG KERN_EMERG
#define UM_KERN_ALERT KERN_ALERT
#define UM_KERN_CRIT KERN_CRIT
#define UM_KERN_ERR KERN_ERR
#define UM_KERN_WARNING KERN_WARNING
#define UM_KERN_NOTICE KERN_NOTICE
#define UM_KERN_INFO KERN_INFO
#define UM_KERN_DEBUG KERN_DEBUG
#define UM_KERN_CONT KERN_CONT
#if IS_ENABLED(CONFIG_PRINTK)
#define printk(...) _printk(__VA_ARGS__)
extern int _printk(const char *fmt, ...)
__attribute__ ((format (printf, 1, 2)));
extern void print_hex_dump(const char *level, const char *prefix_str,
int prefix_type, int rowsize, int groupsize,
const void *buf, size_t len, _Bool ascii);
#else
static inline int printk(const char *fmt, ...)
{
return 0;
}
static inline void print_hex_dump(const char *level, const char *prefix_str,
int prefix_type, int rowsize, int groupsize,
const void *buf, size_t len, _Bool ascii)
{
}
#endif
extern int in_aton(char *str);
extern size_t strlcat(char *, const char *, size_t);
extern size_t sized_strscpy(char *, const char *, size_t);
#define strscpy(dst, src) sized_strscpy(dst, src, sizeof(dst))
/* Copied from linux/compiler-gcc.h since we can't include it directly */
#define barrier() __asm__ __volatile__("": : :"memory")
#endif
@@ -0,0 +1 @@
# SPDX-License-Identifier: GPL-2.0