1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */ 2*4882a593Smuzhiyun #ifndef _ASM_X86_XEN_INTERFACE_64_H 3*4882a593Smuzhiyun #define _ASM_X86_XEN_INTERFACE_64_H 4*4882a593Smuzhiyun 5*4882a593Smuzhiyun /* 6*4882a593Smuzhiyun * 64-bit segment selectors 7*4882a593Smuzhiyun * These flat segments are in the Xen-private section of every GDT. Since these 8*4882a593Smuzhiyun * are also present in the initial GDT, many OSes will be able to avoid 9*4882a593Smuzhiyun * installing their own GDT. 10*4882a593Smuzhiyun */ 11*4882a593Smuzhiyun 12*4882a593Smuzhiyun #define FLAT_RING3_CS32 0xe023 /* GDT index 260 */ 13*4882a593Smuzhiyun #define FLAT_RING3_CS64 0xe033 /* GDT index 261 */ 14*4882a593Smuzhiyun #define FLAT_RING3_DS32 0xe02b /* GDT index 262 */ 15*4882a593Smuzhiyun #define FLAT_RING3_DS64 0x0000 /* NULL selector */ 16*4882a593Smuzhiyun #define FLAT_RING3_SS32 0xe02b /* GDT index 262 */ 17*4882a593Smuzhiyun #define FLAT_RING3_SS64 0xe02b /* GDT index 262 */ 18*4882a593Smuzhiyun 19*4882a593Smuzhiyun #define FLAT_KERNEL_DS64 FLAT_RING3_DS64 20*4882a593Smuzhiyun #define FLAT_KERNEL_DS32 FLAT_RING3_DS32 21*4882a593Smuzhiyun #define FLAT_KERNEL_DS FLAT_KERNEL_DS64 22*4882a593Smuzhiyun #define FLAT_KERNEL_CS64 FLAT_RING3_CS64 23*4882a593Smuzhiyun #define FLAT_KERNEL_CS32 FLAT_RING3_CS32 24*4882a593Smuzhiyun #define FLAT_KERNEL_CS FLAT_KERNEL_CS64 25*4882a593Smuzhiyun #define FLAT_KERNEL_SS64 FLAT_RING3_SS64 26*4882a593Smuzhiyun #define FLAT_KERNEL_SS32 FLAT_RING3_SS32 27*4882a593Smuzhiyun #define FLAT_KERNEL_SS FLAT_KERNEL_SS64 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun #define FLAT_USER_DS64 FLAT_RING3_DS64 30*4882a593Smuzhiyun #define FLAT_USER_DS32 FLAT_RING3_DS32 31*4882a593Smuzhiyun #define FLAT_USER_DS FLAT_USER_DS64 32*4882a593Smuzhiyun #define FLAT_USER_CS64 FLAT_RING3_CS64 33*4882a593Smuzhiyun #define FLAT_USER_CS32 FLAT_RING3_CS32 34*4882a593Smuzhiyun #define FLAT_USER_CS FLAT_USER_CS64 35*4882a593Smuzhiyun #define FLAT_USER_SS64 FLAT_RING3_SS64 36*4882a593Smuzhiyun #define FLAT_USER_SS32 FLAT_RING3_SS32 37*4882a593Smuzhiyun #define FLAT_USER_SS FLAT_USER_SS64 38*4882a593Smuzhiyun 39*4882a593Smuzhiyun #define __HYPERVISOR_VIRT_START 0xFFFF800000000000 40*4882a593Smuzhiyun #define __HYPERVISOR_VIRT_END 0xFFFF880000000000 41*4882a593Smuzhiyun #define __MACH2PHYS_VIRT_START 0xFFFF800000000000 42*4882a593Smuzhiyun #define __MACH2PHYS_VIRT_END 0xFFFF804000000000 43*4882a593Smuzhiyun #define __MACH2PHYS_SHIFT 3 44*4882a593Smuzhiyun 45*4882a593Smuzhiyun /* 46*4882a593Smuzhiyun * int HYPERVISOR_set_segment_base(unsigned int which, unsigned long base) 47*4882a593Smuzhiyun * @which == SEGBASE_* ; @base == 64-bit base address 48*4882a593Smuzhiyun * Returns 0 on success. 49*4882a593Smuzhiyun */ 50*4882a593Smuzhiyun #define SEGBASE_FS 0 51*4882a593Smuzhiyun #define SEGBASE_GS_USER 1 52*4882a593Smuzhiyun #define SEGBASE_GS_KERNEL 2 53*4882a593Smuzhiyun #define SEGBASE_GS_USER_SEL 3 /* Set user %gs specified in base[15:0] */ 54*4882a593Smuzhiyun 55*4882a593Smuzhiyun /* 56*4882a593Smuzhiyun * int HYPERVISOR_iret(void) 57*4882a593Smuzhiyun * All arguments are on the kernel stack, in the following format. 58*4882a593Smuzhiyun * Never returns if successful. Current kernel context is lost. 59*4882a593Smuzhiyun * The saved CS is mapped as follows: 60*4882a593Smuzhiyun * RING0 -> RING3 kernel mode. 61*4882a593Smuzhiyun * RING1 -> RING3 kernel mode. 62*4882a593Smuzhiyun * RING2 -> RING3 kernel mode. 63*4882a593Smuzhiyun * RING3 -> RING3 user mode. 64*4882a593Smuzhiyun * However RING0 indicates that the guest kernel should return to iteself 65*4882a593Smuzhiyun * directly with 66*4882a593Smuzhiyun * orb $3,1*8(%rsp) 67*4882a593Smuzhiyun * iretq 68*4882a593Smuzhiyun * If flags contains VGCF_in_syscall: 69*4882a593Smuzhiyun * Restore RAX, RIP, RFLAGS, RSP. 70*4882a593Smuzhiyun * Discard R11, RCX, CS, SS. 71*4882a593Smuzhiyun * Otherwise: 72*4882a593Smuzhiyun * Restore RAX, R11, RCX, CS:RIP, RFLAGS, SS:RSP. 73*4882a593Smuzhiyun * All other registers are saved on hypercall entry and restored to user. 74*4882a593Smuzhiyun */ 75*4882a593Smuzhiyun /* Guest exited in SYSCALL context? Return to guest with SYSRET? */ 76*4882a593Smuzhiyun #define _VGCF_in_syscall 8 77*4882a593Smuzhiyun #define VGCF_in_syscall (1<<_VGCF_in_syscall) 78*4882a593Smuzhiyun #define VGCF_IN_SYSCALL VGCF_in_syscall 79*4882a593Smuzhiyun 80*4882a593Smuzhiyun #ifndef __ASSEMBLY__ 81*4882a593Smuzhiyun 82*4882a593Smuzhiyun struct iret_context { 83*4882a593Smuzhiyun /* Top of stack (%rsp at point of hypercall). */ 84*4882a593Smuzhiyun uint64_t rax, r11, rcx, flags, rip, cs, rflags, rsp, ss; 85*4882a593Smuzhiyun /* Bottom of iret stack frame. */ 86*4882a593Smuzhiyun }; 87*4882a593Smuzhiyun 88*4882a593Smuzhiyun #if defined(__GNUC__) && !defined(__STRICT_ANSI__) 89*4882a593Smuzhiyun /* Anonymous union includes both 32- and 64-bit names (e.g., eax/rax). */ 90*4882a593Smuzhiyun #define __DECL_REG(name) union { \ 91*4882a593Smuzhiyun uint64_t r ## name, e ## name; \ 92*4882a593Smuzhiyun uint32_t _e ## name; \ 93*4882a593Smuzhiyun } 94*4882a593Smuzhiyun #else 95*4882a593Smuzhiyun /* Non-gcc sources must always use the proper 64-bit name (e.g., rax). */ 96*4882a593Smuzhiyun #define __DECL_REG(name) uint64_t r ## name 97*4882a593Smuzhiyun #endif 98*4882a593Smuzhiyun 99*4882a593Smuzhiyun struct cpu_user_regs { 100*4882a593Smuzhiyun uint64_t r15; 101*4882a593Smuzhiyun uint64_t r14; 102*4882a593Smuzhiyun uint64_t r13; 103*4882a593Smuzhiyun uint64_t r12; 104*4882a593Smuzhiyun __DECL_REG(bp); 105*4882a593Smuzhiyun __DECL_REG(bx); 106*4882a593Smuzhiyun uint64_t r11; 107*4882a593Smuzhiyun uint64_t r10; 108*4882a593Smuzhiyun uint64_t r9; 109*4882a593Smuzhiyun uint64_t r8; 110*4882a593Smuzhiyun __DECL_REG(ax); 111*4882a593Smuzhiyun __DECL_REG(cx); 112*4882a593Smuzhiyun __DECL_REG(dx); 113*4882a593Smuzhiyun __DECL_REG(si); 114*4882a593Smuzhiyun __DECL_REG(di); 115*4882a593Smuzhiyun uint32_t error_code; /* private */ 116*4882a593Smuzhiyun uint32_t entry_vector; /* private */ 117*4882a593Smuzhiyun __DECL_REG(ip); 118*4882a593Smuzhiyun uint16_t cs, _pad0[1]; 119*4882a593Smuzhiyun uint8_t saved_upcall_mask; 120*4882a593Smuzhiyun uint8_t _pad1[3]; 121*4882a593Smuzhiyun __DECL_REG(flags); /* rflags.IF == !saved_upcall_mask */ 122*4882a593Smuzhiyun __DECL_REG(sp); 123*4882a593Smuzhiyun uint16_t ss, _pad2[3]; 124*4882a593Smuzhiyun uint16_t es, _pad3[3]; 125*4882a593Smuzhiyun uint16_t ds, _pad4[3]; 126*4882a593Smuzhiyun uint16_t fs, _pad5[3]; /* Non-zero => takes precedence over fs_base. */ 127*4882a593Smuzhiyun uint16_t gs, _pad6[3]; /* Non-zero => takes precedence over gs_base_usr. */ 128*4882a593Smuzhiyun }; 129*4882a593Smuzhiyun DEFINE_GUEST_HANDLE_STRUCT(cpu_user_regs); 130*4882a593Smuzhiyun 131*4882a593Smuzhiyun #undef __DECL_REG 132*4882a593Smuzhiyun 133*4882a593Smuzhiyun #define xen_pfn_to_cr3(pfn) ((unsigned long)(pfn) << 12) 134*4882a593Smuzhiyun #define xen_cr3_to_pfn(cr3) ((unsigned long)(cr3) >> 12) 135*4882a593Smuzhiyun 136*4882a593Smuzhiyun struct arch_vcpu_info { 137*4882a593Smuzhiyun unsigned long cr2; 138*4882a593Smuzhiyun unsigned long pad; /* sizeof(vcpu_info_t) == 64 */ 139*4882a593Smuzhiyun }; 140*4882a593Smuzhiyun 141*4882a593Smuzhiyun typedef unsigned long xen_callback_t; 142*4882a593Smuzhiyun 143*4882a593Smuzhiyun #define XEN_CALLBACK(__cs, __rip) \ 144*4882a593Smuzhiyun ((unsigned long)(__rip)) 145*4882a593Smuzhiyun 146*4882a593Smuzhiyun #endif /* !__ASSEMBLY__ */ 147*4882a593Smuzhiyun 148*4882a593Smuzhiyun 149*4882a593Smuzhiyun #endif /* _ASM_X86_XEN_INTERFACE_64_H */ 150