Commit 61556703 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 3afe9076 7f341422
......@@ -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
......
......@@ -375,11 +375,11 @@ static int ubd_setup_common(char *str, int *index_out, char **error_out)
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){
......
......@@ -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;
......
......@@ -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
......
......@@ -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
......
#include <asm-generic/set_memory.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;
......
// 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();
......
......@@ -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)
......
......@@ -535,6 +535,31 @@ static int time_travel_connect_external(const char *socket)
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;
}
......
......@@ -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;
}
......@@ -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();
/*
......
......@@ -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;
......
......@@ -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);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment