[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
gnumach/i386/i386 pcb.c thread.h user_ldt.c
From: |
Roland McGrath |
Subject: |
gnumach/i386/i386 pcb.c thread.h user_ldt.c |
Date: |
Thu, 03 Oct 2002 22:45:04 -0400 |
CVSROOT: /cvsroot/hurd
Module name: gnumach
Changes by: Roland McGrath <address@hidden> 02/10/03 22:45:04
Modified files:
i386/i386 : pcb.c thread.h user_ldt.c
Log message:
2002-10-03 Roland McGrath <address@hidden>
* i386/include/mach/i386/mach_i386.defs (i386_set_gdt, i386_get_gdt):
New routines.
* i386/i386/user_ldt.c (i386_set_gdt, i386_get_gdt): New functions.
* i386/i386/gdt.h (USER_GDT, USER_GDT_SLOTS): New macros.
* i386/i386/thread.h (struct i386_machine_state): New member user_gdt.
* i386/i386/pcb.c (switch_ktss): Copy those slots into the GDT.
Remove magic %gs:0 pseudo-register support.
* i386/i386/ldt.h (USER_GS): Macro removed.
* i386/i386/pcb.c (pcb_init): Set gs to USER_DS, not USER_GS.
(thread_setstatus): Likewise.
* i386/i386/mp_desc.h (struct mp_desc_table): Remove member
`user_thread_register'.
* i386/i386/thread.h (struct i386_machine_state): Likewise.
* i386/i386/mp_desc.c (mp_desc_init): Don't set up USER_GS in LDT.
* i386/i386/ldt.c (ldt_init): Likewise.
* i386/intel/pmap.c (pmap_bootstrap): Don't give users access to
direct-mapped pages.
* i386/i386/user_ldt.c (i386_set_ldt): Don't cap segment limits.
CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/gnumach/gnumach/i386/i386/pcb.c.diff?tr1=1.3&tr2=1.4&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnumach/gnumach/i386/i386/thread.h.diff?tr1=1.4&tr2=1.5&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gnumach/gnumach/i386/i386/user_ldt.c.diff?tr1=1.3&tr2=1.4&r1=text&r2=text
Patches:
Index: gnumach/i386/i386/pcb.c
diff -u gnumach/i386/i386/pcb.c:1.3 gnumach/i386/i386/pcb.c:1.4
--- gnumach/i386/i386/pcb.c:1.3 Mon May 27 19:01:50 2002
+++ gnumach/i386/i386/pcb.c Thu Oct 3 22:45:04 2002
@@ -126,13 +126,9 @@
#if NCPUS > 1
#define curr_gdt(mycpu) (mp_gdt[mycpu])
#define curr_ktss(mycpu) (mp_ktss[mycpu])
-#define curr_user_thread_reg(mycpu) \
- (mp_desc_table[mycpu].user_thread_register)
#else
#define curr_gdt(mycpu) (gdt)
#define curr_ktss(mycpu) ((struct task_tss *)&base_tss)
-#define curr_user_thread_reg(mycpu) (user_thread_register)
-natural_t user_thread_register;
#endif
#define gdt_desc_p(mycpu,sel) \
@@ -182,9 +178,11 @@
}
}
- if (old_pcb)
- old_pcb->ims.user_thread_register = curr_user_thread_reg(mycpu);
- curr_user_thread_reg(mycpu) = pcb->ims.user_thread_register;
+ /* Copy in the per-thread GDT slots. No reloading is necessary
+ because just restoring the segment registers on the way back to
+ user mode reloads the shadow registers from the in-memory GDT. */
+ memcpy (gdt_desc_p (mycpu, USER_GDT),
+ pcb->ims.user_gdt, sizeof pcb->ims.user_gdt);
/*
* Load the floating-point context, if necessary.
@@ -363,7 +361,7 @@
pcb->iss.ds = USER_DS;
pcb->iss.es = USER_DS;
pcb->iss.fs = USER_DS;
- pcb->iss.gs = USER_GS;
+ pcb->iss.gs = USER_DS;
pcb->iss.eflags = EFL_USER_SET;
thread->pcb = pcb;
@@ -497,7 +495,7 @@
saved_state->ds = USER_DS;
saved_state->es = USER_DS;
saved_state->fs = USER_DS;
- saved_state->gs = USER_GS;
+ saved_state->gs = USER_DS;
}
else {
/*
Index: gnumach/i386/i386/thread.h
diff -u gnumach/i386/i386/thread.h:1.4 gnumach/i386/i386/thread.h:1.5
--- gnumach/i386/i386/thread.h:1.4 Mon May 27 19:01:51 2002
+++ gnumach/i386/i386/thread.h Thu Oct 3 22:45:04 2002
@@ -36,6 +36,7 @@
#include <mach/boolean.h>
#include <mach/machine/vm_types.h>
#include <mach/machine/fp_reg.h>
+#include "gdt.h"
#include <kern/lock.h>
@@ -130,7 +131,7 @@
struct user_ldt * ldt;
struct i386_fpsave_state *ifps;
struct v86_assist_state v86s;
- natural_t user_thread_register;
+ struct x86_desc user_gdt[USER_GDT_SLOTS];
};
typedef struct pcb {
Index: gnumach/i386/i386/user_ldt.c
diff -u gnumach/i386/i386/user_ldt.c:1.3 gnumach/i386/i386/user_ldt.c:1.4
--- gnumach/i386/i386/user_ldt.c:1.3 Mon May 27 19:01:51 2002
+++ gnumach/i386/i386/user_ldt.c Thu Oct 3 22:45:04 2002
@@ -170,23 +170,6 @@
case ACC_P | ACC_PL_U | ACC_CODE_CR:
case ACC_P | ACC_PL_U | ACC_CALL_GATE_16:
case ACC_P | ACC_PL_U | ACC_CALL_GATE:
- /* Silently cap the segment's limit at VM_MAX_ADDRESS. */
- {
- unsigned base = ((dp->base_high << 24)
- | (dp->base_med << 16) | dp->base_low);
- unsigned limit
- = ((dp->limit_high << 16) | dp->limit_low);
- if (dp->granularity & SZ_G)
- limit <<= 12;
- if (base > VM_MAX_ADDRESS)
- {
- fill_descriptor_base(dp, 0);
- fill_descriptor_limit(dp, 0);
- }
- else if (base + limit > VM_MAX_ADDRESS
- || base + limit < base)
- fill_descriptor_limit(dp, VM_MAX_ADDRESS - base);
- }
break;
default:
return KERN_INVALID_ARGUMENT;
@@ -415,4 +398,59 @@
kfree((vm_offset_t)user_ldt,
user_ldt->desc.limit_low + 1
+ sizeof(struct x86_desc));
+}
+
+
+kern_return_t
+i386_set_gdt (thread_t thread, int *selector, struct x86_desc *desc)
+{
+ int idx;
+
+ if (thread == THREAD_NULL)
+ return KERN_INVALID_ARGUMENT;
+
+ if (*selector == -1)
+ {
+ for (idx = sel_idx (USER_GDT); idx < sel_idx (USER_GDT) + USER_GDT_SLOTS;
+ ++idx)
+ if ((thread->pcb->ims.user_gdt[idx].access & ACC_P) == 0)
+ {
+ *selector = (idx << 3) | SEL_PL_U;
+ break;
+ }
+ if (idx == sel_idx (USER_GDT) + USER_GDT_SLOTS)
+ return KERN_NO_SPACE; /* ? */
+ }
+ else if ((*selector & (SEL_LDT|SEL_PL)) != SEL_PL_U
+ || sel_idx (*selector) < USER_GDT
+ || sel_idx (*selector) >= USER_GDT + USER_GDT_SLOTS)
+ return KERN_INVALID_ARGUMENT;
+ else
+ idx = sel_idx (*selector);
+
+ if ((desc->access & ACC_P) == 0)
+ memset (&thread->pcb->ims.user_gdt[idx], 0,
+ sizeof thread->pcb->ims.user_gdt[idx]);
+ else if ((desc->access & (ACC_TYPE|ACC_PL)) != (ACC_TYPE_USER|ACC_PL_U))
+ return KERN_INVALID_ARGUMENT;
+ else
+ thread->pcb->ims.user_gdt[idx] = *desc;
+
+ return KERN_SUCCESS;
+}
+
+kern_return_t
+i386_get_gdt (thread_t thread, int selector, struct x86_desc *desc)
+{
+ if (thread == THREAD_NULL)
+ return KERN_INVALID_ARGUMENT;
+
+ if ((selector & (SEL_LDT|SEL_PL)) != SEL_PL_U
+ || sel_idx (selector) < USER_GDT
+ || sel_idx (selector) >= USER_GDT + USER_GDT_SLOTS)
+ return KERN_INVALID_ARGUMENT;
+
+ *desc = thread->pcb->ims.user_gdt[sel_idx (selector)];
+
+ return KERN_SUCCESS;
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- gnumach/i386/i386 pcb.c thread.h user_ldt.c,
Roland McGrath <=