162306a36Sopenharmony_ci/****************************************************************************** 262306a36Sopenharmony_ci * arch-x86_32.h 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Guest OS interface to x86 Xen. 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 762306a36Sopenharmony_ci * of this software and associated documentation files (the "Software"), to 862306a36Sopenharmony_ci * deal in the Software without restriction, including without limitation the 962306a36Sopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 1062306a36Sopenharmony_ci * sell copies of the Software, and to permit persons to whom the Software is 1162306a36Sopenharmony_ci * furnished to do so, subject to the following conditions: 1262306a36Sopenharmony_ci * 1362306a36Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 1462306a36Sopenharmony_ci * all copies or substantial portions of the Software. 1562306a36Sopenharmony_ci * 1662306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1762306a36Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1862306a36Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1962306a36Sopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 2062306a36Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2162306a36Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 2262306a36Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 2362306a36Sopenharmony_ci * 2462306a36Sopenharmony_ci * Copyright (c) 2004-2006, K A Fraser 2562306a36Sopenharmony_ci */ 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci#ifndef _ASM_X86_XEN_INTERFACE_H 2862306a36Sopenharmony_ci#define _ASM_X86_XEN_INTERFACE_H 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci/* 3162306a36Sopenharmony_ci * XEN_GUEST_HANDLE represents a guest pointer, when passed as a field 3262306a36Sopenharmony_ci * in a struct in memory. 3362306a36Sopenharmony_ci * XEN_GUEST_HANDLE_PARAM represent a guest pointer, when passed as an 3462306a36Sopenharmony_ci * hypercall argument. 3562306a36Sopenharmony_ci * XEN_GUEST_HANDLE_PARAM and XEN_GUEST_HANDLE are the same on X86 but 3662306a36Sopenharmony_ci * they might not be on other architectures. 3762306a36Sopenharmony_ci */ 3862306a36Sopenharmony_ci#ifdef __XEN__ 3962306a36Sopenharmony_ci#define __DEFINE_GUEST_HANDLE(name, type) \ 4062306a36Sopenharmony_ci typedef struct { type *p; } __guest_handle_ ## name 4162306a36Sopenharmony_ci#else 4262306a36Sopenharmony_ci#define __DEFINE_GUEST_HANDLE(name, type) \ 4362306a36Sopenharmony_ci typedef type * __guest_handle_ ## name 4462306a36Sopenharmony_ci#endif 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci#define DEFINE_GUEST_HANDLE_STRUCT(name) \ 4762306a36Sopenharmony_ci __DEFINE_GUEST_HANDLE(name, struct name) 4862306a36Sopenharmony_ci#define DEFINE_GUEST_HANDLE(name) __DEFINE_GUEST_HANDLE(name, name) 4962306a36Sopenharmony_ci#define GUEST_HANDLE(name) __guest_handle_ ## name 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci#ifdef __XEN__ 5262306a36Sopenharmony_ci#if defined(__i386__) 5362306a36Sopenharmony_ci#define set_xen_guest_handle(hnd, val) \ 5462306a36Sopenharmony_ci do { \ 5562306a36Sopenharmony_ci if (sizeof(hnd) == 8) \ 5662306a36Sopenharmony_ci *(uint64_t *)&(hnd) = 0; \ 5762306a36Sopenharmony_ci (hnd).p = val; \ 5862306a36Sopenharmony_ci } while (0) 5962306a36Sopenharmony_ci#elif defined(__x86_64__) 6062306a36Sopenharmony_ci#define set_xen_guest_handle(hnd, val) do { (hnd).p = val; } while (0) 6162306a36Sopenharmony_ci#endif 6262306a36Sopenharmony_ci#else 6362306a36Sopenharmony_ci#if defined(__i386__) 6462306a36Sopenharmony_ci#define set_xen_guest_handle(hnd, val) \ 6562306a36Sopenharmony_ci do { \ 6662306a36Sopenharmony_ci if (sizeof(hnd) == 8) \ 6762306a36Sopenharmony_ci *(uint64_t *)&(hnd) = 0; \ 6862306a36Sopenharmony_ci (hnd) = val; \ 6962306a36Sopenharmony_ci } while (0) 7062306a36Sopenharmony_ci#elif defined(__x86_64__) 7162306a36Sopenharmony_ci#define set_xen_guest_handle(hnd, val) do { (hnd) = val; } while (0) 7262306a36Sopenharmony_ci#endif 7362306a36Sopenharmony_ci#endif 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci#ifndef __ASSEMBLY__ 7662306a36Sopenharmony_ci/* Explicitly size integers that represent pfns in the public interface 7762306a36Sopenharmony_ci * with Xen so that on ARM we can have one ABI that works for 32 and 64 7862306a36Sopenharmony_ci * bit guests. */ 7962306a36Sopenharmony_citypedef unsigned long xen_pfn_t; 8062306a36Sopenharmony_ci#define PRI_xen_pfn "lx" 8162306a36Sopenharmony_citypedef unsigned long xen_ulong_t; 8262306a36Sopenharmony_ci#define PRI_xen_ulong "lx" 8362306a36Sopenharmony_citypedef long xen_long_t; 8462306a36Sopenharmony_ci#define PRI_xen_long "lx" 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci/* Guest handles for primitive C types. */ 8762306a36Sopenharmony_ci__DEFINE_GUEST_HANDLE(uchar, unsigned char); 8862306a36Sopenharmony_ci__DEFINE_GUEST_HANDLE(uint, unsigned int); 8962306a36Sopenharmony_ciDEFINE_GUEST_HANDLE(char); 9062306a36Sopenharmony_ciDEFINE_GUEST_HANDLE(int); 9162306a36Sopenharmony_ciDEFINE_GUEST_HANDLE(void); 9262306a36Sopenharmony_ciDEFINE_GUEST_HANDLE(uint64_t); 9362306a36Sopenharmony_ciDEFINE_GUEST_HANDLE(uint32_t); 9462306a36Sopenharmony_ciDEFINE_GUEST_HANDLE(xen_pfn_t); 9562306a36Sopenharmony_ciDEFINE_GUEST_HANDLE(xen_ulong_t); 9662306a36Sopenharmony_ci#endif 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci#ifndef HYPERVISOR_VIRT_START 9962306a36Sopenharmony_ci#define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START) 10062306a36Sopenharmony_ci#endif 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci#define MACH2PHYS_VIRT_START mk_unsigned_long(__MACH2PHYS_VIRT_START) 10362306a36Sopenharmony_ci#define MACH2PHYS_VIRT_END mk_unsigned_long(__MACH2PHYS_VIRT_END) 10462306a36Sopenharmony_ci#define MACH2PHYS_NR_ENTRIES ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>__MACH2PHYS_SHIFT) 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci/* Maximum number of virtual CPUs in multi-processor guests. */ 10762306a36Sopenharmony_ci#define MAX_VIRT_CPUS 32 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci/* 11062306a36Sopenharmony_ci * SEGMENT DESCRIPTOR TABLES 11162306a36Sopenharmony_ci */ 11262306a36Sopenharmony_ci/* 11362306a36Sopenharmony_ci * A number of GDT entries are reserved by Xen. These are not situated at the 11462306a36Sopenharmony_ci * start of the GDT because some stupid OSes export hard-coded selector values 11562306a36Sopenharmony_ci * in their ABI. These hard-coded values are always near the start of the GDT, 11662306a36Sopenharmony_ci * so Xen places itself out of the way, at the far end of the GDT. 11762306a36Sopenharmony_ci * 11862306a36Sopenharmony_ci * NB The LDT is set using the MMUEXT_SET_LDT op of HYPERVISOR_mmuext_op 11962306a36Sopenharmony_ci */ 12062306a36Sopenharmony_ci#define FIRST_RESERVED_GDT_PAGE 14 12162306a36Sopenharmony_ci#define FIRST_RESERVED_GDT_BYTE (FIRST_RESERVED_GDT_PAGE * 4096) 12262306a36Sopenharmony_ci#define FIRST_RESERVED_GDT_ENTRY (FIRST_RESERVED_GDT_BYTE / 8) 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci/* 12562306a36Sopenharmony_ci * Send an array of these to HYPERVISOR_set_trap_table(). 12662306a36Sopenharmony_ci * Terminate the array with a sentinel entry, with traps[].address==0. 12762306a36Sopenharmony_ci * The privilege level specifies which modes may enter a trap via a software 12862306a36Sopenharmony_ci * interrupt. On x86/64, since rings 1 and 2 are unavailable, we allocate 12962306a36Sopenharmony_ci * privilege levels as follows: 13062306a36Sopenharmony_ci * Level == 0: No one may enter 13162306a36Sopenharmony_ci * Level == 1: Kernel may enter 13262306a36Sopenharmony_ci * Level == 2: Kernel may enter 13362306a36Sopenharmony_ci * Level == 3: Everyone may enter 13462306a36Sopenharmony_ci */ 13562306a36Sopenharmony_ci#define TI_GET_DPL(_ti) ((_ti)->flags & 3) 13662306a36Sopenharmony_ci#define TI_GET_IF(_ti) ((_ti)->flags & 4) 13762306a36Sopenharmony_ci#define TI_SET_DPL(_ti, _dpl) ((_ti)->flags |= (_dpl)) 13862306a36Sopenharmony_ci#define TI_SET_IF(_ti, _if) ((_ti)->flags |= ((!!(_if))<<2)) 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci#ifndef __ASSEMBLY__ 14162306a36Sopenharmony_cistruct trap_info { 14262306a36Sopenharmony_ci uint8_t vector; /* exception vector */ 14362306a36Sopenharmony_ci uint8_t flags; /* 0-3: privilege level; 4: clear event enable? */ 14462306a36Sopenharmony_ci uint16_t cs; /* code selector */ 14562306a36Sopenharmony_ci unsigned long address; /* code offset */ 14662306a36Sopenharmony_ci}; 14762306a36Sopenharmony_ciDEFINE_GUEST_HANDLE_STRUCT(trap_info); 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_cistruct arch_shared_info { 15062306a36Sopenharmony_ci /* 15162306a36Sopenharmony_ci * Number of valid entries in the p2m table(s) anchored at 15262306a36Sopenharmony_ci * pfn_to_mfn_frame_list_list and/or p2m_vaddr. 15362306a36Sopenharmony_ci */ 15462306a36Sopenharmony_ci unsigned long max_pfn; 15562306a36Sopenharmony_ci /* 15662306a36Sopenharmony_ci * Frame containing list of mfns containing list of mfns containing p2m. 15762306a36Sopenharmony_ci * A value of 0 indicates it has not yet been set up, ~0 indicates it 15862306a36Sopenharmony_ci * has been set to invalid e.g. due to the p2m being too large for the 15962306a36Sopenharmony_ci * 3-level p2m tree. In this case the linear mapper p2m list anchored 16062306a36Sopenharmony_ci * at p2m_vaddr is to be used. 16162306a36Sopenharmony_ci */ 16262306a36Sopenharmony_ci xen_pfn_t pfn_to_mfn_frame_list_list; 16362306a36Sopenharmony_ci unsigned long nmi_reason; 16462306a36Sopenharmony_ci /* 16562306a36Sopenharmony_ci * Following three fields are valid if p2m_cr3 contains a value 16662306a36Sopenharmony_ci * different from 0. 16762306a36Sopenharmony_ci * p2m_cr3 is the root of the address space where p2m_vaddr is valid. 16862306a36Sopenharmony_ci * p2m_cr3 is in the same format as a cr3 value in the vcpu register 16962306a36Sopenharmony_ci * state and holds the folded machine frame number (via xen_pfn_to_cr3) 17062306a36Sopenharmony_ci * of a L3 or L4 page table. 17162306a36Sopenharmony_ci * p2m_vaddr holds the virtual address of the linear p2m list. All 17262306a36Sopenharmony_ci * entries in the range [0...max_pfn[ are accessible via this pointer. 17362306a36Sopenharmony_ci * p2m_generation will be incremented by the guest before and after each 17462306a36Sopenharmony_ci * change of the mappings of the p2m list. p2m_generation starts at 0 17562306a36Sopenharmony_ci * and a value with the least significant bit set indicates that a 17662306a36Sopenharmony_ci * mapping update is in progress. This allows guest external software 17762306a36Sopenharmony_ci * (e.g. in Dom0) to verify that read mappings are consistent and 17862306a36Sopenharmony_ci * whether they have changed since the last check. 17962306a36Sopenharmony_ci * Modifying a p2m element in the linear p2m list is allowed via an 18062306a36Sopenharmony_ci * atomic write only. 18162306a36Sopenharmony_ci */ 18262306a36Sopenharmony_ci unsigned long p2m_cr3; /* cr3 value of the p2m address space */ 18362306a36Sopenharmony_ci unsigned long p2m_vaddr; /* virtual address of the p2m list */ 18462306a36Sopenharmony_ci unsigned long p2m_generation; /* generation count of p2m mapping */ 18562306a36Sopenharmony_ci#ifdef CONFIG_X86_32 18662306a36Sopenharmony_ci uint32_t wc_sec_hi; 18762306a36Sopenharmony_ci#endif 18862306a36Sopenharmony_ci}; 18962306a36Sopenharmony_ci#endif /* !__ASSEMBLY__ */ 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci#ifdef CONFIG_X86_32 19262306a36Sopenharmony_ci#include <asm/xen/interface_32.h> 19362306a36Sopenharmony_ci#else 19462306a36Sopenharmony_ci#include <asm/xen/interface_64.h> 19562306a36Sopenharmony_ci#endif 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci#include <asm/pvclock-abi.h> 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci#ifndef __ASSEMBLY__ 20062306a36Sopenharmony_ci/* 20162306a36Sopenharmony_ci * The following is all CPU context. Note that the fpu_ctxt block is filled 20262306a36Sopenharmony_ci * in by FXSAVE if the CPU has feature FXSR; otherwise FSAVE is used. 20362306a36Sopenharmony_ci * 20462306a36Sopenharmony_ci * Also note that when calling DOMCTL_setvcpucontext and VCPU_initialise 20562306a36Sopenharmony_ci * for HVM and PVH guests, not all information in this structure is updated: 20662306a36Sopenharmony_ci * 20762306a36Sopenharmony_ci * - For HVM guests, the structures read include: fpu_ctxt (if 20862306a36Sopenharmony_ci * VGCT_I387_VALID is set), flags, user_regs, debugreg[*] 20962306a36Sopenharmony_ci * 21062306a36Sopenharmony_ci * - PVH guests are the same as HVM guests, but additionally use ctrlreg[3] to 21162306a36Sopenharmony_ci * set cr3. All other fields not used should be set to 0. 21262306a36Sopenharmony_ci */ 21362306a36Sopenharmony_cistruct vcpu_guest_context { 21462306a36Sopenharmony_ci /* FPU registers come first so they can be aligned for FXSAVE/FXRSTOR. */ 21562306a36Sopenharmony_ci struct { char x[512]; } fpu_ctxt; /* User-level FPU registers */ 21662306a36Sopenharmony_ci#define VGCF_I387_VALID (1<<0) 21762306a36Sopenharmony_ci#define VGCF_IN_KERNEL (1<<2) 21862306a36Sopenharmony_ci#define _VGCF_i387_valid 0 21962306a36Sopenharmony_ci#define VGCF_i387_valid (1<<_VGCF_i387_valid) 22062306a36Sopenharmony_ci#define _VGCF_in_kernel 2 22162306a36Sopenharmony_ci#define VGCF_in_kernel (1<<_VGCF_in_kernel) 22262306a36Sopenharmony_ci#define _VGCF_failsafe_disables_events 3 22362306a36Sopenharmony_ci#define VGCF_failsafe_disables_events (1<<_VGCF_failsafe_disables_events) 22462306a36Sopenharmony_ci#define _VGCF_syscall_disables_events 4 22562306a36Sopenharmony_ci#define VGCF_syscall_disables_events (1<<_VGCF_syscall_disables_events) 22662306a36Sopenharmony_ci#define _VGCF_online 5 22762306a36Sopenharmony_ci#define VGCF_online (1<<_VGCF_online) 22862306a36Sopenharmony_ci unsigned long flags; /* VGCF_* flags */ 22962306a36Sopenharmony_ci struct cpu_user_regs user_regs; /* User-level CPU registers */ 23062306a36Sopenharmony_ci struct trap_info trap_ctxt[256]; /* Virtual IDT */ 23162306a36Sopenharmony_ci unsigned long ldt_base, ldt_ents; /* LDT (linear address, # ents) */ 23262306a36Sopenharmony_ci unsigned long gdt_frames[16], gdt_ents; /* GDT (machine frames, # ents) */ 23362306a36Sopenharmony_ci unsigned long kernel_ss, kernel_sp; /* Virtual TSS (only SS1/SP1) */ 23462306a36Sopenharmony_ci /* NB. User pagetable on x86/64 is placed in ctrlreg[1]. */ 23562306a36Sopenharmony_ci unsigned long ctrlreg[8]; /* CR0-CR7 (control registers) */ 23662306a36Sopenharmony_ci unsigned long debugreg[8]; /* DB0-DB7 (debug registers) */ 23762306a36Sopenharmony_ci#ifdef __i386__ 23862306a36Sopenharmony_ci unsigned long event_callback_cs; /* CS:EIP of event callback */ 23962306a36Sopenharmony_ci unsigned long event_callback_eip; 24062306a36Sopenharmony_ci unsigned long failsafe_callback_cs; /* CS:EIP of failsafe callback */ 24162306a36Sopenharmony_ci unsigned long failsafe_callback_eip; 24262306a36Sopenharmony_ci#else 24362306a36Sopenharmony_ci unsigned long event_callback_eip; 24462306a36Sopenharmony_ci unsigned long failsafe_callback_eip; 24562306a36Sopenharmony_ci unsigned long syscall_callback_eip; 24662306a36Sopenharmony_ci#endif 24762306a36Sopenharmony_ci unsigned long vm_assist; /* VMASST_TYPE_* bitmap */ 24862306a36Sopenharmony_ci#ifdef __x86_64__ 24962306a36Sopenharmony_ci /* Segment base addresses. */ 25062306a36Sopenharmony_ci uint64_t fs_base; 25162306a36Sopenharmony_ci uint64_t gs_base_kernel; 25262306a36Sopenharmony_ci uint64_t gs_base_user; 25362306a36Sopenharmony_ci#endif 25462306a36Sopenharmony_ci}; 25562306a36Sopenharmony_ciDEFINE_GUEST_HANDLE_STRUCT(vcpu_guest_context); 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_ci/* AMD PMU registers and structures */ 25862306a36Sopenharmony_cistruct xen_pmu_amd_ctxt { 25962306a36Sopenharmony_ci /* 26062306a36Sopenharmony_ci * Offsets to counter and control MSRs (relative to xen_pmu_arch.c.amd). 26162306a36Sopenharmony_ci * For PV(H) guests these fields are RO. 26262306a36Sopenharmony_ci */ 26362306a36Sopenharmony_ci uint32_t counters; 26462306a36Sopenharmony_ci uint32_t ctrls; 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_ci /* Counter MSRs */ 26762306a36Sopenharmony_ci#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L 26862306a36Sopenharmony_ci uint64_t regs[]; 26962306a36Sopenharmony_ci#elif defined(__GNUC__) 27062306a36Sopenharmony_ci uint64_t regs[0]; 27162306a36Sopenharmony_ci#endif 27262306a36Sopenharmony_ci}; 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci/* Intel PMU registers and structures */ 27562306a36Sopenharmony_cistruct xen_pmu_cntr_pair { 27662306a36Sopenharmony_ci uint64_t counter; 27762306a36Sopenharmony_ci uint64_t control; 27862306a36Sopenharmony_ci}; 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_cistruct xen_pmu_intel_ctxt { 28162306a36Sopenharmony_ci /* 28262306a36Sopenharmony_ci * Offsets to fixed and architectural counter MSRs (relative to 28362306a36Sopenharmony_ci * xen_pmu_arch.c.intel). 28462306a36Sopenharmony_ci * For PV(H) guests these fields are RO. 28562306a36Sopenharmony_ci */ 28662306a36Sopenharmony_ci uint32_t fixed_counters; 28762306a36Sopenharmony_ci uint32_t arch_counters; 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_ci /* PMU registers */ 29062306a36Sopenharmony_ci uint64_t global_ctrl; 29162306a36Sopenharmony_ci uint64_t global_ovf_ctrl; 29262306a36Sopenharmony_ci uint64_t global_status; 29362306a36Sopenharmony_ci uint64_t fixed_ctrl; 29462306a36Sopenharmony_ci uint64_t ds_area; 29562306a36Sopenharmony_ci uint64_t pebs_enable; 29662306a36Sopenharmony_ci uint64_t debugctl; 29762306a36Sopenharmony_ci 29862306a36Sopenharmony_ci /* Fixed and architectural counter MSRs */ 29962306a36Sopenharmony_ci#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L 30062306a36Sopenharmony_ci uint64_t regs[]; 30162306a36Sopenharmony_ci#elif defined(__GNUC__) 30262306a36Sopenharmony_ci uint64_t regs[0]; 30362306a36Sopenharmony_ci#endif 30462306a36Sopenharmony_ci}; 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ci/* Sampled domain's registers */ 30762306a36Sopenharmony_cistruct xen_pmu_regs { 30862306a36Sopenharmony_ci uint64_t ip; 30962306a36Sopenharmony_ci uint64_t sp; 31062306a36Sopenharmony_ci uint64_t flags; 31162306a36Sopenharmony_ci uint16_t cs; 31262306a36Sopenharmony_ci uint16_t ss; 31362306a36Sopenharmony_ci uint8_t cpl; 31462306a36Sopenharmony_ci uint8_t pad[3]; 31562306a36Sopenharmony_ci}; 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci/* PMU flags */ 31862306a36Sopenharmony_ci#define PMU_CACHED (1<<0) /* PMU MSRs are cached in the context */ 31962306a36Sopenharmony_ci#define PMU_SAMPLE_USER (1<<1) /* Sample is from user or kernel mode */ 32062306a36Sopenharmony_ci#define PMU_SAMPLE_REAL (1<<2) /* Sample is from realmode */ 32162306a36Sopenharmony_ci#define PMU_SAMPLE_PV (1<<3) /* Sample from a PV guest */ 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_ci/* 32462306a36Sopenharmony_ci * Architecture-specific information describing state of the processor at 32562306a36Sopenharmony_ci * the time of PMU interrupt. 32662306a36Sopenharmony_ci * Fields of this structure marked as RW for guest should only be written by 32762306a36Sopenharmony_ci * the guest when PMU_CACHED bit in pmu_flags is set (which is done by the 32862306a36Sopenharmony_ci * hypervisor during PMU interrupt). Hypervisor will read updated data in 32962306a36Sopenharmony_ci * XENPMU_flush hypercall and clear PMU_CACHED bit. 33062306a36Sopenharmony_ci */ 33162306a36Sopenharmony_cistruct xen_pmu_arch { 33262306a36Sopenharmony_ci union { 33362306a36Sopenharmony_ci /* 33462306a36Sopenharmony_ci * Processor's registers at the time of interrupt. 33562306a36Sopenharmony_ci * WO for hypervisor, RO for guests. 33662306a36Sopenharmony_ci */ 33762306a36Sopenharmony_ci struct xen_pmu_regs regs; 33862306a36Sopenharmony_ci /* 33962306a36Sopenharmony_ci * Padding for adding new registers to xen_pmu_regs in 34062306a36Sopenharmony_ci * the future 34162306a36Sopenharmony_ci */ 34262306a36Sopenharmony_ci#define XENPMU_REGS_PAD_SZ 64 34362306a36Sopenharmony_ci uint8_t pad[XENPMU_REGS_PAD_SZ]; 34462306a36Sopenharmony_ci } r; 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_ci /* WO for hypervisor, RO for guest */ 34762306a36Sopenharmony_ci uint64_t pmu_flags; 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_ci /* 35062306a36Sopenharmony_ci * APIC LVTPC register. 35162306a36Sopenharmony_ci * RW for both hypervisor and guest. 35262306a36Sopenharmony_ci * Only APIC_LVT_MASKED bit is loaded by the hypervisor into hardware 35362306a36Sopenharmony_ci * during XENPMU_flush or XENPMU_lvtpc_set. 35462306a36Sopenharmony_ci */ 35562306a36Sopenharmony_ci union { 35662306a36Sopenharmony_ci uint32_t lapic_lvtpc; 35762306a36Sopenharmony_ci uint64_t pad; 35862306a36Sopenharmony_ci } l; 35962306a36Sopenharmony_ci 36062306a36Sopenharmony_ci /* 36162306a36Sopenharmony_ci * Vendor-specific PMU registers. 36262306a36Sopenharmony_ci * RW for both hypervisor and guest (see exceptions above). 36362306a36Sopenharmony_ci * Guest's updates to this field are verified and then loaded by the 36462306a36Sopenharmony_ci * hypervisor into hardware during XENPMU_flush 36562306a36Sopenharmony_ci */ 36662306a36Sopenharmony_ci union { 36762306a36Sopenharmony_ci struct xen_pmu_amd_ctxt amd; 36862306a36Sopenharmony_ci struct xen_pmu_intel_ctxt intel; 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_ci /* 37162306a36Sopenharmony_ci * Padding for contexts (fixed parts only, does not include 37262306a36Sopenharmony_ci * MSR banks that are specified by offsets) 37362306a36Sopenharmony_ci */ 37462306a36Sopenharmony_ci#define XENPMU_CTXT_PAD_SZ 128 37562306a36Sopenharmony_ci uint8_t pad[XENPMU_CTXT_PAD_SZ]; 37662306a36Sopenharmony_ci } c; 37762306a36Sopenharmony_ci}; 37862306a36Sopenharmony_ci 37962306a36Sopenharmony_ci#endif /* !__ASSEMBLY__ */ 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_ci/* 38262306a36Sopenharmony_ci * Prefix forces emulation of some non-trapping instructions. 38362306a36Sopenharmony_ci * Currently only CPUID. 38462306a36Sopenharmony_ci */ 38562306a36Sopenharmony_ci#include <asm/emulate_prefix.h> 38662306a36Sopenharmony_ci 38762306a36Sopenharmony_ci#define XEN_EMULATE_PREFIX __ASM_FORM(.byte __XEN_EMULATE_PREFIX ;) 38862306a36Sopenharmony_ci#define XEN_CPUID XEN_EMULATE_PREFIX __ASM_FORM(cpuid) 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ci#endif /* _ASM_X86_XEN_INTERFACE_H */ 391