Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 47487
b: refs/heads/master
c: f355559
h: refs/heads/master
i:
  47485: 11a5ca2
  47483: 6f92305
  47479: 9a19581
  47471: db62f23
  47455: 651473c
  47423: 6499b36
  47359: 1e30470
v: v3
  • Loading branch information
Jeff Dike authored and Linus Torvalds committed Feb 11, 2007
1 parent e44806d commit 167bc34
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 30 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3a150e1da8bc4e840d5a09fc089052011b5b6503
refs/heads/master: f355559cf78455ed6be103b020e4b800230c64eb
2 changes: 2 additions & 0 deletions trunk/arch/um/include/os.h
Original file line number Diff line number Diff line change
Expand Up @@ -340,4 +340,6 @@ extern void maybe_sigio_broken(int fd, int read);
extern void sig_handler_common_skas(int sig, void *sc_ptr);
extern void user_signal(int sig, union uml_pt_regs *regs, int pid);

extern int os_arch_prctl(int pid, int code, unsigned long *addr);

#endif
2 changes: 1 addition & 1 deletion trunk/arch/um/os-Linux/sys-x86_64/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Licensed under the GPL
#

obj-$(CONFIG_MODE_SKAS) = registers.o signal.o
obj-$(CONFIG_MODE_SKAS) = registers.o prctl.o signal.o

USER_OBJS := $(obj-y)

Expand Down
12 changes: 12 additions & 0 deletions trunk/arch/um/os-Linux/sys-x86_64/prctl.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* Copyright (C) 2007 Jeff Dike (jdike@{addtoit.com,linux.intel.com})
* Licensed under the GPL
*/

#include <sys/ptrace.h>
#include <linux/ptrace.h>

int os_arch_prctl(int pid, int code, unsigned long *addr)
{
return ptrace(PTRACE_ARCH_PRCTL, pid, (unsigned long) addr, code);
}
73 changes: 55 additions & 18 deletions trunk/arch/um/sys-x86_64/syscalls.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "asm/prctl.h" /* XXX This should get the constants from libc */
#include "choose-mode.h"
#include "kern.h"
#include "os.h"

asmlinkage long sys_uname64(struct new_utsname __user * name)
{
Expand Down Expand Up @@ -58,40 +59,67 @@ static long arch_prctl_tt(int code, unsigned long addr)

#ifdef CONFIG_MODE_SKAS

/* XXX: Must also call arch_prctl in the host, beside saving the segment bases! */
static long arch_prctl_skas(int code, unsigned long addr)
static long arch_prctl_skas(int code, unsigned long __user *addr)
{
long ret = 0;
unsigned long *ptr = addr, tmp;
long ret;
int pid = current->mm->context.skas.id.u.pid;

/*
* With ARCH_SET_FS (and ARCH_SET_GS is treated similarly to
* be safe), we need to call arch_prctl on the host because
* setting %fs may result in something else happening (like a
* GDT being set instead). So, we let the host fiddle the
* registers and restore them afterwards.
*
* So, the saved registers are stored to the process (this
* needed because a stub may have been the last thing to run),
* arch_prctl is run on the host, then the registers are read
* back.
*/
switch(code){
case ARCH_SET_FS:
current->thread.regs.regs.skas.regs[FS_BASE / sizeof(unsigned long)] = addr;
break;
case ARCH_SET_GS:
current->thread.regs.regs.skas.regs[GS_BASE / sizeof(unsigned long)] = addr;
restore_registers(pid, &current->thread.regs.regs);
break;
case ARCH_GET_FS:
case ARCH_GET_GS:
/*
* With these two, we read to a local pointer and
* put_user it to the userspace pointer that we were
* given. If addr isn't valid (because it hasn't been
* faulted in or is just bogus), we want put_user to
* fault it in (or return -EFAULT) instead of having
* the host return -EFAULT.
*/
ptr = &tmp;
}

ret = os_arch_prctl(pid, code, ptr);
if(ret)
return ret;

switch(code){
case ARCH_SET_FS:
case ARCH_SET_GS:
save_registers(pid, &current->thread.regs.regs);
break;
case ARCH_GET_FS:
ret = put_user(current->thread.regs.regs.skas.
regs[FS_BASE / sizeof(unsigned long)],
(unsigned long __user *)addr);
ret = put_user(tmp, addr);
break;
case ARCH_GET_GS:
ret = put_user(current->thread.regs.regs.skas.
regs[GS_BASE / sizeof(unsigned long)],
(unsigned long __user *)addr);
ret = put_user(tmp, addr);
break;
default:
ret = -EINVAL;
break;
}

return(ret);
return ret;
}
#endif

long sys_arch_prctl(int code, unsigned long addr)
{
return(CHOOSE_MODE_PROC(arch_prctl_tt, arch_prctl_skas, code, addr));
return CHOOSE_MODE_PROC(arch_prctl_tt, arch_prctl_skas, code,
(unsigned long __user *) addr);
}

long sys_clone(unsigned long clone_flags, unsigned long newsp,
Expand All @@ -105,5 +133,14 @@ long sys_clone(unsigned long clone_flags, unsigned long newsp,
ret = do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid,
child_tid);
current->thread.forking = 0;
return(ret);
return ret;
}

void arch_switch_to_skas(struct task_struct *from, struct task_struct *to)
{
if(to->thread.arch.fs == 0)
return;

arch_prctl_skas(ARCH_SET_FS, (void __user *) to->thread.arch.fs);
}

11 changes: 7 additions & 4 deletions trunk/arch/um/sys-x86_64/tls.c
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
#include "linux/sched.h"

void debug_arch_force_load_TLS(void)
{
}

void clear_flushed_tls(struct task_struct *task)
{
}

int arch_copy_tls(struct task_struct *t)
{
/*
* If CLONE_SETTLS is set, we need to save the thread id
* (which is argument 5, child_tid, of clone) so it can be set
* during context switches.
*/
t->thread.arch.fs = t->thread.regs.regs.skas.regs[R8 / sizeof(long)];

return 0;
}
6 changes: 4 additions & 2 deletions trunk/include/asm-um/processor-x86_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
struct arch_thread {
unsigned long debugregs[8];
int debugregs_seq;
unsigned long fs;
struct faultinfo faultinfo;
};

Expand All @@ -25,8 +26,9 @@ extern inline void rep_nop(void)
#define cpu_relax() rep_nop()

#define INIT_ARCH_THREAD { .debugregs = { [ 0 ... 7 ] = 0 }, \
.debugregs_seq = 0, \
.faultinfo = { 0, 0, 0 } }
.debugregs_seq = 0, \
.fs = 0, \
.faultinfo = { 0, 0, 0 } }

static inline void arch_flush_thread(struct arch_thread *thread)
{
Expand Down
6 changes: 2 additions & 4 deletions trunk/include/asm-um/ptrace-x86_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,7 @@ static inline void arch_switch_to_tt(struct task_struct *from,
{
}

static inline void arch_switch_to_skas(struct task_struct *from,
struct task_struct *to)
{
}
extern void arch_switch_to_skas(struct task_struct *from,
struct task_struct *to);

#endif

0 comments on commit 167bc34

Please sign in to comment.