This pull request contains the following changes for UML:

- set_fs removal
 - Devicetree support
 - Many cleanups from Al
 - Various virtio and build related fixes
 -----BEGIN PGP SIGNATURE-----
 
 iQJKBAABCAA0FiEEdgfidid8lnn52cLTZvlZhesYu8EFAmHbPpwWHHJpY2hhcmRA
 c2lnbWEtc3Rhci5hdAAKCRBm+VmF6xi7wXkcD/9UfDRFqvgtZIlacQ/0IvN24xeq
 +f4aXoXEVyVsCd02jv9pUk3IAezIQyJf3MGtNJ4D/UFXtYfjEYjK5kJpPDP6umaZ
 ZDnpTzn29HW2aGlgOxW9gU7a3Yze629QasIRP6x7Ht+Hk5eXrvRYrgcmKtw1mm04
 SA5v5ZqP3P5r623fpsFiw4Dvl7l6MhDyFeyA2tabNnmv93HgB76PHDtV2Z+SWrC+
 ubjlfBQc87QGHW+eTvce+0qw9APMoJpNFjNN4H8P/9VcDTvw+KL2JqQ02HSMWh4z
 HeHKsv6hbty+GskBhbaWDW7867fPJ3e08TFAAAjeEiBP/CDBwjOTSr3eOw1eHgzU
 xdAqC2Bz0e5G3shClmVEzzvcP6R2cgNZjeBze5m3wQ1NKHEddk6N9t5K+4NrOpgp
 gbNN5Q4FAVOBKeQsZWG81bJKGcu7SbShgiKjlxcaRpMyp6LwyD4naauGjmCzYsbf
 Pd4ilLO1Yocf7nFs2C4vWxE4iAZ6hfQtukerIxCQfb/Y2BaWT3bcWWYHFRFy6Lq+
 hTFGnjf+Ro65QCoa1idaLaUdhwAGi6U9sjjL6G/JdQCCE3ftcXLVA9TJz9CNdMb5
 98IGznxhczOZc7rHNXOF4km5+OUrU6N+C0WRp3yOoUWcI+Ms4PXHzqIwC5cde/V7
 O/o9O1BAoBP6LE1pPg==
 =5J6E
 -----END PGP SIGNATURE-----

Merge tag 'for-linus-5.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml

Pull UML updates from Richard Weinberger:

 - set_fs removal

 - Devicetree support

 - Many cleanups from Al

 - Various virtio and build related fixes

* tag 'for-linus-5.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml: (31 commits)
  um: virtio_uml: Allow probing from devicetree
  um: Add devicetree support
  um: Extract load file helper from initrd.c
  um: remove set_fs
  hostfs: Fix writeback of dirty pages
  um: Use swap() to make code cleaner
  um: header debriding - sigio.h
  um: header debriding - os.h
  um: header debriding - net_*.h
  um: header debriding - mem_user.h
  um: header debriding - activate_ipi()
  um: common-offsets.h debriding...
  um, x86: bury crypto_tfm_ctx_offset
  um: unexport handle_page_fault()
  um: remove a dangling extern of syscall_trace()
  um: kill unused cpu()
  uml/i386: missing include in barrier.h
  um: stop polluting the namespace with registers.h contents
  logic_io instance of iounmap() needs volatile on argument
  um: move amd64 variant of mmap(2) to arch/x86/um/syscalls_64.c
  ...
This commit is contained in:
Linus Torvalds 2022-01-11 15:26:52 -08:00
commit f692121142
51 changed files with 265 additions and 235 deletions

1
arch/um/.gitignore vendored
View File

@ -2,3 +2,4 @@
kernel/config.c
kernel/config.tmp
kernel/vmlinux.lds
kernel/capflags.c

View File

@ -18,10 +18,10 @@ config UML
select HAVE_DEBUG_KMEMLEAK
select HAVE_DEBUG_BUGVERBOSE
select NO_DMA if !UML_DMA_EMULATION
select OF_EARLY_FLATTREE if OF
select GENERIC_IRQ_SHOW
select GENERIC_CPU_DEVICES
select HAVE_GCC_PLUGINS
select SET_FS
select TRACE_IRQFLAGS_SUPPORT
select TTY # Needed for line.c
select HAVE_ARCH_VMAP_STACK

View File

