1843e1988Sjohnlev /****************************************************************************** 2843e1988Sjohnlev * arch-x86/xen.h 3843e1988Sjohnlev * 4843e1988Sjohnlev * Guest OS interface to x86 Xen. 5843e1988Sjohnlev * 6843e1988Sjohnlev * Permission is hereby granted, free of charge, to any person obtaining a copy 7843e1988Sjohnlev * of this software and associated documentation files (the "Software"), to 8843e1988Sjohnlev * deal in the Software without restriction, including without limitation the 9843e1988Sjohnlev * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10843e1988Sjohnlev * sell copies of the Software, and to permit persons to whom the Software is 11843e1988Sjohnlev * furnished to do so, subject to the following conditions: 12843e1988Sjohnlev * 13843e1988Sjohnlev * The above copyright notice and this permission notice shall be included in 14843e1988Sjohnlev * all copies or substantial portions of the Software. 15843e1988Sjohnlev * 16843e1988Sjohnlev * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17843e1988Sjohnlev * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18843e1988Sjohnlev * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19843e1988Sjohnlev * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20843e1988Sjohnlev * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21843e1988Sjohnlev * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22843e1988Sjohnlev * DEALINGS IN THE SOFTWARE. 23843e1988Sjohnlev * 24843e1988Sjohnlev * Copyright (c) 2004-2006, K A Fraser 25843e1988Sjohnlev */ 26843e1988Sjohnlev 27e4b86885SCheng Sean Ye #include "../xen.h" 28e4b86885SCheng Sean Ye 29843e1988Sjohnlev #ifndef __XEN_PUBLIC_ARCH_X86_XEN_H__ 30843e1988Sjohnlev #define __XEN_PUBLIC_ARCH_X86_XEN_H__ 31843e1988Sjohnlev 32843e1988Sjohnlev /* Structural guest handles introduced in 0x00030201. */ 33843e1988Sjohnlev #if __XEN_INTERFACE_VERSION__ >= 0x00030201 34e4b86885SCheng Sean Ye #define ___DEFINE_XEN_GUEST_HANDLE(name, type) \ 35843e1988Sjohnlev typedef struct { type *p; } __guest_handle_ ## name 36843e1988Sjohnlev #else 37e4b86885SCheng Sean Ye #define ___DEFINE_XEN_GUEST_HANDLE(name, type) \ 38843e1988Sjohnlev typedef type * __guest_handle_ ## name 39843e1988Sjohnlev #endif 40843e1988Sjohnlev 41e4b86885SCheng Sean Ye #define __DEFINE_XEN_GUEST_HANDLE(name, type) \ 42*349b53ddSStuart Maybee ___DEFINE_XEN_GUEST_HANDLE(name, type); \ 43*349b53ddSStuart Maybee ___DEFINE_XEN_GUEST_HANDLE(const_##name, const type) 44843e1988Sjohnlev #define DEFINE_XEN_GUEST_HANDLE(name) __DEFINE_XEN_GUEST_HANDLE(name, name) 45a576ab5bSrab #define __XEN_GUEST_HANDLE(name) __guest_handle_ ## name 46a576ab5bSrab #define XEN_GUEST_HANDLE(name) __XEN_GUEST_HANDLE(name) 47843e1988Sjohnlev #define set_xen_guest_handle(hnd, val) do { (hnd).p = val; } while (0) 48*349b53ddSStuart Maybee #ifdef __XEN_TOOLS__ 49843e1988Sjohnlev #define get_xen_guest_handle(val, hnd) do { val = (hnd).p; } while (0) 50*349b53ddSStuart Maybee #endif 51a576ab5bSrab 52a576ab5bSrab #if defined(__i386__) 53a576ab5bSrab #include "xen-x86_32.h" 54a576ab5bSrab #elif defined(__x86_64__) 55a576ab5bSrab #include "xen-x86_64.h" 56a576ab5bSrab #endif 57843e1988Sjohnlev 58843e1988Sjohnlev #ifndef __ASSEMBLY__ 59843e1988Sjohnlev typedef unsigned long xen_pfn_t; 60a576ab5bSrab #define PRI_xen_pfn "lx" 61843e1988Sjohnlev #endif 62843e1988Sjohnlev 63843e1988Sjohnlev /* 64843e1988Sjohnlev * SEGMENT DESCRIPTOR TABLES 65843e1988Sjohnlev */ 66843e1988Sjohnlev /* 67843e1988Sjohnlev * A number of GDT entries are reserved by Xen. These are not situated at the 68843e1988Sjohnlev * start of the GDT because some stupid OSes export hard-coded selector values 69843e1988Sjohnlev * in their ABI. These hard-coded values are always near the start of the GDT, 70843e1988Sjohnlev * so Xen places itself out of the way, at the far end of the GDT. 71843e1988Sjohnlev */ 72843e1988Sjohnlev #define FIRST_RESERVED_GDT_PAGE 14 73843e1988Sjohnlev #define FIRST_RESERVED_GDT_BYTE (FIRST_RESERVED_GDT_PAGE * 4096) 74843e1988Sjohnlev #define FIRST_RESERVED_GDT_ENTRY (FIRST_RESERVED_GDT_BYTE / 8) 75843e1988Sjohnlev 76843e1988Sjohnlev /* Maximum number of virtual CPUs in multi-processor guests. */ 77843e1988Sjohnlev #define MAX_VIRT_CPUS 32 78843e1988Sjohnlev 79843e1988Sjohnlev #ifndef __ASSEMBLY__ 80843e1988Sjohnlev 81843e1988Sjohnlev typedef unsigned long xen_ulong_t; 82843e1988Sjohnlev 83843e1988Sjohnlev /* 84843e1988Sjohnlev * Send an array of these to HYPERVISOR_set_trap_table(). 85843e1988Sjohnlev * The privilege level specifies which modes may enter a trap via a software 86843e1988Sjohnlev * interrupt. On x86/64, since rings 1 and 2 are unavailable, we allocate 87843e1988Sjohnlev * privilege levels as follows: 88843e1988Sjohnlev * Level == 0: Noone may enter 89843e1988Sjohnlev * Level == 1: Kernel may enter 90843e1988Sjohnlev * Level == 2: Kernel may enter 91843e1988Sjohnlev * Level == 3: Everyone may enter 92843e1988Sjohnlev */ 93843e1988Sjohnlev #define TI_GET_DPL(_ti) ((_ti)->flags & 3) 94843e1988Sjohnlev #define TI_GET_IF(_ti) ((_ti)->flags & 4) 95843e1988Sjohnlev #define TI_SET_DPL(_ti,_dpl) ((_ti)->flags |= (_dpl)) 96843e1988Sjohnlev #define TI_SET_IF(_ti,_if) ((_ti)->flags |= ((!!(_if))<<2)) 97843e1988Sjohnlev struct trap_info { 98843e1988Sjohnlev uint8_t vector; /* exception vector */ 99843e1988Sjohnlev uint8_t flags; /* 0-3: privilege level; 4: clear event enable? */ 100843e1988Sjohnlev uint16_t cs; /* code selector */ 101843e1988Sjohnlev unsigned long address; /* code offset */ 102843e1988Sjohnlev }; 103843e1988Sjohnlev typedef struct trap_info trap_info_t; 104843e1988Sjohnlev DEFINE_XEN_GUEST_HANDLE(trap_info_t); 105843e1988Sjohnlev 106843e1988Sjohnlev typedef uint64_t tsc_timestamp_t; /* RDTSC timestamp */ 107843e1988Sjohnlev 108843e1988Sjohnlev /* 109843e1988Sjohnlev * The following is all CPU context. Note that the fpu_ctxt block is filled 110843e1988Sjohnlev * in by FXSAVE if the CPU has feature FXSR; otherwise FSAVE is used. 111843e1988Sjohnlev */ 112843e1988Sjohnlev struct vcpu_guest_context { 113843e1988Sjohnlev /* FPU registers come first so they can be aligned for FXSAVE/FXRSTOR. */ 114843e1988Sjohnlev struct { char x[512]; } fpu_ctxt; /* User-level FPU registers */ 115843e1988Sjohnlev #define VGCF_I387_VALID (1<<0) 116843e1988Sjohnlev #define VGCF_IN_KERNEL (1<<2) 117843e1988Sjohnlev #define _VGCF_i387_valid 0 118843e1988Sjohnlev #define VGCF_i387_valid (1<<_VGCF_i387_valid) 119843e1988Sjohnlev #define _VGCF_in_kernel 2 120843e1988Sjohnlev #define VGCF_in_kernel (1<<_VGCF_in_kernel) 121843e1988Sjohnlev #define _VGCF_failsafe_disables_events 3 122843e1988Sjohnlev #define VGCF_failsafe_disables_events (1<<_VGCF_failsafe_disables_events) 123843e1988Sjohnlev #define _VGCF_syscall_disables_events 4 124843e1988Sjohnlev #define VGCF_syscall_disables_events (1<<_VGCF_syscall_disables_events) 125a576ab5bSrab #define _VGCF_online 5 126a576ab5bSrab #define VGCF_online (1<<_VGCF_online) 127843e1988Sjohnlev unsigned long flags; /* VGCF_* flags */ 128843e1988Sjohnlev struct cpu_user_regs user_regs; /* User-level CPU registers */ 129843e1988Sjohnlev struct trap_info trap_ctxt[256]; /* Virtual IDT */ 130843e1988Sjohnlev unsigned long ldt_base, ldt_ents; /* LDT (linear address, # ents) */ 131843e1988Sjohnlev unsigned long gdt_frames[16], gdt_ents; /* GDT (machine frames, # ents) */ 132843e1988Sjohnlev unsigned long kernel_ss, kernel_sp; /* Virtual TSS (only SS1/SP1) */ 133a576ab5bSrab /* NB. User pagetable on x86/64 is placed in ctrlreg[1]. */ 134843e1988Sjohnlev unsigned long ctrlreg[8]; /* CR0-CR7 (control registers) */ 135843e1988Sjohnlev unsigned long debugreg[8]; /* DB0-DB7 (debug registers) */ 136843e1988Sjohnlev #ifdef __i386__ 137843e1988Sjohnlev unsigned long event_callback_cs; /* CS:EIP of event callback */ 138843e1988Sjohnlev unsigned long event_callback_eip; 139843e1988Sjohnlev unsigned long failsafe_callback_cs; /* CS:EIP of failsafe callback */ 140843e1988Sjohnlev unsigned long failsafe_callback_eip; 141843e1988Sjohnlev #else 142843e1988Sjohnlev unsigned long event_callback_eip; 143843e1988Sjohnlev unsigned long failsafe_callback_eip; 144a576ab5bSrab #ifdef __XEN__ 145a576ab5bSrab union { 146843e1988Sjohnlev unsigned long syscall_callback_eip; 147a576ab5bSrab struct { 148a576ab5bSrab unsigned int event_callback_cs; /* compat CS of event cb */ 149a576ab5bSrab unsigned int failsafe_callback_cs; /* compat CS of failsafe cb */ 150a576ab5bSrab }; 151a576ab5bSrab }; 152a576ab5bSrab #else 153a576ab5bSrab unsigned long syscall_callback_eip; 154a576ab5bSrab #endif 155843e1988Sjohnlev #endif 156843e1988Sjohnlev unsigned long vm_assist; /* VMASST_TYPE_* bitmap */ 157843e1988Sjohnlev #ifdef __x86_64__ 158843e1988Sjohnlev /* Segment base addresses. */ 159843e1988Sjohnlev uint64_t fs_base; 160843e1988Sjohnlev uint64_t gs_base_kernel; 161843e1988Sjohnlev uint64_t gs_base_user; 162843e1988Sjohnlev #endif 163843e1988Sjohnlev }; 164843e1988Sjohnlev typedef struct vcpu_guest_context vcpu_guest_context_t; 165843e1988Sjohnlev DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t); 166843e1988Sjohnlev 167843e1988Sjohnlev struct arch_shared_info { 168843e1988Sjohnlev unsigned long max_pfn; /* max pfn that appears in table */ 169843e1988Sjohnlev /* Frame containing list of mfns containing list of mfns containing p2m. */ 170843e1988Sjohnlev xen_pfn_t pfn_to_mfn_frame_list_list; 171843e1988Sjohnlev unsigned long nmi_reason; 172843e1988Sjohnlev uint64_t pad[32]; 173843e1988Sjohnlev }; 174843e1988Sjohnlev typedef struct arch_shared_info arch_shared_info_t; 175843e1988Sjohnlev 176e4b86885SCheng Sean Ye #define MCA_PANICDATA_MAGIC 0x5044 /* "PD" */ 177e4b86885SCheng Sean Ye #define MCA_PANICDATA_VERS 1 178e4b86885SCheng Sean Ye 179e4b86885SCheng Sean Ye typedef struct xpv_mca_panic_data { 180e4b86885SCheng Sean Ye uint16_t mpd_magic; 181e4b86885SCheng Sean Ye uint16_t mpd_version; 182e4b86885SCheng Sean Ye int mpd_fwdptr_offset; 183e4b86885SCheng Sean Ye int mpd_revptr_offset; 184e4b86885SCheng Sean Ye int mpd_dataptr_offset; 185e4b86885SCheng Sean Ye void *mpd_urgent_processing; 186e4b86885SCheng Sean Ye void *mpd_urgent_dangling; 187e4b86885SCheng Sean Ye void *mpd_urgent_committed; 188e4b86885SCheng Sean Ye void *mpd_nonurgent_processing; 189e4b86885SCheng Sean Ye void *mpd_nonurgent_dangling; 190e4b86885SCheng Sean Ye void *mpd_nonurgent_committed; 191e4b86885SCheng Sean Ye } xpv_mca_panic_data_t; 192e4b86885SCheng Sean Ye 193843e1988Sjohnlev typedef struct panic_regs panic_regs_t; 194843e1988Sjohnlev struct panic_info { 195843e1988Sjohnlev int pi_version; /* panic_info format version */ 196843e1988Sjohnlev panic_regs_t *pi_regs; /* register state */ 197843e1988Sjohnlev void *pi_apic; /* local APIC address */ 198843e1988Sjohnlev char *pi_panicstr; /* panic message */ 199843e1988Sjohnlev void *pi_ram_start; /* Start of all-RAM mapping region */ 200843e1988Sjohnlev void *pi_ram_end; /* End of all-RAM mapping region */ 201a576ab5bSrab void *pi_xen_start; /* Start of Xen's text/heap */ 202a576ab5bSrab void *pi_xen_end; /* End of Xen's text/heap */ 203843e1988Sjohnlev void *pi_stktop; /* Top of current Xen stack */ 204843e1988Sjohnlev struct domain *pi_domain; /* Panicking domain */ 205843e1988Sjohnlev struct vcpu *pi_vcpu; /* Panicking vcpu */ 206843e1988Sjohnlev int pi_dom0cpu; /* cpu number - if a dom0 panic */ 207e4b86885SCheng Sean Ye xpv_mca_panic_data_t pi_mca; /* Machine check error telemetry */ 208843e1988Sjohnlev }; 209843e1988Sjohnlev 210843e1988Sjohnlev struct panic_frame { 211843e1988Sjohnlev unsigned long pf_fp; 212843e1988Sjohnlev unsigned long pf_pc; 213843e1988Sjohnlev }; 214843e1988Sjohnlev 215e4b86885SCheng Sean Ye #define PANIC_INFO_VERSION 3 216843e1988Sjohnlev 217843e1988Sjohnlev #endif /* !__ASSEMBLY__ */ 218843e1988Sjohnlev 219843e1988Sjohnlev /* 220843e1988Sjohnlev * Prefix forces emulation of some non-trapping instructions. 221843e1988Sjohnlev * Currently only CPUID. 222843e1988Sjohnlev */ 223843e1988Sjohnlev #ifdef __ASSEMBLY__ 224843e1988Sjohnlev #define XEN_EMULATE_PREFIX .byte 0x0f,0x0b,0x78,0x65,0x6e ; 225843e1988Sjohnlev #define XEN_CPUID XEN_EMULATE_PREFIX cpuid 226843e1988Sjohnlev #else 227843e1988Sjohnlev #define XEN_EMULATE_PREFIX ".byte 0x0f,0x0b,0x78,0x65,0x6e ; " 228843e1988Sjohnlev #define XEN_CPUID XEN_EMULATE_PREFIX "cpuid" 229843e1988Sjohnlev #endif 230843e1988Sjohnlev 231843e1988Sjohnlev #endif /* __XEN_PUBLIC_ARCH_X86_XEN_H__ */ 232843e1988Sjohnlev 233843e1988Sjohnlev /* 234843e1988Sjohnlev * Local variables: 235843e1988Sjohnlev * mode: C 236843e1988Sjohnlev * c-set-style: "BSD" 237843e1988Sjohnlev * c-basic-offset: 4 238843e1988Sjohnlev * tab-width: 4 239843e1988Sjohnlev * indent-tabs-mode: nil 240843e1988Sjohnlev * End: 241843e1988Sjohnlev */ 242