18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef _ASM_X86_XEN_INTERFACE_64_H 38c2ecf20Sopenharmony_ci#define _ASM_X86_XEN_INTERFACE_64_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci/* 68c2ecf20Sopenharmony_ci * 64-bit segment selectors 78c2ecf20Sopenharmony_ci * These flat segments are in the Xen-private section of every GDT. Since these 88c2ecf20Sopenharmony_ci * are also present in the initial GDT, many OSes will be able to avoid 98c2ecf20Sopenharmony_ci * installing their own GDT. 108c2ecf20Sopenharmony_ci */ 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#define FLAT_RING3_CS32 0xe023 /* GDT index 260 */ 138c2ecf20Sopenharmony_ci#define FLAT_RING3_CS64 0xe033 /* GDT index 261 */ 148c2ecf20Sopenharmony_ci#define FLAT_RING3_DS32 0xe02b /* GDT index 262 */ 158c2ecf20Sopenharmony_ci#define FLAT_RING3_DS64 0x0000 /* NULL selector */ 168c2ecf20Sopenharmony_ci#define FLAT_RING3_SS32 0xe02b /* GDT index 262 */ 178c2ecf20Sopenharmony_ci#define FLAT_RING3_SS64 0xe02b /* GDT index 262 */ 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#define FLAT_KERNEL_DS64 FLAT_RING3_DS64 208c2ecf20Sopenharmony_ci#define FLAT_KERNEL_DS32 FLAT_RING3_DS32 218c2ecf20Sopenharmony_ci#define FLAT_KERNEL_DS FLAT_KERNEL_DS64 228c2ecf20Sopenharmony_ci#define FLAT_KERNEL_CS64 FLAT_RING3_CS64 238c2ecf20Sopenharmony_ci#define FLAT_KERNEL_CS32 FLAT_RING3_CS32 248c2ecf20Sopenharmony_ci#define FLAT_KERNEL_CS FLAT_KERNEL_CS64 258c2ecf20Sopenharmony_ci#define FLAT_KERNEL_SS64 FLAT_RING3_SS64 268c2ecf20Sopenharmony_ci#define FLAT_KERNEL_SS32 FLAT_RING3_SS32 278c2ecf20Sopenharmony_ci#define FLAT_KERNEL_SS FLAT_KERNEL_SS64 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci#define FLAT_USER_DS64 FLAT_RING3_DS64 308c2ecf20Sopenharmony_ci#define FLAT_USER_DS32 FLAT_RING3_DS32 318c2ecf20Sopenharmony_ci#define FLAT_USER_DS FLAT_USER_DS64 328c2ecf20Sopenharmony_ci#define FLAT_USER_CS64 FLAT_RING3_CS64 338c2ecf20Sopenharmony_ci#define FLAT_USER_CS32 FLAT_RING3_CS32 348c2ecf20Sopenharmony_ci#define FLAT_USER_CS FLAT_USER_CS64 358c2ecf20Sopenharmony_ci#define FLAT_USER_SS64 FLAT_RING3_SS64 368c2ecf20Sopenharmony_ci#define FLAT_USER_SS32 FLAT_RING3_SS32 378c2ecf20Sopenharmony_ci#define FLAT_USER_SS FLAT_USER_SS64 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci#define __HYPERVISOR_VIRT_START 0xFFFF800000000000 408c2ecf20Sopenharmony_ci#define __HYPERVISOR_VIRT_END 0xFFFF880000000000 418c2ecf20Sopenharmony_ci#define __MACH2PHYS_VIRT_START 0xFFFF800000000000 428c2ecf20Sopenharmony_ci#define __MACH2PHYS_VIRT_END 0xFFFF804000000000 438c2ecf20Sopenharmony_ci#define __MACH2PHYS_SHIFT 3 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci/* 468c2ecf20Sopenharmony_ci * int HYPERVISOR_set_segment_base(unsigned int which, unsigned long base) 478c2ecf20Sopenharmony_ci * @which == SEGBASE_* ; @base == 64-bit base address 488c2ecf20Sopenharmony_ci * Returns 0 on success. 498c2ecf20Sopenharmony_ci */ 508c2ecf20Sopenharmony_ci#define SEGBASE_FS 0 518c2ecf20Sopenharmony_ci#define SEGBASE_GS_USER 1 528c2ecf20Sopenharmony_ci#define SEGBASE_GS_KERNEL 2 538c2ecf20Sopenharmony_ci#define SEGBASE_GS_USER_SEL 3 /* Set user %gs specified in base[15:0] */ 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci/* 568c2ecf20Sopenharmony_ci * int HYPERVISOR_iret(void) 578c2ecf20Sopenharmony_ci * All arguments are on the kernel stack, in the following format. 588c2ecf20Sopenharmony_ci * Never returns if successful. Current kernel context is lost. 598c2ecf20Sopenharmony_ci * The saved CS is mapped as follows: 608c2ecf20Sopenharmony_ci * RING0 -> RING3 kernel mode. 618c2ecf20Sopenharmony_ci * RING1 -> RING3 kernel mode. 628c2ecf20Sopenharmony_ci * RING2 -> RING3 kernel mode. 638c2ecf20Sopenharmony_ci * RING3 -> RING3 user mode. 648c2ecf20Sopenharmony_ci * However RING0 indicates that the guest kernel should return to iteself 658c2ecf20Sopenharmony_ci * directly with 668c2ecf20Sopenharmony_ci * orb $3,1*8(%rsp) 678c2ecf20Sopenharmony_ci * iretq 688c2ecf20Sopenharmony_ci * If flags contains VGCF_in_syscall: 698c2ecf20Sopenharmony_ci * Restore RAX, RIP, RFLAGS, RSP. 708c2ecf20Sopenharmony_ci * Discard R11, RCX, CS, SS. 718c2ecf20Sopenharmony_ci * Otherwise: 728c2ecf20Sopenharmony_ci * Restore RAX, R11, RCX, CS:RIP, RFLAGS, SS:RSP. 738c2ecf20Sopenharmony_ci * All other registers are saved on hypercall entry and restored to user. 748c2ecf20Sopenharmony_ci */ 758c2ecf20Sopenharmony_ci/* Guest exited in SYSCALL context? Return to guest with SYSRET? */ 768c2ecf20Sopenharmony_ci#define _VGCF_in_syscall 8 778c2ecf20Sopenharmony_ci#define VGCF_in_syscall (1<<_VGCF_in_syscall) 788c2ecf20Sopenharmony_ci#define VGCF_IN_SYSCALL VGCF_in_syscall 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__ 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_cistruct iret_context { 838c2ecf20Sopenharmony_ci /* Top of stack (%rsp at point of hypercall). */ 848c2ecf20Sopenharmony_ci uint64_t rax, r11, rcx, flags, rip, cs, rflags, rsp, ss; 858c2ecf20Sopenharmony_ci /* Bottom of iret stack frame. */ 868c2ecf20Sopenharmony_ci}; 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci#if defined(__GNUC__) && !defined(__STRICT_ANSI__) 898c2ecf20Sopenharmony_ci/* Anonymous union includes both 32- and 64-bit names (e.g., eax/rax). */ 908c2ecf20Sopenharmony_ci#define __DECL_REG(name) union { \ 918c2ecf20Sopenharmony_ci uint64_t r ## name, e ## name; \ 928c2ecf20Sopenharmony_ci uint32_t _e ## name; \ 938c2ecf20Sopenharmony_ci} 948c2ecf20Sopenharmony_ci#else 958c2ecf20Sopenharmony_ci/* Non-gcc sources must always use the proper 64-bit name (e.g., rax). */ 968c2ecf20Sopenharmony_ci#define __DECL_REG(name) uint64_t r ## name 978c2ecf20Sopenharmony_ci#endif 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_cistruct cpu_user_regs { 1008c2ecf20Sopenharmony_ci uint64_t r15; 1018c2ecf20Sopenharmony_ci uint64_t r14; 1028c2ecf20Sopenharmony_ci uint64_t r13; 1038c2ecf20Sopenharmony_ci uint64_t r12; 1048c2ecf20Sopenharmony_ci __DECL_REG(bp); 1058c2ecf20Sopenharmony_ci __DECL_REG(bx); 1068c2ecf20Sopenharmony_ci uint64_t r11; 1078c2ecf20Sopenharmony_ci uint64_t r10; 1088c2ecf20Sopenharmony_ci uint64_t r9; 1098c2ecf20Sopenharmony_ci uint64_t r8; 1108c2ecf20Sopenharmony_ci __DECL_REG(ax); 1118c2ecf20Sopenharmony_ci __DECL_REG(cx); 1128c2ecf20Sopenharmony_ci __DECL_REG(dx); 1138c2ecf20Sopenharmony_ci __DECL_REG(si); 1148c2ecf20Sopenharmony_ci __DECL_REG(di); 1158c2ecf20Sopenharmony_ci uint32_t error_code; /* private */ 1168c2ecf20Sopenharmony_ci uint32_t entry_vector; /* private */ 1178c2ecf20Sopenharmony_ci __DECL_REG(ip); 1188c2ecf20Sopenharmony_ci uint16_t cs, _pad0[1]; 1198c2ecf20Sopenharmony_ci uint8_t saved_upcall_mask; 1208c2ecf20Sopenharmony_ci uint8_t _pad1[3]; 1218c2ecf20Sopenharmony_ci __DECL_REG(flags); /* rflags.IF == !saved_upcall_mask */ 1228c2ecf20Sopenharmony_ci __DECL_REG(sp); 1238c2ecf20Sopenharmony_ci uint16_t ss, _pad2[3]; 1248c2ecf20Sopenharmony_ci uint16_t es, _pad3[3]; 1258c2ecf20Sopenharmony_ci uint16_t ds, _pad4[3]; 1268c2ecf20Sopenharmony_ci uint16_t fs, _pad5[3]; /* Non-zero => takes precedence over fs_base. */ 1278c2ecf20Sopenharmony_ci uint16_t gs, _pad6[3]; /* Non-zero => takes precedence over gs_base_usr. */ 1288c2ecf20Sopenharmony_ci}; 1298c2ecf20Sopenharmony_ciDEFINE_GUEST_HANDLE_STRUCT(cpu_user_regs); 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci#undef __DECL_REG 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci#define xen_pfn_to_cr3(pfn) ((unsigned long)(pfn) << 12) 1348c2ecf20Sopenharmony_ci#define xen_cr3_to_pfn(cr3) ((unsigned long)(cr3) >> 12) 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_cistruct arch_vcpu_info { 1378c2ecf20Sopenharmony_ci unsigned long cr2; 1388c2ecf20Sopenharmony_ci unsigned long pad; /* sizeof(vcpu_info_t) == 64 */ 1398c2ecf20Sopenharmony_ci}; 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_citypedef unsigned long xen_callback_t; 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci#define XEN_CALLBACK(__cs, __rip) \ 1448c2ecf20Sopenharmony_ci ((unsigned long)(__rip)) 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ci#endif /* !__ASSEMBLY__ */ 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci#endif /* _ASM_X86_XEN_INTERFACE_64_H */ 150