@ -181,15 +181,15 @@ static unsigned long um_pci_cfgspace_read(void *priv, unsigned int offset,
/* buf->data is maximum size - we may only use parts of it */
struct um_pci_message_buffer *buf;
u8 *data;
unsigned long ret = ~0ULL;
unsigned long ret = ULONG_MAX;
if (!dev)
return ~0ULL;
return ULONG_MAX;
buf = get_cpu_var(um_pci_msg_bufs);
data = buf->data;
memset(data, 0xff, sizeof(data));
memset(buf->data, 0xff, sizeof(buf->data));
switch (size) {
case 1:
@ -304,7 +304,7 @@ static unsigned long um_pci_bar_read(void *priv, unsigned int offset,
/* buf->data is maximum size - we may only use parts of it */
struct um_pci_message_buffer *buf;
u8 *data;
unsigned long ret = ~0ULL;
unsigned long ret = ULONG_MAX;
buf = get_cpu_var(um_pci_msg_bufs);
data = buf->data;

View File

@ -21,6 +21,7 @@
* Based on Virtio MMIO driver by Pawel Moll, copyright 2011-2014, ARM Ltd.
*/
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/virtio.h>
@ -49,6 +50,7 @@ struct virtio_uml_platform_data {
struct virtio_uml_device {
struct virtio_device vdev;
struct platform_device *pdev;
struct virtio_uml_platform_data *pdata;
spinlock_t sock_lock;
int sock, req_fd, irq;
@ -149,7 +151,7 @@ static int vhost_user_recv(struct virtio_uml_device *vu_dev,
if (rc == -ECONNRESET && vu_dev->registered) {
struct virtio_uml_platform_data *pdata;
pdata = vu_dev->pdev->dev.platform_data;
pdata = vu_dev->pdata;
virtio_break_device(&vu_dev->vdev);
schedule_work(&pdata->conn_broken_wk);
@ -1090,6 +1092,8 @@ static void virtio_uml_release_dev(struct device *d)
container_of(d, struct virtio_device, dev);
struct virtio_uml_device *vu_dev = to_virtio_uml_device(vdev);
time_travel_propagate_time();
/* might not have been opened due to not negotiating the feature */
if (vu_dev->req_fd >= 0) {
um_free_irq(vu_dev->irq, vu_dev);
@ -1113,21 +1117,63 @@ void virtio_uml_set_no_vq_suspend(struct virtio_device *vdev,
no_vq_suspend ? "dis" : "en");
}
static void vu_of_conn_broken(struct work_struct *wk)
{
/*
* We can't remove the device from the devicetree so the only thing we
* can do is warn.
*/
WARN_ON(1);
}
/* Platform device */
static struct virtio_uml_platform_data *
virtio_uml_create_pdata(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct virtio_uml_platform_data *pdata;
int ret;
if (!np)
return ERR_PTR(-EINVAL);
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return ERR_PTR(-ENOMEM);
INIT_WORK(&pdata->conn_broken_wk, vu_of_conn_broken);
pdata->pdev = pdev;
ret = of_property_read_string(np, "socket-path", &pdata->socket_path);
if (ret)
return ERR_PTR(ret);
ret = of_property_read_u32(np, "virtio-device-id",
&pdata->virtio_device_id);
if (ret)
return ERR_PTR(ret);
return pdata;
}
static int virtio_uml_probe(struct platform_device *pdev)
{
struct virtio_uml_platform_data *pdata = pdev->dev.platform_data;
struct virtio_uml_device *vu_dev;
int rc;
if (!pdata)
return -EINVAL;
if (!pdata) {
pdata = virtio_uml_create_pdata(pdev);
if (IS_ERR(pdata))
return PTR_ERR(pdata);
}
vu_dev = kzalloc(sizeof(*vu_dev), GFP_KERNEL);
if (!vu_dev)
return -ENOMEM;
vu_dev->pdata = pdata;
vu_dev->vdev.dev.parent = &pdev->dev;
vu_dev->vdev.dev.release = virtio_uml_release_dev;
vu_dev->vdev.config = &virtio_uml_config_ops;
@ -1136,6 +1182,8 @@ static int virtio_uml_probe(struct platform_device *pdev)
vu_dev->pdev = pdev;
vu_dev->req_fd = -1;
time_travel_propagate_time();
do {
rc = os_connect_socket(pdata->socket_path);
} while (rc == -EINTR);

View File

@ -14,7 +14,7 @@ static inline void um_ndelay(unsigned long nsecs)
ndelay(nsecs);
}
#undef ndelay
#define ndelay um_ndelay
#define ndelay(n) um_ndelay(n)
static inline void um_udelay(unsigned long usecs)
{
@ -26,5 +26,5 @@ static inline void um_udelay(unsigned long usecs)
udelay(usecs);
}
#undef udelay
#define udelay um_udelay
#define udelay(n) um_udelay(n)
#endif /* __UM_DELAY_H */

View File

@ -3,7 +3,7 @@
#define __UM_IRQFLAGS_H
extern int signals_enabled;
int set_signals(int enable);
int um_set_signals(int enable);
void block_signals(void);
void unblock_signals(void);
@ -16,7 +16,7 @@ static inline unsigned long arch_local_save_flags(void)
#define arch_local_irq_restore arch_local_irq_restore
static inline void arch_local_irq_restore(unsigned long flags)
{
set_signals(flags);
um_set_signals(flags);
}
#define arch_local_irq_enable arch_local_irq_enable

View File

@ -11,7 +11,6 @@ struct pt_regs;
struct task_struct;
#include <asm/ptrace.h>
#include <registers.h>
#include <sysdep/archsetjmp.h>
#include <linux/prefetch.h>
@ -105,6 +104,7 @@ extern struct cpuinfo_um boot_cpu_data;
#define current_cpu_data boot_cpu_data
#define cache_line_size() (boot_cpu_data.cache_alignment)
extern unsigned long get_thread_reg(int reg, jmp_buf *buf);
#define KSTK_REG(tsk, reg) get_thread_reg(reg, &tsk->thread.switch_buf)
extern unsigned long __get_wchan(struct task_struct *p);

View File

@ -22,9 +22,6 @@ struct thread_info {
__u32 cpu; /* current CPU */
int preempt_count; /* 0 => preemptable,
<0 => BUG */
mm_segment_t addr_limit; /* thread address space:
0-0xBFFFFFFF for user
0-0xFFFFFFFF for kernel */
struct thread_info *real_thread; /* Points to non-IRQ stack */
unsigned long aux_fp_regs[FP_SIZE]; /* auxiliary fp_regs to save/restore
them out-of-band */
@ -36,7 +33,6 @@ struct thread_info {
.flags = 0, \
.cpu = 0, \
.preempt_count = INIT_PREEMPT_COUNT, \
.addr_limit = KERNEL_DS, \
.real_thread = NULL, \
}

View File

@ -8,6 +8,7 @@
#define __UM_UACCESS_H
#include <asm/elf.h>
#include <asm/unaligned.h>
#define __under_task_size(addr, size) \
(((unsigned long) (addr) < TASK_SIZE) && \
@ -39,8 +40,24 @@ static inline int __access_ok(unsigned long addr, unsigned long size)
{
return __addr_range_nowrap(addr, size) &&
(__under_task_size(addr, size) ||
__access_ok_vsyscall(addr, size) ||
uaccess_kernel());
__access_ok_vsyscall(addr, size));
}
/* no pagefaults for kernel addresses in um */
#define HAVE_GET_KERNEL_NOFAULT 1
#define __get_kernel_nofault(dst, src, type, err_label) \
do { \
*((type *)dst) = get_unaligned((type *)(src)); \
if (0) /* make sure the label looks used to the compiler */ \
goto err_label; \
} while (0)
#define __put_kernel_nofault(dst, src, type, err_label) \
do { \
put_unaligned(*((type *)src), (type *)(dst)); \
if (0) /* make sure the label looks used to the compiler */ \
goto err_label; \
} while (0)
#endif

View File

@ -9,32 +9,17 @@ DEFINE(UM_KERN_PAGE_MASK, PAGE_MASK);
DEFINE(UM_KERN_PAGE_SHIFT, PAGE_SHIFT);
DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC);
DEFINE(UM_ELF_CLASS, ELF_CLASS);
DEFINE(UM_ELFCLASS32, ELFCLASS32);
DEFINE(UM_ELFCLASS64, ELFCLASS64);
DEFINE(UM_NR_CPUS, NR_CPUS);
DEFINE(UM_GFP_KERNEL, GFP_KERNEL);
DEFINE(UM_GFP_ATOMIC, GFP_ATOMIC);
/* For crypto assembler code. */
DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
DEFINE(UM_THREAD_SIZE, THREAD_SIZE);
DEFINE(UM_HZ, HZ);
DEFINE(UM_USEC_PER_SEC, USEC_PER_SEC);
DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC);
DEFINE(UM_NSEC_PER_USEC, NSEC_PER_USEC);
#ifdef CONFIG_PRINTK
DEFINE(UML_CONFIG_PRINTK, CONFIG_PRINTK);
#endif
#ifdef CONFIG_NO_HZ_COMMON
DEFINE(UML_CONFIG_NO_HZ_COMMON, CONFIG_NO_HZ_COMMON);
#endif
#ifdef CONFIG_UML_X86
DEFINE(UML_CONFIG_UML_X86, CONFIG_UML_X86);
#endif

View File

@ -20,6 +20,5 @@ 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);
extern int activate_ipi(int fd, int pid);
#endif

View File

@ -53,13 +53,11 @@ extern void do_uml_exitcalls(void);
extern int __cant_sleep(void);
extern int get_current_pid(void);
extern int copy_from_user_proc(void *to, void *from, int size);
extern int cpu(void);
extern char *uml_strdup(const char *string);
extern unsigned long to_irq_stack(unsigned long *mask_out);
extern unsigned long from_irq_stack(int nested);
extern void syscall_trace(struct uml_pt_regs *regs, int entryexit);
extern int singlestepping(void *t);
extern void segv_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs);

View File

@ -18,7 +18,7 @@ extern void longjmp(jmp_buf, int);
enable = *(volatile int *)&signals_enabled; \
n = setjmp(*buf); \
if(n != 0) \
set_signals_trace(enable); \
um_set_signals_trace(enable); \
n; })
#endif

View File

@ -46,16 +46,11 @@ extern int iomem_size;
#define ROUND_4M(n) ((((unsigned long) (n)) + (1 << 22)) & ~((1 << 22) - 1))
extern int init_mem_user(void);
extern void setup_memory(void *entry);
extern unsigned long find_iomem(char *driver, unsigned long *len_out);
extern void mem_total_pages(unsigned long physmem, unsigned long iomem,
unsigned long highmem);
extern unsigned long get_vm(unsigned long len);
extern void setup_physmem(unsigned long start, unsigned long usable,
unsigned long len, unsigned long long highmem);
extern void add_iomem(char *name, int fd, unsigned long size);
extern unsigned long phys_offset(unsigned long phys);
extern void map_memory(unsigned long virt, unsigned long phys,
unsigned long len, int r, int w, int x);

View File

@ -59,8 +59,6 @@ struct transport {
const int setup_size;
};
extern struct net_device *ether_init(int);
extern unsigned short ether_protocol(struct sk_buff *);
extern int tap_setup_common(char *str, char *type, char **dev_name,
char **mac_out, char **gate_addr);
extern void register_transport(struct transport *new);

View File

@ -24,7 +24,6 @@ struct net_user_info {
int mtu;
};
extern void ether_user_init(void *data, void *dev);
extern void iter_addresses(void *d, void (*cb)(unsigned char *,
unsigned char *, void *),
void *arg);

View File

@ -159,20 +159,11 @@ 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 void os_close_file(int fd);
extern int os_rcv_fd(int fd, int *helper_pid_out);
extern int create_unix_socket(char *file, int len, int close_on_exec);
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 int os_stat_filesystem(char *path, long *bsize_out,
long long *blocks_out, long long *bfree_out,
long long *bavail_out, long long *files_out,
long long *ffree_out, void *fsid_out,
int fsid_size, long *namelen_out,
long *spare_out);
extern int os_change_dir(char *dir);
extern int os_fchange_dir(int fd);
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);
@ -232,14 +223,13 @@ 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 remove_sigstack(void);
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 set_signals(int enable);
extern int set_signals_trace(int enable);
extern int um_set_signals(int enable);
extern int um_set_signals_trace(int enable);
extern int os_is_signal_stack(void);
extern void deliver_alarm(void);
extern void register_pm_wake_signal(void);
@ -266,7 +256,6 @@ 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 void uml_idle_timer(void);
extern long long os_persistent_clock_emulation(void);
extern long long os_nsecs(void);
@ -290,8 +279,6 @@ extern int is_skas_winch(int pid, int fd, void *data);
extern int start_userspace(unsigned long stub_stack);
extern int copy_context_skas0(unsigned long stack, int pid);
extern void userspace(struct uml_pt_regs *regs, unsigned long *aux_fp_regs);
extern int map_stub_pages(int fd, unsigned long code, unsigned long data,
unsigned long stack);
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);

