Hi Jeff,
here is the next patch for UML/s390 preparation.
If new_mm() has a vaild from_fd, it copies the LDT of
from_mm to new_mm using MM_COPY_SEGMENTS.
IMHO, this is arch specific.
So I shifted it to init_new_ldt() in ldt.c. I did this
for i386 only, because x86_64 doesn't have an ldt.c (yet?)
The patch applies on top of the latest LDT fixes/improvements
that AFAIK already are merged in your tree.
Bodo
From: Bodo Stroesser <[EMAIL PROTECTED]>
s390 doesn't have a LDT. So MM_COPY_SEGMENTS will not be
supported on s390.
The only user of MM_COPY_SEGMENTS is new_mm(), but that's
no longer useful, as arch/sys-i386/ldt.c defines init_new_ldt(),
which is called immediately after new_mm().
So we should copy host's LDT in init_new_ldt(), if /proc/mm is
available, to have this subarch specific call in subarch code.
Signed-off-by: Bodo Stroesser <[EMAIL PROTECTED]>
---
diff -puN arch/um/kernel/skas/include/skas.h~shift-MM_COPY_SEGMENTS arch/um/kernel/skas/include/skas.h
--- linux-2.6.11/arch/um/kernel/skas/include/skas.h~shift-MM_COPY_SEGMENTS 2005-04-07 21:28:29.468697914 +0200
+++ linux-2.6.11-root/arch/um/kernel/skas/include/skas.h 2005-04-07 21:28:29.479697320 +0200
@@ -41,7 +41,7 @@ extern int protect(struct mm_id * mm_idp
unsigned long len, int r, int w, int x, int done,
void **data);
extern void user_signal(int sig, union uml_pt_regs *regs, int pid);
-extern int new_mm(int from, unsigned long stack);
+extern int new_mm(unsigned long stack);
extern int start_userspace(unsigned long stub_stack);
extern int copy_context_skas0(unsigned long stack, int pid);
extern void get_skas_faultinfo(int pid, struct faultinfo * fi);
diff -puN arch/um/kernel/skas/process_kern.c~shift-MM_COPY_SEGMENTS arch/um/kernel/skas/process_kern.c
--- linux-2.6.11/arch/um/kernel/skas/process_kern.c~shift-MM_COPY_SEGMENTS 2005-04-07 21:28:29.470697806 +0200
+++ linux-2.6.11-root/arch/um/kernel/skas/process_kern.c 2005-04-07 21:28:29.480697266 +0200
@@ -21,7 +21,6 @@
#include "tlb.h"
#include "kern.h"
#include "mode.h"
-#include "proc_mm.h"
#include "registers.h"
void *switch_to_skas(void *prev, void *next)
@@ -131,25 +130,14 @@ int copy_thread_skas(int nr, unsigned lo
extern void map_stub_pages(int fd, unsigned long code,
unsigned long data, unsigned long stack);
-int new_mm(int from, unsigned long stack)
+int new_mm(unsigned long stack)
{
- struct proc_mm_op copy;
- int n, fd;
+ int fd;
fd = os_open_file("/proc/mm", of_cloexec(of_write(OPENFLAGS())), 0);
if(fd < 0)
return(fd);
- if(from != -1){
- copy = ((struct proc_mm_op) { .op = MM_COPY_SEGMENTS,
- .u =
- { .copy_segments = from } } );
- n = os_write_file(fd, ©, sizeof(copy));
- if(n != sizeof(copy))
- printk("new_mm : /proc/mm copy_segments failed, "
- "err = %d\n", -n);
- }
-
if(skas_needs_stub)
map_stub_pages(fd, CONFIG_STUB_CODE, CONFIG_STUB_DATA, stack);
diff -puN arch/um/sys-i386/ldt.c~shift-MM_COPY_SEGMENTS arch/um/sys-i386/ldt.c
--- linux-2.6.11/arch/um/sys-i386/ldt.c~shift-MM_COPY_SEGMENTS 2005-04-07 21:28:29.473697644 +0200
+++ linux-2.6.11-root/arch/um/sys-i386/ldt.c 2005-04-07 21:32:35.490129841 +0200
@@ -11,6 +11,8 @@
#include "asm/unistd.h"
#include "choose-mode.h"
#include "kern.h"
+#include "proc_mm.h"
+#include "os.h"
#ifdef CONFIG_MODE_TT
extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
@@ -388,13 +390,14 @@ long init_new_ldt(struct mmu_context_ska
int i;
long page, err=0;
void *addr = NULL;
+ struct proc_mm_op copy;
- memset(&desc, 0, sizeof(desc));
if(!ptrace_ldt)
init_MUTEX(&new_mm->ldt.semaphore);
if(!from_mm){
+ memset(&desc, 0, sizeof(desc));
/*
* We have to initialize a clean ldt.
*/
@@ -426,8 +429,26 @@ long init_new_ldt(struct mmu_context_ska
}
}
new_mm->ldt.entry_count = 0;
+
+ goto out;
}
- else if (!ptrace_ldt) {
+
+ if(proc_mm){
+ /* We have a valid from_mm, so we now have to copy the LDT of
+ * from_mm to new_mm, because using proc_mm an new mm with
+ * an empty/default LDT was created in new_mm()
+ */
+ copy = ((struct proc_mm_op) { .op = MM_COPY_SEGMENTS,
+ .u =
+ { .copy_segments =
+ from_mm->u.mm_fd } } );
+ i = os_write_file(new_mm->u.mm_fd, ©, sizeof(copy));
+ if(i != sizeof(copy))
+ printk("new_mm : /proc/mm copy_segments failed, "
+ "err = %d\n", -i);
+ }
+
+ if(!ptrace_ldt) {
/* Our local LDT is used to supply the data for
* modify_ldt(READLDT), if PTRACE_LDT isn't available,
* i.e., we have to use the stub for modify_ldt, which
@@ -455,6 +476,7 @@ long init_new_ldt(struct mmu_context_ska
up(&from_mm->ldt.semaphore);
}
+ out:
return err;
}
diff -puN arch/um/kernel/skas/mmu.c~shift-MM_COPY_SEGMENTS arch/um/kernel/skas/mmu.c
--- linux-2.6.11/arch/um/kernel/skas/mmu.c~shift-MM_COPY_SEGMENTS 2005-04-07 21:28:29.475697536 +0200
+++ linux-2.6.11-root/arch/um/kernel/skas/mmu.c 2005-04-07 21:28:29.487696888 +0200
@@ -54,7 +54,7 @@ static int init_stub_pte(struct mm_struc
int init_new_context_skas(struct task_struct *task, struct mm_struct *mm)
{
- int from_fd, ret = -ENOMEM;
+ int ret = -ENOMEM;
unsigned long stack = 0;
struct mmu_context_skas * from_mm = NULL;
struct mmu_context_skas * to_mm = &mm->context.skas;
@@ -74,11 +74,7 @@ int init_new_context_skas(struct task_st
from_mm = ¤t->mm->context.skas;
if(proc_mm){
- if(from_mm)
- from_fd = from_mm->u.mm_fd;
- else from_fd = -1;
-
- ret = new_mm(from_fd, stack);
+ ret = new_mm(stack);
if(ret < 0){
printk("init_new_context_skas - new_mm failed, "
"errno = %d\n", ret);
_