* UML fixes for 3.1-rcX
@ 2011-08-29 16:03 Richard Weinberger
2011-08-29 16:03 ` [PATCH 1/9] um: disable CMPXCHG_DOUBLE as it breaks UML build Richard Weinberger
` (6 more replies)
0 siblings, 7 replies; 15+ messages in thread
From: Richard Weinberger @ 2011-08-29 16:03 UTC (permalink / raw)
To: akpm; +Cc: linux-kernel, user-mode-linux-devel
[PATCH 1/9] um: disable CMPXCHG_DOUBLE as it breaks UML build
[PATCH 2/9] um: drivers/xterm.c: fix a file descriptor leak
[PATCH 3/9] um: Save FPU registers between task switches
[PATCH 4/9] um: fix oopsable race in line_close()
[PATCH 5/9] um: winch_interrupt() can happen inside of free_winch()
[PATCH 6/9] um: fix free_winch() mess
[PATCH 7/9] um: PTRACE_[GS]ETFPXREGS had been wired on the wrong
[PATCH 8/9] um: fix strrchr problems
[PATCH 9/9] um: clean arch_ptrace() up a bit
arch/um/Kconfig.x86 | 4 ++
arch/um/Makefile | 2 +-
arch/um/drivers/line.c | 61 +++++++++++++++++------------
arch/um/drivers/xterm.c | 1 +
arch/um/include/asm/ptrace-generic.h | 4 --
arch/um/include/shared/line.h | 1 +
arch/um/include/shared/registers.h | 2 +-
arch/um/kernel/process.c | 2 +-
arch/um/kernel/ptrace.c | 28 -------------
arch/um/os-Linux/registers.c | 9 ++++-
arch/um/os-Linux/skas/mem.c | 2 +-
arch/um/os-Linux/skas/process.c | 19 ++++++++-
arch/um/sys-i386/asm/ptrace.h | 5 --
arch/um/sys-i386/ptrace.c | 28 +++++++++++--
arch/um/sys-i386/shared/sysdep/ptrace.h | 1 +
arch/um/sys-x86_64/ptrace.c | 12 ++++--
arch/um/sys-x86_64/shared/sysdep/ptrace.h | 1 +
17 files changed, 105 insertions(+), 77 deletions(-)
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 1/9] um: disable CMPXCHG_DOUBLE as it breaks UML build
2011-08-29 16:03 UML fixes for 3.1-rcX Richard Weinberger
@ 2011-08-29 16:03 ` Richard Weinberger
2011-08-29 16:03 ` [uml-devel] " Richard Weinberger
` (5 subsequent siblings)
6 siblings, 0 replies; 15+ messages in thread
From: Richard Weinberger @ 2011-08-29 16:03 UTC (permalink / raw)
To: akpm
Cc: linux-kernel, user-mode-linux-devel,
Thadeu Lima de Souza Cascardo, Christoph Lameter, Jeff Dike,
Richard Weinberger
From: Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
Commit b789ef518b2a7231b0668c813f677cee528a9d3f tests for cmpxchg_double
support in the SLUB code and it breaks UML builds with SLUB. Since UML
does not support checking for CPU features, disable CMPXCHG_DOUBLE just
like CMPXCHG_LOCAL is disabled for UML.
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
Cc: Christoph Lameter <cl@linux.com>
Cc: Jeff Dike <jdike@addtoit.com>
Cc: Richard Weinberger <richard@nod.at>
Signed-off-by: Richard Weinberger <richard@nod.at>
---
arch/um/Kconfig.x86 | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/arch/um/Kconfig.x86 b/arch/um/Kconfig.x86
index d31ecf3..21bebe6 100644
--- a/arch/um/Kconfig.x86
+++ b/arch/um/Kconfig.x86
@@ -10,6 +10,10 @@ config CMPXCHG_LOCAL
bool
default n
+config CMPXCHG_DOUBLE
+ bool
+ default n
+
source "arch/x86/Kconfig.cpu"
endmenu
--
1.7.6.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 2/9] um: drivers/xterm.c: fix a file descriptor leak
2011-08-29 16:03 UML fixes for 3.1-rcX Richard Weinberger
@ 2011-08-29 16:03 ` Richard Weinberger
2011-08-29 16:03 ` [uml-devel] " Richard Weinberger
` (5 subsequent siblings)
6 siblings, 0 replies; 15+ messages in thread
From: Richard Weinberger @ 2011-08-29 16:03 UTC (permalink / raw)
To: akpm
Cc: linux-kernel, user-mode-linux-devel, Jonathan Neuschäfer,
Richard Weinberger
From: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
I could use out_close1, but that seems to be the code path to close the
fd returned by os_create_unix_socket, and using it to close the fd
returned by mkstemp might lead to some confusion, so I don't do it.
Signed-off-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
Signed-off-by: Richard Weinberger <richard@nod.at>
---
arch/um/drivers/xterm.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
index 8ac7146..2e1de57 100644
--- a/arch/um/drivers/xterm.c
+++ b/arch/um/drivers/xterm.c
@@ -123,6 +123,7 @@ static int xterm_open(int input, int output, int primary, void *d,
err = -errno;
printk(UM_KERN_ERR "xterm_open : unlink failed, errno = %d\n",
errno);
+ close(fd);
return err;
}
close(fd);
--
1.7.6.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [uml-devel] [PATCH 2/9] um: drivers/xterm.c: fix a file descriptor leak
@ 2011-08-29 16:03 ` Richard Weinberger
0 siblings, 0 replies; 15+ messages in thread
From: Richard Weinberger @ 2011-08-29 16:03 UTC (permalink / raw)
To: akpm
Cc: Richard Weinberger, linux-kernel, user-mode-linux-devel,
Jonathan Neuschäfer
From: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
I could use out_close1, but that seems to be the code path to close the
fd returned by os_create_unix_socket, and using it to close the fd
returned by mkstemp might lead to some confusion, so I don't do it.
Signed-off-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
Signed-off-by: Richard Weinberger <richard@nod.at>
---
arch/um/drivers/xterm.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
index 8ac7146..2e1de57 100644
--- a/arch/um/drivers/xterm.c
+++ b/arch/um/drivers/xterm.c
@@ -123,6 +123,7 @@ static int xterm_open(int input, int output, int primary, void *d,
err = -errno;
printk(UM_KERN_ERR "xterm_open : unlink failed, errno = %d\n",
errno);
+ close(fd);
return err;
}
close(fd);
--
1.7.6.1
------------------------------------------------------------------------------
EMC VNX: the world's simplest storage, starting under $10K
The only unified storage solution that offers unified management
Up to 160% more powerful than alternatives and 25% more efficient.
Guaranteed. http://p.sf.net/sfu/emc-vnx-dev2dev
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 3/9] um: Save FPU registers between task switches
2011-08-29 16:03 UML fixes for 3.1-rcX Richard Weinberger
@ 2011-08-29 16:03 ` Richard Weinberger
2011-08-29 16:03 ` [uml-devel] " Richard Weinberger
` (5 subsequent siblings)
6 siblings, 0 replies; 15+ messages in thread
From: Richard Weinberger @ 2011-08-29 16:03 UTC (permalink / raw)
To: akpm
Cc: linux-kernel, user-mode-linux-devel, Ingo van Lil,
Richard Weinberger, Stanislav Meduna
From: Ingo van Lil <inguin@gmx.de>
Some time ago Jeff prepared a patch (42daba3) for UML to stop saving the
process FP state between task switches. The assumption was that since
with SKAS0 every guest process runs inside a host process context the
host OS will take care of keeping the proper FP state. Unfortunately
this is not true for multi-threaded applications, where all guest
threads share a single host process context yet all may use the FPU on
their own. Although I haven't verified it I suspect things to be even
worse in SKAS3 mode where all guest processes run inside a single host
process.
The patch below reintroduces the saving and restoring of the FP context
between task switches.
Signed-off-by: Ingo van Lil <inguin@gmx.de>
Signed-off-by: Richard Weinberger <richard@nod.at>
Reported-by: gunnarlindroth@hotmail.com
Tested-by: gunnarlindroth@hotmail.com
CC: Stanislav Meduna <stano@meduna.org>
[richard@nod.at: Ingo posted this patch in 2009, sadly it was never applied
and got lost. Now in 2011 the problem was reported by Gunnar.]
---
arch/um/include/shared/registers.h | 2 +-
arch/um/kernel/process.c | 2 +-
arch/um/os-Linux/registers.c | 9 ++++++++-
arch/um/os-Linux/skas/mem.c | 2 +-
arch/um/os-Linux/skas/process.c | 19 ++++++++++++++++++-
arch/um/sys-i386/shared/sysdep/ptrace.h | 1 +
arch/um/sys-x86_64/shared/sysdep/ptrace.h | 1 +
7 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/arch/um/include/shared/registers.h b/arch/um/include/shared/registers.h
index b0b4589..f1e0aa5 100644
--- a/arch/um/include/shared/registers.h
+++ b/arch/um/include/shared/registers.h
@@ -16,7 +16,7 @@ extern int restore_fpx_registers(int pid, unsigned long *fp_regs);
extern int save_registers(int pid, struct uml_pt_regs *regs);
extern int restore_registers(int pid, struct uml_pt_regs *regs);
extern int init_registers(int pid);
-extern void get_safe_registers(unsigned long *regs);
+extern void get_safe_registers(unsigned long *regs, unsigned long *fp_regs);
extern unsigned long get_thread_reg(int reg, jmp_buf *buf);
extern int get_fp_registers(int pid, unsigned long *regs);
extern int put_fp_registers(int pid, unsigned long *regs);
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index fab4371..21c1ae7 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -202,7 +202,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
arch_copy_thread(¤t->thread.arch, &p->thread.arch);
}
else {
- get_safe_registers(p->thread.regs.regs.gp);
+ get_safe_registers(p->thread.regs.regs.gp, p->thread.regs.regs.fp);
p->thread.request.u.thread = current->thread.request.u.thread;
handler = new_thread_handler;
}
diff --git a/arch/um/os-Linux/registers.c b/arch/um/os-Linux/registers.c
index 830fe6a..b866b9e 100644
--- a/arch/um/os-Linux/registers.c
+++ b/arch/um/os-Linux/registers.c
@@ -8,6 +8,8 @@
#include <string.h>
#include <sys/ptrace.h>
#include "sysdep/ptrace.h"
+#include "sysdep/ptrace_user.h"
+#include "registers.h"
int save_registers(int pid, struct uml_pt_regs *regs)
{
@@ -32,6 +34,7 @@ int restore_registers(int pid, struct uml_pt_regs *regs)
/* This is set once at boot time and not changed thereafter */
static unsigned long exec_regs[MAX_REG_NR];
+static unsigned long exec_fp_regs[FP_SIZE];
int init_registers(int pid)
{
@@ -42,10 +45,14 @@ int init_registers(int pid)
return -errno;
arch_init_registers(pid);
+ get_fp_registers(pid, exec_fp_regs);
return 0;
}
-void get_safe_registers(unsigned long *regs)
+void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
{
memcpy(regs, exec_regs, sizeof(exec_regs));
+
+ if (fp_regs)
+ memcpy(fp_regs, exec_fp_regs, sizeof(exec_fp_regs));
}
diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c
index d261f17..e771398 100644
--- a/arch/um/os-Linux/skas/mem.c
+++ b/arch/um/os-Linux/skas/mem.c
@@ -39,7 +39,7 @@ static unsigned long syscall_regs[MAX_REG_NR];
static int __init init_syscall_regs(void)
{
- get_safe_registers(syscall_regs);
+ get_safe_registers(syscall_regs, NULL);
syscall_regs[REGS_IP_INDEX] = STUB_CODE +
((unsigned long) &batch_syscall_stub -
(unsigned long) &__syscall_stub_start);
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index d6e0a22..dee0e8c 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -373,6 +373,9 @@ void userspace(struct uml_pt_regs *regs)
if (ptrace(PTRACE_SETREGS, pid, 0, regs->gp))
fatal_sigsegv();
+ if (put_fp_registers(pid, regs->fp))
+ fatal_sigsegv();
+
/* Now we set local_using_sysemu to be used for one loop */
local_using_sysemu = get_using_sysemu();
@@ -399,6 +402,12 @@ void userspace(struct uml_pt_regs *regs)
fatal_sigsegv();
}
+ if (get_fp_registers(pid, regs->fp)) {
+ printk(UM_KERN_ERR "userspace - get_fp_registers failed, "
+ "errno = %d\n", errno);
+ fatal_sigsegv();
+ }
+
UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */
if (WIFSTOPPED(status)) {
@@ -457,10 +466,11 @@ void userspace(struct uml_pt_regs *regs)
}
static unsigned long thread_regs[MAX_REG_NR];
+static unsigned long thread_fp_regs[FP_SIZE];
static int __init init_thread_regs(void)
{
- get_safe_registers(thread_regs);
+ get_safe_registers(thread_regs, thread_fp_regs);
/* Set parent's instruction pointer to start of clone-stub */
thread_regs[REGS_IP_INDEX] = STUB_CODE +
(unsigned long) stub_clone_handler -
@@ -503,6 +513,13 @@ int copy_context_skas0(unsigned long new_stack, int pid)
return err;
}
+ err = put_fp_registers(pid, thread_fp_regs);
+ if (err < 0) {
+ printk(UM_KERN_ERR "copy_context_skas0 : put_fp_registers "
+ "failed, pid = %d, err = %d\n", pid, err);
+ return err;
+ }
+
/* set a well known return code for detection of child write failure */
child_data->err = 12345678;
diff --git a/arch/um/sys-i386/shared/sysdep/ptrace.h b/arch/um/sys-i386/shared/sysdep/ptrace.h
index d50e62e..c398a50 100644
--- a/arch/um/sys-i386/shared/sysdep/ptrace.h
+++ b/arch/um/sys-i386/shared/sysdep/ptrace.h
@@ -53,6 +53,7 @@ extern int sysemu_supported;
struct uml_pt_regs {
unsigned long gp[MAX_REG_NR];
+ unsigned long fp[HOST_FPX_SIZE];
struct faultinfo faultinfo;
long syscall;
int is_user;
diff --git a/arch/um/sys-x86_64/shared/sysdep/ptrace.h b/arch/um/sys-x86_64/shared/sysdep/ptrace.h
index fdba545..8ee8f8e 100644
--- a/arch/um/sys-x86_64/shared/sysdep/ptrace.h
+++ b/arch/um/sys-x86_64/shared/sysdep/ptrace.h
@@ -85,6 +85,7 @@
struct uml_pt_regs {
unsigned long gp[MAX_REG_NR];
+ unsigned long fp[HOST_FP_SIZE];
struct faultinfo faultinfo;
long syscall;
int is_user;
--
1.7.6.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [uml-devel] [PATCH 3/9] um: Save FPU registers between task switches
@ 2011-08-29 16:03 ` Richard Weinberger
0 siblings, 0 replies; 15+ messages in thread
From: Richard Weinberger @ 2011-08-29 16:03 UTC (permalink / raw)
To: akpm
Cc: Richard Weinberger, linux-kernel, user-mode-linux-devel, Ingo van Lil
From: Ingo van Lil <inguin@gmx.de>
Some time ago Jeff prepared a patch (42daba3) for UML to stop saving the
process FP state between task switches. The assumption was that since
with SKAS0 every guest process runs inside a host process context the
host OS will take care of keeping the proper FP state. Unfortunately
this is not true for multi-threaded applications, where all guest
threads share a single host process context yet all may use the FPU on
their own. Although I haven't verified it I suspect things to be even
worse in SKAS3 mode where all guest processes run inside a single host
process.
The patch below reintroduces the saving and restoring of the FP context
between task switches.
Signed-off-by: Ingo van Lil <inguin@gmx.de>
Signed-off-by: Richard Weinberger <richard@nod.at>
Reported-by: gunnarlindroth@hotmail.com
Tested-by: gunnarlindroth@hotmail.com
CC: Stanislav Meduna <stano@meduna.org>
[richard@nod.at: Ingo posted this patch in 2009, sadly it was never applied
and got lost. Now in 2011 the problem was reported by Gunnar.]
---
arch/um/include/shared/registers.h | 2 +-
arch/um/kernel/process.c | 2 +-
arch/um/os-Linux/registers.c | 9 ++++++++-
arch/um/os-Linux/skas/mem.c | 2 +-
arch/um/os-Linux/skas/process.c | 19 ++++++++++++++++++-
arch/um/sys-i386/shared/sysdep/ptrace.h | 1 +
arch/um/sys-x86_64/shared/sysdep/ptrace.h | 1 +
7 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/arch/um/include/shared/registers.h b/arch/um/include/shared/registers.h
index b0b4589..f1e0aa5 100644
--- a/arch/um/include/shared/registers.h
+++ b/arch/um/include/shared/registers.h
@@ -16,7 +16,7 @@ extern int restore_fpx_registers(int pid, unsigned long *fp_regs);
extern int save_registers(int pid, struct uml_pt_regs *regs);
extern int restore_registers(int pid, struct uml_pt_regs *regs);
extern int init_registers(int pid);
-extern void get_safe_registers(unsigned long *regs);
+extern void get_safe_registers(unsigned long *regs, unsigned long *fp_regs);
extern unsigned long get_thread_reg(int reg, jmp_buf *buf);
extern int get_fp_registers(int pid, unsigned long *regs);
extern int put_fp_registers(int pid, unsigned long *regs);
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index fab4371..21c1ae7 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -202,7 +202,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
arch_copy_thread(¤t->thread.arch, &p->thread.arch);
}
else {
- get_safe_registers(p->thread.regs.regs.gp);
+ get_safe_registers(p->thread.regs.regs.gp, p->thread.regs.regs.fp);
p->thread.request.u.thread = current->thread.request.u.thread;
handler = new_thread_handler;
}
diff --git a/arch/um/os-Linux/registers.c b/arch/um/os-Linux/registers.c
index 830fe6a..b866b9e 100644
--- a/arch/um/os-Linux/registers.c
+++ b/arch/um/os-Linux/registers.c
@@ -8,6 +8,8 @@
#include <string.h>
#include <sys/ptrace.h>
#include "sysdep/ptrace.h"
+#include "sysdep/ptrace_user.h"
+#include "registers.h"
int save_registers(int pid, struct uml_pt_regs *regs)
{
@@ -32,6 +34,7 @@ int restore_registers(int pid, struct uml_pt_regs *regs)
/* This is set once at boot time and not changed thereafter */
static unsigned long exec_regs[MAX_REG_NR];
+static unsigned long exec_fp_regs[FP_SIZE];
int init_registers(int pid)
{
@@ -42,10 +45,14 @@ int init_registers(int pid)
return -errno;
arch_init_registers(pid);
+ get_fp_registers(pid, exec_fp_regs);
return 0;
}
-void get_safe_registers(unsigned long *regs)
+void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
{
memcpy(regs, exec_regs, sizeof(exec_regs));
+
+ if (fp_regs)
+ memcpy(fp_regs, exec_fp_regs, sizeof(exec_fp_regs));
}
diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c
index d261f17..e771398 100644
--- a/arch/um/os-Linux/skas/mem.c
+++ b/arch/um/os-Linux/skas/mem.c
@@ -39,7 +39,7 @@ static unsigned long syscall_regs[MAX_REG_NR];
static int __init init_syscall_regs(void)
{
- get_safe_registers(syscall_regs);
+ get_safe_registers(syscall_regs, NULL);
syscall_regs[REGS_IP_INDEX] = STUB_CODE +
((unsigned long) &batch_syscall_stub -
(unsigned long) &__syscall_stub_start);
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index d6e0a22..dee0e8c 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -373,6 +373,9 @@ void userspace(struct uml_pt_regs *regs)
if (ptrace(PTRACE_SETREGS, pid, 0, regs->gp))
fatal_sigsegv();
+ if (put_fp_registers(pid, regs->fp))
+ fatal_sigsegv();
+
/* Now we set local_using_sysemu to be used for one loop */
local_using_sysemu = get_using_sysemu();
@@ -399,6 +402,12 @@ void userspace(struct uml_pt_regs *regs)
fatal_sigsegv();
}
+ if (get_fp_registers(pid, regs->fp)) {
+ printk(UM_KERN_ERR "userspace - get_fp_registers failed, "
+ "errno = %d\n", errno);
+ fatal_sigsegv();
+ }
+
UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */
if (WIFSTOPPED(status)) {
@@ -457,10 +466,11 @@ void userspace(struct uml_pt_regs *regs)
}
static unsigned long thread_regs[MAX_REG_NR];
+static unsigned long thread_fp_regs[FP_SIZE];
static int __init init_thread_regs(void)
{
- get_safe_registers(thread_regs);
+ get_safe_registers(thread_regs, thread_fp_regs);
/* Set parent's instruction pointer to start of clone-stub */
thread_regs[REGS_IP_INDEX] = STUB_CODE +
(unsigned long) stub_clone_handler -
@@ -503,6 +513,13 @@ int copy_context_skas0(unsigned long new_stack, int pid)
return err;
}
+ err = put_fp_registers(pid, thread_fp_regs);
+ if (err < 0) {
+ printk(UM_KERN_ERR "copy_context_skas0 : put_fp_registers "
+ "failed, pid = %d, err = %d\n", pid, err);
+ return err;
+ }
+
/* set a well known return code for detection of child write failure */
child_data->err = 12345678;
diff --git a/arch/um/sys-i386/shared/sysdep/ptrace.h b/arch/um/sys-i386/shared/sysdep/ptrace.h
index d50e62e..c398a50 100644
--- a/arch/um/sys-i386/shared/sysdep/ptrace.h
+++ b/arch/um/sys-i386/shared/sysdep/ptrace.h
@@ -53,6 +53,7 @@ extern int sysemu_supported;
struct uml_pt_regs {
unsigned long gp[MAX_REG_NR];
+ unsigned long fp[HOST_FPX_SIZE];
struct faultinfo faultinfo;
long syscall;
int is_user;
diff --git a/arch/um/sys-x86_64/shared/sysdep/ptrace.h b/arch/um/sys-x86_64/shared/sysdep/ptrace.h
index fdba545..8ee8f8e 100644
--- a/arch/um/sys-x86_64/shared/sysdep/ptrace.h
+++ b/arch/um/sys-x86_64/shared/sysdep/ptrace.h
@@ -85,6 +85,7 @@
struct uml_pt_regs {
unsigned long gp[MAX_REG_NR];
+ unsigned long fp[HOST_FP_SIZE];
struct faultinfo faultinfo;
long syscall;
int is_user;
--
1.7.6.1
------------------------------------------------------------------------------
EMC VNX: the world's simplest storage, starting under $10K
The only unified storage solution that offers unified management
Up to 160% more powerful than alternatives and 25% more efficient.
Guaranteed. http://p.sf.net/sfu/emc-vnx-dev2dev
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 4/9] um: fix oopsable race in line_close()
2011-08-29 16:03 UML fixes for 3.1-rcX Richard Weinberger
@ 2011-08-29 16:03 ` Richard Weinberger
2011-08-29 16:03 ` [uml-devel] " Richard Weinberger
` (5 subsequent siblings)
6 siblings, 0 replies; 15+ messages in thread
From: Richard Weinberger @ 2011-08-29 16:03 UTC (permalink / raw)
To: akpm
Cc: linux-kernel, user-mode-linux-devel, Al Viro, Al Viro,
Richard Weinberger
From: Al Viro <viro@ftp.linux.org.uk>
tty->count is decremented only after ->close() had been called and several
tasks can hit it in parallel. As the result, using tty->count to check if
you are the last one is broken. We end up leaving line->tty not reset to
NULL and the next IRQ on that sucker will blow up trying to dereference
pointers from kfree'd struct tty.
Fix is obvious: we need to use a counter of our own.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Richard Weinberger <richard@nod.at>
---
arch/um/drivers/line.c | 25 ++++++++++++-------------
arch/um/include/shared/line.h | 1 +
2 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index d51c404..c5bff1d 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -399,8 +399,8 @@ int line_setup_irq(int fd, int input, int output, struct line *line, void *data)
* is done under a spinlock. Checking whether the device is in use is
* line->tty->count > 1, also under the spinlock.
*
- * tty->count serves to decide whether the device should be enabled or
- * disabled on the host. If it's equal to 1, then we are doing the
+ * line->count serves to decide whether the device should be enabled or
+ * disabled on the host. If it's equal to 0, then we are doing the
* first open or last close. Otherwise, open and close just return.
*/
@@ -414,16 +414,16 @@ int line_open(struct line *lines, struct tty_struct *tty)
goto out_unlock;
err = 0;
- if (tty->count > 1)
+ if (line->count++)
goto out_unlock;
- spin_unlock(&line->count_lock);
-
+ BUG_ON(tty->driver_data);
tty->driver_data = line;
line->tty = tty;
+ spin_unlock(&line->count_lock);
err = enable_chan(line);
- if (err)
+ if (err) /* line_close() will be called by our caller */
return err;
INIT_DELAYED_WORK(&line->task, line_timer_cb);
@@ -436,7 +436,7 @@ int line_open(struct line *lines, struct tty_struct *tty)
chan_window_size(&line->chan_list, &tty->winsize.ws_row,
&tty->winsize.ws_col);
- return err;
+ return 0;
out_unlock:
spin_unlock(&line->count_lock);
@@ -460,17 +460,16 @@ void line_close(struct tty_struct *tty, struct file * filp)
flush_buffer(line);
spin_lock(&line->count_lock);
- if (!line->valid)
- goto out_unlock;
+ BUG_ON(!line->valid);
- if (tty->count > 1)
+ if (--line->count)
goto out_unlock;
- spin_unlock(&line->count_lock);
-
line->tty = NULL;
tty->driver_data = NULL;
+ spin_unlock(&line->count_lock);
+
if (line->sigio) {
unregister_winch(tty);
line->sigio = 0;
@@ -498,7 +497,7 @@ static int setup_one_line(struct line *lines, int n, char *init, int init_prio,
spin_lock(&line->count_lock);
- if (line->tty != NULL) {
+ if (line->count) {
*error_out = "Device is already open";
goto out;
}
diff --git a/arch/um/include/shared/line.h b/arch/um/include/shared/line.h
index 72f4f25..63df3ca 100644
--- a/arch/um/include/shared/line.h
+++ b/arch/um/include/shared/line.h
@@ -33,6 +33,7 @@ struct line_driver {
struct line {
struct tty_struct *tty;
spinlock_t count_lock;
+ unsigned long count;
int valid;
char *init_str;
--
1.7.6.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [uml-devel] [PATCH 4/9] um: fix oopsable race in line_close()
@ 2011-08-29 16:03 ` Richard Weinberger
0 siblings, 0 replies; 15+ messages in thread
From: Richard Weinberger @ 2011-08-29 16:03 UTC (permalink / raw)
To: akpm
Cc: Richard Weinberger, Al Viro, linux-kernel, user-mode-linux-devel,
Al Viro
From: Al Viro <viro@ftp.linux.org.uk>
tty->count is decremented only after ->close() had been called and several
tasks can hit it in parallel. As the result, using tty->count to check if
you are the last one is broken. We end up leaving line->tty not reset to
NULL and the next IRQ on that sucker will blow up trying to dereference
pointers from kfree'd struct tty.
Fix is obvious: we need to use a counter of our own.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Richard Weinberger <richard@nod.at>
---
arch/um/drivers/line.c | 25 ++++++++++++-------------
arch/um/include/shared/line.h | 1 +
2 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index d51c404..c5bff1d 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -399,8 +399,8 @@ int line_setup_irq(int fd, int input, int output, struct line *line, void *data)
* is done under a spinlock. Checking whether the device is in use is
* line->tty->count > 1, also under the spinlock.
*
- * tty->count serves to decide whether the device should be enabled or
- * disabled on the host. If it's equal to 1, then we are doing the
+ * line->count serves to decide whether the device should be enabled or
+ * disabled on the host. If it's equal to 0, then we are doing the
* first open or last close. Otherwise, open and close just return.
*/
@@ -414,16 +414,16 @@ int line_open(struct line *lines, struct tty_struct *tty)
goto out_unlock;
err = 0;
- if (tty->count > 1)
+ if (line->count++)
goto out_unlock;
- spin_unlock(&line->count_lock);
-
+ BUG_ON(tty->driver_data);
tty->driver_data = line;
line->tty = tty;
+ spin_unlock(&line->count_lock);
err = enable_chan(line);
- if (err)
+ if (err) /* line_close() will be called by our caller */
return err;
INIT_DELAYED_WORK(&line->task, line_timer_cb);
@@ -436,7 +436,7 @@ int line_open(struct line *lines, struct tty_struct *tty)
chan_window_size(&line->chan_list, &tty->winsize.ws_row,
&tty->winsize.ws_col);
- return err;
+ return 0;
out_unlock:
spin_unlock(&line->count_lock);
@@ -460,17 +460,16 @@ void line_close(struct tty_struct *tty, struct file * filp)
flush_buffer(line);
spin_lock(&line->count_lock);
- if (!line->valid)
- goto out_unlock;
+ BUG_ON(!line->valid);
- if (tty->count > 1)
+ if (--line->count)
goto out_unlock;
- spin_unlock(&line->count_lock);
-
line->tty = NULL;
tty->driver_data = NULL;
+ spin_unlock(&line->count_lock);
+
if (line->sigio) {
unregister_winch(tty);
line->sigio = 0;
@@ -498,7 +497,7 @@ static int setup_one_line(struct line *lines, int n, char *init, int init_prio,
spin_lock(&line->count_lock);
- if (line->tty != NULL) {
+ if (line->count) {
*error_out = "Device is already open";
goto out;
}
diff --git a/arch/um/include/shared/line.h b/arch/um/include/shared/line.h
index 72f4f25..63df3ca 100644
--- a/arch/um/include/shared/line.h
+++ b/arch/um/include/shared/line.h
@@ -33,6 +33,7 @@ struct line_driver {
struct line {
struct tty_struct *tty;
spinlock_t count_lock;
+ unsigned long count;
int valid;
char *init_str;
--
1.7.6.1
------------------------------------------------------------------------------
EMC VNX: the world's simplest storage, starting under $10K
The only unified storage solution that offers unified management
Up to 160% more powerful than alternatives and 25% more efficient.
Guaranteed. http://p.sf.net/sfu/emc-vnx-dev2dev
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 5/9] um: winch_interrupt() can happen inside of free_winch()
2011-08-29 16:03 UML fixes for 3.1-rcX Richard Weinberger
@ 2011-08-29 16:03 ` Richard Weinberger
2011-08-29 16:03 ` [uml-devel] " Richard Weinberger
` (5 subsequent siblings)
6 siblings, 0 replies; 15+ messages in thread
From: Richard Weinberger @ 2011-08-29 16:03 UTC (permalink / raw)
To: akpm
Cc: linux-kernel, user-mode-linux-devel, Al Viro, Al Viro,
Richard Weinberger
From: Al Viro <viro@ftp.linux.org.uk>
... so set winch->fd to -1 before doing free_irq(), to avoid having
winch_interrupt() come from/during the latter and attempt to do
reactivate_fd() on something that's already gone.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Richard Weinberger <richard@nod.at>
---
arch/um/drivers/line.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index c5bff1d..91bf1894 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -725,6 +725,8 @@ struct winch {
static void free_winch(struct winch *winch, int free_irq_ok)
{
+ int fd = winch->fd;
+ winch->fd = -1;
if (free_irq_ok)
free_irq(WINCH_IRQ, winch);
@@ -732,8 +734,8 @@ static void free_winch(struct winch *winch, int free_irq_ok)
if (winch->pid != -1)
os_kill_process(winch->pid, 1);
- if (winch->fd != -1)
- os_close_file(winch->fd);
+ if (fd != -1)
+ os_close_file(fd);
if (winch->stack != 0)
free_stack(winch->stack, 0);
kfree(winch);
--
1.7.6.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [uml-devel] [PATCH 5/9] um: winch_interrupt() can happen inside of free_winch()
@ 2011-08-29 16:03 ` Richard Weinberger
0 siblings, 0 replies; 15+ messages in thread
From: Richard Weinberger @ 2011-08-29 16:03 UTC (permalink / raw)
To: akpm
Cc: Richard Weinberger, Al Viro, linux-kernel, user-mode-linux-devel,
Al Viro
From: Al Viro <viro@ftp.linux.org.uk>
... so set winch->fd to -1 before doing free_irq(), to avoid having
winch_interrupt() come from/during the latter and attempt to do
reactivate_fd() on something that's already gone.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Richard Weinberger <richard@nod.at>
---
arch/um/drivers/line.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index c5bff1d..91bf1894 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -725,6 +725,8 @@ struct winch {
static void free_winch(struct winch *winch, int free_irq_ok)
{
+ int fd = winch->fd;
+ winch->fd = -1;
if (free_irq_ok)
free_irq(WINCH_IRQ, winch);
@@ -732,8 +734,8 @@ static void free_winch(struct winch *winch, int free_irq_ok)
if (winch->pid != -1)
os_kill_process(winch->pid, 1);
- if (winch->fd != -1)
- os_close_file(winch->fd);
+ if (fd != -1)
+ os_close_file(fd);
if (winch->stack != 0)
free_stack(winch->stack, 0);
kfree(winch);
--
1.7.6.1
------------------------------------------------------------------------------
EMC VNX: the world's simplest storage, starting under $10K
The only unified storage solution that offers unified management
Up to 160% more powerful than alternatives and 25% more efficient.
Guaranteed. http://p.sf.net/sfu/emc-vnx-dev2dev
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 6/9] um: fix free_winch() mess
2011-08-29 16:03 UML fixes for 3.1-rcX Richard Weinberger
@ 2011-08-29 16:03 ` Richard Weinberger
2011-08-29 16:03 ` [uml-devel] " Richard Weinberger
` (5 subsequent siblings)
6 siblings, 0 replies; 15+ messages in thread
From: Richard Weinberger @ 2011-08-29 16:03 UTC (permalink / raw)
To: akpm
Cc: linux-kernel, user-mode-linux-devel, Al Viro, Al Viro,
Richard Weinberger
From: Al Viro <viro@ftp.linux.org.uk>
while not doing free_irq() from irq handler is commendable, kfree() on
the data passed to said handler before free_irq() is Not Good(tm).
Freeing the stack it's being run on is also not nice... Solution:
delay actually freeing stuff.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Richard Weinberger <richard@nod.at>
---
arch/um/drivers/line.c | 38 ++++++++++++++++++++++++--------------
1 files changed, 24 insertions(+), 14 deletions(-)
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 91bf1894..364c8a1 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -721,43 +721,53 @@ struct winch {
int pid;
struct tty_struct *tty;
unsigned long stack;
+ struct work_struct work;
};
-static void free_winch(struct winch *winch, int free_irq_ok)
+static void __free_winch(struct work_struct *work)
{
- int fd = winch->fd;
- winch->fd = -1;
- if (free_irq_ok)
- free_irq(WINCH_IRQ, winch);
-
- list_del(&winch->list);
+ struct winch *winch = container_of(work, struct winch, work);
+ free_irq(WINCH_IRQ, winch);
if (winch->pid != -1)
os_kill_process(winch->pid, 1);
- if (fd != -1)
- os_close_file(fd);
if (winch->stack != 0)
free_stack(winch->stack, 0);
kfree(winch);
}
+static void free_winch(struct winch *winch)
+{
+ int fd = winch->fd;
+ winch->fd = -1;
+ if (fd != -1)
+ os_close_file(fd);
+ list_del(&winch->list);
+ __free_winch(&winch->work);
+}
+
static irqreturn_t winch_interrupt(int irq, void *data)
{
struct winch *winch = data;
struct tty_struct *tty;
struct line *line;
+ int fd = winch->fd;
int err;
char c;
- if (winch->fd != -1) {
- err = generic_read(winch->fd, &c, NULL);
+ if (fd != -1) {
+ err = generic_read(fd, &c, NULL);
if (err < 0) {
if (err != -EAGAIN) {
+ winch->fd = -1;
+ list_del(&winch->list);
+ os_close_file(fd);
printk(KERN_ERR "winch_interrupt : "
"read failed, errno = %d\n", -err);
printk(KERN_ERR "fd %d is losing SIGWINCH "
"support\n", winch->tty_fd);
- free_winch(winch, 0);
+ INIT_WORK(&winch->work, __free_winch);
+ schedule_work(&winch->work);
return IRQ_HANDLED;
}
goto out;
@@ -829,7 +839,7 @@ static void unregister_winch(struct tty_struct *tty)
list_for_each_safe(ele, next, &winch_handlers) {
winch = list_entry(ele, struct winch, list);
if (winch->tty == tty) {
- free_winch(winch, 1);
+ free_winch(winch);
break;
}
}
@@ -845,7 +855,7 @@ static void winch_cleanup(void)
list_for_each_safe(ele, next, &winch_handlers) {
winch = list_entry(ele, struct winch, list);
- free_winch(winch, 1);
+ free_winch(winch);
}
spin_unlock(&winch_handler_lock);
--
1.7.6.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [uml-devel] [PATCH 6/9] um: fix free_winch() mess
@ 2011-08-29 16:03 ` Richard Weinberger
0 siblings, 0 replies; 15+ messages in thread
From: Richard Weinberger @ 2011-08-29 16:03 UTC (permalink / raw)
To: akpm
Cc: Richard Weinberger, Al Viro, linux-kernel, user-mode-linux-devel,
Al Viro
From: Al Viro <viro@ftp.linux.org.uk>
while not doing free_irq() from irq handler is commendable, kfree() on
the data passed to said handler before free_irq() is Not Good(tm).
Freeing the stack it's being run on is also not nice... Solution:
delay actually freeing stuff.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Richard Weinberger <richard@nod.at>
---
arch/um/drivers/line.c | 38 ++++++++++++++++++++++++--------------
1 files changed, 24 insertions(+), 14 deletions(-)
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 91bf1894..364c8a1 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -721,43 +721,53 @@ struct winch {
int pid;
struct tty_struct *tty;
unsigned long stack;
+ struct work_struct work;
};
-static void free_winch(struct winch *winch, int free_irq_ok)
+static void __free_winch(struct work_struct *work)
{
- int fd = winch->fd;
- winch->fd = -1;
- if (free_irq_ok)
- free_irq(WINCH_IRQ, winch);
-
- list_del(&winch->list);
+ struct winch *winch = container_of(work, struct winch, work);
+ free_irq(WINCH_IRQ, winch);
if (winch->pid != -1)
os_kill_process(winch->pid, 1);
- if (fd != -1)
- os_close_file(fd);
if (winch->stack != 0)
free_stack(winch->stack, 0);
kfree(winch);
}
+static void free_winch(struct winch *winch)
+{
+ int fd = winch->fd;
+ winch->fd = -1;
+ if (fd != -1)
+ os_close_file(fd);
+ list_del(&winch->list);
+ __free_winch(&winch->work);
+}
+
static irqreturn_t winch_interrupt(int irq, void *data)
{
struct winch *winch = data;
struct tty_struct *tty;
struct line *line;
+ int fd = winch->fd;
int err;
char c;
- if (winch->fd != -1) {
- err = generic_read(winch->fd, &c, NULL);
+ if (fd != -1) {
+ err = generic_read(fd, &c, NULL);
if (err < 0) {
if (err != -EAGAIN) {
+ winch->fd = -1;
+ list_del(&winch->list);
+ os_close_file(fd);
printk(KERN_ERR "winch_interrupt : "
"read failed, errno = %d\n", -err);
printk(KERN_ERR "fd %d is losing SIGWINCH "
"support\n", winch->tty_fd);
- free_winch(winch, 0);
+ INIT_WORK(&winch->work, __free_winch);
+ schedule_work(&winch->work);
return IRQ_HANDLED;
}
goto out;
@@ -829,7 +839,7 @@ static void unregister_winch(struct tty_struct *tty)
list_for_each_safe(ele, next, &winch_handlers) {
winch = list_entry(ele, struct winch, list);
if (winch->tty == tty) {
- free_winch(winch, 1);
+ free_winch(winch);
break;
}
}
@@ -845,7 +855,7 @@ static void winch_cleanup(void)
list_for_each_safe(ele, next, &winch_handlers) {
winch = list_entry(ele, struct winch, list);
- free_winch(winch, 1);
+ free_winch(winch);
}
spin_unlock(&winch_handler_lock);
--
1.7.6.1
------------------------------------------------------------------------------
EMC VNX: the world's simplest storage, starting under $10K
The only unified storage solution that offers unified management
Up to 160% more powerful than alternatives and 25% more efficient.
Guaranteed. http://p.sf.net/sfu/emc-vnx-dev2dev
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 7/9] um: PTRACE_[GS]ETFPXREGS had been wired on the wrong subarch
2011-08-29 16:03 UML fixes for 3.1-rcX Richard Weinberger
@ 2011-08-29 16:04 ` Richard Weinberger
2011-08-29 16:03 ` [uml-devel] " Richard Weinberger
` (5 subsequent siblings)
6 siblings, 0 replies; 15+ messages in thread
From: Richard Weinberger @ 2011-08-29 16:04 UTC (permalink / raw)
To: akpm
Cc: linux-kernel, user-mode-linux-devel, Al Viro, Al Viro,
Richard Weinberger
From: Al Viro <viro@ftp.linux.org.uk>
It's 32bit-only, not 64bit-only... And while we are at it, it's
set_fpxregs(), not set_fpregs()...
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Richard Weinberger <richard@nod.at>
---
arch/um/sys-i386/ptrace.c | 14 +++++++++++++-
arch/um/sys-x86_64/ptrace.c | 14 +-------------
2 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c
index d23b2d3..49fd25a 100644
--- a/arch/um/sys-i386/ptrace.c
+++ b/arch/um/sys-i386/ptrace.c
@@ -206,5 +206,17 @@ int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
long subarch_ptrace(struct task_struct *child, long request,
unsigned long addr, unsigned long data)
{
- return -EIO;
+ int ret = -EIO;
+ void __user *datap = (void __user *) data;
+
+ switch (request) {
+ case PTRACE_GETFPXREGS: /* Get the child FPU state. */
+ ret = get_fpxregs(datap, child);
+ break;
+ case PTRACE_SETFPXREGS: /* Set the child FPU state. */
+ ret = set_fpxregs(datap, child);
+ break;
+ }
+
+ return ret;
}
diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c
index f436136..7ed49ac 100644
--- a/arch/um/sys-x86_64/ptrace.c
+++ b/arch/um/sys-x86_64/ptrace.c
@@ -178,17 +178,5 @@ int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
long subarch_ptrace(struct task_struct *child, long request,
unsigned long addr, unsigned long data)
{
- int ret = -EIO;
- void __user *datap = (void __user *) data;
-
- switch (request) {
- case PTRACE_GETFPXREGS: /* Get the child FPU state. */
- ret = get_fpregs(datap, child);
- break;
- case PTRACE_SETFPXREGS: /* Set the child FPU state. */
- ret = set_fpregs(datap, child);
- break;
- }
-
- return ret;
+ return -EIO;
}
--
1.7.6.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [uml-devel] [PATCH 7/9] um: PTRACE_[GS]ETFPXREGS had been wired on the wrong subarch
@ 2011-08-29 16:04 ` Richard Weinberger
0 siblings, 0 replies; 15+ messages in thread
From: Richard Weinberger @ 2011-08-29 16:04 UTC (permalink / raw)
To: akpm
Cc: Richard Weinberger, Al Viro, linux-kernel, user-mode-linux-devel,
Al Viro
From: Al Viro <viro@ftp.linux.org.uk>
It's 32bit-only, not 64bit-only... And while we are at it, it's
set_fpxregs(), not set_fpregs()...
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Richard Weinberger <richard@nod.at>
---
arch/um/sys-i386/ptrace.c | 14 +++++++++++++-
arch/um/sys-x86_64/ptrace.c | 14 +-------------
2 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c
index d23b2d3..49fd25a 100644
--- a/arch/um/sys-i386/ptrace.c
+++ b/arch/um/sys-i386/ptrace.c
@@ -206,5 +206,17 @@ int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
long subarch_ptrace(struct task_struct *child, long request,
unsigned long addr, unsigned long data)
{
- return -EIO;
+ int ret = -EIO;
+ void __user *datap = (void __user *) data;
+
+ switch (request) {
+ case PTRACE_GETFPXREGS: /* Get the child FPU state. */
+ ret = get_fpxregs(datap, child);
+ break;
+ case PTRACE_SETFPXREGS: /* Set the child FPU state. */
+ ret = set_fpxregs(datap, child);
+ break;
+ }
+
+ return ret;
}
diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c
index f436136..7ed49ac 100644
--- a/arch/um/sys-x86_64/ptrace.c
+++ b/arch/um/sys-x86_64/ptrace.c
@@ -178,17 +178,5 @@ int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
long subarch_ptrace(struct task_struct *child, long request,
unsigned long addr, unsigned long data)
{
- int ret = -EIO;
- void __user *datap = (void __user *) data;
-
- switch (request) {
- case PTRACE_GETFPXREGS: /* Get the child FPU state. */
- ret = get_fpregs(datap, child);
- break;
- case PTRACE_SETFPXREGS: /* Set the child FPU state. */
- ret = set_fpregs(datap, child);
- break;
- }
-
- return ret;
+ return -EIO;
}
--
1.7.6.1
------------------------------------------------------------------------------
EMC VNX: the world's simplest storage, starting under $10K
The only unified storage solution that offers unified management
Up to 160% more powerful than alternatives and 25% more efficient.
Guaranteed. http://p.sf.net/sfu/emc-vnx-dev2dev
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 4/9] um: fix oopsable race in line_close()
2011-08-29 16:13 UML fixes for 3.1-rcX (2nd try) Richard Weinberger
@ 2011-08-29 16:13 ` Richard Weinberger
0 siblings, 0 replies; 15+ messages in thread
From: Richard Weinberger @ 2011-08-29 16:13 UTC (permalink / raw)
To: akpm
Cc: linux-kernel, user-mode-linux-devel, Al Viro, Al Viro,
Richard Weinberger
From: Al Viro <viro@ftp.linux.org.uk>
tty->count is decremented only after ->close() had been called and several
tasks can hit it in parallel. As the result, using tty->count to check if
you are the last one is broken. We end up leaving line->tty not reset to
NULL and the next IRQ on that sucker will blow up trying to dereference
pointers from kfree'd struct tty.
Fix is obvious: we need to use a counter of our own.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Richard Weinberger <richard@nod.at>
---
arch/um/drivers/line.c | 25 ++++++++++++-------------
arch/um/include/shared/line.h | 1 +
2 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index d51c404..c5bff1d 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -399,8 +399,8 @@ int line_setup_irq(int fd, int input, int output, struct line *line, void *data)
* is done under a spinlock. Checking whether the device is in use is
* line->tty->count > 1, also under the spinlock.
*
- * tty->count serves to decide whether the device should be enabled or
- * disabled on the host. If it's equal to 1, then we are doing the
+ * line->count serves to decide whether the device should be enabled or
+ * disabled on the host. If it's equal to 0, then we are doing the
* first open or last close. Otherwise, open and close just return.
*/
@@ -414,16 +414,16 @@ int line_open(struct line *lines, struct tty_struct *tty)
goto out_unlock;
err = 0;
- if (tty->count > 1)
+ if (line->count++)
goto out_unlock;
- spin_unlock(&line->count_lock);
-
+ BUG_ON(tty->driver_data);
tty->driver_data = line;
line->tty = tty;
+ spin_unlock(&line->count_lock);
err = enable_chan(line);
- if (err)
+ if (err) /* line_close() will be called by our caller */
return err;
INIT_DELAYED_WORK(&line->task, line_timer_cb);
@@ -436,7 +436,7 @@ int line_open(struct line *lines, struct tty_struct *tty)
chan_window_size(&line->chan_list, &tty->winsize.ws_row,
&tty->winsize.ws_col);
- return err;
+ return 0;
out_unlock:
spin_unlock(&line->count_lock);
@@ -460,17 +460,16 @@ void line_close(struct tty_struct *tty, struct file * filp)
flush_buffer(line);
spin_lock(&line->count_lock);
- if (!line->valid)
- goto out_unlock;
+ BUG_ON(!line->valid);
- if (tty->count > 1)
+ if (--line->count)
goto out_unlock;
- spin_unlock(&line->count_lock);
-
line->tty = NULL;
tty->driver_data = NULL;
+ spin_unlock(&line->count_lock);
+
if (line->sigio) {
unregister_winch(tty);
line->sigio = 0;
@@ -498,7 +497,7 @@ static int setup_one_line(struct line *lines, int n, char *init, int init_prio,
spin_lock(&line->count_lock);
- if (line->tty != NULL) {
+ if (line->count) {
*error_out = "Device is already open";
goto out;
}
diff --git a/arch/um/include/shared/line.h b/arch/um/include/shared/line.h
index 72f4f25..63df3ca 100644
--- a/arch/um/include/shared/line.h
+++ b/arch/um/include/shared/line.h
@@ -33,6 +33,7 @@ struct line_driver {
struct line {
struct tty_struct *tty;
spinlock_t count_lock;
+ unsigned long count;
int valid;
char *init_str;
--
1.7.6.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
end of thread, other threads:[~2011-08-29 16:15 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-29 16:03 UML fixes for 3.1-rcX Richard Weinberger
2011-08-29 16:03 ` [PATCH 1/9] um: disable CMPXCHG_DOUBLE as it breaks UML build Richard Weinberger
2011-08-29 16:03 ` [PATCH 2/9] um: drivers/xterm.c: fix a file descriptor leak Richard Weinberger
2011-08-29 16:03 ` [uml-devel] " Richard Weinberger
2011-08-29 16:03 ` [PATCH 3/9] um: Save FPU registers between task switches Richard Weinberger
2011-08-29 16:03 ` [uml-devel] " Richard Weinberger
2011-08-29 16:03 ` [PATCH 4/9] um: fix oopsable race in line_close() Richard Weinberger
2011-08-29 16:03 ` [uml-devel] " Richard Weinberger
2011-08-29 16:03 ` [PATCH 5/9] um: winch_interrupt() can happen inside of free_winch() Richard Weinberger
2011-08-29 16:03 ` [uml-devel] " Richard Weinberger
2011-08-29 16:03 ` [PATCH 6/9] um: fix free_winch() mess Richard Weinberger
2011-08-29 16:03 ` [uml-devel] " Richard Weinberger
2011-08-29 16:04 ` [PATCH 7/9] um: PTRACE_[GS]ETFPXREGS had been wired on the wrong subarch Richard Weinberger
2011-08-29 16:04 ` [uml-devel] " Richard Weinberger
2011-08-29 16:13 UML fixes for 3.1-rcX (2nd try) Richard Weinberger
2011-08-29 16:13 ` [PATCH 4/9] um: fix oopsable race in line_close() Richard Weinberger
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.