View File

@ -7,7 +7,6 @@
#define __REGISTERS_H
#include <sysdep/ptrace.h>
#include <sysdep/archsetjmp.h>
extern int save_i387_registers(int pid, unsigned long *fp_regs);
extern int restore_i387_registers(int pid, unsigned long *fp_regs);
@ -16,10 +15,9 @@ extern int restore_fp_registers(int pid, unsigned long *fp_regs);
extern int save_fpx_registers(int pid, unsigned long *fp_regs);
extern int restore_fpx_registers(int pid, unsigned long *fp_regs);
extern int save_registers(int pid, struct uml_pt_regs *regs);
extern int restore_registers(int pid, struct uml_pt_regs *regs);
extern int init_registers(int pid);
extern int restore_pid_registers(int pid, struct uml_pt_regs *regs);
extern int init_pid_registers(int pid);
extern void get_safe_registers(unsigned long *regs, unsigned long *fp_regs);
extern unsigned long get_thread_reg(int reg, jmp_buf *buf);
extern int get_fp_registers(int pid, unsigned long *regs);
extern int put_fp_registers(int pid, unsigned long *regs);

View File

@ -7,7 +7,6 @@
#define __SIGIO_H__
extern int write_sigio_irq(int fd);
extern int register_sigio_fd(int fd);
extern void sigio_lock(void);
extern void sigio_unlock(void);

