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