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