View File

@ -16,11 +16,13 @@ extra-y := vmlinux.lds
obj-y = config.o exec.o exitcode.o irq.o ksyms.o mem.o \
physmem.o process.o ptrace.o reboot.o sigio.o \
signal.o syscall.o sysrq.o time.o tlb.o trap.o \
signal.o sysrq.o time.o tlb.o trap.o \
um_arch.o umid.o maccess.o kmsg_dump.o capflags.o skas/
obj-y += load_file.o
obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
obj-$(CONFIG_GPROF) += gprof_syms.o
obj-$(CONFIG_OF) += dtb.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-$(CONFIG_GENERIC_PCI_IOMAP) += ioport.o

41
arch/um/kernel/dtb.c Normal file
View File

@ -0,0 +1,41 @@
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/init.h>
#include <linux/of_fdt.h>
#include <linux/printk.h>
#include <linux/memblock.h>
#include <init.h>
#include "um_arch.h"
static char *dtb __initdata;
void uml_dtb_init(void)
{
long long size;
void *area;
area = uml_load_file(dtb, &size);
if (!area)
return;
if (!early_init_dt_scan(area)) {
pr_err("invalid DTB %s\n", dtb);
memblock_free(area, size);
return;
}
unflatten_device_tree();
early_init_fdt_scan_reserved_mem();
}
static int __init uml_dtb_setup(char *line, int *add)
{
dtb = line;
return 0;
}
__uml_setup("dtb=", uml_dtb_setup,
"dtb=<file>\n"
" Boot the kernel with the devicetree blob from the specified file.\n"
);

View File

