um: fix stub location calculation
In commit9f0b4807a4
("um: rework userspace stubs to not hard-code stub location") I changed stub_segv_handler() to do a calculation with a pointer to a stack variable to find the data page that we're using for the stack and the rest of the data. This same commit was meant to do it as well for stub_clone_handler(), but the change inadvertently went into commit84b2789d61
("um: separate child and parent errors in clone stub") instead. This was reported to not be compiled correctly by gcc 5, causing the code to crash here. I'm not sure why, perhaps it's UB because the var isn't initialized? In any case, this trick always seemed bad, so just create a new inline function that does the calculation in assembly. Reported-by: subashab@codeaurora.org Fixes:9f0b4807a4
("um: rework userspace stubs to not hard-code stub location") Fixes:84b2789d61
("um: separate child and parent errors in clone stub") Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Richard Weinberger <richard@nod.at>
This commit is contained in:
parent
6a241d2923
commit
adf9ae0d15
@ -24,8 +24,7 @@
|
|||||||
void __attribute__ ((__section__ (".__syscall_stub")))
|
void __attribute__ ((__section__ (".__syscall_stub")))
|
||||||
stub_clone_handler(void)
|
stub_clone_handler(void)
|
||||||
{
|
{
|
||||||
int stack;
|
struct stub_data *data = get_stub_page();
|
||||||
struct stub_data *data = (void *) ((unsigned long)&stack & ~(UM_KERN_PAGE_SIZE - 1));
|
|
||||||
long err;
|
long err;
|
||||||
|
|
||||||
err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD,
|
err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD,
|
||||||
|
@ -101,4 +101,16 @@ static inline void remap_stack_and_trap(void)
|
|||||||
"memory");
|
"memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static __always_inline void *get_stub_page(void)
|
||||||
|
{
|
||||||
|
unsigned long ret;
|
||||||
|
|
||||||
|
asm volatile (
|
||||||
|
"movl %%esp,%0 ;"
|
||||||
|
"andl %1,%0"
|
||||||
|
: "=a" (ret)
|
||||||
|
: "g" (~(UM_KERN_PAGE_SIZE - 1)));
|
||||||
|
|
||||||
|
return (void *)ret;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -108,4 +108,16 @@ static inline void remap_stack_and_trap(void)
|
|||||||
__syscall_clobber, "r10", "r8", "r9");
|
__syscall_clobber, "r10", "r8", "r9");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static __always_inline void *get_stub_page(void)
|
||||||
|
{
|
||||||
|
unsigned long ret;
|
||||||
|
|
||||||
|
asm volatile (
|
||||||
|
"movq %%rsp,%0 ;"
|
||||||
|
"andq %1,%0"
|
||||||
|
: "=a" (ret)
|
||||||
|
: "g" (~(UM_KERN_PAGE_SIZE - 1)));
|
||||||
|
|
||||||
|
return (void *)ret;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -11,9 +11,8 @@
|
|||||||
void __attribute__ ((__section__ (".__syscall_stub")))
|
void __attribute__ ((__section__ (".__syscall_stub")))
|
||||||
stub_segv_handler(int sig, siginfo_t *info, void *p)
|
stub_segv_handler(int sig, siginfo_t *info, void *p)
|
||||||
{
|
{
|
||||||
int stack;
|
struct faultinfo *f = get_stub_page();
|
||||||
ucontext_t *uc = p;
|
ucontext_t *uc = p;
|
||||||
struct faultinfo *f = (void *)(((unsigned long)&stack) & ~(UM_KERN_PAGE_SIZE - 1));
|
|
||||||
|
|
||||||
GET_FAULTINFO_FROM_MC(*f, &uc->uc_mcontext);
|
GET_FAULTINFO_FROM_MC(*f, &uc->uc_mcontext);
|
||||||
trap_myself();
|
trap_myself();
|
||||||
|
Loading…
Reference in New Issue
Block a user