svn commit: r183927 - in projects/releng_6_xen/sys: i386/i386
i386/include i386/include/xen i386/xen kern
Kip Macy
kmacy at FreeBSD.org
Thu Oct 16 01:33:04 UTC 2008
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 ***
More information about the svn-src-projects
mailing list