@ -16,6 +16,7 @@
#include <linux/uaccess.h>
#include <as-layout.h>
#include <mem_user.h>
#include <registers.h>
#include <skas.h>
#include <os.h>

View File

@ -10,37 +10,21 @@
#include <init.h>
#include <os.h>
#include "um_arch.h"
/* Changed by uml_initrd_setup, which is a setup */
static char *initrd __initdata = NULL;
static int load_initrd(char *filename, void *buf, int size);
int __init read_initrd(void)
{
unsigned long long size;
void *area;
long long size;
int err;
if (initrd == NULL)
if (!initrd)
return 0;
err = os_file_size(initrd, &size);
if (err)
return 0;
/*
* This is necessary because alloc_bootmem craps out if you
* ask for no memory.
*/
if (size == 0) {
printk(KERN_ERR "\"%s\" is a zero-size initrd\n", initrd);
return 0;
}
area = memblock_alloc(size, SMP_CACHE_BYTES);
area = uml_load_file(initrd, &size);
if (!area)
panic("%s: Failed to allocate %llu bytes\n", __func__, size);
if (load_initrd(initrd, area, size) == -1)
return 0;
initrd_start = (unsigned long) area;
@ -59,25 +43,3 @@ __uml_setup("initrd=", uml_initrd_setup,
" This is used to boot UML from an initrd image. The argument is the\n"
" name of the file containing the image.\n\n"
);
static int load_initrd(char *filename, void *buf, int size)
{
int fd, n;
fd = os_open_file(filename, of_read(OPENFLAGS()), 0);
if (fd < 0) {
printk(KERN_ERR "Opening '%s' failed - err = %d\n", filename,
-fd);
return -1;
}
n = os_read_file(fd, buf, size);
if (n != size) {
printk(KERN_ERR "Read of %d bytes from '%s' failed, "
"err = %d\n", size,
filename, -n);
return -1;
}
os_close_file(fd);
return 0;
}

View File

@ -6,7 +6,7 @@
#include <linux/module.h>
#include <os.h>
EXPORT_SYMBOL(set_signals);
EXPORT_SYMBOL(um_set_signals);
EXPORT_SYMBOL(signals_enabled);
EXPORT_SYMBOL(os_stat_fd);

View File

@ -0,0 +1,61 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
*/
#include <linux/memblock.h>
#include <os.h>
#include "um_arch.h"
static int __init __uml_load_file(const char *filename, void *buf, int size)
{
int fd, n;
fd = os_open_file(filename, of_read(OPENFLAGS()), 0);
if (fd < 0) {
printk(KERN_ERR "Opening '%s' failed - err = %d\n", filename,
-fd);
return -1;
}
n = os_read_file(fd, buf, size);
if (n != size) {
printk(KERN_ERR "Read of %d bytes from '%s' failed, "
"err = %d\n", size,
filename, -n);
return -1;
}
os_close_file(fd);
return 0;
}
void *uml_load_file(const char *filename, unsigned long long *size)
{
void *area;
int err;
*size = 0;
if (!filename)
return NULL;
err = os_file_size(filename, size);
if (err)
return NULL;
if (*size == 0) {
printk(KERN_ERR "\"%s\" is empty\n", filename);
return NULL;
}
area = memblock_alloc(*size, SMP_CACHE_BYTES);
if (!area)
panic("%s: Failed to allocate %llu bytes\n", __func__, *size);
if (__uml_load_file(filename, area, *size)) {
memblock_free(area, *size);
return NULL;
}
return area;
}

View File

@ -85,8 +85,7 @@ static void __init one_md_table_init(pud_t *pud)
__func__, PAGE_SIZE, PAGE_SIZE);
set_pud(pud, __pud(_KERNPG_TABLE + (unsigned long) __pa(pmd_table)));
if (pmd_table != pmd_offset(pud, 0))
BUG();
BUG_ON(pmd_table != pmd_offset(pud, 0));
#endif
}

View File

