d94742232d
This patch is inspired by work previously done by Jeremy Morse, ported by me to -current, merged with the work previously done for port-xen, together with additionals fixes and improvements. PAE option is disabled by default in GENERIC (but will be enabled in ALL in the next few days). In quick, PAE switches the CPU to a mode where physical addresses become 36 bits (64 GiB). Virtual address space remains at 32 bits (4 GiB). To cope with the increased size of the physical address, they are manipulated as 64 bits variables by kernel and MMU. When supported by the CPU, it also allows the use of the NX/XD bit that provides no-execution right enforcement on a per physical page basis. Notes: - reworked locore.S - introduce cpu_load_pmap(), used to switch pmap for the curcpu. Due to the different handling of pmap mappings with PAE vs !PAE, Xen vs native, details are hidden within this function. This helps calling it from assembly, as some features, like BIOS calls, switch to pmap_kernel before mapping trampoline code in low memory. - some changes in bioscall and kvm86_call, to reflect the above. - the L3 is "pinned" per-CPU, and is only manipulated by a reduced set of functions within pmap. To track the L3, I added two elements to struct cpu_info, namely ci_l3_pdirpa (PA of the L3), and ci_l3_pdir (the L3 VA). Rest of the code considers that it runs "just like" a normal i386, except that the L2 is 4 pages long (PTP_LEVELS is still 2). - similar to the ci_pae_l3_pdir{,pa} variables, amd64's xen_current_user_pgd becomes an element of cpu_info (slowly paving the way for MP world). - bootinfo_source struct declaration is modified, to cope with paddr_t size change with PAE (it is not correct to assume that bs_addr is a paddr_t when compiled with PAE - it should remain 32 bits). bs_addrs is now a void * array (in bootloader's code under i386/stand/, the bs_addrs is a physaddr_t, which is an unsigned long). - fixes in multiboot code (same reason as bootinfo): paddr_t size change. I used Elf32_* types, use RELOC() where necessary, and move the memcpy() functions out of the if/else if (I do not expect sym and str tables to overlap with ELF). - 64 bits atomic functions for pmap - all pmap_pdirpa access are now done through the pmap_pdirpa macro. It hides the L3/L2 stuff from PAE, as well as the pm_pdirpa change in struct pmap (it now becomes a PDP_SIZE array, with or without PAE). - manipulation of recursive mappings ( PDIR_SLOT_{,A}PTEs ) is done via loops on PDP_SIZE. See also http://mail-index.netbsd.org/port-i386/2010/07/17/msg002062.html No objection raised on port-i386@ and port-xen@R for about a week. XXX kvm(3) will be fixed in another patch to properly handle both PAE and !PAE kernel dumps (VA => PA macros are slightly different, and need proper 64 bits PA support in kvm_i386). XXX Mixing PAE and !PAE modules may lead to unwanted/unexpected results. This cannot be solved easily, and needs lots of thinking before being declared safe (paddr_t/bus_addr_t size handling, PD/PT macros abstractions).
152 lines
3.0 KiB
C
152 lines
3.0 KiB
C
/* $NetBSD: xenfunc.c,v 1.11 2010/07/24 00:45:56 jym Exp $ */
|
|
|
|
/*
|
|
*
|
|
* Copyright (c) 2004 Christian Limpach.
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#include <sys/cdefs.h>
|
|
__KERNEL_RCSID(0, "$NetBSD: xenfunc.c,v 1.11 2010/07/24 00:45:56 jym Exp $");
|
|
|
|
#include <sys/param.h>
|
|
|
|
#include <uvm/uvm_extern.h>
|
|
|
|
#include <machine/intr.h>
|
|
#include <machine/vmparam.h>
|
|
#include <machine/pmap.h>
|
|
#include <xen/xen.h>
|
|
#include <xen/hypervisor.h>
|
|
//#include <xen/evtchn.h>
|
|
#include <xen/xenpmap.h>
|
|
#include <machine/pte.h>
|
|
|
|
#ifdef XENDEBUG_LOW
|
|
#define __PRINTK(x) printk x
|
|
#else
|
|
#define __PRINTK(x)
|
|
#endif
|
|
|
|
void xen_set_ldt(vaddr_t, uint32_t);
|
|
|
|
void
|
|
invlpg(vaddr_t addr)
|
|
{
|
|
int s = splvm();
|
|
xpq_queue_invlpg(addr);
|
|
splx(s);
|
|
}
|
|
|
|
void
|
|
lldt(u_short sel)
|
|
{
|
|
#ifndef __x86_64__
|
|
struct cpu_info *ci;
|
|
|
|
ci = curcpu();
|
|
|
|
if (ci->ci_curldt == sel)
|
|
return;
|
|
/* __PRINTK(("ldt %x\n", IDXSELN(sel))); */
|
|
if (sel == GSEL(GLDT_SEL, SEL_KPL))
|
|
xen_set_ldt((vaddr_t)ldt, NLDT);
|
|
else
|
|
xen_set_ldt(ci->ci_gdt[IDXSELN(sel)].ld.ld_base,
|
|
ci->ci_gdt[IDXSELN(sel)].ld.ld_entries);
|
|
ci->ci_curldt = sel;
|
|
#endif
|
|
}
|
|
|
|
void
|
|
ltr(u_short sel)
|
|
{
|
|
__PRINTK(("XXX ltr not supported\n"));
|
|
}
|
|
|
|
void
|
|
lcr0(u_long val)
|
|
{
|
|
__PRINTK(("XXX lcr0 not supported\n"));
|
|
}
|
|
|
|
u_long
|
|
rcr0(void)
|
|
{
|
|
__PRINTK(("XXX rcr0 not supported\n"));
|
|
return 0;
|
|
}
|
|
|
|
#ifndef __x86_64__
|
|
void
|
|
lcr3(vaddr_t val)
|
|
{
|
|
int s = splvm();
|
|
xpq_queue_pt_switch(xpmap_ptom_masked(val));
|
|
splx(s);
|
|
}
|
|
#endif
|
|
|
|
void
|
|
tlbflush(void)
|
|
{
|
|
int s = splvm();
|
|
xpq_queue_tlb_flush();
|
|
splx(s);
|
|
}
|
|
|
|
void
|
|
tlbflushg(void)
|
|
{
|
|
tlbflush();
|
|
}
|
|
|
|
vaddr_t
|
|
rdr6(void)
|
|
{
|
|
u_int val;
|
|
|
|
val = HYPERVISOR_get_debugreg(6);
|
|
return val;
|
|
}
|
|
|
|
void
|
|
ldr6(vaddr_t val)
|
|
{
|
|
|
|
HYPERVISOR_set_debugreg(6, val);
|
|
}
|
|
|
|
void
|
|
wbinvd(void)
|
|
{
|
|
|
|
xpq_flush_cache();
|
|
}
|
|
|
|
vaddr_t
|
|
rcr2(void)
|
|
{
|
|
return curcpu()->ci_vcpu->arch.cr2;
|
|
}
|