Date: Thu, 16 Oct 2008 01:33:03 +0000 (UTC) From: Kip Macy <kmacy@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r183927 - in projects/releng_6_xen/sys: i386/i386 i386/include i386/include/xen i386/xen kern Message-ID: <200810160133.m9G1X3dZ048068@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kmacy Date: Thu Oct 16 01:33:03 2008 New Revision: 183927 URL: http://svn.freebsd.org/changeset/base/183927 Log: - pull in xen_machdep.c from HEAD - pull in xen changes to common files - remove unused i386/xen/machdep.c Deleted: projects/releng_6_xen/sys/i386/xen/machdep.c Modified: projects/releng_6_xen/sys/i386/i386/busdma_machdep.c projects/releng_6_xen/sys/i386/i386/intr_machdep.c projects/releng_6_xen/sys/i386/i386/machdep.c projects/releng_6_xen/sys/i386/i386/swtch.s projects/releng_6_xen/sys/i386/i386/sys_machdep.c projects/releng_6_xen/sys/i386/i386/trap.c projects/releng_6_xen/sys/i386/i386/vm_machdep.c projects/releng_6_xen/sys/i386/include/cpufunc.h projects/releng_6_xen/sys/i386/include/param.h projects/releng_6_xen/sys/i386/include/vmparam.h projects/releng_6_xen/sys/i386/include/xen/xen-os.h projects/releng_6_xen/sys/i386/include/xen/xenpmap.h projects/releng_6_xen/sys/i386/xen/pmap.c projects/releng_6_xen/sys/i386/xen/xen_machdep.c projects/releng_6_xen/sys/kern/kern_fork.c projects/releng_6_xen/sys/kern/kern_synch.c projects/releng_6_xen/sys/kern/subr_trap.c Modified: projects/releng_6_xen/sys/i386/i386/busdma_machdep.c ============================================================================== --- projects/releng_6_xen/sys/i386/i386/busdma_machdep.c Wed Oct 15 21:47:01 2008 (r183926) +++ projects/releng_6_xen/sys/i386/i386/busdma_machdep.c Thu Oct 16 01:33:03 2008 (r183927) @@ -140,6 +140,11 @@ static bus_addr_t add_bounce_page(bus_dm static void free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage); static __inline int run_filter(bus_dma_tag_t dmat, bus_addr_t paddr); +#ifdef XEN +#undef pmap_kextract +#define pmap_kextract pmap_kextract_ma +#endif + /* * Return true if a match is made. * Modified: projects/releng_6_xen/sys/i386/i386/intr_machdep.c ============================================================================== --- projects/releng_6_xen/sys/i386/i386/intr_machdep.c Wed Oct 15 21:47:01 2008 (r183926) +++ projects/releng_6_xen/sys/i386/i386/intr_machdep.c Thu Oct 16 01:33:03 2008 (r183927) @@ -284,7 +284,12 @@ intr_execute_handlers(struct intsrc *isr /* Schedule the ithread if needed. */ if (thread) { error = intr_event_schedule_thread(ie); +#ifndef XEN KASSERT(error == 0, ("bad stray interrupt")); +#else + if (error != 0) + log(LOG_CRIT, "bad stray interrupt %d", vector); +#endif } critical_exit(); td->td_intr_nesting_level--; Modified: projects/releng_6_xen/sys/i386/i386/machdep.c ============================================================================== --- projects/releng_6_xen/sys/i386/i386/machdep.c Wed Oct 15 21:47:01 2008 (r183926) +++ projects/releng_6_xen/sys/i386/i386/machdep.c Thu Oct 16 01:33:03 2008 (r183927) @@ -152,7 +152,7 @@ uint32_t arch_i386_xbox_memsize = 0; void Xhypervisor_callback(void); void failsafe_callback(void); -int gdt_set; +int gdtset; extern trap_info_t trap_table[]; struct proc_ldt default_proc_ldt; extern int init_first; @@ -2264,7 +2264,7 @@ init386(int first) PT_SET_MA(gdt, *vtopte((unsigned long)gdt) & ~(PG_RW|PG_M|PG_A)); PANIC_IF(HYPERVISOR_set_gdt(&gdtmachpfn, 512) != 0); lgdt(&r_gdt /* unused */); - gdt_set = 1; + gdtset = 1; if ((error = HYPERVISOR_set_trap_table(trap_table)) != 0) { panic("set_trap_table failed - error %d\n", error); Modified: projects/releng_6_xen/sys/i386/i386/swtch.s ============================================================================== --- projects/releng_6_xen/sys/i386/i386/swtch.s Wed Oct 15 21:47:01 2008 (r183926) +++ projects/releng_6_xen/sys/i386/i386/swtch.s Thu Oct 16 01:33:03 2008 (r183927) @@ -71,7 +71,7 @@ ENTRY(cpu_throw) movl 8(%esp),%ecx /* New thread */ movl TD_PCB(%ecx),%edx movl PCB_CR3(%edx),%eax - movl %eax,%cr3 /* new address space */ + LOAD_CR3(%eax) /* new address space */ /* set bit in new pm_active */ movl TD_PROC(%ecx),%eax movl P_VMSPACE(%eax), %ebx @@ -114,11 +114,13 @@ ENTRY(cpu_switch) movl %gs,PCB_GS(%edx) pushfl /* PSL */ popl PCB_PSL(%edx) +#ifndef XEN /* Check to see if we need to call a switchout function. */ movl PCB_SWITCHOUT(%edx),%eax cmpl $0, %eax je 1f call *%eax +#endif 1: /* Test if debug registers should be saved. */ testl $PCB_DBREGS,PCB_FLAGS(%edx) @@ -171,7 +173,7 @@ ENTRY(cpu_switch) movl %cr3,%ebx /* The same address space? */ cmpl %ebx,%eax je sw1 - movl %eax,%cr3 /* new address space */ + LOAD_CR3(%eax) /* new address space */ /* Release bit from old pmap->pm_active */ movl PCPU(CURPMAP), %ebx @@ -191,6 +193,18 @@ ENTRY(cpu_switch) btsl %esi, PM_ACTIVE(%ebx) /* set new */ sw1: +#ifdef XEN + pushl %eax + pushl %ecx + pushl %edx + call xen_handle_thread_switch + popl %edx + popl %ecx + popl %eax + /* + * XXX set IOPL + */ +#else /* * At this point, we've switched address spaces and are ready * to load up the rest of the next context. @@ -238,7 +252,7 @@ sw1: movl 12(%esi), %ebx movl %eax, 8(%edi) movl %ebx, 12(%edi) - +#endif /* Restore context. */ movl PCB_EBX(%edx),%ebx movl PCB_ESP(%edx),%esp @@ -263,7 +277,7 @@ sw1: movl _default_ldt,%eax cmpl PCPU(CURRENTLDT),%eax je 2f - lldt _default_ldt + LLDT(_default_ldt) movl %eax,PCPU(CURRENTLDT) jmp 2f 1: @@ -366,7 +380,7 @@ ENTRY(savectx) * parent's npx state for forks by forgetting to reload. */ pushfl - cli + CLI movl PCPU(FPCURTHREAD),%eax testl %eax,%eax je 1f Modified: projects/releng_6_xen/sys/i386/i386/sys_machdep.c ============================================================================== --- projects/releng_6_xen/sys/i386/i386/sys_machdep.c Wed Oct 15 21:47:01 2008 (r183926) +++ projects/releng_6_xen/sys/i386/i386/sys_machdep.c Thu Oct 16 01:33:03 2008 (r183927) @@ -58,6 +58,25 @@ __FBSDID("$FreeBSD$"); #include <vm/vm_kern.h> /* for kernel_map */ +#ifdef XEN +#include <machine/xen/xenfunc.h> + +void i386_reset_ldt(struct proc_ldt *pldt); + +void +i386_reset_ldt(struct proc_ldt *pldt) +{ + xen_set_ldt((vm_offset_t)pldt->ldt_base, pldt->ldt_len); +} +#define SEG_VIRT_END (HYPERVISOR_VIRT_START >> 12) & 0xffff +#define SET_DESCRIPTOR(index, sd) \ + HYPERVISOR_update_descriptor(vtomach(&PCPU_GET(fsgs_gdt)[index]), *(uint64_t *)&(sd)); +#else +#define i386_reset_ldt(x) +#define SEG_VIRT_END 0xffff +#define SET_DESCRIPTOR(index, sd) PCPU_GET(fsgs_gdt)[index] = (sd); +#endif + #define MAX_LD 8192 #define LD_PER_PAGE 512 #define NEW_MAX_LD(num) ((num + LD_PER_PAGE) & ~(LD_PER_PAGE-1)) @@ -163,7 +182,7 @@ sysarch(td, uap) */ sd.sd_lobase = base & 0xffffff; sd.sd_hibase = (base >> 24) & 0xff; - sd.sd_lolimit = 0xffff; /* 4GB limit, wraps around */ + sd.sd_lolimit = SEG_VIRT_END; /* 4GB limit, wraps */ sd.sd_hilimit = 0xf; sd.sd_type = SDT_MEMRWA; sd.sd_dpl = SEL_UPL; @@ -173,7 +192,7 @@ sysarch(td, uap) sd.sd_gran = 1; critical_enter(); td->td_pcb->pcb_fsd = sd; - PCPU_GET(fsgs_gdt)[0] = sd; + SET_DESCRIPTOR(0, sd); critical_exit(); td->td_frame->tf_fs = GSEL(GUFS_SEL, SEL_UPL); } @@ -193,7 +212,7 @@ sysarch(td, uap) */ sd.sd_lobase = base & 0xffffff; sd.sd_hibase = (base >> 24) & 0xff; - sd.sd_lolimit = 0xffff; /* 4GB limit, wraps around */ + sd.sd_lolimit = SEG_VIRT_END; /* 4GB limit, wraps */ sd.sd_hilimit = 0xf; sd.sd_type = SDT_MEMRWA; sd.sd_dpl = SEL_UPL; @@ -203,7 +222,7 @@ sysarch(td, uap) sd.sd_gran = 1; critical_enter(); td->td_pcb->pcb_gsd = sd; - PCPU_GET(fsgs_gdt)[1] = sd; + SET_DESCRIPTOR(1, sd); critical_exit(); load_gs(GSEL(GUGS_SEL, SEL_UPL)); } @@ -364,6 +383,10 @@ set_user_ldt(struct mdproc *mdp) struct proc_ldt *pldt; 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 @@ -371,6 +394,7 @@ set_user_ldt(struct mdproc *mdp) #endif lldt(GSEL(GUSERLDT_SEL, SEL_KPL)); PCPU_SET(currentldt, GSEL(GUSERLDT_SEL, SEL_KPL)); +#endif /* !XEN */ } #ifdef SMP @@ -385,6 +409,39 @@ set_user_ldt_rv(struct thread *td) } #endif +#ifdef XEN + +struct proc_ldt * +user_ldt_alloc(struct mdproc *mdp, int len) +{ + struct proc_ldt *pldt, *new_ldt; + + 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 /* * Must be called with either sched_lock free or held but not recursed. * If it does not return NULL, it will return with it owned. @@ -425,6 +482,7 @@ user_ldt_alloc(struct mdproc *mdp, int l } return new_ldt; } +#endif /* * Must be called either with sched_lock free or held but not recursed. @@ -443,8 +501,11 @@ user_ldt_free(struct thread *td) mtx_lock_spin(&sched_lock); mtx_assert(&sched_lock, MA_OWNED | MA_NOTRECURSED); 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; @@ -549,6 +610,9 @@ i386_set_ldt(td, uap, descs) } if (!(uap->start == LDT_AUTO_ALLOC && uap->num == 1)) { +#ifdef XEN + load_gs(0); /* XXX check if we really still need this */ +#endif /* complain a for a while if using old methods */ if (ldt_warnings++ < NUM_LDT_WARNINGS) { printf("Warning: pid %d used static ldt allocation.\n", @@ -671,6 +735,23 @@ again: 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; + + 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) @@ -686,6 +767,7 @@ i386_set_ldt_data(struct thread *td, int num * sizeof(union descriptor)); return (0); } +#endif static int i386_ldt_grow(struct thread *td, int len) Modified: projects/releng_6_xen/sys/i386/i386/trap.c ============================================================================== --- projects/releng_6_xen/sys/i386/i386/trap.c Wed Oct 15 21:47:01 2008 (r183926) +++ projects/releng_6_xen/sys/i386/i386/trap.c Thu Oct 16 01:33:03 2008 (r183927) @@ -215,6 +215,7 @@ trap(frame) goto out; #endif +#ifndef XEN if ((frame.tf_eflags & PSL_I) == 0) { /* * Buggy application or kernel code has disabled @@ -245,6 +246,7 @@ trap(frame) enable_intr(); } } +#endif eva = 0; code = frame.tf_err; Modified: projects/releng_6_xen/sys/i386/i386/vm_machdep.c ============================================================================== --- projects/releng_6_xen/sys/i386/i386/vm_machdep.c Wed Oct 15 21:47:01 2008 (r183926) +++ projects/releng_6_xen/sys/i386/i386/vm_machdep.c Thu Oct 16 01:33:03 2008 (r183927) @@ -89,6 +89,9 @@ __FBSDID("$FreeBSD$"); #include <vm/vm_map.h> #include <vm/vm_param.h> +#ifdef XEN +#include <machine/xen/hypervisor.h> +#endif #ifdef PC98 #include <pc98/cbus/cbus.h> #else @@ -264,7 +267,7 @@ cpu_fork(td1, p2, td2, flags) /* Setup to release sched_lock in fork_exit(). */ td2->td_md.md_spinlock_count = 1; - td2->td_md.md_saved_flags = PSL_KERNEL | PSL_I; + td2->td_md.md_saved_flags = PSL_USER; /* * Now, cpu_switch() can schedule the new process. @@ -436,7 +439,7 @@ cpu_set_upcall(struct thread *td, struct /* Setup to release sched_lock in fork_exit(). */ td->td_md.md_spinlock_count = 1; - td->td_md.md_saved_flags = PSL_KERNEL | PSL_I; + td->td_md.md_saved_flags = PSL_USER; } /* @@ -593,6 +596,9 @@ cpu_reset_real() int b; #endif +#ifdef XEN + HYPERVISOR_shutdown(SHUTDOWN_poweroff); +#endif disable_intr(); #ifdef CPU_ELAN if (elan_mmcr != NULL) @@ -762,8 +768,11 @@ sf_buf_alloc(struct vm_page *m, int flag */ ptep = vtopte(sf->kva); opte = *ptep; +#ifdef XEN + PT_SET_MA(sf->kva, xpmap_ptom(VM_PAGE_TO_PHYS(m)) | pgeflag | PG_RW | PG_V); +#else *ptep = VM_PAGE_TO_PHYS(m) | pgeflag | PG_RW | PG_V; - +#endif /* * Avoid unnecessary TLB invalidations: If the sf_buf's old * virtual-to-physical mapping was not used, then any processor @@ -812,6 +821,14 @@ sf_buf_free(struct sf_buf *sf) if (sf->ref_count == 0) { TAILQ_INSERT_TAIL(&sf_buf_freelist, sf, free_entry); nsfbufsused--; +#ifdef XEN + /* + * Xen doesn't like having dangling R/W mappings + */ + pmap_qremove(sf->kva, 1); + sf->m = NULL; + LIST_REMOVE(sf, list_entry); +#endif if (sf_buf_alloc_want > 0) wakeup_one(&sf_buf_freelist); } Modified: projects/releng_6_xen/sys/i386/include/cpufunc.h ============================================================================== --- projects/releng_6_xen/sys/i386/include/cpufunc.h Wed Oct 15 21:47:01 2008 (r183926) +++ projects/releng_6_xen/sys/i386/include/cpufunc.h Thu Oct 16 01:33:03 2008 (r183927) @@ -42,6 +42,16 @@ #error this file needs sys/cdefs.h as a prerequisite #endif +#ifdef XEN +extern void xen_cli(void); +extern void xen_sti(void); +extern void xen_load_cr3(u_int data); +extern void xen_tlb_flush(void); +extern void xen_invlpg(u_int addr); +extern int xen_save_and_cli(void); +extern void xen_restore_flags(u_int eflags); +#endif + struct region_descriptor; #define readb(va) (*(volatile u_int8_t *) (va)) @@ -81,7 +91,11 @@ bsrl(u_int mask) static __inline void disable_intr(void) { +#ifdef XEN + xen_cli(); +#else __asm __volatile("cli" : : : "memory"); +#endif } static __inline void @@ -103,7 +117,11 @@ cpuid_count(u_int ax, u_int cx, u_int *p static __inline void enable_intr(void) { +#ifdef XEN + xen_sti(); +#else __asm __volatile("sti"); +#endif } #ifdef _KERNEL @@ -399,8 +417,11 @@ rcr2(void) static __inline void load_cr3(u_int data) { - +#ifdef XEN + xen_load_cr3(data); +#else __asm __volatile("movl %0,%%cr3" : : "r" (data) : "memory"); +#endif } static __inline u_int @@ -433,8 +454,11 @@ rcr4(void) static __inline void invltlb(void) { - +#ifdef XEN + xen_tlb_flush(); +#else load_cr3(rcr3()); +#endif } /* @@ -444,8 +468,11 @@ invltlb(void) static __inline void invlpg(u_int addr) { - +#ifdef XEN + xen_invlpg(addr); +#else __asm __volatile("invlpg %0" : : "m" (*(char *)addr) : "memory"); +#endif } static __inline u_int @@ -619,15 +646,23 @@ intr_disable(void) { register_t eflags; +#ifdef XEN + return (xen_save_and_cli()); +#endif eflags = read_eflags(); disable_intr(); + return (eflags); } static __inline void intr_restore(register_t eflags) { +#ifdef XEN + xen_restore_flags(eflags); +#else write_eflags(eflags); +#endif } #else /* !(__GNUCLIKE_ASM && __CC_SUPPORTS___INLINE) */ Modified: projects/releng_6_xen/sys/i386/include/param.h ============================================================================== --- projects/releng_6_xen/sys/i386/include/param.h Wed Oct 15 21:47:01 2008 (r183926) +++ projects/releng_6_xen/sys/i386/include/param.h Thu Oct 16 01:33:03 2008 (r183927) @@ -86,9 +86,11 @@ #ifdef PAE #define NPGPTD 4 #define PDRSHIFT 21 /* LOG2(NBPDR) */ +#define NPGPTD_SHIFT 9 #else #define NPGPTD 1 #define PDRSHIFT 22 /* LOG2(NBPDR) */ +#define NPGPTD_SHIFT 10 #endif #define NBPTD (NPGPTD<<PAGE_SHIFT) Modified: projects/releng_6_xen/sys/i386/include/vmparam.h ============================================================================== --- projects/releng_6_xen/sys/i386/include/vmparam.h Wed Oct 15 21:47:01 2008 (r183926) +++ projects/releng_6_xen/sys/i386/include/vmparam.h Thu Oct 16 01:33:03 2008 (r183927) @@ -83,8 +83,12 @@ * Kernel physical load address. */ #ifndef KERNLOAD +#if defined(XEN) && !defined(XEN_PRIVILEGED_GUEST) +#define KERNLOAD 0 +#else #define KERNLOAD (1 << PDRSHIFT) #endif +#endif /* * Virtual addresses of things. Derived from the page directory and @@ -93,7 +97,11 @@ * messy at times, but hey, we'll do anything to save a page :-) */ +#ifdef XEN +#define VM_MAX_KERNEL_ADDRESS HYPERVISOR_VIRT_START +#else #define VM_MAX_KERNEL_ADDRESS VADDR(KPTDI+NKPDE-1, NPTEPG-1) +#endif #define VM_MIN_KERNEL_ADDRESS VADDR(PTDPTDI, PTDPTDI) #define KERNBASE VADDR(KPTDI, 0) Modified: projects/releng_6_xen/sys/i386/include/xen/xen-os.h ============================================================================== --- projects/releng_6_xen/sys/i386/include/xen/xen-os.h Wed Oct 15 21:47:01 2008 (r183926) +++ projects/releng_6_xen/sys/i386/include/xen/xen-os.h Thu Oct 16 01:33:03 2008 (r183927) @@ -30,14 +30,14 @@ void force_evtchn_callback(void); #include <vm/pmap.h> #endif +extern int gdtset; #ifdef SMP #include <sys/time.h> /* XXX for pcpu.h */ #include <sys/pcpu.h> /* XXX for PCPU_GET */ -extern int gdt_set; static inline int smp_processor_id(void) { - if (likely(gdt_set)) + if (likely(gdtset)) return PCPU_GET(cpuid); return 0; } Modified: projects/releng_6_xen/sys/i386/include/xen/xenpmap.h ============================================================================== --- projects/releng_6_xen/sys/i386/include/xen/xenpmap.h Wed Oct 15 21:47:01 2008 (r183926) +++ projects/releng_6_xen/sys/i386/include/xen/xenpmap.h Thu Oct 16 01:33:03 2008 (r183927) @@ -33,12 +33,9 @@ #ifndef _XEN_XENPMAP_H_ #define _XEN_XENPMAP_H_ -void xen_invlpg(vm_offset_t); -void xen_load_cr3(vm_paddr_t); void _xen_queue_pt_update(vm_paddr_t, vm_paddr_t, char *, int); void xen_pt_switch(vm_paddr_t); void xen_set_ldt(vm_paddr_t, unsigned long); -void xen_tlb_flush(void); void xen_pgdpt_pin(vm_paddr_t); void xen_pgd_pin(vm_paddr_t); void xen_pgd_unpin(vm_paddr_t); Modified: projects/releng_6_xen/sys/i386/xen/pmap.c ============================================================================== --- projects/releng_6_xen/sys/i386/xen/pmap.c Wed Oct 15 21:47:01 2008 (r183926) +++ projects/releng_6_xen/sys/i386/xen/pmap.c Thu Oct 16 01:33:03 2008 (r183927) @@ -208,7 +208,7 @@ vm_offset_t virtual_end; /* VA of last a int pgeflag = 0; /* PG_G or-in */ int pseflag = 0; /* PG_PS or-in */ -static int nkpt; +int nkpt; vm_offset_t kernel_vm_end; extern u_int32_t KERNend; Modified: projects/releng_6_xen/sys/i386/xen/xen_machdep.c ============================================================================== --- projects/releng_6_xen/sys/i386/xen/xen_machdep.c Wed Oct 15 21:47:01 2008 (r183926) +++ projects/releng_6_xen/sys/i386/xen/xen_machdep.c Thu Oct 16 01:33:03 2008 (r183927) @@ -1,7 +1,7 @@ /* * * Copyright (c) 2004 Christian Limpach. - * Copyright (c) 2004-2006 Kip Macy + * Copyright (c) 2004-2006,2008 Kip Macy * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,6 +31,7 @@ */ #include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/systm.h> @@ -41,11 +42,10 @@ #include <sys/reboot.h> #include <sys/sysproto.h> +#include <machine/xen/xen-os.h> #include <vm/vm.h> #include <vm/pmap.h> -#include <vm/vm_page.h> - #include <machine/segments.h> #include <machine/pcb.h> #include <machine/stdarg.h> @@ -57,7 +57,6 @@ - #include <machine/xen/hypervisor.h> #include <machine/xen/xenvar.h> #include <machine/xen/xenfunc.h> @@ -70,6 +69,10 @@ #include <machine/privatespace.h> #endif + +#include <vm/vm_page.h> + + #define IDTVEC(name) __CONCAT(X,name) extern inthand_t @@ -79,6 +82,7 @@ IDTVEC(div), IDTVEC(dbg), IDTVEC(nmi), I IDTVEC(page), IDTVEC(mchk), IDTVEC(rsvd), IDTVEC(fpu), IDTVEC(align), IDTVEC(xmm), IDTVEC(lcall_syscall), IDTVEC(int0x80_syscall); + int xendebug_flags; start_info_t *xen_start_info; shared_info_t *HYPERVISOR_shared_info; @@ -86,7 +90,6 @@ xen_pfn_t *xen_machine_phys = machine_to xen_pfn_t *xen_phys_machine; int preemptable, init_first; extern unsigned int avail_space; -extern int gdt_set; void ni_cli(void); void ni_sti(void); @@ -175,6 +178,8 @@ printk(const char *fmt, ...) int retval; static char buf[PRINTK_BUFSIZE]; + return; + va_start(ap, fmt); retval = vsnprintf(buf, PRINTK_BUFSIZE - 1, fmt, ap); va_end(ap); @@ -184,28 +189,38 @@ printk(const char *fmt, ...) #define XPQUEUE_SIZE 128 + +struct mmu_log { + char *file; + int line; +}; + #ifdef SMP /* per-cpu queues and indices */ -static mmu_update_t xpq_queue[MAX_VIRT_CPUS][XPQUEUE_SIZE]; +#ifdef INVARIANTS +static struct mmu_log xpq_queue_log[MAX_VIRT_CPUS][XPQUEUE_SIZE]; +#endif + static int xpq_idx[MAX_VIRT_CPUS]; +static mmu_update_t xpq_queue[MAX_VIRT_CPUS][XPQUEUE_SIZE]; #define XPQ_QUEUE xpq_queue[vcpu] #define XPQ_IDX xpq_idx[vcpu] #define SET_VCPU() int vcpu = smp_processor_id() + +#define XPQ_QUEUE_LOG xpq_queue_log[vcpu] #else -struct mmu_log { - char *file; - int line; -}; static mmu_update_t xpq_queue[XPQUEUE_SIZE]; static struct mmu_log xpq_queue_log[XPQUEUE_SIZE]; static int xpq_idx = 0; +#define XPQ_QUEUE_LOG xpq_queue_log #define XPQ_QUEUE xpq_queue #define XPQ_IDX xpq_idx #define SET_VCPU() -#endif +#endif /* !SMP */ + #define XPQ_IDX_INC atomic_add_int(&XPQ_IDX, 1); #if 0 @@ -234,7 +249,7 @@ _xen_flush_queue(void) int error, i; /* window of vulnerability here? */ - if (__predict_true(gdt_set)) + if (__predict_true(gdtset)) critical_enter(); XPQ_IDX = 0; /* Make sure index is cleared first to avoid double updates. */ @@ -242,31 +257,39 @@ _xen_flush_queue(void) _xpq_idx, NULL, DOMID_SELF); #if 0 - if (__predict_true(gdt_set)) + if (__predict_true(gdtset)) for (i = _xpq_idx; i > 0;) { if (i >= 3) { - CTR6(KTR_PMAP, "mmu:val: %lx ptr: %lx val: %lx ptr: %lx val: %lx ptr: %lx", - (XPQ_QUEUE[i-1].val & 0xffffffff), (XPQ_QUEUE[i-1].ptr & 0xffffffff), - (XPQ_QUEUE[i-2].val & 0xffffffff), (XPQ_QUEUE[i-2].ptr & 0xffffffff), - (XPQ_QUEUE[i-3].val & 0xffffffff), (XPQ_QUEUE[i-3].ptr & 0xffffffff)); + CTR6(KTR_PMAP, "mmu:val: %lx ptr: %lx val: %lx " + "ptr: %lx val: %lx ptr: %lx", + (XPQ_QUEUE[i-1].val & 0xffffffff), + (XPQ_QUEUE[i-1].ptr & 0xffffffff), + (XPQ_QUEUE[i-2].val & 0xffffffff), + (XPQ_QUEUE[i-2].ptr & 0xffffffff), + (XPQ_QUEUE[i-3].val & 0xffffffff), + (XPQ_QUEUE[i-3].ptr & 0xffffffff)); i -= 3; } else if (i == 2) { CTR4(KTR_PMAP, "mmu: val: %lx ptr: %lx val: %lx ptr: %lx", - (XPQ_QUEUE[i-1].val & 0xffffffff), (XPQ_QUEUE[i-1].ptr & 0xffffffff), - (XPQ_QUEUE[i-2].val & 0xffffffff), (XPQ_QUEUE[i-2].ptr & 0xffffffff)); + (XPQ_QUEUE[i-1].val & 0xffffffff), + (XPQ_QUEUE[i-1].ptr & 0xffffffff), + (XPQ_QUEUE[i-2].val & 0xffffffff), + (XPQ_QUEUE[i-2].ptr & 0xffffffff)); i = 0; } else { CTR2(KTR_PMAP, "mmu: val: %lx ptr: %lx", - (XPQ_QUEUE[i-1].val & 0xffffffff), (XPQ_QUEUE[i-1].ptr & 0xffffffff)); + (XPQ_QUEUE[i-1].val & 0xffffffff), + (XPQ_QUEUE[i-1].ptr & 0xffffffff)); i = 0; } } #endif - if (__predict_true(gdt_set)) + if (__predict_true(gdtset)) critical_exit(); if (__predict_false(error < 0)) { for (i = 0; i < _xpq_idx; i++) - printf("val: %llx ptr: %llx\n", XPQ_QUEUE[i].val, XPQ_QUEUE[i].ptr); + printf("val: %llx ptr: %llx\n", + XPQ_QUEUE[i].val, XPQ_QUEUE[i].ptr); panic("Failed to execute MMU updates: %d", error); } @@ -292,7 +315,11 @@ xen_increment_idx(void) void xen_check_queue(void) { +#ifdef INVARIANTS + SET_VCPU(); + KASSERT(XPQ_IDX == 0, ("pending operations XPQ_IDX=%d", XPQ_IDX)); +#endif } void @@ -305,56 +332,86 @@ xen_invlpg(vm_offset_t va) } void -xen_load_cr3(vm_paddr_t val) +xen_load_cr3(u_int val) { struct mmuext_op op; - +#ifdef INVARIANTS + SET_VCPU(); + KASSERT(XPQ_IDX == 0, ("pending operations XPQ_IDX=%d", XPQ_IDX)); +#endif op.cmd = MMUEXT_NEW_BASEPTR; op.arg1.mfn = xpmap_ptom(val) >> PAGE_SHIFT; PANIC_IF(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0); } void -_xen_machphys_update(vm_paddr_t mfn, vm_paddr_t pfn, char *file, int line) +xen_restore_flags(u_int eflags) { - if (__predict_true(gdt_set)) - critical_enter(); + __restore_flags(eflags); +} + +int +xen_save_and_cli(void) +{ + int eflags; + + __save_and_cli(eflags); + return (eflags); +} + +void +xen_cli(void) +{ + __cli(); +} + +void +xen_sti(void) +{ + __sti(); +} + +void +_xen_machphys_update(vm_paddr_t mfn, vm_paddr_t pfn, char *file, int line) +{ SET_VCPU(); + + if (__predict_true(gdtset)) + critical_enter(); XPQ_QUEUE[XPQ_IDX].ptr = (mfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE; XPQ_QUEUE[XPQ_IDX].val = pfn; #ifdef INVARIANTS - xpq_queue_log[XPQ_IDX].file = file; - xpq_queue_log[XPQ_IDX].line = line; + XPQ_QUEUE_LOG[XPQ_IDX].file = file; + XPQ_QUEUE_LOG[XPQ_IDX].line = line; #endif xen_increment_idx(); - if (__predict_true(gdt_set)) + if (__predict_true(gdtset)) critical_exit(); } void _xen_queue_pt_update(vm_paddr_t ptr, vm_paddr_t val, char *file, int line) { + SET_VCPU(); - - if (__predict_true(gdt_set)) + if (__predict_true(gdtset)) mtx_assert(&vm_page_queue_mtx, MA_OWNED); - if (__predict_true(gdt_set)) + KASSERT((ptr & 7) == 0, ("misaligned update")); + + if (__predict_true(gdtset)) critical_enter(); - SET_VCPU(); + XPQ_QUEUE[XPQ_IDX].ptr = ((uint64_t)ptr) | MMU_NORMAL_PT_UPDATE; XPQ_QUEUE[XPQ_IDX].val = (uint64_t)val; - if (val) - KASSERT(val & PG_V, - ("setting invalid address ptr=0x%jx 0x%jx", ptr, val)); #ifdef INVARIANTS - xpq_queue_log[XPQ_IDX].file = file; - xpq_queue_log[XPQ_IDX].line = line; + XPQ_QUEUE_LOG[XPQ_IDX].file = file; + XPQ_QUEUE_LOG[XPQ_IDX].line = line; #endif xen_increment_idx(); - if (__predict_true(gdt_set)) + if (__predict_true(gdtset)) critical_exit(); } @@ -503,7 +560,6 @@ xen_create_contiguous_region(vm_page_t p .domid = DOMID_SELF }; set_xen_guest_handle(reservation.extent_start, &mfn); - balloon_lock(flags); @@ -633,7 +689,7 @@ extern unsigned long *SMPpt; extern struct user *proc0uarea; extern vm_offset_t proc0kstack; extern int vm86paddr, vm86phystk; -char *bootmem_start, *bootmem_current, *bootmem_end; +char *bootmem_start, *bootmem_current, *bootmem_end; pteinfo_t *pteinfo_list; void initvalues(start_info_t *startinfo); @@ -745,9 +801,13 @@ shift_phys_machine(unsigned long *phys_m memset(phys_machine, INVALID_P2M_ENTRY, PAGE_SIZE); } -#endif +#endif /* ADD_ISA_HOLE */ extern unsigned long physfree; + +int pdir, curoffset; +extern int nkpt; + void initvalues(start_info_t *startinfo) { @@ -763,11 +823,20 @@ initvalues(start_info_t *startinfo) vm_paddr_t IdlePDPTma, IdlePDPTnewma; vm_paddr_t IdlePTDnewma[4]; pd_entry_t *IdlePDPTnew, *IdlePTDnew; +#else + vm_paddr_t pdir_shadow_ma; #endif unsigned long i; + int ncpus; + nkpt = min(max((startinfo->nr_pages >> NPGPTD_SHIFT), nkpt), + NPGPTD*NPDEPG - KPTDI); +#ifdef SMP + ncpus = MAXCPU; +#else + ncpus = 1; +#endif - HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_writable_pagetables); HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments); #ifdef notyet /* @@ -783,7 +852,9 @@ initvalues(start_info_t *startinfo) ((xen_start_info->nr_pt_frames) + 3 )*PAGE_SIZE; printk("initvalues(): wooh - availmem=%x,%x\n", avail_space, cur_space); - printk("KERNBASE=%x,pt_base=%x, VTOPFN(base)=%x, nr_pt_frames=%x\n", KERNBASE,xen_start_info->pt_base, VTOPFN(xen_start_info->pt_base), xen_start_info->nr_pt_frames); + printk("KERNBASE=%x,pt_base=%x, VTOPFN(base)=%x, nr_pt_frames=%x\n", + KERNBASE,xen_start_info->pt_base, VTOPFN(xen_start_info->pt_base), + xen_start_info->nr_pt_frames); xendebug_flags = 0; /* 0xffffffff; */ /* allocate 4 pages for bootmem allocator */ @@ -797,13 +868,13 @@ initvalues(start_info_t *startinfo) /* * pre-zero unused mapped pages - mapped on 4MB boundary */ -/* - bzero((char *)cur_space, (cur_space + 0x3fffff) % 0x400000); - */ - #ifdef PAE IdlePDPT = (pd_entry_t *)startinfo->pt_base; IdlePDPTma = xpmap_ptom(VTOP(startinfo->pt_base)); + /* + * Note that only one page directory has been allocated at this point. + * Thus, if KERNBASE + */ IdlePTD = (pd_entry_t *)((uint8_t *)startinfo->pt_base + PAGE_SIZE); IdlePTDma = xpmap_ptom(VTOP(IdlePTD)); l3_pages = 1; @@ -813,9 +884,10 @@ initvalues(start_info_t *startinfo) l3_pages = 0; #endif l2_pages = 1; - l1_pages = 4; /* XXX not certain if this varies */ + l1_pages = xen_start_info->nr_pt_frames - l2_pages - l3_pages; + KPTphysoff = (l2_pages + l3_pages)*PAGE_SIZE; - + KPTphys = xpmap_ptom(VTOP(startinfo->pt_base + KPTphysoff)); XENPRINTF("IdlePTD %p\n", IdlePTD); XENPRINTF("nr_pages: %ld shared_info: 0x%lx flags: 0x%lx pt_base: 0x%lx " @@ -827,7 +899,7 @@ initvalues(start_info_t *startinfo) proc0kstack = cur_space; cur_space += (KSTACK_PAGES * PAGE_SIZE); printk("proc0kstack=%u\n", proc0kstack); - + /* vm86/bios stack */ cur_space += PAGE_SIZE; @@ -838,79 +910,100 @@ initvalues(start_info_t *startinfo) #ifdef PAE IdlePDPTnew = (pd_entry_t *)cur_space; cur_space += PAGE_SIZE; bzero(IdlePDPTnew, PAGE_SIZE); + IdlePDPTnewma = xpmap_ptom(VTOP(IdlePDPTnew)); *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200810160133.m9G1X3dZ048068>