@ -31,6 +31,7 @@
#include <kern_util.h>
#include <os.h>
#include <skas.h>
#include <registers.h>
#include <linux/time-internal.h>
/*
@ -263,11 +264,6 @@ int clear_user_proc(void __user *buf, int size)
return clear_user(buf, size);
}
int cpu(void)
{
return current_thread_info()->cpu;
}
static atomic_t using_sysemu = ATOMIC_INIT(0);
int sysemu_supported;

View File

@ -146,11 +146,6 @@ static int copy_chunk_from_user(unsigned long from, int len, void *arg)
unsigned long raw_copy_from_user(void *to, const void __user *from, unsigned long n)
{
if (uaccess_kernel()) {
memcpy(to, (__force void*)from, n);
return 0;
}
return buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to);
}
EXPORT_SYMBOL(raw_copy_from_user);
@ -166,11 +161,6 @@ static int copy_chunk_to_user(unsigned long to, int len, void *arg)
unsigned long raw_copy_to_user(void __user *to, const void *from, unsigned long n)
{
if (uaccess_kernel()) {
memcpy((__force void *) to, from, n);
return 0;
}
return buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from);
}
EXPORT_SYMBOL(raw_copy_to_user);
@ -196,12 +186,6 @@ long strncpy_from_user(char *dst, const char __user *src, long count)
if (!access_ok(src, 1))
return -EFAULT;
if (uaccess_kernel()) {
strncpy(dst, (__force void *) src, count);
return strnlen(dst, count);
}
n = buffer_op((unsigned long) src, count, 0, strncpy_chunk_from_user,
&ptr);
if (n != 0)
@ -218,11 +202,6 @@ static int clear_chunk(unsigned long addr, int len, void *unused)
unsigned long __clear_user(void __user *mem, unsigned long len)
{
if (uaccess_kernel()) {
memset((__force void*)mem, 0, len);
return 0;
}
return buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL);
}
EXPORT_SYMBOL(__clear_user);
@ -245,10 +224,6 @@ long strnlen_user(const char __user *str, long len)
if (!access_ok(str, 1))
return -EFAULT;
if (uaccess_kernel())
return strnlen((__force char*)str, len) + 1;
n = buffer_op((unsigned long) str, len, 0, strnlen_chunk, &count);
if (n == 0)
return count + 1;

View File

@ -1,28 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
*/
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/utsname.h>
#include <linux/syscalls.h>
#include <asm/current.h>
#include <asm/mman.h>
#include <linux/uaccess.h>
#include <asm/unistd.h>
long old_mmap(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long offset)
{
long err = -EINVAL;
if (offset & ~PAGE_MASK)
goto out;
err = ksys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
out:
return err;
}

View File

@ -127,7 +127,6 @@ out_of_memory:
pagefault_out_of_memory();
return 0;
}
EXPORT_SYMBOL(handle_page_fault);
static void show_segv_info(struct uml_pt_regs *regs)
{

View File

@ -29,6 +29,8 @@
#include <mem_user.h>
#include <os.h>
#include "um_arch.h"
#define DEFAULT_COMMAND_LINE_ROOT "root=98:0"
#define DEFAULT_COMMAND_LINE_CONSOLE "console=tty"
@ -407,6 +409,7 @@ void __init setup_arch(char **cmdline_p)
stack_protections((unsigned long) &init_thread_info);
setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem);
mem_total_pages(physmem_size, iomem_size, highmem);
uml_dtb_init();
read_initrd();
paging_init();

14
arch/um/kernel/um_arch.h Normal file
View File

@ -0,0 +1,14 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef __UML_ARCH_H__
#define __UML_ARCH_H__
extern void * __init uml_load_file(const char *filename, unsigned long long *size);
#ifdef CONFIG_OF
extern void __init uml_dtb_init(void);
#else
static inline void uml_dtb_init(void) { }
#endif
#endif

View File

@ -21,7 +21,7 @@ int save_registers(int pid, struct uml_pt_regs *regs)
return 0;
}
int restore_registers(int pid, struct uml_pt_regs *regs)
int restore_pid_registers(int pid, struct uml_pt_regs *regs)
{
int err;
@ -36,7 +36,7 @@ int restore_registers(int pid, struct uml_pt_regs *regs)
static unsigned long exec_regs[MAX_REG_NR];
static unsigned long exec_fp_regs[FP_SIZE];
int init_registers(int pid)
int init_pid_registers(int pid)
{
int err;

View File

@ -3,6 +3,7 @@
* Copyright (C) 2002 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com)
*/
#include <linux/minmax.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
@ -50,7 +51,7 @@ static struct pollfds all_sigio_fds;
static int write_sigio_thread(void *unused)
{
struct pollfds *fds, tmp;
struct pollfds *fds;
struct pollfd *p;
int i, n, respond_fd;
char c;
@ -77,9 +78,7 @@ static int write_sigio_thread(void *unused)
"write_sigio_thread : "
"read on socket failed, "
"err = %d\n", errno);
tmp = current_poll;
current_poll = next_poll;
next_poll = tmp;
swap(current_poll, next_poll);
respond_fd = sigio_private[1];
}
else {
@ -132,7 +131,7 @@ static void update_thread(void)
int n;
char c;
flags = set_signals_trace(0);
flags = um_set_signals_trace(0);
CATCH_EINTR(n = write(sigio_private[0], &c, sizeof(c)));
if (n != sizeof(c)) {
printk(UM_KERN_ERR "update_thread : write failed, err = %d\n",
@ -147,7 +146,7 @@ static void update_thread(void)
goto fail;
}
set_signals_trace(flags);
um_set_signals_trace(flags);
return;
fail:
/* Critical section start */
@ -161,7 +160,7 @@ static void update_thread(void)
close(write_sigio_fds[0]);
close(write_sigio_fds[1]);
/* Critical section end */
set_signals_trace(flags);
um_set_signals_trace(flags);
}
int __add_sigio_fd(int fd)

View File

@ -94,7 +94,7 @@ void sig_handler(int sig, struct siginfo *si, mcontext_t *mc)
sig_handler_common(sig, si, mc);
set_signals_trace(enabled);
um_set_signals_trace(enabled);
}
static void timer_real_alarm_handler(mcontext_t *mc)
@ -126,7 +126,7 @@ void timer_alarm_handler(int sig, struct siginfo *unused_si, mcontext_t *mc)
signals_active &= ~SIGALRM_MASK;
set_signals_trace(enabled);
um_set_signals_trace(enabled);
}
void deliver_alarm(void) {
@ -348,7 +348,7 @@ void unblock_signals(void)
}
}
int set_signals(int enable)
int um_set_signals(int enable)
{
int ret;
if (signals_enabled == enable)
@ -362,7 +362,7 @@ int set_signals(int enable)
return ret;
}
int set_signals_trace(int enable)
int um_set_signals_trace(int enable)
{
int ret;
if (signals_enabled == enable)

View File

@ -368,7 +368,7 @@ void __init os_early_checks(void)
check_tmpexec();
pid = start_ptraced_child();
if (init_registers(pid))
if (init_pid_registers(pid))
fatal("Failed to initialize default registers");
stop_ptraced_child(pid, 1, 1);
}

