18c2ecf20Sopenharmony_ci/****************************************************************************** 28c2ecf20Sopenharmony_ci * arch-x86_32.h 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Guest OS interface to x86 Xen. 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 78c2ecf20Sopenharmony_ci * of this software and associated documentation files (the "Software"), to 88c2ecf20Sopenharmony_ci * deal in the Software without restriction, including without limitation the 98c2ecf20Sopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 108c2ecf20Sopenharmony_ci * sell copies of the Software, and to permit persons to whom the Software is 118c2ecf20Sopenharmony_ci * furnished to do so, subject to the following conditions: 128c2ecf20Sopenharmony_ci * 138c2ecf20Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 148c2ecf20Sopenharmony_ci * all copies or substantial portions of the Software. 158c2ecf20Sopenharmony_ci * 168c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 178c2ecf20Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 188c2ecf20Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 198c2ecf20Sopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 208c2ecf20Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 218c2ecf20Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 228c2ecf20Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 238c2ecf20Sopenharmony_ci * 248c2ecf20Sopenharmony_ci * Copyright (c) 2004-2006, K A Fraser 258c2ecf20Sopenharmony_ci */ 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci#ifndef _ASM_X86_XEN_INTERFACE_H 288c2ecf20Sopenharmony_ci#define _ASM_X86_XEN_INTERFACE_H 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci/* 318c2ecf20Sopenharmony_ci * XEN_GUEST_HANDLE represents a guest pointer, when passed as a field 328c2ecf20Sopenharmony_ci * in a struct in memory. 338c2ecf20Sopenharmony_ci * XEN_GUEST_HANDLE_PARAM represent a guest pointer, when passed as an 348c2ecf20Sopenharmony_ci * hypercall argument. 358c2ecf20Sopenharmony_ci * XEN_GUEST_HANDLE_PARAM and XEN_GUEST_HANDLE are the same on X86 but 368c2ecf20Sopenharmony_ci * they might not be on other architectures. 378c2ecf20Sopenharmony_ci */ 388c2ecf20Sopenharmony_ci#ifdef __XEN__ 398c2ecf20Sopenharmony_ci#define __DEFINE_GUEST_HANDLE(name, type) \ 408c2ecf20Sopenharmony_ci typedef struct { type *p; } __guest_handle_ ## name 418c2ecf20Sopenharmony_ci#else 428c2ecf20Sopenharmony_ci#define __DEFINE_GUEST_HANDLE(name, type) \ 438c2ecf20Sopenharmony_ci typedef type * __guest_handle_ ## name 448c2ecf20Sopenharmony_ci#endif 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci#define DEFINE_GUEST_HANDLE_STRUCT(name) \ 478c2ecf20Sopenharmony_ci __DEFINE_GUEST_HANDLE(name, struct name) 488c2ecf20Sopenharmony_ci#define DEFINE_GUEST_HANDLE(name) __DEFINE_GUEST_HANDLE(name, name) 498c2ecf20Sopenharmony_ci#define GUEST_HANDLE(name) __guest_handle_ ## name 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci#ifdef __XEN__ 528c2ecf20Sopenharmony_ci#if defined(__i386__) 538c2ecf20Sopenharmony_ci#define set_xen_guest_handle(hnd, val) \ 548c2ecf20Sopenharmony_ci do { \ 558c2ecf20Sopenharmony_ci if (sizeof(hnd) == 8) \ 568c2ecf20Sopenharmony_ci *(uint64_t *)&(hnd) = 0; \ 578c2ecf20Sopenharmony_ci (hnd).p = val; \ 588c2ecf20Sopenharmony_ci } while (0) 598c2ecf20Sopenharmony_ci#elif defined(__x86_64__) 608c2ecf20Sopenharmony_ci#define set_xen_guest_handle(hnd, val) do { (hnd).p = val; } while (0) 618c2ecf20Sopenharmony_ci#endif 628c2ecf20Sopenharmony_ci#else 638c2ecf20Sopenharmony_ci#if defined(__i386__) 648c2ecf20Sopenharmony_ci#define set_xen_guest_handle(hnd, val) \ 658c2ecf20Sopenharmony_ci do { \ 668c2ecf20Sopenharmony_ci if (sizeof(hnd) == 8) \ 678c2ecf20Sopenharmony_ci *(uint64_t *)&(hnd) = 0; \ 688c2ecf20Sopenharmony_ci (hnd) = val; \ 698c2ecf20Sopenharmony_ci } while (0) 708c2ecf20Sopenharmony_ci#elif defined(__x86_64__) 718c2ecf20Sopenharmony_ci#define set_xen_guest_handle(hnd, val) do { (hnd) = val; } while (0) 728c2ecf20Sopenharmony_ci#endif 738c2ecf20Sopenharmony_ci#endif 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__ 768c2ecf20Sopenharmony_ci/* Explicitly size integers that represent pfns in the public interface 778c2ecf20Sopenharmony_ci * with Xen so that on ARM we can have one ABI that works for 32 and 64 788c2ecf20Sopenharmony_ci * bit guests. */ 798c2ecf20Sopenharmony_citypedef unsigned long xen_pfn_t; 808c2ecf20Sopenharmony_ci#define PRI_xen_pfn "lx" 818c2ecf20Sopenharmony_citypedef unsigned long xen_ulong_t; 828c2ecf20Sopenharmony_ci#define PRI_xen_ulong "lx" 838c2ecf20Sopenharmony_citypedef long xen_long_t; 848c2ecf20Sopenharmony_ci#define PRI_xen_long "lx" 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci/* Guest handles for primitive C types. */ 878c2ecf20Sopenharmony_ci__DEFINE_GUEST_HANDLE(uchar, unsigned char); 888c2ecf20Sopenharmony_ci__DEFINE_GUEST_HANDLE(uint, unsigned int); 898c2ecf20Sopenharmony_ciDEFINE_GUEST_HANDLE(char); 908c2ecf20Sopenharmony_ciDEFINE_GUEST_HANDLE(int); 918c2ecf20Sopenharmony_ciDEFINE_GUEST_HANDLE(void); 928c2ecf20Sopenharmony_ciDEFINE_GUEST_HANDLE(uint64_t); 938c2ecf20Sopenharmony_ciDEFINE_GUEST_HANDLE(uint32_t); 948c2ecf20Sopenharmony_ciDEFINE_GUEST_HANDLE(xen_pfn_t); 958c2ecf20Sopenharmony_ciDEFINE_GUEST_HANDLE(xen_ulong_t); 968c2ecf20Sopenharmony_ci#endif 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci#ifndef HYPERVISOR_VIRT_START 998c2ecf20Sopenharmony_ci#define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START) 1008c2ecf20Sopenharmony_ci#endif 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci#define MACH2PHYS_VIRT_START mk_unsigned_long(__MACH2PHYS_VIRT_START) 1038c2ecf20Sopenharmony_ci#define MACH2PHYS_VIRT_END mk_unsigned_long(__MACH2PHYS_VIRT_END) 1048c2ecf20Sopenharmony_ci#define MACH2PHYS_NR_ENTRIES ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>__MACH2PHYS_SHIFT) 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci/* Maximum number of virtual CPUs in multi-processor guests. */ 1078c2ecf20Sopenharmony_ci#define MAX_VIRT_CPUS 32 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci/* 1108c2ecf20Sopenharmony_ci * SEGMENT DESCRIPTOR TABLES 1118c2ecf20Sopenharmony_ci */ 1128c2ecf20Sopenharmony_ci/* 1138c2ecf20Sopenharmony_ci * A number of GDT entries are reserved by Xen. These are not situated at the 1148c2ecf20Sopenharmony_ci * start of the GDT because some stupid OSes export hard-coded selector values 1158c2ecf20Sopenharmony_ci * in their ABI. These hard-coded values are always near the start of the GDT, 1168c2ecf20Sopenharmony_ci * so Xen places itself out of the way, at the far end of the GDT. 1178c2ecf20Sopenharmony_ci * 1188c2ecf20Sopenharmony_ci * NB The LDT is set using the MMUEXT_SET_LDT op of HYPERVISOR_mmuext_op 1198c2ecf20Sopenharmony_ci */ 1208c2ecf20Sopenharmony_ci#define FIRST_RESERVED_GDT_PAGE 14 1218c2ecf20Sopenharmony_ci#define FIRST_RESERVED_GDT_BYTE (FIRST_RESERVED_GDT_PAGE * 4096) 1228c2ecf20Sopenharmony_ci#define FIRST_RESERVED_GDT_ENTRY (FIRST_RESERVED_GDT_BYTE / 8) 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci/* 1258c2ecf20Sopenharmony_ci * Send an array of these to HYPERVISOR_set_trap_table(). 1268c2ecf20Sopenharmony_ci * Terminate the array with a sentinel entry, with traps[].address==0. 1278c2ecf20Sopenharmony_ci * The privilege level specifies which modes may enter a trap via a software 1288c2ecf20Sopenharmony_ci * interrupt. On x86/64, since rings 1 and 2 are unavailable, we allocate 1298c2ecf20Sopenharmony_ci * privilege levels as follows: 1308c2ecf20Sopenharmony_ci * Level == 0: No one may enter 1318c2ecf20Sopenharmony_ci * Level == 1: Kernel may enter 1328c2ecf20Sopenharmony_ci * Level == 2: Kernel may enter 1338c2ecf20Sopenharmony_ci * Level == 3: Everyone may enter 1348c2ecf20Sopenharmony_ci */ 1358c2ecf20Sopenharmony_ci#define TI_GET_DPL(_ti) ((_ti)->flags & 3) 1368c2ecf20Sopenharmony_ci#define TI_GET_IF(_ti) ((_ti)->flags & 4) 1378c2ecf20Sopenharmony_ci#define TI_SET_DPL(_ti, _dpl) ((_ti)->flags |= (_dpl)) 1388c2ecf20Sopenharmony_ci#define TI_SET_IF(_ti, _if) ((_ti)->flags |= ((!!(_if))<<2)) 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__ 1418c2ecf20Sopenharmony_cistruct trap_info { 1428c2ecf20Sopenharmony_ci uint8_t vector; /* exception vector */ 1438c2ecf20Sopenharmony_ci uint8_t flags; /* 0-3: privilege level; 4: clear event enable? */ 1448c2ecf20Sopenharmony_ci uint16_t cs; /* code selector */ 1458c2ecf20Sopenharmony_ci unsigned long address; /* code offset */ 1468c2ecf20Sopenharmony_ci}; 1478c2ecf20Sopenharmony_ciDEFINE_GUEST_HANDLE_STRUCT(trap_info); 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_cistruct arch_shared_info { 1508c2ecf20Sopenharmony_ci /* 1518c2ecf20Sopenharmony_ci * Number of valid entries in the p2m table(s) anchored at 1528c2ecf20Sopenharmony_ci * pfn_to_mfn_frame_list_list and/or p2m_vaddr. 1538c2ecf20Sopenharmony_ci */ 1548c2ecf20Sopenharmony_ci unsigned long max_pfn; 1558c2ecf20Sopenharmony_ci /* 1568c2ecf20Sopenharmony_ci * Frame containing list of mfns containing list of mfns containing p2m. 1578c2ecf20Sopenharmony_ci * A value of 0 indicates it has not yet been set up, ~0 indicates it 1588c2ecf20Sopenharmony_ci * has been set to invalid e.g. due to the p2m being too large for the 1598c2ecf20Sopenharmony_ci * 3-level p2m tree. In this case the linear mapper p2m list anchored 1608c2ecf20Sopenharmony_ci * at p2m_vaddr is to be used. 1618c2ecf20Sopenharmony_ci */ 1628c2ecf20Sopenharmony_ci xen_pfn_t pfn_to_mfn_frame_list_list; 1638c2ecf20Sopenharmony_ci unsigned long nmi_reason; 1648c2ecf20Sopenharmony_ci /* 1658c2ecf20Sopenharmony_ci * Following three fields are valid if p2m_cr3 contains a value 1668c2ecf20Sopenharmony_ci * different from 0. 1678c2ecf20Sopenharmony_ci * p2m_cr3 is the root of the address space where p2m_vaddr is valid. 1688c2ecf20Sopenharmony_ci * p2m_cr3 is in the same format as a cr3 value in the vcpu register 1698c2ecf20Sopenharmony_ci * state and holds the folded machine frame number (via xen_pfn_to_cr3) 1708c2ecf20Sopenharmony_ci * of a L3 or L4 page table. 1718c2ecf20Sopenharmony_ci * p2m_vaddr holds the virtual address of the linear p2m list. All 1728c2ecf20Sopenharmony_ci * entries in the range [0...max_pfn[ are accessible via this pointer. 1738c2ecf20Sopenharmony_ci * p2m_generation will be incremented by the guest before and after each 1748c2ecf20Sopenharmony_ci * change of the mappings of the p2m list. p2m_generation starts at 0 1758c2ecf20Sopenharmony_ci * and a value with the least significant bit set indicates that a 1768c2ecf20Sopenharmony_ci * mapping update is in progress. This allows guest external software 1778c2ecf20Sopenharmony_ci * (e.g. in Dom0) to verify that read mappings are consistent and 1788c2ecf20Sopenharmony_ci * whether they have changed since the last check. 1798c2ecf20Sopenharmony_ci * Modifying a p2m element in the linear p2m list is allowed via an 1808c2ecf20Sopenharmony_ci * atomic write only. 1818c2ecf20Sopenharmony_ci */ 1828c2ecf20Sopenharmony_ci unsigned long p2m_cr3; /* cr3 value of the p2m address space */ 1838c2ecf20Sopenharmony_ci unsigned long p2m_vaddr; /* virtual address of the p2m list */ 1848c2ecf20Sopenharmony_ci unsigned long p2m_generation; /* generation count of p2m mapping */ 1858c2ecf20Sopenharmony_ci}; 1868c2ecf20Sopenharmony_ci#endif /* !__ASSEMBLY__ */ 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci#ifdef CONFIG_X86_32 1898c2ecf20Sopenharmony_ci#include <asm/xen/interface_32.h> 1908c2ecf20Sopenharmony_ci#else 1918c2ecf20Sopenharmony_ci#include <asm/xen/interface_64.h> 1928c2ecf20Sopenharmony_ci#endif 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci#include <asm/pvclock-abi.h> 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__ 1978c2ecf20Sopenharmony_ci/* 1988c2ecf20Sopenharmony_ci * The following is all CPU context. Note that the fpu_ctxt block is filled 1998c2ecf20Sopenharmony_ci * in by FXSAVE if the CPU has feature FXSR; otherwise FSAVE is used. 2008c2ecf20Sopenharmony_ci * 2018c2ecf20Sopenharmony_ci * Also note that when calling DOMCTL_setvcpucontext and VCPU_initialise 2028c2ecf20Sopenharmony_ci * for HVM and PVH guests, not all information in this structure is updated: 2038c2ecf20Sopenharmony_ci * 2048c2ecf20Sopenharmony_ci * - For HVM guests, the structures read include: fpu_ctxt (if 2058c2ecf20Sopenharmony_ci * VGCT_I387_VALID is set), flags, user_regs, debugreg[*] 2068c2ecf20Sopenharmony_ci * 2078c2ecf20Sopenharmony_ci * - PVH guests are the same as HVM guests, but additionally use ctrlreg[3] to 2088c2ecf20Sopenharmony_ci * set cr3. All other fields not used should be set to 0. 2098c2ecf20Sopenharmony_ci */ 2108c2ecf20Sopenharmony_cistruct vcpu_guest_context { 2118c2ecf20Sopenharmony_ci /* FPU registers come first so they can be aligned for FXSAVE/FXRSTOR. */ 2128c2ecf20Sopenharmony_ci struct { char x[512]; } fpu_ctxt; /* User-level FPU registers */ 2138c2ecf20Sopenharmony_ci#define VGCF_I387_VALID (1<<0) 2148c2ecf20Sopenharmony_ci#define VGCF_IN_KERNEL (1<<2) 2158c2ecf20Sopenharmony_ci#define _VGCF_i387_valid 0 2168c2ecf20Sopenharmony_ci#define VGCF_i387_valid (1<<_VGCF_i387_valid) 2178c2ecf20Sopenharmony_ci#define _VGCF_in_kernel 2 2188c2ecf20Sopenharmony_ci#define VGCF_in_kernel (1<<_VGCF_in_kernel) 2198c2ecf20Sopenharmony_ci#define _VGCF_failsafe_disables_events 3 2208c2ecf20Sopenharmony_ci#define VGCF_failsafe_disables_events (1<<_VGCF_failsafe_disables_events) 2218c2ecf20Sopenharmony_ci#define _VGCF_syscall_disables_events 4 2228c2ecf20Sopenharmony_ci#define VGCF_syscall_disables_events (1<<_VGCF_syscall_disables_events) 2238c2ecf20Sopenharmony_ci#define _VGCF_online 5 2248c2ecf20Sopenharmony_ci#define VGCF_online (1<<_VGCF_online) 2258c2ecf20Sopenharmony_ci unsigned long flags; /* VGCF_* flags */ 2268c2ecf20Sopenharmony_ci struct cpu_user_regs user_regs; /* User-level CPU registers */ 2278c2ecf20Sopenharmony_ci struct trap_info trap_ctxt[256]; /* Virtual IDT */ 2288c2ecf20Sopenharmony_ci unsigned long ldt_base, ldt_ents; /* LDT (linear address, # ents) */ 2298c2ecf20Sopenharmony_ci unsigned long gdt_frames[16], gdt_ents; /* GDT (machine frames, # ents) */ 2308c2ecf20Sopenharmony_ci unsigned long kernel_ss, kernel_sp; /* Virtual TSS (only SS1/SP1) */ 2318c2ecf20Sopenharmony_ci /* NB. User pagetable on x86/64 is placed in ctrlreg[1]. */ 2328c2ecf20Sopenharmony_ci unsigned long ctrlreg[8]; /* CR0-CR7 (control registers) */ 2338c2ecf20Sopenharmony_ci unsigned long debugreg[8]; /* DB0-DB7 (debug registers) */ 2348c2ecf20Sopenharmony_ci#ifdef __i386__ 2358c2ecf20Sopenharmony_ci unsigned long event_callback_cs; /* CS:EIP of event callback */ 2368c2ecf20Sopenharmony_ci unsigned long event_callback_eip; 2378c2ecf20Sopenharmony_ci unsigned long failsafe_callback_cs; /* CS:EIP of failsafe callback */ 2388c2ecf20Sopenharmony_ci unsigned long failsafe_callback_eip; 2398c2ecf20Sopenharmony_ci#else 2408c2ecf20Sopenharmony_ci unsigned long event_callback_eip; 2418c2ecf20Sopenharmony_ci unsigned long failsafe_callback_eip; 2428c2ecf20Sopenharmony_ci unsigned long syscall_callback_eip; 2438c2ecf20Sopenharmony_ci#endif 2448c2ecf20Sopenharmony_ci unsigned long vm_assist; /* VMASST_TYPE_* bitmap */ 2458c2ecf20Sopenharmony_ci#ifdef __x86_64__ 2468c2ecf20Sopenharmony_ci /* Segment base addresses. */ 2478c2ecf20Sopenharmony_ci uint64_t fs_base; 2488c2ecf20Sopenharmony_ci uint64_t gs_base_kernel; 2498c2ecf20Sopenharmony_ci uint64_t gs_base_user; 2508c2ecf20Sopenharmony_ci#endif 2518c2ecf20Sopenharmony_ci}; 2528c2ecf20Sopenharmony_ciDEFINE_GUEST_HANDLE_STRUCT(vcpu_guest_context); 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci/* AMD PMU registers and structures */ 2558c2ecf20Sopenharmony_cistruct xen_pmu_amd_ctxt { 2568c2ecf20Sopenharmony_ci /* 2578c2ecf20Sopenharmony_ci * Offsets to counter and control MSRs (relative to xen_pmu_arch.c.amd). 2588c2ecf20Sopenharmony_ci * For PV(H) guests these fields are RO. 2598c2ecf20Sopenharmony_ci */ 2608c2ecf20Sopenharmony_ci uint32_t counters; 2618c2ecf20Sopenharmony_ci uint32_t ctrls; 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_ci /* Counter MSRs */ 2648c2ecf20Sopenharmony_ci#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L 2658c2ecf20Sopenharmony_ci uint64_t regs[]; 2668c2ecf20Sopenharmony_ci#elif defined(__GNUC__) 2678c2ecf20Sopenharmony_ci uint64_t regs[0]; 2688c2ecf20Sopenharmony_ci#endif 2698c2ecf20Sopenharmony_ci}; 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci/* Intel PMU registers and structures */ 2728c2ecf20Sopenharmony_cistruct xen_pmu_cntr_pair { 2738c2ecf20Sopenharmony_ci uint64_t counter; 2748c2ecf20Sopenharmony_ci uint64_t control; 2758c2ecf20Sopenharmony_ci}; 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_cistruct xen_pmu_intel_ctxt { 2788c2ecf20Sopenharmony_ci /* 2798c2ecf20Sopenharmony_ci * Offsets to fixed and architectural counter MSRs (relative to 2808c2ecf20Sopenharmony_ci * xen_pmu_arch.c.intel). 2818c2ecf20Sopenharmony_ci * For PV(H) guests these fields are RO. 2828c2ecf20Sopenharmony_ci */ 2838c2ecf20Sopenharmony_ci uint32_t fixed_counters; 2848c2ecf20Sopenharmony_ci uint32_t arch_counters; 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_ci /* PMU registers */ 2878c2ecf20Sopenharmony_ci uint64_t global_ctrl; 2888c2ecf20Sopenharmony_ci uint64_t global_ovf_ctrl; 2898c2ecf20Sopenharmony_ci uint64_t global_status; 2908c2ecf20Sopenharmony_ci uint64_t fixed_ctrl; 2918c2ecf20Sopenharmony_ci uint64_t ds_area; 2928c2ecf20Sopenharmony_ci uint64_t pebs_enable; 2938c2ecf20Sopenharmony_ci uint64_t debugctl; 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_ci /* Fixed and architectural counter MSRs */ 2968c2ecf20Sopenharmony_ci#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L 2978c2ecf20Sopenharmony_ci uint64_t regs[]; 2988c2ecf20Sopenharmony_ci#elif defined(__GNUC__) 2998c2ecf20Sopenharmony_ci uint64_t regs[0]; 3008c2ecf20Sopenharmony_ci#endif 3018c2ecf20Sopenharmony_ci}; 3028c2ecf20Sopenharmony_ci 3038c2ecf20Sopenharmony_ci/* Sampled domain's registers */ 3048c2ecf20Sopenharmony_cistruct xen_pmu_regs { 3058c2ecf20Sopenharmony_ci uint64_t ip; 3068c2ecf20Sopenharmony_ci uint64_t sp; 3078c2ecf20Sopenharmony_ci uint64_t flags; 3088c2ecf20Sopenharmony_ci uint16_t cs; 3098c2ecf20Sopenharmony_ci uint16_t ss; 3108c2ecf20Sopenharmony_ci uint8_t cpl; 3118c2ecf20Sopenharmony_ci uint8_t pad[3]; 3128c2ecf20Sopenharmony_ci}; 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_ci/* PMU flags */ 3158c2ecf20Sopenharmony_ci#define PMU_CACHED (1<<0) /* PMU MSRs are cached in the context */ 3168c2ecf20Sopenharmony_ci#define PMU_SAMPLE_USER (1<<1) /* Sample is from user or kernel mode */ 3178c2ecf20Sopenharmony_ci#define PMU_SAMPLE_REAL (1<<2) /* Sample is from realmode */ 3188c2ecf20Sopenharmony_ci#define PMU_SAMPLE_PV (1<<3) /* Sample from a PV guest */ 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci/* 3218c2ecf20Sopenharmony_ci * Architecture-specific information describing state of the processor at 3228c2ecf20Sopenharmony_ci * the time of PMU interrupt. 3238c2ecf20Sopenharmony_ci * Fields of this structure marked as RW for guest should only be written by 3248c2ecf20Sopenharmony_ci * the guest when PMU_CACHED bit in pmu_flags is set (which is done by the 3258c2ecf20Sopenharmony_ci * hypervisor during PMU interrupt). Hypervisor will read updated data in 3268c2ecf20Sopenharmony_ci * XENPMU_flush hypercall and clear PMU_CACHED bit. 3278c2ecf20Sopenharmony_ci */ 3288c2ecf20Sopenharmony_cistruct xen_pmu_arch { 3298c2ecf20Sopenharmony_ci union { 3308c2ecf20Sopenharmony_ci /* 3318c2ecf20Sopenharmony_ci * Processor's registers at the time of interrupt. 3328c2ecf20Sopenharmony_ci * WO for hypervisor, RO for guests. 3338c2ecf20Sopenharmony_ci */ 3348c2ecf20Sopenharmony_ci struct xen_pmu_regs regs; 3358c2ecf20Sopenharmony_ci /* 3368c2ecf20Sopenharmony_ci * Padding for adding new registers to xen_pmu_regs in 3378c2ecf20Sopenharmony_ci * the future 3388c2ecf20Sopenharmony_ci */ 3398c2ecf20Sopenharmony_ci#define XENPMU_REGS_PAD_SZ 64 3408c2ecf20Sopenharmony_ci uint8_t pad[XENPMU_REGS_PAD_SZ]; 3418c2ecf20Sopenharmony_ci } r; 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_ci /* WO for hypervisor, RO for guest */ 3448c2ecf20Sopenharmony_ci uint64_t pmu_flags; 3458c2ecf20Sopenharmony_ci 3468c2ecf20Sopenharmony_ci /* 3478c2ecf20Sopenharmony_ci * APIC LVTPC register. 3488c2ecf20Sopenharmony_ci * RW for both hypervisor and guest. 3498c2ecf20Sopenharmony_ci * Only APIC_LVT_MASKED bit is loaded by the hypervisor into hardware 3508c2ecf20Sopenharmony_ci * during XENPMU_flush or XENPMU_lvtpc_set. 3518c2ecf20Sopenharmony_ci */ 3528c2ecf20Sopenharmony_ci union { 3538c2ecf20Sopenharmony_ci uint32_t lapic_lvtpc; 3548c2ecf20Sopenharmony_ci uint64_t pad; 3558c2ecf20Sopenharmony_ci } l; 3568c2ecf20Sopenharmony_ci 3578c2ecf20Sopenharmony_ci /* 3588c2ecf20Sopenharmony_ci * Vendor-specific PMU registers. 3598c2ecf20Sopenharmony_ci * RW for both hypervisor and guest (see exceptions above). 3608c2ecf20Sopenharmony_ci * Guest's updates to this field are verified and then loaded by the 3618c2ecf20Sopenharmony_ci * hypervisor into hardware during XENPMU_flush 3628c2ecf20Sopenharmony_ci */ 3638c2ecf20Sopenharmony_ci union { 3648c2ecf20Sopenharmony_ci struct xen_pmu_amd_ctxt amd; 3658c2ecf20Sopenharmony_ci struct xen_pmu_intel_ctxt intel; 3668c2ecf20Sopenharmony_ci 3678c2ecf20Sopenharmony_ci /* 3688c2ecf20Sopenharmony_ci * Padding for contexts (fixed parts only, does not include 3698c2ecf20Sopenharmony_ci * MSR banks that are specified by offsets) 3708c2ecf20Sopenharmony_ci */ 3718c2ecf20Sopenharmony_ci#define XENPMU_CTXT_PAD_SZ 128 3728c2ecf20Sopenharmony_ci uint8_t pad[XENPMU_CTXT_PAD_SZ]; 3738c2ecf20Sopenharmony_ci } c; 3748c2ecf20Sopenharmony_ci}; 3758c2ecf20Sopenharmony_ci 3768c2ecf20Sopenharmony_ci#endif /* !__ASSEMBLY__ */ 3778c2ecf20Sopenharmony_ci 3788c2ecf20Sopenharmony_ci/* 3798c2ecf20Sopenharmony_ci * Prefix forces emulation of some non-trapping instructions. 3808c2ecf20Sopenharmony_ci * Currently only CPUID. 3818c2ecf20Sopenharmony_ci */ 3828c2ecf20Sopenharmony_ci#include <asm/emulate_prefix.h> 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_ci#define XEN_EMULATE_PREFIX __ASM_FORM(.byte __XEN_EMULATE_PREFIX ;) 3858c2ecf20Sopenharmony_ci#define XEN_CPUID XEN_EMULATE_PREFIX __ASM_FORM(cpuid) 3868c2ecf20Sopenharmony_ci 3878c2ecf20Sopenharmony_ci#endif /* _ASM_X86_XEN_INTERFACE_H */ 388