xen-x86_32.h revision 181624
1332866Sdteske/****************************************************************************** 2332866Sdteske * xen-x86_32.h 3332866Sdteske * 4332866Sdteske * Guest OS interface to x86 32-bit Xen. 5332866Sdteske * 6332866Sdteske * Permission is hereby granted, free of charge, to any person obtaining a copy 7332866Sdteske * of this software and associated documentation files (the "Software"), to 8332866Sdteske * deal in the Software without restriction, including without limitation the 9332866Sdteske * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10332866Sdteske * sell copies of the Software, and to permit persons to whom the Software is 11332866Sdteske * furnished to do so, subject to the following conditions: 12332866Sdteske * 13332866Sdteske * The above copyright notice and this permission notice shall be included in 14332866Sdteske * all copies or substantial portions of the Software. 15332866Sdteske * 16332866Sdteske * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17332866Sdteske * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18332866Sdteske * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19332866Sdteske * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20332866Sdteske * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21332866Sdteske * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22332866Sdteske * DEALINGS IN THE SOFTWARE. 23332866Sdteske * 24332866Sdteske * Copyright (c) 2004-2007, K A Fraser 25332866Sdteske */ 26332866Sdteske 27332866Sdteske#include <sys/param.h> 28332866Sdteske#include <sys/types.h> 29332866Sdteske 30333617Sdteske#ifndef __XEN_PUBLIC_ARCH_X86_XEN_X86_32_H__ 31333617Sdteske#define __XEN_PUBLIC_ARCH_X86_XEN_X86_32_H__ 32332866Sdteske 33333617Sdteske/* Structural guest handles introduced in 0x00030201. */ 34332866Sdteske#define __DEFINE_XEN_GUEST_HANDLE(name, type) \ 35332866Sdteske typedef struct name { type *p; } __guest_handle_ ## name 36332866Sdteske 37332866Sdteske#define DEFINE_XEN_GUEST_HANDLE(name) __DEFINE_XEN_GUEST_HANDLE(name, name) 38332866Sdteske#define __XEN_GUEST_HANDLE(name) __guest_handle_ ## name 39332866Sdteske#define XEN_GUEST_HANDLE(name) __XEN_GUEST_HANDLE(name) 40332866Sdteske#define set_xen_guest_handle(hnd, val) do { (hnd).p = val; } while (0) 41332866Sdteske#ifdef __XEN_TOOLS__ 42332866Sdteske#define get_xen_guest_handle(val, hnd) do { val = (hnd).p; } while (0) 43332866Sdteske#endif 44332866Sdteske 45332866Sdteske/* 46332866Sdteske * Hypercall interface: 47332866Sdteske * Input: %ebx, %ecx, %edx, %esi, %edi (arguments 1-5) 48332866Sdteske * Output: %eax 49332866Sdteske * Access is via hypercall page (set up by guest loader or via a Xen MSR): 50332866Sdteske * call hypercall_page + hypercall-number * 32 51332866Sdteske * Clobbered: Argument registers (e.g., 2-arg hypercall clobbers %ebx,%ecx) 52332866Sdteske */ 53332866Sdteske 54332866Sdteske#if __XEN_INTERFACE_VERSION__ < 0x00030203 55332866Sdteske/* 56332866Sdteske * Legacy hypercall interface: 57332866Sdteske * As above, except the entry sequence to the hypervisor is: 58332866Sdteske * mov $hypercall-number*32,%eax ; int $0x82 59332866Sdteske */ 60332866Sdteske#define TRAP_INSTR "int $0x82" 61332866Sdteske#endif 62332866Sdteske 63332866Sdteske/* 64332866Sdteske * These flat segments are in the Xen-private section of every GDT. Since these 65332866Sdteske * are also present in the initial GDT, many OSes will be able to avoid 66332866Sdteske * installing their own GDT. 67332866Sdteske */ 68332866Sdteske#define FLAT_RING1_CS 0xe019 /* GDT index 259 */ 69332866Sdteske#define FLAT_RING1_DS 0xe021 /* GDT index 260 */ 70332866Sdteske#define FLAT_RING1_SS 0xe021 /* GDT index 260 */ 71332866Sdteske#define FLAT_RING3_CS 0xe02b /* GDT index 261 */ 72332866Sdteske#define FLAT_RING3_DS 0xe033 /* GDT index 262 */ 73332866Sdteske#define FLAT_RING3_SS 0xe033 /* GDT index 262 */ 74332866Sdteske 75332866Sdteske#define FLAT_KERNEL_CS FLAT_RING1_CS 76332866Sdteske#define FLAT_KERNEL_DS FLAT_RING1_DS 77332866Sdteske#define FLAT_KERNEL_SS FLAT_RING1_SS 78332866Sdteske#define FLAT_USER_CS FLAT_RING3_CS 79332866Sdteske#define FLAT_USER_DS FLAT_RING3_DS 80332866Sdteske#define FLAT_USER_SS FLAT_RING3_SS 81332866Sdteske 82332866Sdteske#define __HYPERVISOR_VIRT_START_PAE 0xF5800000 83332866Sdteske#define __MACH2PHYS_VIRT_START_PAE 0xF5800000 84332866Sdteske#define __MACH2PHYS_VIRT_END_PAE 0xF6800000 85332866Sdteske#define HYPERVISOR_VIRT_START_PAE \ 86332866Sdteske mk_unsigned_long(__HYPERVISOR_VIRT_START_PAE) 87332866Sdteske#define MACH2PHYS_VIRT_START_PAE \ 88332866Sdteske mk_unsigned_long(__MACH2PHYS_VIRT_START_PAE) 89332866Sdteske#define MACH2PHYS_VIRT_END_PAE \ 90332866Sdteske mk_unsigned_long(__MACH2PHYS_VIRT_END_PAE) 91332866Sdteske 92332866Sdteske#define __HYPERVISOR_VIRT_START_NONPAE 0xFC000000 93332866Sdteske#define __MACH2PHYS_VIRT_START_NONPAE 0xFC000000 94332866Sdteske#define __MACH2PHYS_VIRT_END_NONPAE 0xFC400000 95332866Sdteske#define HYPERVISOR_VIRT_START_NONPAE \ 96332866Sdteske mk_unsigned_long(__HYPERVISOR_VIRT_START_NONPAE) 97332866Sdteske#define MACH2PHYS_VIRT_START_NONPAE \ 98332866Sdteske mk_unsigned_long(__MACH2PHYS_VIRT_START_NONPAE) 99332866Sdteske#define MACH2PHYS_VIRT_END_NONPAE \ 100332866Sdteske mk_unsigned_long(__MACH2PHYS_VIRT_END_NONPAE) 101332866Sdteske 102332866Sdteske#ifdef CONFIG_X86_PAE 103333617Sdteske#define __HYPERVISOR_VIRT_START __HYPERVISOR_VIRT_START_PAE 104333617Sdteske#define __MACH2PHYS_VIRT_START __MACH2PHYS_VIRT_START_PAE 105332866Sdteske#define __MACH2PHYS_VIRT_END __MACH2PHYS_VIRT_END_PAE 106332866Sdteske#else 107332866Sdteske#warning "not using PAE!!!" 108332866Sdteske#define __HYPERVISOR_VIRT_START __HYPERVISOR_VIRT_START_NONPAE 109332866Sdteske#define __MACH2PHYS_VIRT_START __MACH2PHYS_VIRT_START_NONPAE 110332866Sdteske#define __MACH2PHYS_VIRT_END __MACH2PHYS_VIRT_END_NONPAE 111332866Sdteske#endif 112332866Sdteske 113332866Sdteske#ifndef HYPERVISOR_VIRT_START 114332866Sdteske#define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START) 115332866Sdteske#endif 116332866Sdteske 117332866Sdteske#define MACH2PHYS_VIRT_START mk_unsigned_long(__MACH2PHYS_VIRT_START) 118332866Sdteske#define MACH2PHYS_VIRT_END mk_unsigned_long(__MACH2PHYS_VIRT_END) 119332866Sdteske#define MACH2PHYS_NR_ENTRIES ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>2) 120332866Sdteske#ifndef machine_to_phys_mapping 121332866Sdteske#define machine_to_phys_mapping ((unsigned long *)MACH2PHYS_VIRT_START) 122332866Sdteske#endif 123332866Sdteske 124333617Sdteske/* 32-/64-bit invariability for control interfaces (domctl/sysctl). */ 125333617Sdteske#if defined(__XEN__) || defined(__XEN_TOOLS__) 126333617Sdteske#undef __DEFINE_XEN_GUEST_HANDLE 127333617Sdteske#define __DEFINE_XEN_GUEST_HANDLE(name, type) \ 128333617Sdteske typedef struct { type *p; } \ 129333617Sdteske __guest_handle_ ## name; \ 130333617Sdteske typedef struct { union { type *p; uint64_aligned_t q; }; } \ 131333617Sdteske __guest_handle_64_ ## name 132332866Sdteske#undef set_xen_guest_handle 133332866Sdteske#define set_xen_guest_handle(hnd, val) \ 134332866Sdteske do { if ( sizeof(hnd) == 8 ) *(uint64_t *)&(hnd) = 0; \ 135332866Sdteske (hnd).p = val; \ 136332866Sdteske } while ( 0 ) 137332866Sdteske#define uint64_aligned_t uint64_t __attribute__((aligned(8))) 138332866Sdteske#define XEN_GUEST_HANDLE_64(name) __guest_handle_64_ ## name 139332866Sdteske#endif 140332866Sdteske 141332866Sdteske#ifndef __ASSEMBLY__ 142332866Sdteske 143332866Sdteskestruct cpu_user_regs { 144332866Sdteske uint32_t ebx; 145332866Sdteske uint32_t ecx; 146332866Sdteske uint32_t edx; 147332866Sdteske uint32_t esi; 148332866Sdteske uint32_t edi; 149332866Sdteske uint32_t ebp; 150332866Sdteske uint32_t eax; 151332866Sdteske uint16_t error_code; /* private */ 152332866Sdteske uint16_t entry_vector; /* private */ 153332866Sdteske uint32_t eip; 154332866Sdteske uint16_t cs; 155332866Sdteske uint8_t saved_upcall_mask; 156332866Sdteske uint8_t _pad0; 157332866Sdteske uint32_t eflags; /* eflags.IF == !saved_upcall_mask */ 158332866Sdteske uint32_t esp; 159332866Sdteske uint16_t ss, _pad1; 160332866Sdteske uint16_t es, _pad2; 161333617Sdteske uint16_t ds, _pad3; 162333617Sdteske uint16_t fs, _pad4; 163332866Sdteske uint16_t gs, _pad5; 164332866Sdteske}; 165332866Sdtesketypedef struct cpu_user_regs cpu_user_regs_t; 166332866Sdteske__DEFINE_XEN_GUEST_HANDLE(foobarbaz, cpu_user_regs_t); 167332866Sdteske 168332866Sdteske/* 169332866Sdteske * Page-directory addresses above 4GB do not fit into architectural %cr3. 170332866Sdteske * When accessing %cr3, or equivalent field in vcpu_guest_context, guests 171332866Sdteske * must use the following accessor macros to pack/unpack valid MFNs. 172332866Sdteske */ 173332866Sdteske#define xen_pfn_to_cr3(pfn) (((unsigned)(pfn) << 12) | ((unsigned)(pfn) >> 20)) 174332866Sdteske#define xen_cr3_to_pfn(cr3) (((unsigned)(cr3) >> 12) | ((unsigned)(cr3) << 20)) 175333617Sdteske 176332866Sdteskestruct arch_vcpu_info { 177332866Sdteske unsigned long cr2; 178333617Sdteske unsigned long pad[5]; /* sizeof(vcpu_info_t) == 64 */ 179333617Sdteske}; 180333617Sdtesketypedef struct arch_vcpu_info arch_vcpu_info_t; 181333617Sdteske 182333617Sdteskestruct xen_callback { 183333617Sdteske unsigned long cs; 184332866Sdteske unsigned long eip; 185333617Sdteske}; 186333617Sdtesketypedef struct xen_callback xen_callback_t; 187332866Sdteske 188332866Sdteske#endif /* !__ASSEMBLY__ */ 189332866Sdteske 190332866Sdteske#endif /* __XEN_PUBLIC_ARCH_X86_XEN_X86_32_H__ */ 191332866Sdteske 192332866Sdteske/* 193332866Sdteske * Local variables: 194332866Sdteske * mode: C 195333617Sdteske * c-set-style: "BSD" 196332866Sdteske * c-basic-offset: 4 197333617Sdteske * tab-width: 4 198332866Sdteske * indent-tabs-mode: nil 199333617Sdteske * End: 200333617Sdteske */ 201332866Sdteske