View File

@ -37,9 +37,6 @@ static void __used common(void)
OFFSET(TASK_stack_canary, task_struct, stack_canary);
#endif
BLANK();
OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx);
BLANK();
OFFSET(pbe_address, pbe, address);
OFFSET(pbe_orig_address, pbe, orig_address);

View File

@ -40,7 +40,7 @@ $(obj)/user-offsets.s: c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) \
-Iarch/x86/include/generated
targets += user-offsets.s
include/generated/user_constants.h: $(obj)/user-offsets.s
include/generated/user_constants.h: $(obj)/user-offsets.s FORCE
$(call filechk,offsets,__USER_CONSTANT_H__)
UNPROFILE_OBJS := stub_segv.o

View File

@ -2,6 +2,7 @@
#ifndef _ASM_UM_BARRIER_H_
#define _ASM_UM_BARRIER_H_
#include <asm/cpufeatures.h>
#include <asm/alternative.h>
/*

View File

@ -8,12 +8,4 @@ extern int host_gdt_entry_tls_min;
#define GDT_ENTRY_TLS_MIN host_gdt_entry_tls_min
#define GDT_ENTRY_TLS_MAX (GDT_ENTRY_TLS_MIN + GDT_ENTRY_TLS_ENTRIES - 1)
typedef struct {
unsigned long seg;
} mm_segment_t;
#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
#define KERNEL_DS MAKE_MM_SEG(~0UL)
#define USER_DS MAKE_MM_SEG(TASK_SIZE)
#endif

View File

@ -15,6 +15,7 @@
#include <sys/uio.h>
#include <asm/sigcontext.h>
#include <linux/elf.h>
#include <registers.h>
int have_xstate_support;

View File

@ -7,6 +7,7 @@
#include <linux/sched.h>
#include <linux/uaccess.h>
#include <asm/ptrace-abi.h>
#include <registers.h>
#include <skas.h>
extern int arch_switch_tls(struct task_struct *to);

View File

@ -11,6 +11,7 @@
#define __FRAME_OFFSETS
#include <asm/ptrace.h>
#include <linux/uaccess.h>
#include <registers.h>
#include <asm/ptrace-abi.h>
/*

View File

@ -23,9 +23,6 @@ extern syscall_handler_t *sys_call_table[];
UPT_SYSCALL_ARG5(&regs->regs), \
UPT_SYSCALL_ARG6(&regs->regs)))
extern long old_mmap(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff);
extern syscall_handler_t sys_modify_ldt;
extern syscall_handler_t sys_arch_prctl;

View File

@ -12,6 +12,7 @@
#include <linux/uaccess.h>
#include <asm/ucontext.h>
#include <frame_kern.h>
#include <registers.h>
#include <skas.h>
#ifdef CONFIG_X86_32

View File

@ -9,8 +9,6 @@
#include <linux/cache.h>
#include <asm/syscall.h>
#define __NO_STUBS
/*
* Below you can see, in terms of #define's, the differences between the x86-64
* and the UML syscall table.
@ -23,8 +21,6 @@
#define sys_vm86old sys_ni_syscall
#define sys_vm86 sys_ni_syscall
#define old_mmap sys_old_mmap
#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native)
#define __SYSCALL(nr, sym) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);

View File

@ -9,8 +9,6 @@
#include <linux/cache.h>
#include <asm/syscall.h>
#define __NO_STUBS
/*
* Below you can see, in terms of #define's, the differences between the x86-64
* and the UML syscall table.
@ -20,21 +18,6 @@
#define sys_iopl sys_ni_syscall
#define sys_ioperm sys_ni_syscall
/*
* The UML TLS problem. Note that x86_64 does not implement this, so the below
* is needed only for the ia32 compatibility.
*/
/* On UML we call it this way ("old" means it's not mmap2) */
#define sys_mmap old_mmap
#define stub_clone sys_clone
#define stub_fork sys_fork
#define stub_vfork sys_vfork
#define stub_execve sys_execve
#define stub_execveat sys_execveat
#define stub_rt_sigreturn sys_rt_sigreturn
#define __SYSCALL(nr, sym) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
#include <asm/syscalls_64.h>

View File

