diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-02-03 11:56:58 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-02-03 11:56:58 -0800 |
commit | 61556703b610a104de324e4f061dc6cf7b218b46 (patch) | |
tree | 5f07a62d460491e983551bbc24d31e1833a235d8 /arch | |
parent | 3afe9076a7c19140b789d144d0ba1e9be2db4265 (diff) | |
parent | 7f3414226b58b0df0426104c8ab5e8d50ae71d11 (diff) |
Merge tag 'for-linus-5.11-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml
Pull UML fixes from Richard Weinberger:
- Make sure to set a default console, otherwise ttynull is selected
- Revert initial ARCH_HAS_SET_MEMORY support, this needs more work
- Fix a regression due to ubd refactoring
- Various small fixes
* tag 'for-linus-5.11-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml:
um: time: fix initialization in time-travel mode
um: fix os_idle_sleep() to not hang
Revert "um: support some of ARCH_HAS_SET_MEMORY"
Revert "um: allocate a guard page to helper threads"
um: virtio: free vu_dev only with the contained struct device
um: kmsg_dumper: always dump when not tty console
um: stdio_console: Make preferred console
um: return error from ioremap()
um: ubd: fix command line handling of ubd
Diffstat (limited to 'arch')
-rw-r--r-- | arch/um/Kconfig | 1 | ||||
-rw-r--r-- | arch/um/drivers/ubd_kern.c | 6 | ||||
-rw-r--r-- | arch/um/drivers/virtio_uml.c | 3 | ||||
-rw-r--r-- | arch/um/include/asm/io.h | 2 | ||||
-rw-r--r-- | arch/um/include/asm/pgtable.h | 3 | ||||
-rw-r--r-- | arch/um/include/asm/set_memory.h | 1 | ||||
-rw-r--r-- | arch/um/include/shared/kern_util.h | 2 | ||||
-rw-r--r-- | arch/um/kernel/kmsg_dump.c | 9 | ||||
-rw-r--r-- | arch/um/kernel/process.c | 11 | ||||
-rw-r--r-- | arch/um/kernel/time.c | 50 | ||||
-rw-r--r-- | arch/um/kernel/tlb.c | 54 | ||||
-rw-r--r-- | arch/um/kernel/um_arch.c | 22 | ||||
-rw-r--r-- | arch/um/os-Linux/helper.c | 4 | ||||
-rw-r--r-- | arch/um/os-Linux/time.c | 15 |
14 files changed, 84 insertions, 99 deletions
diff --git a/arch/um/Kconfig b/arch/um/Kconfig index 34d302d1a07f..c3030db3325f 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig @@ -15,7 +15,6 @@ config UML select HAVE_DEBUG_KMEMLEAK select HAVE_DEBUG_BUGVERBOSE select NO_DMA - select ARCH_HAS_SET_MEMORY select GENERIC_IRQ_SHOW select GENERIC_CPU_DEVICES select HAVE_GCC_PLUGINS diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 13b1fe694b90..8e0b43cf089f 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -375,11 +375,11 @@ break_loop: file = NULL; backing_file = strsep(&str, ",:"); - if (*backing_file == '\0') + if (backing_file && *backing_file == '\0') backing_file = NULL; serial = strsep(&str, ",:"); - if (*serial == '\0') + if (serial && *serial == '\0') serial = NULL; if (backing_file && ubd_dev->no_cow) { @@ -1241,7 +1241,7 @@ static int __init ubd_driver_init(void){ /* Letting ubd=sync be like using ubd#s= instead of ubd#= is * enough. So use anyway the io thread. */ } - stack = alloc_stack(0); + stack = alloc_stack(0, 0); io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *), &thread_fd); if(io_pid < 0){ diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c index 27e92d3881ff..5d957b7e7fd5 100644 --- a/arch/um/drivers/virtio_uml.c +++ b/arch/um/drivers/virtio_uml.c @@ -1084,6 +1084,7 @@ static void virtio_uml_release_dev(struct device *d) } os_close_file(vu_dev->sock); + kfree(vu_dev); } /* Platform device */ @@ -1097,7 +1098,7 @@ static int virtio_uml_probe(struct platform_device *pdev) if (!pdata) return -EINVAL; - vu_dev = devm_kzalloc(&pdev->dev, sizeof(*vu_dev), GFP_KERNEL); + vu_dev = kzalloc(sizeof(*vu_dev), GFP_KERNEL); if (!vu_dev) return -ENOMEM; diff --git a/arch/um/include/asm/io.h b/arch/um/include/asm/io.h index 96f77b5232aa..cef03e3aa0f9 100644 --- a/arch/um/include/asm/io.h +++ b/arch/um/include/asm/io.h @@ -5,7 +5,7 @@ #define ioremap ioremap static inline void __iomem *ioremap(phys_addr_t offset, size_t size) { - return (void __iomem *)(unsigned long)offset; + return NULL; } #define iounmap iounmap diff --git a/arch/um/include/asm/pgtable.h b/arch/um/include/asm/pgtable.h index 39376bb63abf..def376194dce 100644 --- a/arch/um/include/asm/pgtable.h +++ b/arch/um/include/asm/pgtable.h @@ -55,15 +55,12 @@ extern unsigned long end_iomem; #define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) #define __PAGE_KERNEL_EXEC \ (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED) -#define __PAGE_KERNEL_RO \ - (_PAGE_PRESENT | _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) -#define PAGE_KERNEL_RO __pgprot(__PAGE_KERNEL_RO) /* * The i386 can't do page protection for execute, and considers that the same diff --git a/arch/um/include/asm/set_memory.h b/arch/um/include/asm/set_memory.h deleted file mode 100644 index 24266c63720d..000000000000 --- a/arch/um/include/asm/set_memory.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/set_memory.h> diff --git a/arch/um/include/shared/kern_util.h b/arch/um/include/shared/kern_util.h index d8c279e3312f..2888ec812f6e 100644 --- a/arch/um/include/shared/kern_util.h +++ b/arch/um/include/shared/kern_util.h @@ -19,7 +19,7 @@ extern int kmalloc_ok; #define UML_ROUND_UP(addr) \ ((((unsigned long) addr) + PAGE_SIZE - 1) & PAGE_MASK) -extern unsigned long alloc_stack(int atomic); +extern unsigned long alloc_stack(int order, int atomic); extern void free_stack(unsigned long stack, int order); struct pt_regs; diff --git a/arch/um/kernel/kmsg_dump.c b/arch/um/kernel/kmsg_dump.c index e4abac6c9727..6516ef1f8274 100644 --- a/arch/um/kernel/kmsg_dump.c +++ b/arch/um/kernel/kmsg_dump.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include <linux/kmsg_dump.h> #include <linux/console.h> +#include <linux/string.h> #include <shared/init.h> #include <shared/kern.h> #include <os.h> @@ -16,8 +17,12 @@ static void kmsg_dumper_stdout(struct kmsg_dumper *dumper, if (!console_trylock()) return; - for_each_console(con) - break; + for_each_console(con) { + if(strcmp(con->name, "tty") == 0 && + (con->flags & (CON_ENABLED | CON_CONSDEV)) != 0) { + break; + } + } console_unlock(); diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 2a986ece5478..81d508daf67c 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -32,7 +32,6 @@ #include <os.h> #include <skas.h> #include <linux/time-internal.h> -#include <asm/set_memory.h> /* * This is a per-cpu array. A processor only modifies its entry and it only @@ -63,18 +62,16 @@ void free_stack(unsigned long stack, int order) free_pages(stack, order); } -unsigned long alloc_stack(int atomic) +unsigned long alloc_stack(int order, int atomic) { - unsigned long addr; + unsigned long page; gfp_t flags = GFP_KERNEL; if (atomic) flags = GFP_ATOMIC; - addr = __get_free_pages(flags, 1); + page = __get_free_pages(flags, order); - set_memory_ro(addr, 1); - - return addr + PAGE_SIZE; + return page; } static inline void set_current(struct task_struct *task) diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c index f4db89b5b5a6..315248b03941 100644 --- a/arch/um/kernel/time.c +++ b/arch/um/kernel/time.c @@ -535,6 +535,31 @@ invalid_number: return 1; } + +static void time_travel_set_start(void) +{ + if (time_travel_start_set) + return; + + switch (time_travel_mode) { + case TT_MODE_EXTERNAL: + time_travel_start = time_travel_ext_req(UM_TIMETRAVEL_GET_TOD, -1); + /* controller gave us the *current* time, so adjust by that */ + time_travel_ext_get_time(); + time_travel_start -= time_travel_time; + break; + case TT_MODE_INFCPU: + case TT_MODE_BASIC: + if (!time_travel_start_set) + time_travel_start = os_persistent_clock_emulation(); + break; + case TT_MODE_OFF: + /* we just read the host clock with os_persistent_clock_emulation() */ + break; + } + + time_travel_start_set = true; +} #else /* CONFIG_UML_TIME_TRAVEL_SUPPORT */ #define time_travel_start_set 0 #define time_travel_start 0 @@ -553,6 +578,10 @@ static void time_travel_set_interval(unsigned long long interval) { } +static inline void time_travel_set_start(void) +{ +} + /* fail link if this actually gets used */ extern u64 time_travel_ext_req(u32 op, u64 time); @@ -731,6 +760,8 @@ void read_persistent_clock64(struct timespec64 *ts) { long long nsecs; + time_travel_set_start(); + if (time_travel_mode != TT_MODE_OFF) nsecs = time_travel_start + time_travel_time; else @@ -742,25 +773,6 @@ void read_persistent_clock64(struct timespec64 *ts) void __init time_init(void) { -#ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT - switch (time_travel_mode) { - case TT_MODE_EXTERNAL: - time_travel_start = time_travel_ext_req(UM_TIMETRAVEL_GET_TOD, -1); - /* controller gave us the *current* time, so adjust by that */ - time_travel_ext_get_time(); - time_travel_start -= time_travel_time; - break; - case TT_MODE_INFCPU: - case TT_MODE_BASIC: - if (!time_travel_start_set) - time_travel_start = os_persistent_clock_emulation(); - break; - case TT_MODE_OFF: - /* we just read the host clock with os_persistent_clock_emulation() */ - break; - } -#endif - timer_set_signal_handler(); late_time_init = um_timer_setup; } diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index 437d1f1cc5ec..61776790cd67 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -608,57 +608,3 @@ void force_flush_all(void) vma = vma->vm_next; } } - -struct page_change_data { - unsigned int set_mask, clear_mask; -}; - -static int change_page_range(pte_t *ptep, unsigned long addr, void *data) -{ - struct page_change_data *cdata = data; - pte_t pte = READ_ONCE(*ptep); - - pte_clear_bits(pte, cdata->clear_mask); - pte_set_bits(pte, cdata->set_mask); - - set_pte(ptep, pte); - return 0; -} - -static int change_memory(unsigned long start, unsigned long pages, - unsigned int set_mask, unsigned int clear_mask) -{ - unsigned long size = pages * PAGE_SIZE; - struct page_change_data data; - int ret; - - data.set_mask = set_mask; - data.clear_mask = clear_mask; - - ret = apply_to_page_range(&init_mm, start, size, change_page_range, - &data); - - flush_tlb_kernel_range(start, start + size); - - return ret; -} - -int set_memory_ro(unsigned long addr, int numpages) -{ - return change_memory(addr, numpages, 0, _PAGE_RW); -} - -int set_memory_rw(unsigned long addr, int numpages) -{ - return change_memory(addr, numpages, _PAGE_RW, 0); -} - -int set_memory_nx(unsigned long addr, int numpages) -{ - return -EOPNOTSUPP; -} - -int set_memory_x(unsigned long addr, int numpages) -{ - return -EOPNOTSUPP; -} diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 31d356b1ffd8..80e2660782a0 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -26,7 +26,8 @@ #include <mem_user.h> #include <os.h> -#define DEFAULT_COMMAND_LINE "root=98:0" +#define DEFAULT_COMMAND_LINE_ROOT "root=98:0" +#define DEFAULT_COMMAND_LINE_CONSOLE "console=tty" /* Changed in add_arg and setup_arch, which run before SMP is started */ static char __initdata command_line[COMMAND_LINE_SIZE] = { 0 }; @@ -109,7 +110,8 @@ unsigned long end_vm; int ncpus = 1; /* Set in early boot */ -static int have_root __initdata = 0; +static int have_root __initdata; +static int have_console __initdata; /* Set in uml_mem_setup and modified in linux_main */ long long physmem_size = 32 * 1024 * 1024; @@ -161,6 +163,17 @@ __uml_setup("debug", no_skas_debug_setup, " this flag is not needed to run gdb on UML in skas mode\n\n" ); +static int __init uml_console_setup(char *line, int *add) +{ + have_console = 1; + return 0; +} + +__uml_setup("console=", uml_console_setup, +"console=<preferred console>\n" +" Specify the preferred console output driver\n\n" +); + static int __init Usage(char *line, int *add) { const char **p; @@ -264,7 +277,10 @@ int __init linux_main(int argc, char **argv) add_arg(argv[i]); } if (have_root == 0) - add_arg(DEFAULT_COMMAND_LINE); + add_arg(DEFAULT_COMMAND_LINE_ROOT); + + if (have_console == 0) + add_arg(DEFAULT_COMMAND_LINE_CONSOLE); host_task_size = os_get_top_address(); /* diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c index feb48d796e00..9fa6e4187d4f 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c @@ -45,7 +45,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv) unsigned long stack, sp; int pid, fds[2], ret, n; - stack = alloc_stack(__cant_sleep()); + stack = alloc_stack(0, __cant_sleep()); if (stack == 0) return -ENOMEM; @@ -116,7 +116,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, unsigned long stack, sp; int pid, status, err; - stack = alloc_stack(__cant_sleep()); + stack = alloc_stack(0, __cant_sleep()); if (stack == 0) return -ENOMEM; diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index a61cbf73a179..6c5041c5560b 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c @@ -104,5 +104,18 @@ long long os_nsecs(void) */ void os_idle_sleep(void) { - pause(); + struct itimerspec its; + sigset_t set, old; + + /* block SIGALRM while we analyze the timer state */ + sigemptyset(&set); + sigaddset(&set, SIGALRM); + sigprocmask(SIG_BLOCK, &set, &old); + + /* check the timer, and if it'll fire then wait for it */ + timer_gettime(event_high_res_timer, &its); + if (its.it_value.tv_sec || its.it_value.tv_nsec) + sigsuspend(&old); + /* either way, restore the signal mask */ + sigprocmask(SIG_UNBLOCK, &set, NULL); } |