PERFORCE change 132225 for review
Kip Macy
kmacy at FreeBSD.org
Mon Dec 31 22:32:00 PST 2007
http://perforce.freebsd.org/chv.cgi?CH=132225
Change 132225 by kmacy at pandemonium:kmacy:xen31 on 2008/01/01 06:31:00
fix descriptor updates to work on xen
Affected files ...
.. //depot/projects/xen31/sys/i386/i386/sys_machdep.c#3 edit
Differences ...
==== //depot/projects/xen31/sys/i386/i386/sys_machdep.c#3 (text+ko) ====
@@ -178,7 +178,11 @@
*/
sd.sd_lobase = base & 0xffffff;
sd.sd_hibase = (base >> 24) & 0xff;
+#ifdef XEN
+ sd.sd_lolimit = 0x0; /* need to do nosegneg like Linux */
+#else
sd.sd_lolimit = 0xffff; /* 4GB limit, wraps around */
+#endif
sd.sd_hilimit = 0xf;
sd.sd_type = SDT_MEMRWA;
sd.sd_dpl = SEL_UPL;
@@ -188,7 +192,11 @@
sd.sd_gran = 1;
critical_enter();
td->td_pcb->pcb_fsd = sd;
+#ifdef XEN
+ HYPERVISOR_update_descriptor(vtomach(&PCPU_GET(fsgs_gdt)[0]), *(uint64_t *)&sd);
+#else
PCPU_GET(fsgs_gdt)[0] = sd;
+#endif
critical_exit();
td->td_frame->tf_fs = GSEL(GUFS_SEL, SEL_UPL);
}
@@ -208,7 +216,11 @@
*/
sd.sd_lobase = base & 0xffffff;
sd.sd_hibase = (base >> 24) & 0xff;
+#ifdef XEN
+ sd.sd_lolimit = 0x0; /* need nosegneg */
+#else
sd.sd_lolimit = 0xffff; /* 4GB limit, wraps around */
+#endif
sd.sd_hilimit = 0xf;
sd.sd_type = SDT_MEMRWA;
sd.sd_dpl = SEL_UPL;
@@ -218,7 +230,11 @@
sd.sd_gran = 1;
critical_enter();
td->td_pcb->pcb_gsd = sd;
+#ifdef XEN
+ HYPERVISOR_update_descriptor(vtomach(&PCPU_GET(fsgs_gdt)[1]), *(uint64_t *)&sd);
+#else
PCPU_GET(fsgs_gdt)[1] = sd;
+#endif
critical_exit();
load_gs(GSEL(GUGS_SEL, SEL_UPL));
}
@@ -377,6 +393,10 @@
}
pldt = mdp->md_ldt;
+#ifdef XEN
+ i386_reset_ldt(pldt);
+ PCPU_SET(currentldt, (int)pldt);
+#else
#ifdef SMP
gdt[PCPU_GET(cpuid) * NGDT + GUSERLDT_SEL].sd = pldt->ldt_sd;
#else
@@ -384,6 +404,7 @@
#endif
lldt(GSEL(GUSERLDT_SEL, SEL_KPL));
PCPU_SET(currentldt, GSEL(GUSERLDT_SEL, SEL_KPL));
+#endif
if (dtlocked)
mtx_unlock_spin(&dt_lock);
}
@@ -402,6 +423,44 @@
}
#endif
+#ifdef XEN
+
+/*
+ * dt_lock must be held. Returns with dt_lock held.
+ */
+struct proc_ldt *
+user_ldt_alloc(struct mdproc *mdp, int len)
+{
+ struct proc_ldt *pldt, *new_ldt;
+
+ mtx_assert(&dt_lock, MA_OWNED);
+ mtx_unlock_spin(&dt_lock);
+ MALLOC(new_ldt, struct proc_ldt *, sizeof(struct proc_ldt),
+ M_SUBPROC, M_WAITOK);
+
+ new_ldt->ldt_len = len = NEW_MAX_LD(len);
+ new_ldt->ldt_base = (caddr_t)kmem_alloc(kernel_map,
+ round_page(len * sizeof(union descriptor)));
+ if (new_ldt->ldt_base == NULL) {
+ FREE(new_ldt, M_SUBPROC);
+ return NULL;
+ }
+ new_ldt->ldt_refcnt = 1;
+ new_ldt->ldt_active = 0;
+
+ if ((pldt = mdp->md_ldt)) {
+ if (len > pldt->ldt_len)
+ len = pldt->ldt_len;
+ bcopy(pldt->ldt_base, new_ldt->ldt_base,
+ len * sizeof(union descriptor));
+ } else {
+ bcopy(ldt, new_ldt->ldt_base, PAGE_SIZE);
+ }
+ pmap_map_readonly(kernel_pmap, (vm_offset_t)new_ldt->ldt_base,
+ new_ldt->ldt_len*sizeof(union descriptor));
+ return new_ldt;
+}
+#else
/*
* dt_lock must be held. Returns with dt_lock held.
*/
@@ -440,7 +499,7 @@
return (new_ldt);
}
-
+#endif
/*
* Must be called with dt_lock held. Returns with dt_lock unheld.
*/
@@ -455,10 +514,12 @@
return;
if (td == PCPU_GET(curthread)) {
+#ifndef XEN
lldt(_default_ldt);
+#endif
PCPU_SET(currentldt, _default_ldt);
+ i386_reset_ldt((struct proc_ldt *)_default_ldt);
}
-
mdp->md_ldt = NULL;
if (--pldt->ldt_refcnt == 0) {
mtx_unlock_spin(&dt_lock);
@@ -643,6 +704,9 @@
if (uap->start == LDT_AUTO_ALLOC && uap->num == 1) {
/* Allocate a free slot */
mtx_lock_spin(&dt_lock);
+#ifdef XEN
+ load_gs(0); /* XXX check if we really still need this */
+#endif
if ((pldt = mdp->md_ldt) == NULL) {
if ((error = i386_ldt_grow(td, NLDT + 1))) {
mtx_unlock_spin(&dt_lock);
@@ -685,6 +749,25 @@
return (error);
}
+#ifdef XEN
+static int
+i386_set_ldt_data(struct thread *td, int start, int num,
+ union descriptor *descs)
+{
+ struct mdproc *mdp = &td->td_proc->p_md;
+ struct proc_ldt *pldt = mdp->md_ldt;
+ int i, error;
+
+ mtx_assert(&dt_lock, MA_OWNED);
+ for (i = 0; i < num; i++) {
+ error = HYPERVISOR_update_descriptor(vtomach(&((union descriptor *)(pldt->ldt_base))[start + i]), *(uint64_t *)(descs + i));
+ if (error)
+ panic("failed to update ldt: %d", error);
+ }
+ return (0);
+}
+
+#else
static int
i386_set_ldt_data(struct thread *td, int start, int num,
union descriptor *descs)
@@ -700,7 +783,7 @@
num * sizeof(union descriptor));
return (0);
}
-
+#endif
static int
i386_ldt_grow(struct thread *td, int len)
{
More information about the p4-projects
mailing list