@ -10,7 +10,9 @@
#include <linux/syscalls.h>
#include <linux/uaccess.h>
#include <asm/prctl.h> /* XXX This should get the constants from libc */
#include <registers.h>
#include <os.h>
#include <registers.h>
long arch_prctl(struct task_struct *task, int option,
unsigned long __user *arg2)
@ -35,7 +37,7 @@ long arch_prctl(struct task_struct *task, int option,
switch (option) {
case ARCH_SET_FS:
case ARCH_SET_GS:
ret = restore_registers(pid, &current->thread.regs.regs);
ret = restore_pid_registers(pid, &current->thread.regs.regs);
if (ret)
return ret;
break;
@ -87,3 +89,13 @@ void arch_switch_to(struct task_struct *to)
arch_prctl(to, ARCH_SET_FS, (void __user *) to->thread.arch.fs);
}
SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
unsigned long, prot, unsigned long, flags,
unsigned long, fd, unsigned long, off)
{
if (off & ~PAGE_MASK)
return -EINVAL;
return ksys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
}

View File

@ -924,6 +924,9 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
sb->s_op = &hostfs_sbops;
sb->s_d_op = &simple_dentry_operations;
sb->s_maxbytes = MAX_LFS_FILESIZE;
err = super_setup_bdi(sb);
if (err)
goto out;
/* NULL is printed as '(null)' by printf(): avoid that. */
if (req_root == NULL)

View File

@ -34,7 +34,7 @@
void __iomem *ioremap(phys_addr_t offset, size_t size);
#define iounmap iounmap
void iounmap(void __iomem *addr);
void iounmap(void volatile __iomem *addr);
#define __raw_readb __raw_readb
u8 __raw_readb(const volatile void __iomem *addr);

View File

@ -21,15 +21,15 @@ struct logic_iomem_area {
#define AREA_SHIFT 24
#define MAX_AREA_SIZE (1 << AREA_SHIFT)
#define MAX_AREAS ((1ULL<<32) / MAX_AREA_SIZE)
#define MAX_AREAS ((1U << 31) / MAX_AREA_SIZE)
#define AREA_BITS ((MAX_AREAS - 1) << AREA_SHIFT)
#define AREA_MASK (MAX_AREA_SIZE - 1)
#ifdef CONFIG_64BIT
#define IOREMAP_BIAS 0xDEAD000000000000UL
#define IOREMAP_MASK 0xFFFFFFFF00000000UL
#else
#define IOREMAP_BIAS 0
#define IOREMAP_MASK 0
#define IOREMAP_BIAS 0x80000000UL
#define IOREMAP_MASK 0x80000000UL
#endif
static DEFINE_MUTEX(regions_mtx);
@ -76,10 +76,10 @@ static void __iomem *real_ioremap(phys_addr_t offset, size_t size)
return NULL;
}
static void real_iounmap(void __iomem *addr)
static void real_iounmap(volatile void __iomem *addr)
{
WARN(1, "invalid iounmap for addr 0x%llx\n",
(unsigned long long __force)addr);
(unsigned long long)(uintptr_t __force)addr);
}
#endif /* CONFIG_LOGIC_IOMEM_FALLBACK */
@ -149,7 +149,7 @@ get_area(const volatile void __iomem *addr)
return NULL;
}
void iounmap(void __iomem *addr)
void iounmap(volatile void __iomem *addr)
{
struct logic_iomem_area *area = get_area(addr);
@ -173,7 +173,7 @@ EXPORT_SYMBOL(iounmap);
static u##sz real_raw_read ## op(const volatile void __iomem *addr) \
{ \
WARN(1, "Invalid read" #op " at address %llx\n", \
(unsigned long long __force)addr); \
(unsigned long long)(uintptr_t __force)addr); \
return (u ## sz)~0ULL; \
} \
\
@ -181,7 +181,8 @@ static void real_raw_write ## op(u ## sz val, \
volatile void __iomem *addr) \
{ \
WARN(1, "Invalid writeq" #op " of 0x%llx at address %llx\n", \
(unsigned long long)val, (unsigned long long __force)addr);\
(unsigned long long)val, \
(unsigned long long)(uintptr_t __force)addr);\
} \
MAKE_FALLBACK(b, 8);
@ -194,14 +195,14 @@ MAKE_FALLBACK(q, 64);
static void real_memset_io(volatile void __iomem *addr, int value, size_t size)
{
WARN(1, "Invalid memset_io at address 0x%llx\n",
(unsigned long long __force)addr);
(unsigned long long)(uintptr_t __force)addr);
}
static void real_memcpy_fromio(void *buffer, const volatile void __iomem *addr,
size_t size)
{
WARN(1, "Invalid memcpy_fromio at address 0x%llx\n",
(unsigned long long __force)addr);
(unsigned long long)(uintptr_t __force)addr);
memset(buffer, 0xff, size);
}
@ -210,7 +211,7 @@ static void real_memcpy_toio(volatile void __iomem *addr, const void *buffer,
size_t size)
{
WARN(1, "Invalid memcpy_toio at address 0x%llx\n",
(unsigned long long __force)addr);
(unsigned long long)(uintptr_t __force)addr);
}
#endif /* CONFIG_LOGIC_IOMEM_FALLBACK */