New LDT handling in 2.3.x

David Woodhouse (David.Woodhouse@mvhi.com)
Sat, 28 Aug 1999 14:32:34 +0100


Could someone explain what happened to the LDT handling in 2.3, please?

The lcall7 call gate for iBCS no longer seems to be active by default.

The following patch ought to add a call gate for lcall27, to allow Solaris/x86
binary emulation, but obviously it doesn't work either.

--- ./linux/kernel/exec_domain.c.lcall27 Fri Aug 27 14:52:49 1999
+++ ./linux/kernel/exec_domain.c Sat Aug 28 13:25:17 1999
@@ -2,7 +2,7 @@
#include <linux/smp_lock.h>
#include <linux/module.h>

-static asmlinkage void no_lcall7(struct pt_regs * regs);
+static asmlinkage void no_lcall7(int segment, struct pt_regs * regs);


static unsigned long ident_map[32] = {
@@ -25,7 +25,7 @@
static struct exec_domain *exec_domains = &default_exec_domain;


-static asmlinkage void no_lcall7(struct pt_regs * regs)
+static asmlinkage void no_lcall7(int segment, struct pt_regs * regs)
{

/*
@@ -33,6 +33,7 @@
* personality set incorrectly. Check to see whether SVr4 is available,
* and use it, otherwise give the user a SEGV.
*/
+ printk("Kernel no_lcall7 called\n");
if (current->exec_domain && current->exec_domain->module)
__MOD_DEC_USE_COUNT(current->exec_domain->module);

@@ -44,7 +45,7 @@

if (current->exec_domain && current->exec_domain->handler
&& current->exec_domain->handler != no_lcall7) {
- current->exec_domain->handler(regs);
+ current->exec_domain->handler(segment, regs);
return;
}

--- ./linux/include/linux/personality.h.lcall27 Fri Aug 27 14:52:48 1999
+++ ./linux/include/linux/personality.h Sat Aug 28 12:33:53 1999
@@ -28,9 +28,10 @@
#define PER_IRIXN32 (0x000a | STICKY_TIMEOUTS) /* IRIX6 new 32-bit */
#define PER_IRIX64 (0x000b | STICKY_TIMEOUTS) /* IRIX6 64-bit */
#define PER_RISCOS (0x000c)
+#define PER_SOLARIS (0x000d | STICKY_TIMEOUTS)

/* Prototype for an lcall7 syscall handler. */
-typedef void (*lcall7_func)(struct pt_regs *);
+typedef void (*lcall7_func)(int, struct pt_regs *);


/* Description of an execution domain - personality range supported,
--- ./linux/include/asm-i386/desc.h.lcall27 Mon Jul 26 07:15:13 1999
+++ ./linux/include/asm-i386/desc.h Sat Aug 28 13:46:20 1999
@@ -64,7 +64,7 @@
* This is the ldt that every process will get unless we need
* something other than this.
*/
-extern struct desc_struct default_ldt;
+extern struct desc_struct default_ldt[];
extern void set_intr_gate(unsigned int irq, void * addr);
extern void set_ldt_desc(unsigned int n, void *addr, unsigned int size);
extern void set_tss_desc(unsigned int n, void *addr);
@@ -72,7 +72,7 @@
extern inline void clear_LDT(void)
{
int cpu = smp_processor_id();
- set_ldt_desc(cpu, &default_ldt, 1);
+ set_ldt_desc(cpu, &default_ldt[0], 5);
__load_LDT(cpu);
}

@@ -86,8 +86,8 @@
int count = LDT_ENTRIES;

if (!segments) {
- segments = &default_ldt;
- count = 1;
+ segments = &default_ldt[0];
+ count = 5;
}

set_ldt_desc(cpu, segments, count);
--- ./linux/arch/i386/kernel/entry.S.lcall27 Thu Jul 29 23:18:50 1999
+++ ./linux/arch/i386/kernel/entry.S Sat Aug 28 12:31:59 1999
@@ -145,7 +145,30 @@
andl $-8192,%ebx # GET_CURRENT
movl exec_domain(%ebx),%edx # Get the execution domain
movl 4(%edx),%edx # Get the lcall7 handler for the domain
+ pushl $0x7
call *%edx
+ addl $4, %esp
+ popl %eax
+ jmp ret_from_sys_call
+
+ENTRY(lcall27)
+ pushfl # We get a different stack layout with call gates,
+ pushl %eax # which has to be cleaned up later..
+ SAVE_ALL
+ movl EIP(%esp),%eax # due to call gates, this is eflags, not eip..
+ movl CS(%esp),%edx # this is eip..
+ movl EFLAGS(%esp),%ecx # and this is cs..
+ movl %eax,EFLAGS(%esp) #
+ movl %edx,EIP(%esp) # Now we move them to their "normal" places
+ movl %ecx,CS(%esp) #
+ movl %esp,%ebx
+ pushl %ebx
+ andl $-8192,%ebx # GET_CURRENT
+ movl exec_domain(%ebx),%edx # Get the execution domain
+ movl 4(%edx),%edx # Get the lcall7 handler for the domain
+ pushl $0x27
+ call *%edx
+ addl $4, %esp
popl %eax
jmp ret_from_sys_call

--- ./linux/arch/i386/kernel/traps.c.lcall27 Wed Aug 18 19:27:34 1999
+++ ./linux/arch/i386/kernel/traps.c Sat Aug 28 12:36:12 1999
@@ -46,8 +46,10 @@

asmlinkage int system_call(void);
asmlinkage void lcall7(void);
+asmlinkage void lcall27(void);

-struct desc_struct default_ldt = { 0, 0 };
+struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
+ { 0, 0 }, { 0, 0 } };

/*
* The IDT has to be page-aligned to simplify the Pentium
@@ -696,9 +698,11 @@
set_system_gate(SYSCALL_VECTOR,&system_call);

/*
- * default LDT is a single-entry callgate to lcall7
+ * default LDT is a single-entry callgate to lcall7 for iBCS
+ * and a callgate to lcall27 for Solaris/x86 binaries
*/
set_call_gate(&default_ldt,lcall7);
+ set_call_gate(&default_ldt,lcall27);

/*
* on SMP we do not yet know which CPU is on which TSS,

---- ---- ----
David Woodhouse David.Woodhouse@mvhi.com Office: (+44) 1223 810302
Project Leader, Process Information Systems Mobile: (+44) 976 658355
Axiom (Cambridge) Ltd., Swaffham Bulbeck, Cambridge, CB5 0NA, UK.
finger dwmw2@ferret.lmh.ox.ac.uk for PGP key.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/