1/****************************************************************************** 2 * xen-x86_64.h 3 * 4 * Guest OS interface to x86 64-bit Xen. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to 8 * deal in the Software without restriction, including without limitation the 9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 * sell copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 * 24 * Copyright (c) 2004-2006, K A Fraser 25 */ 26 27#ifndef __XEN_PUBLIC_ARCH_X86_XEN_X86_64_H__ 28#define __XEN_PUBLIC_ARCH_X86_XEN_X86_64_H__ 29 30/* 31 * Hypercall interface: 32 * Input: %rdi, %rsi, %rdx, %r10, %r8, %r9 (arguments 1-6) 33 * Output: %rax 34 * Access is via hypercall page (set up by guest loader or via a Xen MSR): 35 * call hypercall_page + hypercall-number * 32 36 * Clobbered: argument registers (e.g., 2-arg hypercall clobbers %rdi,%rsi) 37 */ 38 39/* 40 * 64-bit segment selectors 41 * These flat segments are in the Xen-private section of every GDT. Since these 42 * are also present in the initial GDT, many OSes will be able to avoid 43 * installing their own GDT. 44 */ 45 46#define FLAT_RING3_CS32 0xe023 /* GDT index 260 */ 47#define FLAT_RING3_CS64 0xe033 /* GDT index 261 */ 48#define FLAT_RING3_DS32 0xe02b /* GDT index 262 */ 49#define FLAT_RING3_DS64 0x0000 /* NULL selector */ 50#define FLAT_RING3_SS32 0xe02b /* GDT index 262 */ 51#define FLAT_RING3_SS64 0xe02b /* GDT index 262 */ 52 53#define FLAT_KERNEL_DS64 FLAT_RING3_DS64 54#define FLAT_KERNEL_DS32 FLAT_RING3_DS32 55#define FLAT_KERNEL_DS FLAT_KERNEL_DS64 56#define FLAT_KERNEL_CS64 FLAT_RING3_CS64 57#define FLAT_KERNEL_CS32 FLAT_RING3_CS32 58#define FLAT_KERNEL_CS FLAT_KERNEL_CS64 59#define FLAT_KERNEL_SS64 FLAT_RING3_SS64 60#define FLAT_KERNEL_SS32 FLAT_RING3_SS32 61#define FLAT_KERNEL_SS FLAT_KERNEL_SS64 62 63#define FLAT_USER_DS64 FLAT_RING3_DS64 64#define FLAT_USER_DS32 FLAT_RING3_DS32 65#define FLAT_USER_DS FLAT_USER_DS64 66#define FLAT_USER_CS64 FLAT_RING3_CS64 67#define FLAT_USER_CS32 FLAT_RING3_CS32 68#define FLAT_USER_CS FLAT_USER_CS64 69#define FLAT_USER_SS64 FLAT_RING3_SS64 70#define FLAT_USER_SS32 FLAT_RING3_SS32 71#define FLAT_USER_SS FLAT_USER_SS64 72 73#define __HYPERVISOR_VIRT_START 0xFFFF800000000000 74#define __HYPERVISOR_VIRT_END 0xFFFF880000000000 75#define __MACH2PHYS_VIRT_START 0xFFFF800000000000 76#define __MACH2PHYS_VIRT_END 0xFFFF804000000000 77 78#ifndef HYPERVISOR_VIRT_START 79#define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START) 80#define HYPERVISOR_VIRT_END mk_unsigned_long(__HYPERVISOR_VIRT_END) 81#endif 82 83#define MACH2PHYS_VIRT_START mk_unsigned_long(__MACH2PHYS_VIRT_START) 84#define MACH2PHYS_VIRT_END mk_unsigned_long(__MACH2PHYS_VIRT_END) 85#define MACH2PHYS_NR_ENTRIES ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>3) 86#ifndef machine_to_phys_mapping 87#define machine_to_phys_mapping ((unsigned long *)HYPERVISOR_VIRT_START) 88#endif 89 90/* 91 * int HYPERVISOR_set_segment_base(unsigned int which, unsigned long base) 92 * @which == SEGBASE_* ; @base == 64-bit base address 93 * Returns 0 on success. 94 */ 95#define SEGBASE_FS 0 96#define SEGBASE_GS_USER 1 97#define SEGBASE_GS_KERNEL 2 98#define SEGBASE_GS_USER_SEL 3 /* Set user %gs specified in base[15:0] */ 99 100/* 101 * int HYPERVISOR_iret(void) 102 * All arguments are on the kernel stack, in the following format. 103 * Never returns if successful. Current kernel context is lost. 104 * The saved CS is mapped as follows: 105 * RING0 -> RING3 kernel mode. 106 * RING1 -> RING3 kernel mode. 107 * RING2 -> RING3 kernel mode. 108 * RING3 -> RING3 user mode. 109 * However RING0 indicates that the guest kernel should return to iteself 110 * directly with 111 * orb $3,1*8(%rsp) 112 * iretq 113 * If flags contains VGCF_in_syscall: 114 * Restore RAX, RIP, RFLAGS, RSP. 115 * Discard R11, RCX, CS, SS. 116 * Otherwise: 117 * Restore RAX, R11, RCX, CS:RIP, RFLAGS, SS:RSP. 118 * All other registers are saved on hypercall entry and restored to user. 119 */ 120/* Guest exited in SYSCALL context? Return to guest with SYSRET? */ 121#define _VGCF_in_syscall 8 122#define VGCF_in_syscall (1<<_VGCF_in_syscall) 123#define VGCF_IN_SYSCALL VGCF_in_syscall 124 125#ifndef __ASSEMBLY__ 126 127struct iret_context { 128 /* Top of stack (%rsp at point of hypercall). */ 129 uint64_t rax, r11, rcx, flags, rip, cs, rflags, rsp, ss; 130 /* Bottom of iret stack frame. */ 131}; 132 133#if defined(__GNUC__) && !defined(__STRICT_ANSI__) 134/* Anonymous union includes both 32- and 64-bit names (e.g., eax/rax). */ 135#define __DECL_REG(name) union { \ 136 uint64_t r ## name, e ## name; \ 137 uint32_t _e ## name; \ 138} 139#else 140/* Non-gcc sources must always use the proper 64-bit name (e.g., rax). */ 141#define __DECL_REG(name) uint64_t r ## name 142#endif 143 144struct cpu_user_regs { 145 uint64_t r15; 146 uint64_t r14; 147 uint64_t r13; 148 uint64_t r12; 149 __DECL_REG(bp); 150 __DECL_REG(bx); 151 uint64_t r11; 152 uint64_t r10; 153 uint64_t r9; 154 uint64_t r8; 155 __DECL_REG(ax); 156 __DECL_REG(cx); 157 __DECL_REG(dx); 158 __DECL_REG(si); 159 __DECL_REG(di); 160 uint32_t error_code; /* private */ 161 uint32_t entry_vector; /* private */ 162 __DECL_REG(ip); 163 uint16_t cs, _pad0[1]; 164 uint8_t saved_upcall_mask; 165 uint8_t _pad1[3]; 166 __DECL_REG(flags); /* rflags.IF == !saved_upcall_mask */ 167 __DECL_REG(sp); 168 uint16_t ss, _pad2[3]; 169 uint16_t es, _pad3[3]; 170 uint16_t ds, _pad4[3]; 171 uint16_t fs, _pad5[3]; /* Non-zero => takes precedence over fs_base. */ 172 uint16_t gs, _pad6[3]; /* Non-zero => takes precedence over gs_base_usr. */ 173}; 174typedef struct cpu_user_regs cpu_user_regs_t; 175DEFINE_XEN_GUEST_HANDLE(cpu_user_regs_t); 176 177#undef __DECL_REG 178 179#define xen_pfn_to_cr3(pfn) ((unsigned long)(pfn) << 12) 180#define xen_cr3_to_pfn(cr3) ((unsigned long)(cr3) >> 12) 181 182struct arch_vcpu_info { 183 unsigned long cr2; 184 unsigned long pad; /* sizeof(vcpu_info_t) == 64 */ 185}; 186typedef struct arch_vcpu_info arch_vcpu_info_t; 187 188typedef unsigned long xen_callback_t; 189 190#endif /* !__ASSEMBLY__ */ 191 192#endif /* __XEN_PUBLIC_ARCH_X86_XEN_X86_64_H__ */ 193 194/* 195 * Local variables: 196 * mode: C 197 * c-set-style: "BSD" 198 * c-basic-offset: 4 199 * tab-width: 4 200 * indent-tabs-mode: nil 201 * End: 202 */ 203