Date: Tue, 1 Jan 2008 06:31:59 GMT From: Kip Macy <kmacy@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 132225 for review Message-ID: <200801010631.m016VxLG014495@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=132225 Change 132225 by kmacy@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) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200801010631.m016VxLG014495>