Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aa6758d4 authored by Paolo 'Blaisorblade' Giarrusso's avatar Paolo 'Blaisorblade' Giarrusso Committed by Linus Torvalds
Browse files

[PATCH] uml: implement {get,set}_thread_area for i386



Implement sys_[gs]et_thread_area and the corresponding ptrace operations for
UML.  This is the main chunk, additional parts follow.  This implementation is
now well tested and has run reliably for some time, and we've understood all
the previously existing problems.

Their implementation saves the new GDT content and then forwards the call to
the host when appropriate, i.e.  immediately when the target process is
running or on context switch otherwise (i.e.  on fork and on ptrace() calls).

In SKAS mode, we must switch registers on each context switch (because SKAS
does not switches tls_array together with current->mm).

Also, added get_cpu() locking; this has been done for SKAS mode, since TT does
not need it (it does not use smp_processor_id()).

Signed-off-by: default avatarPaolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
Acked-by: default avatarJeff Dike <jdike@addtoit.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 972410b0
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -236,6 +236,10 @@ extern int run_helper_thread(int (*proc)(void *), void *arg,
			     int stack_order);
extern int helper_wait(int pid);


/* tls.c */
extern int os_set_thread_area(void *data, int pid);
extern int os_get_thread_area(void *data, int pid);
/* umid.c */

extern int umid_file_name(char *name, char *buf, int len);
+1 −11
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@

void flush_thread(void)
{
	arch_flush_thread(&current->thread.arch);
	CHOOSE_MODE(flush_thread_tt(), flush_thread_skas());
}

@@ -74,14 +75,3 @@ long sys_execve(char __user *file, char __user *__user *argv,
	unlock_kernel();
	return(error);
}

/*
 * Overrides for Emacs so that we follow Linus's tabbing style.
 * Emacs will notice this stuff at the end of the file and automatically
 * adjust the settings for this buffer only.  This must remain at the end
 * of the file.
 * ---------------------------------------------------------------------------
 * Local variables:
 * c-file-style: "linux"
 * End:
 */
+18 −2
Original line number Diff line number Diff line
@@ -156,9 +156,25 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
		unsigned long stack_top, struct task_struct * p, 
		struct pt_regs *regs)
{
	int ret;

	p->thread = (struct thread_struct) INIT_THREAD;
	return(CHOOSE_MODE_PROC(copy_thread_tt, copy_thread_skas, nr, 
				clone_flags, sp, stack_top, p, regs));
	ret = CHOOSE_MODE_PROC(copy_thread_tt, copy_thread_skas, nr,
				clone_flags, sp, stack_top, p, regs);

	if (ret || !current->thread.forking)
		goto out;

	clear_flushed_tls(p);

	/*
	 * Set a new TLS for the child thread?
	 */
	if (clone_flags & CLONE_SETTLS)
		ret = arch_copy_tls(p);

out:
	return ret;
}

void initial_thread_cb(void (*proc)(void *), void *arg)
+10 −0
Original line number Diff line number Diff line
@@ -185,6 +185,16 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
		ret = set_fpxregs(data, child);
		break;
#endif
	case PTRACE_GET_THREAD_AREA:
		ret = ptrace_get_thread_area(child, addr,
					     (struct user_desc __user *) data);
		break;

	case PTRACE_SET_THREAD_AREA:
		ret = ptrace_set_thread_area(child, addr,
					     (struct user_desc __user *) data);
		break;

	case PTRACE_FAULTINFO: {
		/* Take the info from thread->arch->faultinfo,
		 * but transfer max. sizeof(struct ptrace_faultinfo).
+2 −0
Original line number Diff line number Diff line
@@ -111,6 +111,8 @@ int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp,
		if(sp != 0) REGS_SP(p->thread.regs.regs.skas.regs) = sp;

		handler = fork_handler;

		arch_copy_thread(&current->thread.arch, &p->thread.arch);
	}
	else {
		init_thread_registers(&p->thread.regs.regs);
Loading