2019-08-25 10:49:19 +01:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
2006-01-08 01:01:31 -08:00
|
|
|
/*
|
2007-10-16 01:27:00 -07:00
|
|
|
* Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
2005-04-16 15:20:36 -07:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __KERN_UTIL_H__
|
|
|
|
#define __KERN_UTIL_H__
|
|
|
|
|
2012-10-08 03:27:32 +01:00
|
|
|
#include <sysdep/ptrace.h>
|
|
|
|
#include <sysdep/faultinfo.h>
|
2005-04-16 15:20:36 -07:00
|
|
|
|
2012-08-02 00:49:17 +02:00
|
|
|
struct siginfo;
|
|
|
|
|
2008-02-04 22:31:08 -08:00
|
|
|
extern int uml_exitcode;
|
|
|
|
|
2005-04-16 15:20:36 -07:00
|
|
|
extern int ncpus;
|
|
|
|
extern int kmalloc_ok;
|
|
|
|
|
|
|
|
#define UML_ROUND_UP(addr) \
|
2008-02-04 22:30:46 -08:00
|
|
|
((((unsigned long) addr) + PAGE_SIZE - 1) & PAGE_MASK)
|
2005-04-16 15:20:36 -07:00
|
|
|
|
2021-01-10 19:05:08 +01:00
|
|
|
extern unsigned long alloc_stack(int order, int atomic);
|
2008-02-04 22:30:46 -08:00
|
|
|
extern void free_stack(unsigned long stack, int order);
|
|
|
|
|
2015-07-03 12:44:20 -07:00
|
|
|
struct pt_regs;
|
|
|
|
extern void do_signal(struct pt_regs *regs);
|
2008-02-04 22:30:46 -08:00
|
|
|
extern void interrupt_end(void);
|
2012-08-02 00:49:17 +02:00
|
|
|
extern void relay_signal(int sig, struct siginfo *si, struct uml_pt_regs *regs);
|
2008-02-04 22:30:46 -08:00
|
|
|
|
[PATCH] uml: S390 preparation, abstract host page fault data
This patch removes the arch-specific fault/trap-infos from thread and
skas-regs.
It adds a new struct faultinfo, that is arch-specific defined in
sysdep/faultinfo.h.
The structure is inserted in thread.arch and thread.regs.skas and
thread.regs.tt
Now, segv and other trap-handlers can copy the contents from regs.X.faultinfo
to thread.arch.faultinfo with one simple assignment.
Also, the number of macros necessary is reduced to
FAULT_ADDRESS(struct faultinfo)
extracts the faulting address from faultinfo
FAULT_WRITE(struct faultinfo)
extracts the "is_write" flag
SEGV_IS_FIXABLE(struct faultinfo)
is true for the fixable segvs, i.e. (TRAP == 14)
on i386
UPT_FAULTINFO(regs)
result is (struct faultinfo *) to the faultinfo
in regs->skas.faultinfo
GET_FAULTINFO_FROM_SC(struct faultinfo, struct sigcontext *)
copies the relevant parts of the sigcontext to
struct faultinfo.
On SIGSEGV, call user_signal() instead of handle_segv(), if the architecture
provides the information needed in PTRACE_FAULTINFO, or if PTRACE_FAULTINFO is
missing, because segv-stub will provide the info.
The benefit of the change is, that in case of a non-fixable SIGSEGV, we can
give user processes a SIGSEGV, instead of possibly looping on pagefault
handling.
Since handle_segv() sikked arch_fixup() implicitly by passing ip==0 to segv(),
I changed segv() to call arch_fixup() only, if !is_user.
Signed-off-by: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
Signed-off-by: Jeff Dike <jdike@addtoit.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-05-05 16:15:31 -07:00
|
|
|
extern unsigned long segv(struct faultinfo fi, unsigned long ip,
|
2007-10-16 01:26:58 -07:00
|
|
|
int is_user, struct uml_pt_regs *regs);
|
2005-04-16 15:20:36 -07:00
|
|
|
extern int handle_page_fault(unsigned long address, unsigned long ip,
|
|
|
|
int is_write, int is_user, int *code_out);
|
2008-02-04 22:30:46 -08:00
|
|
|
|
2007-10-16 01:26:58 -07:00
|
|
|
extern unsigned int do_IRQ(int irq, struct uml_pt_regs *regs);
|
2008-02-04 22:30:46 -08:00
|
|
|
extern void initial_thread_cb(void (*proc)(void *), void *arg);
|
2005-04-16 15:20:36 -07:00
|
|
|
extern int is_syscall(unsigned long addr);
|
[PATCH] uml: clean arch_switch usage
Call arch_switch also in switch_to_skas, even if it's, for now, a no-op for
that case (and mark this in the comment); this will change soon.
Also, arch_switch for TT mode is actually useless when the PT proxy (a
complicate debugging instrumentation for TT mode) is not enabled. In fact, it
only calls update_debugregs, which checks debugregs_seq against seq (to check
if the registers are up-to-date - seq here means a "version number" of the
registers).
If the ptrace proxy is not enabled, debugregs_seq always stays 0 and
update_debugregs will be a no-op. So, optimize this out (the compiler can't
do it).
Also, I've been disappointed by the fact that it would make a lot of sense if,
after calling a successful
update_debugregs(current->thread.arch.debugregs_seq),
current->thread.arch.debugregs_seq were updated with the new debugregs_seq.
But this is not done. Is this a bug or a feature? For all purposes, it seems
a bug (otherwise the whole mechanism does not make sense, which is also a
possibility to check), which causes some performance only problems (not
correctness), since we write_debugregs when not needed.
Also, as suggested by Jeff, remove a redundant enabling of SIGVTALRM,
comprised in the subsequent local_irq_enable(). I'm just a bit dubious if
ordering matters there...
Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
Acked-by: Jeff Dike <jdike@addtoit.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-03-31 02:30:21 -08:00
|
|
|
|
2012-08-02 00:49:17 +02:00
|
|
|
extern void timer_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs);
|
2008-02-04 22:30:46 -08:00
|
|
|
|
2020-12-02 20:58:06 +01:00
|
|
|
extern void uml_pm_wake(void);
|
|
|
|
|
2008-02-04 22:30:46 -08:00
|
|
|
extern int start_uml(void);
|
|
|
|
extern void paging_init(void);
|
2006-01-18 17:42:58 -08:00
|
|
|
|
2008-02-04 22:30:46 -08:00
|
|
|
extern void uml_cleanup(void);
|
|
|
|
extern void do_uml_exitcalls(void);
|
2006-06-04 02:51:46 -07:00
|
|
|
|
2008-02-04 22:30:46 -08:00
|
|
|
/*
|
|
|
|
* Are we disallowed to sleep? Used to choose between GFP_KERNEL and
|
|
|
|
* GFP_ATOMIC.
|
|
|
|
*/
|
2006-01-18 17:42:58 -08:00
|
|
|
extern int __cant_sleep(void);
|
2012-01-30 16:30:48 -05:00
|
|
|
extern int get_current_pid(void);
|
2008-02-04 22:30:46 -08:00
|
|
|
extern int copy_from_user_proc(void *to, void *from, int size);
|
|
|
|
extern char *uml_strdup(const char *string);
|
|
|
|
|
uml: fix irqstack crash
This patch fixes a crash caused by an interrupt coming in when an IRQ stack
is being torn down. When this happens, handle_signal will loop, setting up
the IRQ stack again because the tearing down had finished, and handling
whatever signals had come in.
However, to_irq_stack returns a mask of pending signals to be handled, plus
bit zero is set if the IRQ stack was already active, and thus shouldn't be
torn down. This causes a problem because when handle_signal goes around
the loop, sig will be zero, and to_irq_stack will duly set bit zero in the
returned mask, faking handle_signal into believing that it shouldn't tear
down the IRQ stack and return thread_info pointers back to their original
values.
This will eventually cause a crash, as the IRQ stack thread_info will
continue pointing to the original task_struct and an interrupt will look
into it after it has been freed.
The fix is to stop passing a signal number into to_irq_stack. Rather, the
pending signals mask is initialized beforehand with the bit for sig already
set. References to sig in to_irq_stack can be replaced with references to
the mask.
[akpm@linux-foundation.org: use UL]
Signed-off-by: Jeff Dike <jdike@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-09-18 22:46:49 -07:00
|
|
|
extern unsigned long to_irq_stack(unsigned long *mask_out);
|
2008-02-04 22:30:46 -08:00
|
|
|
extern unsigned long from_irq_stack(int nested);
|
|
|
|
|
|
|
|
extern int singlestepping(void *t);
|
|
|
|
|
2012-08-02 00:49:17 +02:00
|
|
|
extern void segv_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs);
|
|
|
|
extern void bus_handler(int sig, struct siginfo *si, struct uml_pt_regs *regs);
|
|
|
|
extern void winch(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs);
|
2008-02-04 22:30:58 -08:00
|
|
|
extern void fatal_sigsegv(void) __attribute__ ((noreturn));
|
2008-02-04 22:30:46 -08:00
|
|
|
|
um: Support suspend to RAM
With all the previous bits in place, we can now also support
suspend to RAM, in the sense that everything is suspended,
not just most, including userspace, processes like in s2idle.
Since um_idle_sleep() now waits forever, we can simply call
that to "suspend" the system.
As before, you can wake it up using SIGUSR1 since we're just
in a pause() call that only needs to return.
In order to implement selective resume from certain devices,
and not have any arbitrary device interrupt wake up, suspend
interrupts by removing SIGIO notification (O_ASYNC) from all
the FDs that are not supposed to wake up the system. However,
swap out the handler so we don't actually handle the SIGIO as
an interrupt.
Since we're in pause(), the mere act of receiving SIGIO wakes
us up, and then after things have been restored enough, re-set
O_ASYNC for all previously suspended FDs, reinstall the proper
SIGIO handler, and send SIGIO to self to process anything that
might now be pending.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Richard Weinberger <richard@nod.at>
2020-12-02 20:58:07 +01:00
|
|
|
void um_idle_sleep(void);
|
2008-02-04 22:30:46 -08:00
|
|
|
|
2005-04-16 15:20:36 -07:00
|
|
|
#endif
|