162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef _ASM_X86_XEN_INTERFACE_64_H 362306a36Sopenharmony_ci#define _ASM_X86_XEN_INTERFACE_64_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci/* 662306a36Sopenharmony_ci * 64-bit segment selectors 762306a36Sopenharmony_ci * These flat segments are in the Xen-private section of every GDT. Since these 862306a36Sopenharmony_ci * are also present in the initial GDT, many OSes will be able to avoid 962306a36Sopenharmony_ci * installing their own GDT. 1062306a36Sopenharmony_ci */ 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#define FLAT_RING3_CS32 0xe023 /* GDT index 260 */ 1362306a36Sopenharmony_ci#define FLAT_RING3_CS64 0xe033 /* GDT index 261 */ 1462306a36Sopenharmony_ci#define FLAT_RING3_DS32 0xe02b /* GDT index 262 */ 1562306a36Sopenharmony_ci#define FLAT_RING3_DS64 0x0000 /* NULL selector */ 1662306a36Sopenharmony_ci#define FLAT_RING3_SS32 0xe02b /* GDT index 262 */ 1762306a36Sopenharmony_ci#define FLAT_RING3_SS64 0xe02b /* GDT index 262 */ 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#define FLAT_KERNEL_DS64 FLAT_RING3_DS64 2062306a36Sopenharmony_ci#define FLAT_KERNEL_DS32 FLAT_RING3_DS32 2162306a36Sopenharmony_ci#define FLAT_KERNEL_DS FLAT_KERNEL_DS64 2262306a36Sopenharmony_ci#define FLAT_KERNEL_CS64 FLAT_RING3_CS64 2362306a36Sopenharmony_ci#define FLAT_KERNEL_CS32 FLAT_RING3_CS32 2462306a36Sopenharmony_ci#define FLAT_KERNEL_CS FLAT_KERNEL_CS64 2562306a36Sopenharmony_ci#define FLAT_KERNEL_SS64 FLAT_RING3_SS64 2662306a36Sopenharmony_ci#define FLAT_KERNEL_SS32 FLAT_RING3_SS32 2762306a36Sopenharmony_ci#define FLAT_KERNEL_SS FLAT_KERNEL_SS64 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci#define FLAT_USER_DS64 FLAT_RING3_DS64 3062306a36Sopenharmony_ci#define FLAT_USER_DS32 FLAT_RING3_DS32 3162306a36Sopenharmony_ci#define FLAT_USER_DS FLAT_USER_DS64 3262306a36Sopenharmony_ci#define FLAT_USER_CS64 FLAT_RING3_CS64 3362306a36Sopenharmony_ci#define FLAT_USER_CS32 FLAT_RING3_CS32 3462306a36Sopenharmony_ci#define FLAT_USER_CS FLAT_USER_CS64 3562306a36Sopenharmony_ci#define FLAT_USER_SS64 FLAT_RING3_SS64 3662306a36Sopenharmony_ci#define FLAT_USER_SS32 FLAT_RING3_SS32 3762306a36Sopenharmony_ci#define FLAT_USER_SS FLAT_USER_SS64 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci#define __HYPERVISOR_VIRT_START 0xFFFF800000000000 4062306a36Sopenharmony_ci#define __HYPERVISOR_VIRT_END 0xFFFF880000000000 4162306a36Sopenharmony_ci#define __MACH2PHYS_VIRT_START 0xFFFF800000000000 4262306a36Sopenharmony_ci#define __MACH2PHYS_VIRT_END 0xFFFF804000000000 4362306a36Sopenharmony_ci#define __MACH2PHYS_SHIFT 3 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci/* 4662306a36Sopenharmony_ci * int HYPERVISOR_set_segment_base(unsigned int which, unsigned long base) 4762306a36Sopenharmony_ci * @which == SEGBASE_* ; @base == 64-bit base address 4862306a36Sopenharmony_ci * Returns 0 on success. 4962306a36Sopenharmony_ci */ 5062306a36Sopenharmony_ci#define SEGBASE_FS 0 5162306a36Sopenharmony_ci#define SEGBASE_GS_USER 1 5262306a36Sopenharmony_ci#define SEGBASE_GS_KERNEL 2 5362306a36Sopenharmony_ci#define SEGBASE_GS_USER_SEL 3 /* Set user %gs specified in base[15:0] */ 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci/* 5662306a36Sopenharmony_ci * int HYPERVISOR_iret(void) 5762306a36Sopenharmony_ci * All arguments are on the kernel stack, in the following format. 5862306a36Sopenharmony_ci * Never returns if successful. Current kernel context is lost. 5962306a36Sopenharmony_ci * The saved CS is mapped as follows: 6062306a36Sopenharmony_ci * RING0 -> RING3 kernel mode. 6162306a36Sopenharmony_ci * RING1 -> RING3 kernel mode. 6262306a36Sopenharmony_ci * RING2 -> RING3 kernel mode. 6362306a36Sopenharmony_ci * RING3 -> RING3 user mode. 6462306a36Sopenharmony_ci * However RING0 indicates that the guest kernel should return to iteself 6562306a36Sopenharmony_ci * directly with 6662306a36Sopenharmony_ci * orb $3,1*8(%rsp) 6762306a36Sopenharmony_ci * iretq 6862306a36Sopenharmony_ci * If flags contains VGCF_in_syscall: 6962306a36Sopenharmony_ci * Restore RAX, RIP, RFLAGS, RSP. 7062306a36Sopenharmony_ci * Discard R11, RCX, CS, SS. 7162306a36Sopenharmony_ci * Otherwise: 7262306a36Sopenharmony_ci * Restore RAX, R11, RCX, CS:RIP, RFLAGS, SS:RSP. 7362306a36Sopenharmony_ci * All other registers are saved on hypercall entry and restored to user. 7462306a36Sopenharmony_ci */ 7562306a36Sopenharmony_ci/* Guest exited in SYSCALL context? Return to guest with SYSRET? */ 7662306a36Sopenharmony_ci#define _VGCF_in_syscall 8 7762306a36Sopenharmony_ci#define VGCF_in_syscall (1<<_VGCF_in_syscall) 7862306a36Sopenharmony_ci#define VGCF_IN_SYSCALL VGCF_in_syscall 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci#ifndef __ASSEMBLY__ 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_cistruct iret_context { 8362306a36Sopenharmony_ci /* Top of stack (%rsp at point of hypercall). */ 8462306a36Sopenharmony_ci uint64_t rax, r11, rcx, flags, rip, cs, rflags, rsp, ss; 8562306a36Sopenharmony_ci /* Bottom of iret stack frame. */ 8662306a36Sopenharmony_ci}; 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci#if defined(__GNUC__) && !defined(__STRICT_ANSI__) 8962306a36Sopenharmony_ci/* Anonymous union includes both 32- and 64-bit names (e.g., eax/rax). */ 9062306a36Sopenharmony_ci#define __DECL_REG(name) union { \ 9162306a36Sopenharmony_ci uint64_t r ## name, e ## name; \ 9262306a36Sopenharmony_ci uint32_t _e ## name; \ 9362306a36Sopenharmony_ci} 9462306a36Sopenharmony_ci#else 9562306a36Sopenharmony_ci/* Non-gcc sources must always use the proper 64-bit name (e.g., rax). */ 9662306a36Sopenharmony_ci#define __DECL_REG(name) uint64_t r ## name 9762306a36Sopenharmony_ci#endif 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_cistruct cpu_user_regs { 10062306a36Sopenharmony_ci uint64_t r15; 10162306a36Sopenharmony_ci uint64_t r14; 10262306a36Sopenharmony_ci uint64_t r13; 10362306a36Sopenharmony_ci uint64_t r12; 10462306a36Sopenharmony_ci __DECL_REG(bp); 10562306a36Sopenharmony_ci __DECL_REG(bx); 10662306a36Sopenharmony_ci uint64_t r11; 10762306a36Sopenharmony_ci uint64_t r10; 10862306a36Sopenharmony_ci uint64_t r9; 10962306a36Sopenharmony_ci uint64_t r8; 11062306a36Sopenharmony_ci __DECL_REG(ax); 11162306a36Sopenharmony_ci __DECL_REG(cx); 11262306a36Sopenharmony_ci __DECL_REG(dx); 11362306a36Sopenharmony_ci __DECL_REG(si); 11462306a36Sopenharmony_ci __DECL_REG(di); 11562306a36Sopenharmony_ci uint32_t error_code; /* private */ 11662306a36Sopenharmony_ci uint32_t entry_vector; /* private */ 11762306a36Sopenharmony_ci __DECL_REG(ip); 11862306a36Sopenharmony_ci uint16_t cs, _pad0[1]; 11962306a36Sopenharmony_ci uint8_t saved_upcall_mask; 12062306a36Sopenharmony_ci uint8_t _pad1[3]; 12162306a36Sopenharmony_ci __DECL_REG(flags); /* rflags.IF == !saved_upcall_mask */ 12262306a36Sopenharmony_ci __DECL_REG(sp); 12362306a36Sopenharmony_ci uint16_t ss, _pad2[3]; 12462306a36Sopenharmony_ci uint16_t es, _pad3[3]; 12562306a36Sopenharmony_ci uint16_t ds, _pad4[3]; 12662306a36Sopenharmony_ci uint16_t fs, _pad5[3]; /* Non-zero => takes precedence over fs_base. */ 12762306a36Sopenharmony_ci uint16_t gs, _pad6[3]; /* Non-zero => takes precedence over gs_base_usr. */ 12862306a36Sopenharmony_ci}; 12962306a36Sopenharmony_ciDEFINE_GUEST_HANDLE_STRUCT(cpu_user_regs); 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci#undef __DECL_REG 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci#define xen_pfn_to_cr3(pfn) ((unsigned long)(pfn) << 12) 13462306a36Sopenharmony_ci#define xen_cr3_to_pfn(cr3) ((unsigned long)(cr3) >> 12) 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_cistruct arch_vcpu_info { 13762306a36Sopenharmony_ci unsigned long cr2; 13862306a36Sopenharmony_ci unsigned long pad; /* sizeof(vcpu_info_t) == 64 */ 13962306a36Sopenharmony_ci}; 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_citypedef unsigned long xen_callback_t; 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci#define XEN_CALLBACK(__cs, __rip) \ 14462306a36Sopenharmony_ci ((unsigned long)(__rip)) 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci#endif /* !__ASSEMBLY__ */ 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci#endif /* _ASM_X86_XEN_INTERFACE_64_H */ 150