[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [MINIOS PATCH] Update public headers from Xen
Signed-off-by: Wei Liu <wei.liu2@xxxxxxxxxx> --- include/xen/arch-arm.h | 94 +++- include/xen/arch-x86/cpufeatureset.h | 263 +++++++++++ include/xen/arch-x86/cpuid.h | 32 +- include/xen/arch-x86/hvm/save.h | 101 ++-- include/xen/arch-x86/pmu.h | 167 +++++++ include/xen/arch-x86/xen-mca.h | 60 +-- include/xen/arch-x86/xen-x86_32.h | 69 ++- include/xen/arch-x86/xen-x86_64.h | 87 +++- include/xen/arch-x86/xen.h | 74 ++- include/xen/domctl.h | 555 +++++++++++++--------- include/xen/elfnote.h | 4 +- include/xen/errno.h | 124 +++++ include/xen/event_channel.h | 2 +- include/xen/features.h | 3 + include/xen/gcov.h | 115 ----- include/xen/grant_table.h | 19 +- include/xen/hvm/dm_op.h | 417 +++++++++++++++++ include/xen/hvm/e820.h | 8 +- include/xen/hvm/hvm_info_table.h | 10 + include/xen/hvm/hvm_op.h | 340 +++++--------- include/xen/hvm/hvm_vcpu.h | 144 ++++++ include/xen/hvm/hvm_xs_strings.h | 3 + include/xen/hvm/ioreq.h | 22 +- include/xen/hvm/params.h | 129 +++++- include/xen/hvm/save.h | 10 +- include/xen/io/9pfs.h | 49 ++ include/xen/io/blkif.h | 74 ++- include/xen/io/console.h | 6 + include/xen/io/displif.h | 864 +++++++++++++++++++++++++++++++++++ include/xen/io/kbdif.h | 472 +++++++++++++++++-- include/xen/io/libxenvchan.h | 26 +- include/xen/io/netif.h | 772 ++++++++++++++++++++++++++++--- include/xen/io/protocols.h | 2 + include/xen/io/pvcalls.h | 153 +++++++ include/xen/io/ring.h | 176 ++++++- include/xen/io/sndif.h | 803 ++++++++++++++++++++++++++++++++ include/xen/io/usbif.h | 146 +++++- include/xen/io/vscsiif.h | 74 ++- include/xen/io/xs_wire.h | 10 +- include/xen/kexec.h | 14 + include/xen/mem_event.h | 134 ------ include/xen/memory.h | 118 ++++- include/xen/physdev.h | 7 + include/xen/platform.h | 95 +++- include/xen/pmu.h | 143 ++++++ include/xen/sched.h | 29 +- include/xen/sysctl.h | 649 +++++++++++++++++++++----- include/xen/tmem.h | 64 +-- include/xen/trace.h | 10 +- include/xen/vcpu.h | 12 +- include/xen/version.h | 24 +- include/xen/vm_event.h | 378 +++++++++++++++ include/xen/xen-compat.h | 2 +- include/xen/xen.h | 144 ++++-- include/xen/xenoprof.h | 2 +- include/xen/xsm/flask_op.h | 17 +- 56 files changed, 7043 insertions(+), 1278 deletions(-) create mode 100644 include/xen/arch-x86/cpufeatureset.h create mode 100644 include/xen/arch-x86/pmu.h create mode 100644 include/xen/errno.h delete mode 100644 include/xen/gcov.h create mode 100644 include/xen/hvm/dm_op.h create mode 100644 include/xen/hvm/hvm_vcpu.h create mode 100644 include/xen/io/9pfs.h create mode 100644 include/xen/io/displif.h create mode 100644 include/xen/io/pvcalls.h create mode 100644 include/xen/io/sndif.h delete mode 100644 include/xen/mem_event.h create mode 100644 include/xen/pmu.h create mode 100644 include/xen/vm_event.h diff --git a/include/xen/arch-arm.h b/include/xen/arch-arm.h index 124fc90..5708cd2 100644 --- a/include/xen/arch-arm.h +++ b/include/xen/arch-arm.h @@ -61,15 +61,15 @@ * * All memory which is shared with other entities in the system * (including the hypervisor and other guests) must reside in memory - * which is mapped as Normal Inner-cacheable. This applies to: + * which is mapped as Normal Inner Write-Back Outer Write-Back Inner-Shareable. + * This applies to: * - hypercall arguments passed via a pointer to guest memory. * - memory shared via the grant table mechanism (including PV I/O * rings etc). * - memory shared with the hypervisor (struct shared_info, struct * vcpu_info, the grant table, etc). * - * Any Inner cache allocation strategy (Write-Back, Write-Through etc) - * is acceptable. There is no restriction on the Outer-cacheability. + * Any cache allocation hints are acceptable. */ /* @@ -165,6 +165,7 @@ #define XEN_HYPERCALL_TAG 0XEA1 +#define int64_aligned_t int64_t __attribute__((aligned(8))) #define uint64_aligned_t uint64_t __attribute__((aligned(8))) #ifndef __ASSEMBLY__ @@ -172,7 +173,7 @@ typedef union { type *p; unsigned long q; } \ __guest_handle_ ## name; \ typedef union { type *p; uint64_aligned_t q; } \ - __guest_handle_64_ ## name; + __guest_handle_64_ ## name /* * XEN_GUEST_HANDLE represents a guest pointer, when passed as a field @@ -194,9 +195,6 @@ _sxghr_tmp->q = 0; \ _sxghr_tmp->p = val; \ } while ( 0 ) -#ifdef __XEN_TOOLS__ -#define get_xen_guest_handle(val, hnd) do { val = (hnd).p; } while (0) -#endif #define set_xen_guest_handle(hnd, val) set_xen_guest_handle_raw(hnd, val) #if defined(__GNUC__) && !defined(__STRICT_ANSI__) @@ -297,7 +295,35 @@ struct vcpu_guest_context { }; typedef struct vcpu_guest_context vcpu_guest_context_t; DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t); -#endif + +/* + * struct xen_arch_domainconfig's ABI is covered by + * XEN_DOMCTL_INTERFACE_VERSION. + */ +#define XEN_DOMCTL_CONFIG_GIC_NATIVE 0 +#define XEN_DOMCTL_CONFIG_GIC_V2 1 +#define XEN_DOMCTL_CONFIG_GIC_V3 2 +struct xen_arch_domainconfig { + /* IN/OUT */ + uint8_t gic_version; + /* IN */ + uint32_t nr_spis; + /* + * OUT + * Based on the property clock-frequency in the DT timer node. + * The property may be present when the bootloader/firmware doesn't + * set correctly CNTFRQ which hold the timer frequency. + * + * As it's not possible to trap this register, we have to replicate + * the value in the guest DT. + * + * = 0 => property not present + * > 0 => Value of the property + * + */ + uint32_t clock_frequency; +}; +#endif /* __XEN__ || __XEN_TOOLS__ */ struct arch_vcpu_info { }; @@ -365,38 +391,46 @@ typedef uint64_t xen_callback_t; */ /* vGIC v2 mappings */ -#define GUEST_GICD_BASE 0x03001000ULL -#define GUEST_GICD_SIZE 0x00001000ULL -#define GUEST_GICC_BASE 0x03002000ULL -#define GUEST_GICC_SIZE 0x00000100ULL +#define GUEST_GICD_BASE xen_mk_ullong(0x03001000) +#define GUEST_GICD_SIZE xen_mk_ullong(0x00001000) +#define GUEST_GICC_BASE xen_mk_ullong(0x03002000) +#define GUEST_GICC_SIZE xen_mk_ullong(0x00002000) /* vGIC v3 mappings */ -#define GUEST_GICV3_GICD_BASE 0x03001000ULL -#define GUEST_GICV3_GICD_SIZE 0x00010000ULL +#define GUEST_GICV3_GICD_BASE xen_mk_ullong(0x03001000) +#define GUEST_GICV3_GICD_SIZE xen_mk_ullong(0x00010000) -#define GUEST_GICV3_RDIST_STRIDE 0x20000ULL +#define GUEST_GICV3_RDIST_STRIDE xen_mk_ullong(0x00020000) #define GUEST_GICV3_RDIST_REGIONS 1 -#define GUEST_GICV3_GICR0_BASE 0x03020000ULL /* vCPU0 - vCPU7 */ -#define GUEST_GICV3_GICR0_SIZE 0x00100000ULL +#define GUEST_GICV3_GICR0_BASE xen_mk_ullong(0x03020000) /* vCPU0..127 */ +#define GUEST_GICV3_GICR0_SIZE xen_mk_ullong(0x01000000) + +/* ACPI tables physical address */ +#define GUEST_ACPI_BASE 0x20000000ULL +#define GUEST_ACPI_SIZE 0x02000000ULL + +/* PL011 mappings */ +#define GUEST_PL011_BASE 0x22000000ULL +#define GUEST_PL011_SIZE 0x00001000ULL /* * 16MB == 4096 pages reserved for guest to use as a region to map its * grant table in. */ -#define GUEST_GNTTAB_BASE 0x38000000ULL -#define GUEST_GNTTAB_SIZE 0x01000000ULL +#define GUEST_GNTTAB_BASE xen_mk_ullong(0x38000000) +#define GUEST_GNTTAB_SIZE xen_mk_ullong(0x01000000) -#define GUEST_MAGIC_BASE 0x39000000ULL -#define GUEST_MAGIC_SIZE 0x01000000ULL +#define GUEST_MAGIC_BASE xen_mk_ullong(0x39000000) +#define GUEST_MAGIC_SIZE xen_mk_ullong(0x01000000) #define GUEST_RAM_BANKS 2 -#define GUEST_RAM0_BASE 0x40000000ULL /* 3GB of low RAM @ 1GB */ -#define GUEST_RAM0_SIZE 0xc0000000ULL +#define GUEST_RAM0_BASE xen_mk_ullong(0x40000000) /* 3GB of low RAM @ 1GB */ +#define GUEST_RAM0_SIZE xen_mk_ullong(0xc0000000) -#define GUEST_RAM1_BASE 0x0200000000ULL /* 1016GB of RAM @ 8GB */ -#define GUEST_RAM1_SIZE 0xfe00000000ULL +#define GUEST_RAM1_BASE xen_mk_ullong(0x0200000000) /* 1016GB of RAM @ 8GB */ +#define GUEST_RAM1_SIZE xen_mk_ullong(0xfe00000000) #define GUEST_RAM_BASE GUEST_RAM0_BASE /* Lowest RAM address */ /* Largest amount of actual RAM, not including holes */ @@ -405,12 +439,17 @@ typedef uint64_t xen_callback_t; #define GUEST_RAM_BANK_BASES { GUEST_RAM0_BASE, GUEST_RAM1_BASE } #define GUEST_RAM_BANK_SIZES { GUEST_RAM0_SIZE, GUEST_RAM1_SIZE } +/* Current supported guest VCPUs */ +#define GUEST_MAX_VCPUS 128 + /* Interrupts */ #define GUEST_TIMER_VIRT_PPI 27 #define GUEST_TIMER_PHYS_S_PPI 29 #define GUEST_TIMER_PHYS_NS_PPI 30 #define GUEST_EVTCHN_PPI 31 +#define GUEST_VPL011_SPI 32 + /* PSCI functions */ #define PSCI_cpu_suspend 0 #define PSCI_cpu_off 1 @@ -419,6 +458,11 @@ typedef uint64_t xen_callback_t; #endif +#ifndef __ASSEMBLY__ +/* Stub definition of PMU structure */ +typedef struct xen_pmu_arch { uint8_t dummy; } xen_pmu_arch_t; +#endif + #endif /* __XEN_PUBLIC_ARCH_ARM_H__ */ /* diff --git a/include/xen/arch-x86/cpufeatureset.h b/include/xen/arch-x86/cpufeatureset.h new file mode 100644 index 0000000..0ee3ea3 --- /dev/null +++ b/include/xen/arch-x86/cpufeatureset.h @@ -0,0 +1,263 @@ +/* + * arch-x86/cpufeatureset.h + * + * CPU featureset definitions + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2015, 2016 Citrix Systems, Inc. + */ + +/* + * There are two expected ways of including this header. + * + * 1) The "default" case (expected from tools etc). + * + * Simply #include <public/arch-x86/cpufeatureset.h> + * + * In this circumstance, normal header guards apply and the includer shall get + * an enumeration in the XEN_X86_FEATURE_xxx namespace. + * + * 2) The special case where the includer provides XEN_CPUFEATURE() in scope. + * + * In this case, no inclusion guards apply and the caller is responsible for + * their XEN_CPUFEATURE() being appropriate in the included context. + */ + +#ifndef XEN_CPUFEATURE + +/* + * Includer has not provided a custom XEN_CPUFEATURE(). Arrange for normal + * header guards, an enum and constants in the XEN_X86_FEATURE_xxx namespace. + */ +#ifndef __XEN_PUBLIC_ARCH_X86_CPUFEATURESET_H__ +#define __XEN_PUBLIC_ARCH_X86_CPUFEATURESET_H__ + +#define XEN_CPUFEATURESET_DEFAULT_INCLUDE + +#define XEN_CPUFEATURE(name, value) XEN_X86_FEATURE_##name = value, +enum { + +#endif /* __XEN_PUBLIC_ARCH_X86_CPUFEATURESET_H__ */ +#endif /* !XEN_CPUFEATURE */ + + +#ifdef XEN_CPUFEATURE +/* + * A featureset is a bitmap of x86 features, represented as a collection of + * 32bit words. + * + * Words are as specified in vendors programming manuals, and shall not + * contain any synthesied values. New words may be added to the end of + * featureset. + * + * All featureset words currently originate from leaves specified for the + * CPUID instruction, but this is not preclude other sources of information. + */ + +/* + * Attribute syntax: + * + * Attributes for a particular feature are provided as characters before the + * first space in the comment immediately following the feature value. Note - + * none of these attributes form part of the Xen public ABI. + * + * Special: '!' + * This bit has special properties and is not a straight indication of a + * piece of new functionality. Xen will handle these differently, + * and may override toolstack settings completely. + * + * Applicability to guests: 'A', 'S' or 'H' + * 'A' = All guests. + * 'S' = All HVM guests (not PV guests). + * 'H' = HVM HAP guests (not PV or HVM Shadow guests). + */ + +/* Intel-defined CPU features, CPUID level 0x00000001.edx, word 0 */ +XEN_CPUFEATURE(FPU, 0*32+ 0) /*A Onboard FPU */ +XEN_CPUFEATURE(VME, 0*32+ 1) /*S Virtual Mode Extensions */ +XEN_CPUFEATURE(DE, 0*32+ 2) /*A Debugging Extensions */ +XEN_CPUFEATURE(PSE, 0*32+ 3) /*S Page Size Extensions */ +XEN_CPUFEATURE(TSC, 0*32+ 4) /*A Time Stamp Counter */ +XEN_CPUFEATURE(MSR, 0*32+ 5) /*A Model-Specific Registers, RDMSR, WRMSR */ +XEN_CPUFEATURE(PAE, 0*32+ 6) /*A Physical Address Extensions */ +XEN_CPUFEATURE(MCE, 0*32+ 7) /*A Machine Check Architecture */ +XEN_CPUFEATURE(CX8, 0*32+ 8) /*A CMPXCHG8 instruction */ +XEN_CPUFEATURE(APIC, 0*32+ 9) /*!A Onboard APIC */ +XEN_CPUFEATURE(SEP, 0*32+11) /*A SYSENTER/SYSEXIT */ +XEN_CPUFEATURE(MTRR, 0*32+12) /*S Memory Type Range Registers */ +XEN_CPUFEATURE(PGE, 0*32+13) /*S Page Global Enable */ +XEN_CPUFEATURE(MCA, 0*32+14) /*A Machine Check Architecture */ +XEN_CPUFEATURE(CMOV, 0*32+15) /*A CMOV instruction (FCMOVCC and FCOMI too if FPU present) */ +XEN_CPUFEATURE(PAT, 0*32+16) /*A Page Attribute Table */ +XEN_CPUFEATURE(PSE36, 0*32+17) /*S 36-bit PSEs */ +XEN_CPUFEATURE(CLFLUSH, 0*32+19) /*A CLFLUSH instruction */ +XEN_CPUFEATURE(DS, 0*32+21) /* Debug Store */ +XEN_CPUFEATURE(ACPI, 0*32+22) /*A ACPI via MSR */ +XEN_CPUFEATURE(MMX, 0*32+23) /*A Multimedia Extensions */ +XEN_CPUFEATURE(FXSR, 0*32+24) /*A FXSAVE and FXRSTOR instructions */ +XEN_CPUFEATURE(SSE, 0*32+25) /*A Streaming SIMD Extensions */ +XEN_CPUFEATURE(SSE2, 0*32+26) /*A Streaming SIMD Extensions-2 */ +XEN_CPUFEATURE(SS, 0*32+27) /*A CPU self snoop */ +XEN_CPUFEATURE(HTT, 0*32+28) /*!A Hyper-Threading Technology */ +XEN_CPUFEATURE(TM1, 0*32+29) /* Thermal Monitor 1 */ +XEN_CPUFEATURE(PBE, 0*32+31) /* Pending Break Enable */ + +/* Intel-defined CPU features, CPUID level 0x00000001.ecx, word 1 */ +XEN_CPUFEATURE(SSE3, 1*32+ 0) /*A Streaming SIMD Extensions-3 */ +XEN_CPUFEATURE(PCLMULQDQ, 1*32+ 1) /*A Carry-less mulitplication */ +XEN_CPUFEATURE(DTES64, 1*32+ 2) /* 64-bit Debug Store */ +XEN_CPUFEATURE(MONITOR, 1*32+ 3) /* Monitor/Mwait support */ +XEN_CPUFEATURE(DSCPL, 1*32+ 4) /* CPL Qualified Debug Store */ +XEN_CPUFEATURE(VMX, 1*32+ 5) /*S Virtual Machine Extensions */ +XEN_CPUFEATURE(SMX, 1*32+ 6) /* Safer Mode Extensions */ +XEN_CPUFEATURE(EIST, 1*32+ 7) /* Enhanced SpeedStep */ +XEN_CPUFEATURE(TM2, 1*32+ 8) /* Thermal Monitor 2 */ +XEN_CPUFEATURE(SSSE3, 1*32+ 9) /*A Supplemental Streaming SIMD Extensions-3 */ +XEN_CPUFEATURE(FMA, 1*32+12) /*A Fused Multiply Add */ +XEN_CPUFEATURE(CX16, 1*32+13) /*A CMPXCHG16B */ +XEN_CPUFEATURE(XTPR, 1*32+14) /* Send Task Priority Messages */ +XEN_CPUFEATURE(PDCM, 1*32+15) /* Perf/Debug Capability MSR */ +XEN_CPUFEATURE(PCID, 1*32+17) /*H Process Context ID */ +XEN_CPUFEATURE(DCA, 1*32+18) /* Direct Cache Access */ +XEN_CPUFEATURE(SSE4_1, 1*32+19) /*A Streaming SIMD Extensions 4.1 */ +XEN_CPUFEATURE(SSE4_2, 1*32+20) /*A Streaming SIMD Extensions 4.2 */ +XEN_CPUFEATURE(X2APIC, 1*32+21) /*!A Extended xAPIC */ +XEN_CPUFEATURE(MOVBE, 1*32+22) /*A movbe instruction */ +XEN_CPUFEATURE(POPCNT, 1*32+23) /*A POPCNT instruction */ +XEN_CPUFEATURE(TSC_DEADLINE, 1*32+24) /*S TSC Deadline Timer */ +XEN_CPUFEATURE(AESNI, 1*32+25) /*A AES instructions */ +XEN_CPUFEATURE(XSAVE, 1*32+26) /*A XSAVE/XRSTOR/XSETBV/XGETBV */ +XEN_CPUFEATURE(OSXSAVE, 1*32+27) /*! OSXSAVE */ +XEN_CPUFEATURE(AVX, 1*32+28) /*A Advanced Vector Extensions */ +XEN_CPUFEATURE(F16C, 1*32+29) /*A Half-precision convert instruction */ +XEN_CPUFEATURE(RDRAND, 1*32+30) /*A Digital Random Number Generator */ +XEN_CPUFEATURE(HYPERVISOR, 1*32+31) /*!A Running under some hypervisor */ + +/* AMD-defined CPU features, CPUID level 0x80000001.edx, word 2 */ +XEN_CPUFEATURE(SYSCALL, 2*32+11) /*A SYSCALL/SYSRET */ +XEN_CPUFEATURE(NX, 2*32+20) /*A Execute Disable */ +XEN_CPUFEATURE(MMXEXT, 2*32+22) /*A AMD MMX extensions */ +XEN_CPUFEATURE(FFXSR, 2*32+25) /*A FFXSR instruction optimizations */ +XEN_CPUFEATURE(PAGE1GB, 2*32+26) /*H 1Gb large page support */ +XEN_CPUFEATURE(RDTSCP, 2*32+27) /*S RDTSCP */ +XEN_CPUFEATURE(LM, 2*32+29) /*A Long Mode (x86-64) */ +XEN_CPUFEATURE(3DNOWEXT, 2*32+30) /*A AMD 3DNow! extensions */ +XEN_CPUFEATURE(3DNOW, 2*32+31) /*A 3DNow! */ + +/* AMD-defined CPU features, CPUID level 0x80000001.ecx, word 3 */ +XEN_CPUFEATURE(LAHF_LM, 3*32+ 0) /*A LAHF/SAHF in long mode */ +XEN_CPUFEATURE(CMP_LEGACY, 3*32+ 1) /*!A If yes HyperThreading not valid */ +XEN_CPUFEATURE(SVM, 3*32+ 2) /*S Secure virtual machine */ +XEN_CPUFEATURE(EXTAPIC, 3*32+ 3) /* Extended APIC space */ +XEN_CPUFEATURE(CR8_LEGACY, 3*32+ 4) /*S CR8 in 32-bit mode */ +XEN_CPUFEATURE(ABM, 3*32+ 5) /*A Advanced bit manipulation */ +XEN_CPUFEATURE(SSE4A, 3*32+ 6) /*A SSE-4A */ +XEN_CPUFEATURE(MISALIGNSSE, 3*32+ 7) /*A Misaligned SSE mode */ +XEN_CPUFEATURE(3DNOWPREFETCH, 3*32+ 8) /*A 3DNow prefetch instructions */ +XEN_CPUFEATURE(OSVW, 3*32+ 9) /* OS Visible Workaround */ +XEN_CPUFEATURE(IBS, 3*32+10) /* Instruction Based Sampling */ +XEN_CPUFEATURE(XOP, 3*32+11) /*A extended AVX instructions */ +XEN_CPUFEATURE(SKINIT, 3*32+12) /* SKINIT/STGI instructions */ +XEN_CPUFEATURE(WDT, 3*32+13) /* Watchdog timer */ +XEN_CPUFEATURE(LWP, 3*32+15) /*S Light Weight Profiling */ +XEN_CPUFEATURE(FMA4, 3*32+16) /*A 4 operands MAC instructions */ +XEN_CPUFEATURE(NODEID_MSR, 3*32+19) /* NodeId MSR */ +XEN_CPUFEATURE(TBM, 3*32+21) /*A trailing bit manipulations */ +XEN_CPUFEATURE(TOPOEXT, 3*32+22) /* topology extensions CPUID leafs */ +XEN_CPUFEATURE(DBEXT, 3*32+26) /*A data breakpoint extension */ +XEN_CPUFEATURE(MONITORX, 3*32+29) /* MONITOR extension (MONITORX/MWAITX) */ + +/* Intel-defined CPU features, CPUID level 0x0000000D:1.eax, word 4 */ +XEN_CPUFEATURE(XSAVEOPT, 4*32+ 0) /*A XSAVEOPT instruction */ +XEN_CPUFEATURE(XSAVEC, 4*32+ 1) /*A XSAVEC/XRSTORC instructions */ +XEN_CPUFEATURE(XGETBV1, 4*32+ 2) /*A XGETBV with %ecx=1 */ +XEN_CPUFEATURE(XSAVES, 4*32+ 3) /*S XSAVES/XRSTORS instructions */ + +/* Intel-defined CPU features, CPUID level 0x00000007:0.ebx, word 5 */ +XEN_CPUFEATURE(FSGSBASE, 5*32+ 0) /*A {RD,WR}{FS,GS}BASE instructions */ +XEN_CPUFEATURE(TSC_ADJUST, 5*32+ 1) /*S TSC_ADJUST MSR available */ +XEN_CPUFEATURE(SGX, 5*32+ 2) /* Software Guard extensions */ +XEN_CPUFEATURE(BMI1, 5*32+ 3) /*A 1st bit manipulation extensions */ +XEN_CPUFEATURE(HLE, 5*32+ 4) /*A Hardware Lock Elision */ +XEN_CPUFEATURE(AVX2, 5*32+ 5) /*A AVX2 instructions */ +XEN_CPUFEATURE(FDP_EXCP_ONLY, 5*32+ 6) /*! x87 FDP only updated on exception. */ +XEN_CPUFEATURE(SMEP, 5*32+ 7) /*S Supervisor Mode Execution Protection */ +XEN_CPUFEATURE(BMI2, 5*32+ 8) /*A 2nd bit manipulation extensions */ +XEN_CPUFEATURE(ERMS, 5*32+ 9) /*A Enhanced REP MOVSB/STOSB */ +XEN_CPUFEATURE(INVPCID, 5*32+10) /*H Invalidate Process Context ID */ +XEN_CPUFEATURE(RTM, 5*32+11) /*A Restricted Transactional Memory */ +XEN_CPUFEATURE(PQM, 5*32+12) /* Platform QoS Monitoring */ +XEN_CPUFEATURE(NO_FPU_SEL, 5*32+13) /*! FPU CS/DS stored as zero */ +XEN_CPUFEATURE(MPX, 5*32+14) /*S Memory Protection Extensions */ +XEN_CPUFEATURE(PQE, 5*32+15) /* Platform QoS Enforcement */ +XEN_CPUFEATURE(AVX512F, 5*32+16) /*A AVX-512 Foundation Instructions */ +XEN_CPUFEATURE(AVX512DQ, 5*32+17) /*A AVX-512 Doubleword & Quadword Instrs */ +XEN_CPUFEATURE(RDSEED, 5*32+18) /*A RDSEED instruction */ +XEN_CPUFEATURE(ADX, 5*32+19) /*A ADCX, ADOX instructions */ +XEN_CPUFEATURE(SMAP, 5*32+20) /*S Supervisor Mode Access Prevention */ +XEN_CPUFEATURE(AVX512IFMA, 5*32+21) /*A AVX-512 Integer Fused Multiply Add */ +XEN_CPUFEATURE(CLFLUSHOPT, 5*32+23) /*A CLFLUSHOPT instruction */ +XEN_CPUFEATURE(CLWB, 5*32+24) /*A CLWB instruction */ +XEN_CPUFEATURE(AVX512PF, 5*32+26) /*A AVX-512 Prefetch Instructions */ +XEN_CPUFEATURE(AVX512ER, 5*32+27) /*A AVX-512 Exponent & Reciprocal Instrs */ +XEN_CPUFEATURE(AVX512CD, 5*32+28) /*A AVX-512 Conflict Detection Instrs */ +XEN_CPUFEATURE(SHA, 5*32+29) /*A SHA1 & SHA256 instructions */ +XEN_CPUFEATURE(AVX512BW, 5*32+30) /*A AVX-512 Byte and Word Instructions */ +XEN_CPUFEATURE(AVX512VL, 5*32+31) /*A AVX-512 Vector Length Extensions */ + +/* Intel-defined CPU features, CPUID level 0x00000007:0.ecx, word 6 */ +XEN_CPUFEATURE(PREFETCHWT1, 6*32+ 0) /*A PREFETCHWT1 instruction */ +XEN_CPUFEATURE(AVX512VBMI, 6*32+ 1) /*A AVX-512 Vector Byte Manipulation Instrs */ +XEN_CPUFEATURE(UMIP, 6*32+ 2) /*S User Mode Instruction Prevention */ +XEN_CPUFEATURE(PKU, 6*32+ 3) /*H Protection Keys for Userspace */ +XEN_CPUFEATURE(OSPKE, 6*32+ 4) /*! OS Protection Keys Enable */ +XEN_CPUFEATURE(AVX512_VPOPCNTDQ, 6*32+14) /*A POPCNT for vectors of DW/QW */ +XEN_CPUFEATURE(RDPID, 6*32+22) /*A RDPID instruction */ + +/* AMD-defined CPU features, CPUID level 0x80000007.edx, word 7 */ +XEN_CPUFEATURE(ITSC, 7*32+ 8) /* Invariant TSC */ +XEN_CPUFEATURE(EFRO, 7*32+10) /* APERF/MPERF Read Only interface */ + +/* AMD-defined CPU features, CPUID level 0x80000008.ebx, word 8 */ +XEN_CPUFEATURE(CLZERO, 8*32+ 0) /*A CLZERO instruction */ + +/* Intel-defined CPU features, CPUID level 0x00000007:0.edx, word 9 */ +XEN_CPUFEATURE(AVX512_4VNNIW, 9*32+ 2) /*A AVX512 Neural Network Instructions */ +XEN_CPUFEATURE(AVX512_4FMAPS, 9*32+ 3) /*A AVX512 Multiply Accumulation Single Precision */ + +#endif /* XEN_CPUFEATURE */ + +/* Clean up from a default include. Close the enum (for C). */ +#ifdef XEN_CPUFEATURESET_DEFAULT_INCLUDE +#undef XEN_CPUFEATURESET_DEFAULT_INCLUDE +#undef XEN_CPUFEATURE +}; + +#endif /* XEN_CPUFEATURESET_DEFAULT_INCLUDE */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/xen/arch-x86/cpuid.h b/include/xen/arch-x86/cpuid.h index d709340..eb76875 100644 --- a/include/xen/arch-x86/cpuid.h +++ b/include/xen/arch-x86/cpuid.h @@ -73,11 +73,27 @@ #define _XEN_CPUID_FEAT1_MMU_PT_UPDATE_PRESERVE_AD 0 #define XEN_CPUID_FEAT1_MMU_PT_UPDATE_PRESERVE_AD (1u<<0) +/* + * Leaf 4 (0x40000x03) + * Sub-leaf 0: EAX: bit 0: emulated tsc + * bit 1: host tsc is known to be reliable + * bit 2: RDTSCP instruction available + * EBX: tsc_mode: 0=default (emulate if necessary), 1=emulate, + * 2=no emulation, 3=no emulation + TSC_AUX support + * ECX: guest tsc frequency in kHz + * EDX: guest tsc incarnation (migration count) + * Sub-leaf 1: EAX: tsc offset low part + * EBX: tsc offset high part + * ECX: multiplicator for tsc->ns conversion + * EDX: shift amount for tsc->ns conversion + * Sub-leaf 2: EAX: host tsc frequency in kHz + */ + /* * Leaf 5 (0x40000x04) * HVM-specific features - * EAX: Features - * EBX: vcpu id (iff EAX has XEN_HVM_CPUID_VCPU_ID_PRESENT flag) + * Sub-leaf 0: EAX: Features + * Sub-leaf 0: EBX: vcpu id (iff EAX has XEN_HVM_CPUID_VCPU_ID_PRESENT flag) */ #define XEN_HVM_CPUID_APIC_ACCESS_VIRT (1u << 0) /* Virtualized APIC registers */ #define XEN_HVM_CPUID_X2APIC_VIRT (1u << 1) /* Virtualized x2APIC accesses */ @@ -85,6 +101,16 @@ #define XEN_HVM_CPUID_IOMMU_MAPPINGS (1u << 2) #define XEN_HVM_CPUID_VCPU_ID_PRESENT (1u << 3) /* vcpu id is present in EBX */ -#define XEN_CPUID_MAX_NUM_LEAVES 4 +/* + * Leaf 6 (0x40000x05) + * PV-specific parameters + * Sub-leaf 0: EAX: max available sub-leaf + * Sub-leaf 0: EBX: bits 0-7: max machine address width + */ + +/* Max. address width in bits taking memory hotplug into account. */ +#define XEN_CPUID_MACHINE_ADDRESS_WIDTH_MASK (0xffu << 0) + +#define XEN_CPUID_MAX_NUM_LEAVES 5 #endif /* __XEN_PUBLIC_ARCH_X86_CPUID_H__ */ diff --git a/include/xen/arch-x86/hvm/save.h b/include/xen/arch-x86/hvm/save.h index efb0b62..fd7bf3f 100644 --- a/include/xen/arch-x86/hvm/save.h +++ b/include/xen/arch-x86/hvm/save.h @@ -47,7 +47,9 @@ DECLARE_HVM_SAVE_TYPE(HEADER, 1, struct hvm_save_header); /* * Processor * - * Compat: Pre-3.4 didn't have msr_tsc_aux + * Compat: + * - Pre-3.4 didn't have msr_tsc_aux + * - Pre-4.7 didn't have fpu_initialised */ struct hvm_hw_cpu { @@ -133,7 +135,7 @@ struct hvm_hw_cpu { uint64_t shadow_gs; /* msr content saved/restored. */ - uint64_t msr_flags; + uint64_t msr_flags; /* Obsolete, ignored. */ uint64_t msr_lstar; uint64_t msr_star; uint64_t msr_cstar; @@ -157,6 +159,11 @@ struct hvm_hw_cpu { }; /* error code for pending event */ uint32_t error_code; + +#define _XEN_X86_FPU_INITIALISED 0 +#define XEN_X86_FPU_INITIALISED (1U<<_XEN_X86_FPU_INITIALISED) + uint32_t flags; + uint32_t pad0; }; struct hvm_hw_cpu_compat { @@ -242,7 +249,7 @@ struct hvm_hw_cpu_compat { uint64_t shadow_gs; /* msr content saved/restored. */ - uint64_t msr_flags; + uint64_t msr_flags; /* Obsolete, ignored. */ uint64_t msr_lstar; uint64_t msr_star; uint64_t msr_cstar; @@ -268,19 +275,26 @@ struct hvm_hw_cpu_compat { uint32_t error_code; }; -static inline int _hvm_hw_fix_cpu(void *h) { +static inline int _hvm_hw_fix_cpu(void *h, uint32_t size) { union hvm_hw_cpu_union { struct hvm_hw_cpu nat; struct hvm_hw_cpu_compat cmp; } *ucpu = (union hvm_hw_cpu_union *)h; - /* If we copy from the end backwards, we should - * be able to do the modification in-place */ - ucpu->nat.error_code = ucpu->cmp.error_code; - ucpu->nat.pending_event = ucpu->cmp.pending_event; - ucpu->nat.tsc = ucpu->cmp.tsc; - ucpu->nat.msr_tsc_aux = 0; + if ( size == sizeof(struct hvm_hw_cpu_compat) ) + { + /* + * If we copy from the end backwards, we should + * be able to do the modification in-place. + */ + ucpu->nat.error_code = ucpu->cmp.error_code; + ucpu->nat.pending_event = ucpu->cmp.pending_event; + ucpu->nat.tsc = ucpu->cmp.tsc; + ucpu->nat.msr_tsc_aux = 0; + } + /* Mimic the old behaviour by unconditionally setting fpu_initialised. */ + ucpu->nat.flags = XEN_X86_FPU_INITIALISED; return 0; } @@ -347,30 +361,41 @@ DECLARE_HVM_SAVE_TYPE(PIC, 3, struct hvm_hw_vpic); * IO-APIC */ +union vioapic_redir_entry +{ + uint64_t bits; + struct { + uint8_t vector; + uint8_t delivery_mode:3; + uint8_t dest_mode:1; + uint8_t delivery_status:1; + uint8_t polarity:1; + uint8_t remote_irr:1; + uint8_t trig_mode:1; + uint8_t mask:1; + uint8_t reserve:7; + uint8_t reserved[4]; + uint8_t dest_id; + } fields; +}; + #define VIOAPIC_NUM_PINS 48 /* 16 ISA IRQs, 32 non-legacy PCI IRQS. */ -struct hvm_hw_vioapic { - uint64_t base_address; - uint32_t ioregsel; - uint32_t id; - union vioapic_redir_entry - { - uint64_t bits; - struct { - uint8_t vector; - uint8_t delivery_mode:3; - uint8_t dest_mode:1; - uint8_t delivery_status:1; - uint8_t polarity:1; - uint8_t remote_irr:1; - uint8_t trig_mode:1; - uint8_t mask:1; - uint8_t reserve:7; - uint8_t reserved[4]; - uint8_t dest_id; - } fields; - } redirtbl[VIOAPIC_NUM_PINS]; -}; +#define XEN_HVM_VIOAPIC(name, cnt) \ + struct name { \ + uint64_t base_address; \ + uint32_t ioregsel; \ + uint32_t id; \ + union vioapic_redir_entry redirtbl[cnt]; \ + } + +XEN_HVM_VIOAPIC(hvm_hw_vioapic, VIOAPIC_NUM_PINS); + +#ifndef __XEN__ +#undef XEN_HVM_VIOAPIC +#else +#undef VIOAPIC_NUM_PINS +#endif DECLARE_HVM_SAVE_TYPE(IOAPIC, 4, struct hvm_hw_vioapic); @@ -550,12 +575,11 @@ struct hvm_hw_cpu_xsave { struct { struct { char x[512]; } fpu_sse; - struct { + struct hvm_hw_cpu_xsave_hdr { uint64_t xstate_bv; /* Updated by XRSTOR */ - uint64_t reserved[7]; + uint64_t xcomp_bv; /* Updated by XRSTOR{C,S} */ + uint64_t reserved[6]; } xsave_hdr; /* The 64-byte header */ - - struct { char x[0]; } ymm; /* YMM */ } save_area; }; @@ -575,7 +599,9 @@ struct hvm_viridian_domain_context { DECLARE_HVM_SAVE_TYPE(VIRIDIAN_DOMAIN, 15, struct hvm_viridian_domain_context); struct hvm_viridian_vcpu_context { - uint64_t apic_assist; + uint64_t vp_assist_msr; + uint8_t vp_assist_vector; + uint8_t _pad[7]; }; DECLARE_HVM_SAVE_TYPE(VIRIDIAN_VCPU, 17, struct hvm_viridian_vcpu_context); @@ -584,6 +610,7 @@ struct hvm_vmce_vcpu { uint64_t caps; uint64_t mci_ctl2_bank0; uint64_t mci_ctl2_bank1; + uint64_t mcg_ext_ctl; }; DECLARE_HVM_SAVE_TYPE(VMCE_VCPU, 18, struct hvm_vmce_vcpu); diff --git a/include/xen/arch-x86/pmu.h b/include/xen/arch-x86/pmu.h new file mode 100644 index 0000000..68ebf12 --- /dev/null +++ b/include/xen/arch-x86/pmu.h @@ -0,0 +1,167 @@ +/* + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. + */ + +#ifndef __XEN_PUBLIC_ARCH_X86_PMU_H__ +#define __XEN_PUBLIC_ARCH_X86_PMU_H__ + +/* x86-specific PMU definitions */ + +/* AMD PMU registers and structures */ +struct xen_pmu_amd_ctxt { + /* + * Offsets to counter and control MSRs (relative to xen_pmu_arch.c.amd). + * For PV(H) guests these fields are RO. + */ + uint32_t counters; + uint32_t ctrls; + + /* Counter MSRs */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + uint64_t regs[]; +#elif defined(__GNUC__) + uint64_t regs[0]; +#endif +}; +typedef struct xen_pmu_amd_ctxt xen_pmu_amd_ctxt_t; +DEFINE_XEN_GUEST_HANDLE(xen_pmu_amd_ctxt_t); + +/* Intel PMU registers and structures */ +struct xen_pmu_cntr_pair { + uint64_t counter; + uint64_t control; +}; +typedef struct xen_pmu_cntr_pair xen_pmu_cntr_pair_t; +DEFINE_XEN_GUEST_HANDLE(xen_pmu_cntr_pair_t); + +struct xen_pmu_intel_ctxt { + /* + * Offsets to fixed and architectural counter MSRs (relative to + * xen_pmu_arch.c.intel). + * For PV(H) guests these fields are RO. + */ + uint32_t fixed_counters; + uint32_t arch_counters; + + /* PMU registers */ + uint64_t global_ctrl; + uint64_t global_ovf_ctrl; + uint64_t global_status; + uint64_t fixed_ctrl; + uint64_t ds_area; + uint64_t pebs_enable; + uint64_t debugctl; + + /* Fixed and architectural counter MSRs */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + uint64_t regs[]; +#elif defined(__GNUC__) + uint64_t regs[0]; +#endif +}; +typedef struct xen_pmu_intel_ctxt xen_pmu_intel_ctxt_t; +DEFINE_XEN_GUEST_HANDLE(xen_pmu_intel_ctxt_t); + +/* Sampled domain's registers */ +struct xen_pmu_regs { + uint64_t ip; + uint64_t sp; + uint64_t flags; + uint16_t cs; + uint16_t ss; + uint8_t cpl; + uint8_t pad[3]; +}; +typedef struct xen_pmu_regs xen_pmu_regs_t; +DEFINE_XEN_GUEST_HANDLE(xen_pmu_regs_t); + +/* PMU flags */ +#define PMU_CACHED (1<<0) /* PMU MSRs are cached in the context */ +#define PMU_SAMPLE_USER (1<<1) /* Sample is from user or kernel mode */ +#define PMU_SAMPLE_REAL (1<<2) /* Sample is from realmode */ +#define PMU_SAMPLE_PV (1<<3) /* Sample from a PV guest */ + +/* + * Architecture-specific information describing state of the processor at + * the time of PMU interrupt. + * Fields of this structure marked as RW for guest should only be written by + * the guest when PMU_CACHED bit in pmu_flags is set (which is done by the + * hypervisor during PMU interrupt). Hypervisor will read updated data in + * XENPMU_flush hypercall and clear PMU_CACHED bit. + */ +struct xen_pmu_arch { + union { + /* + * Processor's registers at the time of interrupt. + * WO for hypervisor, RO for guests. + */ + struct xen_pmu_regs regs; + /* Padding for adding new registers to xen_pmu_regs in the future */ +#define XENPMU_REGS_PAD_SZ 64 + uint8_t pad[XENPMU_REGS_PAD_SZ]; + } r; + + /* WO for hypervisor, RO for guest */ + uint64_t pmu_flags; + + /* + * APIC LVTPC register. + * RW for both hypervisor and guest. + * Only APIC_LVT_MASKED bit is loaded by the hypervisor into hardware + * during XENPMU_flush or XENPMU_lvtpc_set. + */ + union { + uint32_t lapic_lvtpc; + uint64_t pad; + } l; + + /* + * Vendor-specific PMU registers. + * RW for both hypervisor and guest (see exceptions above). + * Guest's updates to this field are verified and then loaded by the + * hypervisor into hardware during XENPMU_flush + */ + union { + struct xen_pmu_amd_ctxt amd; + struct xen_pmu_intel_ctxt intel; + + /* + * Padding for contexts (fixed parts only, does not include MSR banks + * that are specified by offsets) + */ +#define XENPMU_CTXT_PAD_SZ 128 + uint8_t pad[XENPMU_CTXT_PAD_SZ]; + } c; +}; +typedef struct xen_pmu_arch xen_pmu_arch_t; +DEFINE_XEN_GUEST_HANDLE(xen_pmu_arch_t); + +#endif /* __XEN_PUBLIC_ARCH_X86_PMU_H__ */ +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ + diff --git a/include/xen/arch-x86/xen-mca.h b/include/xen/arch-x86/xen-mca.h index 04382ed..dc35267 100644 --- a/include/xen/arch-x86/xen-mca.h +++ b/include/xen/arch-x86/xen-mca.h @@ -1,11 +1,11 @@ /****************************************************************************** * arch-x86/mca.h - * + * * Contributed by Advanced Micro Devices, Inc. * Author: Christoph Egger <Christoph.Egger@xxxxxxx> * * Guest OS machine check interface to x86 Xen. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the @@ -88,6 +88,8 @@ #define XEN_MC_NOTDELIVERED 0x10 /* Note, XEN_MC_CANNOTHANDLE and XEN_MC_NOTDELIVERED are mutually exclusive. */ +/* Applicable to all mc_vcpuid fields below. */ +#define XEN_MC_VCPUID_INVALID 0xffff #ifndef __ASSEMBLY__ @@ -156,7 +158,7 @@ struct mcinfo_msr { }; /* contains mc information from other - * or additional mc MSRs */ + * or additional mc MSRs */ struct mcinfo_extended { struct mcinfo_common common; @@ -193,10 +195,10 @@ struct mcinfo_extended { /* L3 cache disable Action */ #define MC_ACTION_CACHE_SHRINK (0x1 << 2) -/* Below interface used between XEN/DOM0 for passing XEN's recovery action - * information to DOM0. +/* Below interface used between XEN/DOM0 for passing XEN's recovery action + * information to DOM0. * usage Senario: After offlining broken page, XEN might pass its page offline - * recovery action result to DOM0. DOM0 will save the information in + * recovery action result to DOM0. DOM0 will save the information in * non-volatile memory for further proactive actions, such as offlining the * easy broken page earlier when doing next reboot. */ @@ -255,8 +257,8 @@ DEFINE_XEN_GUEST_HANDLE(mc_info_t); #define MC_CAPS_AMD_ECX 6 /* cpuid level 0x80000001 (%ecx) */ struct mcinfo_logical_cpu { - uint32_t mc_cpunr; - uint32_t mc_chipid; + uint32_t mc_cpunr; + uint32_t mc_chipid; uint16_t mc_coreid; uint16_t mc_threadid; uint32_t mc_apicid; @@ -281,7 +283,7 @@ typedef struct mcinfo_logical_cpu xen_mc_logical_cpu_t; DEFINE_XEN_GUEST_HANDLE(xen_mc_logical_cpu_t); -/* +/* * OS's should use these instead of writing their own lookup function * each with its own bugs and drawbacks. * We use macros instead of static inline functions to allow guests @@ -312,8 +314,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_mc_logical_cpu_t); struct mcinfo_common *_mic; \ \ found = 0; \ - (_ret) = NULL; \ - if (_mi == NULL) break; \ + (_ret) = NULL; \ + if (_mi == NULL) break; \ _mic = x86_mcinfo_first(_mi); \ for (i = 0; i < x86_mcinfo_nentries(_mi); i++) { \ if (_mic->type == (_type)) { \ @@ -345,8 +347,8 @@ struct xen_mc_fetch { /* IN/OUT variables. */ uint32_t flags; /* IN: XEN_MC_NONURGENT, XEN_MC_URGENT, XEN_MC_ACK if ack'ing an earlier fetch */ - /* OUT: XEN_MC_OK, XEN_MC_FETCHFAILED, - XEN_MC_NODATA, XEN_MC_NOMATCH */ + /* OUT: XEN_MC_OK, XEN_MC_FETCHFAILED, + XEN_MC_NODATA, XEN_MC_NOMATCH */ uint32_t _pad0; uint64_t fetch_id; /* OUT: id for ack, IN: id we are ack'ing */ @@ -378,30 +380,33 @@ DEFINE_XEN_GUEST_HANDLE(xen_mc_notifydomain_t); #define XEN_MC_physcpuinfo 3 struct xen_mc_physcpuinfo { - /* IN/OUT */ - uint32_t ncpus; - uint32_t _pad0; - /* OUT */ - XEN_GUEST_HANDLE(xen_mc_logical_cpu_t) info; + /* IN/OUT */ + uint32_t ncpus; + uint32_t _pad0; + /* OUT */ + XEN_GUEST_HANDLE(xen_mc_logical_cpu_t) info; }; #define XEN_MC_msrinject 4 #define MC_MSRINJ_MAXMSRS 8 struct xen_mc_msrinject { - /* IN */ - uint32_t mcinj_cpunr; /* target processor id */ - uint32_t mcinj_flags; /* see MC_MSRINJ_F_* below */ - uint32_t mcinj_count; /* 0 .. count-1 in array are valid */ - uint32_t _pad0; - struct mcinfo_msr mcinj_msr[MC_MSRINJ_MAXMSRS]; + /* IN */ + uint32_t mcinj_cpunr; /* target processor id */ + uint32_t mcinj_flags; /* see MC_MSRINJ_F_* below */ + uint32_t mcinj_count; /* 0 .. count-1 in array are valid */ + domid_t mcinj_domid; /* valid only if MC_MSRINJ_F_GPADDR is + present in mcinj_flags */ + uint16_t _pad0; + struct mcinfo_msr mcinj_msr[MC_MSRINJ_MAXMSRS]; }; /* Flags for mcinj_flags above; bits 16-31 are reserved */ #define MC_MSRINJ_F_INTERPOSE 0x1 +#define MC_MSRINJ_F_GPADDR 0x2 #define XEN_MC_mceinject 5 struct xen_mc_mceinject { - unsigned int mceinj_cpunr; /* target processor id */ + unsigned int mceinj_cpunr; /* target processor id */ }; #if defined(__XEN__) || defined(__XEN_TOOLS__) @@ -409,12 +414,13 @@ struct xen_mc_mceinject { #define XEN_MC_INJECT_TYPE_MASK 0x7 #define XEN_MC_INJECT_TYPE_MCE 0x0 #define XEN_MC_INJECT_TYPE_CMCI 0x1 +#define XEN_MC_INJECT_TYPE_LMCE 0x2 #define XEN_MC_INJECT_CPU_BROADCAST 0x8 struct xen_mc_inject_v2 { - uint32_t flags; - struct xenctl_bitmap cpumap; + uint32_t flags; + struct xenctl_bitmap cpumap; }; #endif diff --git a/include/xen/arch-x86/xen-x86_32.h b/include/xen/arch-x86/xen-x86_32.h index 6339727..aa388b7 100644 --- a/include/xen/arch-x86/xen-x86_32.h +++ b/include/xen/arch-x86/xen-x86_32.h @@ -55,43 +55,38 @@ #define FLAT_USER_DS FLAT_RING3_DS #define FLAT_USER_SS FLAT_RING3_SS -#ifdef CONFIG_PARAVIRT #define __HYPERVISOR_VIRT_START_PAE 0xF5800000 #define __MACH2PHYS_VIRT_START_PAE 0xF5800000 #define __MACH2PHYS_VIRT_END_PAE 0xF6800000 -#define HYPERVISOR_VIRT_START_PAE \ - mk_unsigned_long(__HYPERVISOR_VIRT_START_PAE) -#define MACH2PHYS_VIRT_START_PAE \ - mk_unsigned_long(__MACH2PHYS_VIRT_START_PAE) -#define MACH2PHYS_VIRT_END_PAE \ - mk_unsigned_long(__MACH2PHYS_VIRT_END_PAE) +#define HYPERVISOR_VIRT_START_PAE xen_mk_ulong(__HYPERVISOR_VIRT_START_PAE) +#define MACH2PHYS_VIRT_START_PAE xen_mk_ulong(__MACH2PHYS_VIRT_START_PAE) +#define MACH2PHYS_VIRT_END_PAE xen_mk_ulong(__MACH2PHYS_VIRT_END_PAE) /* Non-PAE bounds are obsolete. */ #define __HYPERVISOR_VIRT_START_NONPAE 0xFC000000 #define __MACH2PHYS_VIRT_START_NONPAE 0xFC000000 #define __MACH2PHYS_VIRT_END_NONPAE 0xFC400000 #define HYPERVISOR_VIRT_START_NONPAE \ - mk_unsigned_long(__HYPERVISOR_VIRT_START_NONPAE) + xen_mk_ulong(__HYPERVISOR_VIRT_START_NONPAE) #define MACH2PHYS_VIRT_START_NONPAE \ - mk_unsigned_long(__MACH2PHYS_VIRT_START_NONPAE) + xen_mk_ulong(__MACH2PHYS_VIRT_START_NONPAE) #define MACH2PHYS_VIRT_END_NONPAE \ - mk_unsigned_long(__MACH2PHYS_VIRT_END_NONPAE) + xen_mk_ulong(__MACH2PHYS_VIRT_END_NONPAE) #define __HYPERVISOR_VIRT_START __HYPERVISOR_VIRT_START_PAE #define __MACH2PHYS_VIRT_START __MACH2PHYS_VIRT_START_PAE #define __MACH2PHYS_VIRT_END __MACH2PHYS_VIRT_END_PAE #ifndef HYPERVISOR_VIRT_START -#define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START) +#define HYPERVISOR_VIRT_START xen_mk_ulong(__HYPERVISOR_VIRT_START) #endif -#define MACH2PHYS_VIRT_START mk_unsigned_long(__MACH2PHYS_VIRT_START) -#define MACH2PHYS_VIRT_END mk_unsigned_long(__MACH2PHYS_VIRT_END) +#define MACH2PHYS_VIRT_START xen_mk_ulong(__MACH2PHYS_VIRT_START) +#define MACH2PHYS_VIRT_END xen_mk_ulong(__MACH2PHYS_VIRT_END) #define MACH2PHYS_NR_ENTRIES ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>2) #ifndef machine_to_phys_mapping #define machine_to_phys_mapping ((unsigned long *)MACH2PHYS_VIRT_START) #endif -#endif /* 32-/64-bit invariability for control interfaces (domctl/sysctl). */ #if defined(__XEN__) || defined(__XEN_TOOLS__) @@ -106,6 +101,7 @@ do { if ( sizeof(hnd) == 8 ) *(uint64_t *)&(hnd) = 0; \ (hnd).p = val; \ } while ( 0 ) +#define int64_aligned_t int64_t __attribute__((aligned(8))) #define uint64_aligned_t uint64_t __attribute__((aligned(8))) #define __XEN_GUEST_HANDLE_64(name) __guest_handle_64_ ## name #define XEN_GUEST_HANDLE_64(name) __XEN_GUEST_HANDLE_64(name) @@ -113,22 +109,44 @@ #ifndef __ASSEMBLY__ +#if defined(XEN_GENERATING_COMPAT_HEADERS) +/* nothing */ +#elif defined(__XEN__) || defined(__XEN_TOOLS__) +/* Anonymous unions include all permissible names (e.g., al/ah/ax/eax). */ +#define __DECL_REG_LO8(which) union { \ + uint32_t e ## which ## x; \ + uint16_t which ## x; \ + struct { \ + uint8_t which ## l; \ + uint8_t which ## h; \ + }; \ +} +#define __DECL_REG_LO16(name) union { \ + uint32_t e ## name, _e ## name; \ + uint16_t name; \ +} +#else +/* Other sources must always use the proper 32-bit name (e.g., eax). */ +#define __DECL_REG_LO8(which) uint32_t e ## which ## x +#define __DECL_REG_LO16(name) uint32_t e ## name +#endif + struct cpu_user_regs { - uint32_t ebx; - uint32_t ecx; - uint32_t edx; - uint32_t esi; - uint32_t edi; - uint32_t ebp; - uint32_t eax; + __DECL_REG_LO8(b); + __DECL_REG_LO8(c); + __DECL_REG_LO8(d); + __DECL_REG_LO16(si); + __DECL_REG_LO16(di); + __DECL_REG_LO16(bp); + __DECL_REG_LO8(a); uint16_t error_code; /* private */ uint16_t entry_vector; /* private */ - uint32_t eip; + __DECL_REG_LO16(ip); uint16_t cs; uint8_t saved_upcall_mask; uint8_t _pad0; - uint32_t eflags; /* eflags.IF == !saved_upcall_mask */ - uint32_t esp; + __DECL_REG_LO16(flags); /* eflags.IF == !saved_upcall_mask */ + __DECL_REG_LO16(sp); uint16_t ss, _pad1; uint16_t es, _pad2; uint16_t ds, _pad3; @@ -138,6 +156,9 @@ struct cpu_user_regs { typedef struct cpu_user_regs cpu_user_regs_t; DEFINE_XEN_GUEST_HANDLE(cpu_user_regs_t); +#undef __DECL_REG_LO8 +#undef __DECL_REG_LO16 + /* * Page-directory addresses above 4GB do not fit into architectural %cr3. * When accessing %cr3, or equivalent field in vcpu_guest_context, guests diff --git a/include/xen/arch-x86/xen-x86_64.h b/include/xen/arch-x86/xen-x86_64.h index 2c00111..978f8cb 100644 --- a/include/xen/arch-x86/xen-x86_64.h +++ b/include/xen/arch-x86/xen-x86_64.h @@ -70,24 +70,22 @@ #define FLAT_USER_SS32 FLAT_RING3_SS32 #define FLAT_USER_SS FLAT_USER_SS64 -#ifdef CONFIG_PARAVIRT #define __HYPERVISOR_VIRT_START 0xFFFF800000000000 #define __HYPERVISOR_VIRT_END 0xFFFF880000000000 #define __MACH2PHYS_VIRT_START 0xFFFF800000000000 #define __MACH2PHYS_VIRT_END 0xFFFF804000000000 #ifndef HYPERVISOR_VIRT_START -#define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START) -#define HYPERVISOR_VIRT_END mk_unsigned_long(__HYPERVISOR_VIRT_END) +#define HYPERVISOR_VIRT_START xen_mk_ulong(__HYPERVISOR_VIRT_START) +#define HYPERVISOR_VIRT_END xen_mk_ulong(__HYPERVISOR_VIRT_END) #endif -#define MACH2PHYS_VIRT_START mk_unsigned_long(__MACH2PHYS_VIRT_START) -#define MACH2PHYS_VIRT_END mk_unsigned_long(__MACH2PHYS_VIRT_END) +#define MACH2PHYS_VIRT_START xen_mk_ulong(__MACH2PHYS_VIRT_START) +#define MACH2PHYS_VIRT_END xen_mk_ulong(__MACH2PHYS_VIRT_END) #define MACH2PHYS_NR_ENTRIES ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>3) #ifndef machine_to_phys_mapping #define machine_to_phys_mapping ((unsigned long *)HYPERVISOR_VIRT_START) #endif -#endif /* * int HYPERVISOR_set_segment_base(unsigned int which, unsigned long base) @@ -132,7 +130,35 @@ struct iret_context { /* Bottom of iret stack frame. */ }; -#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +#if defined(__XEN__) || defined(__XEN_TOOLS__) +/* Anonymous unions include all permissible names (e.g., al/ah/ax/eax/rax). */ +#define __DECL_REG_LOHI(which) union { \ + uint64_t r ## which ## x; \ + uint32_t e ## which ## x; \ + uint16_t which ## x; \ + struct { \ + uint8_t which ## l; \ + uint8_t which ## h; \ + }; \ +} +#define __DECL_REG_LO8(name) union { \ + uint64_t r ## name; \ + uint32_t e ## name; \ + uint16_t name; \ + uint8_t name ## l; \ +} +#define __DECL_REG_LO16(name) union { \ + uint64_t r ## name; \ + uint32_t e ## name; \ + uint16_t name; \ +} +#define __DECL_REG_HI(num) union { \ + uint64_t r ## num; \ + uint32_t r ## num ## d; \ + uint16_t r ## num ## w; \ + uint8_t r ## num ## b; \ +} +#elif defined(__GNUC__) && !defined(__STRICT_ANSI__) /* Anonymous union includes both 32- and 64-bit names (e.g., eax/rax). */ #define __DECL_REG(name) union { \ uint64_t r ## name, e ## name; \ @@ -143,30 +169,37 @@ struct iret_context { #define __DECL_REG(name) uint64_t r ## name #endif +#ifndef __DECL_REG_LOHI +#define __DECL_REG_LOHI(name) __DECL_REG(name ## x) +#define __DECL_REG_LO8 __DECL_REG +#define __DECL_REG_LO16 __DECL_REG +#define __DECL_REG_HI(num) uint64_t r ## num +#endif + struct cpu_user_regs { - uint64_t r15; - uint64_t r14; - uint64_t r13; - uint64_t r12; - __DECL_REG(bp); - __DECL_REG(bx); - uint64_t r11; - uint64_t r10; - uint64_t r9; - uint64_t r8; - __DECL_REG(ax); - __DECL_REG(cx); - __DECL_REG(dx); - __DECL_REG(si); - __DECL_REG(di); + __DECL_REG_HI(15); + __DECL_REG_HI(14); + __DECL_REG_HI(13); + __DECL_REG_HI(12); + __DECL_REG_LO8(bp); + __DECL_REG_LOHI(b); + __DECL_REG_HI(11); + __DECL_REG_HI(10); + __DECL_REG_HI(9); + __DECL_REG_HI(8); + __DECL_REG_LOHI(a); + __DECL_REG_LOHI(c); + __DECL_REG_LOHI(d); + __DECL_REG_LO8(si); + __DECL_REG_LO8(di); uint32_t error_code; /* private */ uint32_t entry_vector; /* private */ - __DECL_REG(ip); + __DECL_REG_LO16(ip); uint16_t cs, _pad0[1]; uint8_t saved_upcall_mask; uint8_t _pad1[3]; - __DECL_REG(flags); /* rflags.IF == !saved_upcall_mask */ - __DECL_REG(sp); + __DECL_REG_LO16(flags); /* rflags.IF == !saved_upcall_mask */ + __DECL_REG_LO8(sp); uint16_t ss, _pad2[3]; uint16_t es, _pad3[3]; uint16_t ds, _pad4[3]; @@ -177,6 +210,10 @@ typedef struct cpu_user_regs cpu_user_regs_t; DEFINE_XEN_GUEST_HANDLE(cpu_user_regs_t); #undef __DECL_REG +#undef __DECL_REG_LOHI +#undef __DECL_REG_LO8 +#undef __DECL_REG_LO16 +#undef __DECL_REG_HI #define xen_pfn_to_cr3(pfn) ((unsigned long)(pfn) << 12) #define xen_cr3_to_pfn(cr3) ((unsigned long)(cr3) >> 12) diff --git a/include/xen/arch-x86/xen.h b/include/xen/arch-x86/xen.h index c5e880b..ff91831 100644 --- a/include/xen/arch-x86/xen.h +++ b/include/xen/arch-x86/xen.h @@ -54,13 +54,20 @@ #define XEN_GUEST_HANDLE(name) __XEN_GUEST_HANDLE(name) #define XEN_GUEST_HANDLE_PARAM(name) XEN_GUEST_HANDLE(name) #define set_xen_guest_handle_raw(hnd, val) do { (hnd).p = val; } while (0) -#ifdef __XEN_TOOLS__ -#define get_xen_guest_handle(val, hnd) do { val = (hnd).p; } while (0) -#endif #define set_xen_guest_handle(hnd, val) set_xen_guest_handle_raw(hnd, val) #if defined(__i386__) +# ifdef __XEN__ +__DeFiNe__ __DECL_REG_LO8(which) uint32_t e ## which ## x +__DeFiNe__ __DECL_REG_LO16(name) union { uint32_t e ## name; } +# endif #include "xen-x86_32.h" +# ifdef __XEN__ +__UnDeF__ __DECL_REG_LO8 +__UnDeF__ __DECL_REG_LO16 +__DeFiNe__ __DECL_REG_LO8(which) e ## which ## x +__DeFiNe__ __DECL_REG_LO16(name) e ## name +# endif #elif defined(__x86_64__) #include "xen-x86_64.h" #endif @@ -152,17 +159,15 @@ DEFINE_XEN_GUEST_HANDLE(trap_info_t); typedef uint64_t tsc_timestamp_t; /* RDTSC timestamp */ /* - * The following is all CPU context. Note that the fpu_ctxt block is filled + * The following is all CPU context. Note that the fpu_ctxt block is filled * in by FXSAVE if the CPU has feature FXSR; otherwise FSAVE is used. * - * Also note that when calling DOMCTL_setvcpucontext and VCPU_initialise - * for HVM and PVH guests, not all information in this structure is updated: - * - * - For HVM guests, the structures read include: fpu_ctxt (if - * VGCT_I387_VALID is set), flags, user_regs, debugreg[*] + * Also note that when calling DOMCTL_setvcpucontext for HVM guests, not all + * information in this structure is updated, the fields read include: fpu_ctxt + * (if VGCT_I387_VALID is set), flags, user_regs and debugreg[*]. * - * - PVH guests are the same as HVM guests, but additionally use ctrlreg[3] to - * set cr3. All other fields not used should be set to 0. + * Note: VCPUOP_initialise for HVM guests is non-symetric with + * DOMCTL_setvcpucontext, and uses struct vcpu_hvm_context from hvm/hvm_vcpu.h */ struct vcpu_guest_context { /* FPU registers come first so they can be aligned for FXSAVE/FXRSTOR. */ @@ -255,9 +260,56 @@ struct arch_shared_info { unsigned long p2m_cr3; /* cr3 value of the p2m address space */ unsigned long p2m_vaddr; /* virtual address of the p2m list */ unsigned long p2m_generation; /* generation count of p2m mapping */ +#ifdef __i386__ + /* There's no room for this field in the generic structure. */ + uint32_t wc_sec_hi; +#endif }; typedef struct arch_shared_info arch_shared_info_t; +#if defined(__XEN__) || defined(__XEN_TOOLS__) +/* + * struct xen_arch_domainconfig's ABI is covered by + * XEN_DOMCTL_INTERFACE_VERSION. + */ +struct xen_arch_domainconfig { +#define _XEN_X86_EMU_LAPIC 0 +#define XEN_X86_EMU_LAPIC (1U<<_XEN_X86_EMU_LAPIC) +#define _XEN_X86_EMU_HPET 1 +#define XEN_X86_EMU_HPET (1U<<_XEN_X86_EMU_HPET) +#define _XEN_X86_EMU_PM 2 +#define XEN_X86_EMU_PM (1U<<_XEN_X86_EMU_PM) +#define _XEN_X86_EMU_RTC 3 +#define XEN_X86_EMU_RTC (1U<<_XEN_X86_EMU_RTC) +#define _XEN_X86_EMU_IOAPIC 4 +#define XEN_X86_EMU_IOAPIC (1U<<_XEN_X86_EMU_IOAPIC) +#define _XEN_X86_EMU_PIC 5 +#define XEN_X86_EMU_PIC (1U<<_XEN_X86_EMU_PIC) +#define _XEN_X86_EMU_VGA 6 +#define XEN_X86_EMU_VGA (1U<<_XEN_X86_EMU_VGA) +#define _XEN_X86_EMU_IOMMU 7 +#define XEN_X86_EMU_IOMMU (1U<<_XEN_X86_EMU_IOMMU) +#define _XEN_X86_EMU_PIT 8 +#define XEN_X86_EMU_PIT (1U<<_XEN_X86_EMU_PIT) +#define _XEN_X86_EMU_USE_PIRQ 9 +#define XEN_X86_EMU_USE_PIRQ (1U<<_XEN_X86_EMU_USE_PIRQ) + +#define XEN_X86_EMU_ALL (XEN_X86_EMU_LAPIC | XEN_X86_EMU_HPET | \ + XEN_X86_EMU_PM | XEN_X86_EMU_RTC | \ + XEN_X86_EMU_IOAPIC | XEN_X86_EMU_PIC | \ + XEN_X86_EMU_VGA | XEN_X86_EMU_IOMMU | \ + XEN_X86_EMU_PIT | XEN_X86_EMU_USE_PIRQ) + uint32_t emulation_flags; +}; + +/* Location of online VCPU bitmap. */ +#define XEN_ACPI_CPU_MAP 0xaf00 +#define XEN_ACPI_CPU_MAP_LEN ((HVM_MAX_VCPUS + 7) / 8) + +/* GPE0 bit set during CPU hotplug */ +#define XEN_ACPI_GPE0_CPUHP_BIT 2 +#endif + #endif /* !__ASSEMBLY__ */ /* diff --git a/include/xen/domctl.h b/include/xen/domctl.h index 57e2ed7..8853445 100644 --- a/include/xen/domctl.h +++ b/include/xen/domctl.h @@ -33,11 +33,12 @@ #endif #include "xen.h" +#include "event_channel.h" #include "grant_table.h" #include "hvm/save.h" #include "memory.h" -#define XEN_DOMCTL_INTERFACE_VERSION 0x0000000a +#define XEN_DOMCTL_INTERFACE_VERSION 0x0000000e /* * NB. xen_domctl.domain is an IN/OUT parameter for this operation. @@ -60,26 +61,12 @@ struct xen_domctl_createdomain { /* Disable out-of-sync shadow page tables? */ #define _XEN_DOMCTL_CDF_oos_off 3 #define XEN_DOMCTL_CDF_oos_off (1U<<_XEN_DOMCTL_CDF_oos_off) - /* Is this a PVH guest (as opposed to an HVM or PV guest)? */ -#define _XEN_DOMCTL_CDF_pvh_guest 4 -#define XEN_DOMCTL_CDF_pvh_guest (1U<<_XEN_DOMCTL_CDF_pvh_guest) + /* Is this a xenstore domain? */ +#define _XEN_DOMCTL_CDF_xs_domain 4 +#define XEN_DOMCTL_CDF_xs_domain (1U<<_XEN_DOMCTL_CDF_xs_domain) uint32_t flags; + struct xen_arch_domainconfig config; }; -typedef struct xen_domctl_createdomain xen_domctl_createdomain_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_createdomain_t); - -#if defined(__arm__) || defined(__aarch64__) -#define XEN_DOMCTL_CONFIG_GIC_DEFAULT 0 -#define XEN_DOMCTL_CONFIG_GIC_V2 1 -#define XEN_DOMCTL_CONFIG_GIC_V3 2 -/* XEN_DOMCTL_configure_domain */ -struct xen_domctl_arm_configuredomain { - /* IN/OUT parameters */ - uint8_t gic_version; -}; -typedef struct xen_domctl_arm_configuredomain xen_domctl_arm_configuredomain_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_arm_configuredomain_t); -#endif /* XEN_DOMCTL_getdomaininfo */ struct xen_domctl_getdomaininfo { @@ -106,9 +93,12 @@ struct xen_domctl_getdomaininfo { /* Being debugged. */ #define _XEN_DOMINF_debugged 6 #define XEN_DOMINF_debugged (1U<<_XEN_DOMINF_debugged) -/* domain is PVH */ -#define _XEN_DOMINF_pvh_guest 7 -#define XEN_DOMINF_pvh_guest (1U<<_XEN_DOMINF_pvh_guest) +/* domain is a xenstore domain */ +#define _XEN_DOMINF_xs_domain 7 +#define XEN_DOMINF_xs_domain (1U<<_XEN_DOMINF_xs_domain) +/* domain has hardware assisted paging */ +#define _XEN_DOMINF_hap 8 +#define XEN_DOMINF_hap (1U<<_XEN_DOMINF_hap) /* XEN_DOMINF_shutdown guest-supplied code. */ #define XEN_DOMINF_shutdownmask 255 #define XEN_DOMINF_shutdownshift 16 @@ -142,8 +132,6 @@ struct xen_domctl_getmemlist { /* OUT variables. */ uint64_aligned_t num_pfns; }; -typedef struct xen_domctl_getmemlist xen_domctl_getmemlist_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_getmemlist_t); /* XEN_DOMCTL_getpageframeinfo */ @@ -161,27 +149,6 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_getmemlist_t); #define XEN_DOMCTL_PFINFO_BROKEN (0xdU<<28) /* broken page */ #define XEN_DOMCTL_PFINFO_LTAB_MASK (0xfU<<28) -struct xen_domctl_getpageframeinfo { - /* IN variables. */ - uint64_aligned_t gmfn; /* GMFN to query */ - /* OUT variables. */ - /* Is the page PINNED to a type? */ - uint32_t type; /* see above type defs */ -}; -typedef struct xen_domctl_getpageframeinfo xen_domctl_getpageframeinfo_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_getpageframeinfo_t); - - -/* XEN_DOMCTL_getpageframeinfo2 */ -struct xen_domctl_getpageframeinfo2 { - /* IN variables. */ - uint64_aligned_t num; - /* IN/OUT variables. */ - XEN_GUEST_HANDLE_64(uint32) array; -}; -typedef struct xen_domctl_getpageframeinfo2 xen_domctl_getpageframeinfo2_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_getpageframeinfo2_t); - /* XEN_DOMCTL_getpageframeinfo3 */ struct xen_domctl_getpageframeinfo3 { /* IN variables. */ @@ -217,8 +184,11 @@ struct xen_domctl_getpageframeinfo3 { #define XEN_DOMCTL_SHADOW_OP_ENABLE_TEST 1 /* Equiv. to ENABLE with mode flag ENABLE_LOG_DIRTY. */ #define XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY 2 - /* Equiv. to ENABLE with mode flags ENABLE_REFCOUNT and ENABLE_TRANSLATE. */ + /* + * No longer supported, was equiv. to ENABLE with mode flags + * ENABLE_REFCOUNT and ENABLE_TRANSLATE: #define XEN_DOMCTL_SHADOW_OP_ENABLE_TRANSLATE 3 + */ /* Mode flags for XEN_DOMCTL_SHADOW_OP_ENABLE. */ /* @@ -241,19 +211,25 @@ struct xen_domctl_getpageframeinfo3 { */ #define XEN_DOMCTL_SHADOW_ENABLE_EXTERNAL (1 << 4) +/* Mode flags for XEN_DOMCTL_SHADOW_OP_{CLEAN,PEEK}. */ + /* + * This is the final iteration: Requesting to include pages mapped + * writably by the hypervisor in the dirty bitmap. + */ +#define XEN_DOMCTL_SHADOW_LOGDIRTY_FINAL (1 << 0) + struct xen_domctl_shadow_op_stats { uint32_t fault_count; uint32_t dirty_count; }; -typedef struct xen_domctl_shadow_op_stats xen_domctl_shadow_op_stats_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_shadow_op_stats_t); struct xen_domctl_shadow_op { /* IN variables. */ uint32_t op; /* XEN_DOMCTL_SHADOW_OP_* */ - /* OP_ENABLE */ - uint32_t mode; /* XEN_DOMCTL_SHADOW_ENABLE_* */ + /* OP_ENABLE: XEN_DOMCTL_SHADOW_ENABLE_* */ + /* OP_PEAK / OP_CLEAN: XEN_DOMCTL_SHADOW_LOGDIRTY_* */ + uint32_t mode; /* OP_GET_ALLOCATION / OP_SET_ALLOCATION */ uint32_t mb; /* Shadow memory allocation in MB */ @@ -263,8 +239,6 @@ struct xen_domctl_shadow_op { uint64_aligned_t pages; /* Size of buffer. Updated with actual size. */ struct xen_domctl_shadow_op_stats stats; }; -typedef struct xen_domctl_shadow_op xen_domctl_shadow_op_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_shadow_op_t); /* XEN_DOMCTL_max_mem */ @@ -272,8 +246,6 @@ struct xen_domctl_max_mem { /* IN variables. */ uint64_aligned_t max_memkb; }; -typedef struct xen_domctl_max_mem xen_domctl_max_mem_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_max_mem_t); /* XEN_DOMCTL_setvcpucontext */ @@ -282,8 +254,6 @@ struct xen_domctl_vcpucontext { uint32_t vcpu; /* IN */ XEN_GUEST_HANDLE_64(vcpu_guest_context_t) ctxt; /* IN/OUT */ }; -typedef struct xen_domctl_vcpucontext xen_domctl_vcpucontext_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_vcpucontext_t); /* XEN_DOMCTL_getvcpuinfo */ @@ -297,8 +267,6 @@ struct xen_domctl_getvcpuinfo { uint64_aligned_t cpu_time; /* total cpu time consumed (ns) */ uint32_t cpu; /* current mapping */ }; -typedef struct xen_domctl_getvcpuinfo xen_domctl_getvcpuinfo_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_getvcpuinfo_t); /* Get/set the NUMA node(s) with which the guest has affinity with. */ @@ -307,8 +275,6 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_getvcpuinfo_t); struct xen_domctl_nodeaffinity { struct xenctl_bitmap nodemap;/* IN */ }; -typedef struct xen_domctl_nodeaffinity xen_domctl_nodeaffinity_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_nodeaffinity_t); /* Get/set which physical cpus a vcpu can execute on. */ @@ -323,6 +289,9 @@ struct xen_domctl_vcpuaffinity { /* Set/get the soft affinity for vcpu */ #define _XEN_VCPUAFFINITY_SOFT 1 #define XEN_VCPUAFFINITY_SOFT (1U<<_XEN_VCPUAFFINITY_SOFT) + /* Undo SCHEDOP_pin_override */ +#define _XEN_VCPUAFFINITY_FORCE 2 +#define XEN_VCPUAFFINITY_FORCE (1U<<_XEN_VCPUAFFINITY_FORCE) uint32_t flags; /* * IN/OUT variables. @@ -343,71 +312,95 @@ struct xen_domctl_vcpuaffinity { struct xenctl_bitmap cpumap_hard; struct xenctl_bitmap cpumap_soft; }; -typedef struct xen_domctl_vcpuaffinity xen_domctl_vcpuaffinity_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_vcpuaffinity_t); /* XEN_DOMCTL_max_vcpus */ struct xen_domctl_max_vcpus { uint32_t max; /* maximum number of vcpus */ }; -typedef struct xen_domctl_max_vcpus xen_domctl_max_vcpus_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_max_vcpus_t); /* XEN_DOMCTL_scheduler_op */ /* Scheduler types. */ -#define XEN_SCHEDULER_SEDF 4 +/* #define XEN_SCHEDULER_SEDF 4 (Removed) */ #define XEN_SCHEDULER_CREDIT 5 #define XEN_SCHEDULER_CREDIT2 6 #define XEN_SCHEDULER_ARINC653 7 #define XEN_SCHEDULER_RTDS 8 +#define XEN_SCHEDULER_NULL 9 + +struct xen_domctl_sched_credit { + uint16_t weight; + uint16_t cap; +}; + +struct xen_domctl_sched_credit2 { + uint16_t weight; + uint16_t cap; +}; + +struct xen_domctl_sched_rtds { + uint32_t period; + uint32_t budget; +}; + +typedef struct xen_domctl_schedparam_vcpu { + union { + struct xen_domctl_sched_credit credit; + struct xen_domctl_sched_credit2 credit2; + struct xen_domctl_sched_rtds rtds; + } u; + uint32_t vcpuid; +} xen_domctl_schedparam_vcpu_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_schedparam_vcpu_t); -/* Set or get info? */ +/* + * Set or get info? + * For schedulers supporting per-vcpu settings (e.g., RTDS): + * XEN_DOMCTL_SCHEDOP_putinfo sets params for all vcpus; + * XEN_DOMCTL_SCHEDOP_getinfo gets default params; + * XEN_DOMCTL_SCHEDOP_put(get)vcpuinfo sets (gets) params of vcpus; + * + * For schedulers not supporting per-vcpu settings: + * XEN_DOMCTL_SCHEDOP_putinfo sets params for all vcpus; + * XEN_DOMCTL_SCHEDOP_getinfo gets domain-wise params; + * XEN_DOMCTL_SCHEDOP_put(get)vcpuinfo returns error; + */ #define XEN_DOMCTL_SCHEDOP_putinfo 0 #define XEN_DOMCTL_SCHEDOP_getinfo 1 +#define XEN_DOMCTL_SCHEDOP_putvcpuinfo 2 +#define XEN_DOMCTL_SCHEDOP_getvcpuinfo 3 struct xen_domctl_scheduler_op { uint32_t sched_id; /* XEN_SCHEDULER_* */ uint32_t cmd; /* XEN_DOMCTL_SCHEDOP_* */ + /* IN/OUT */ union { - struct xen_domctl_sched_sedf { - uint64_aligned_t period; - uint64_aligned_t slice; - uint64_aligned_t latency; - uint32_t extratime; - uint32_t weight; - } sedf; - struct xen_domctl_sched_credit { - uint16_t weight; - uint16_t cap; - } credit; - struct xen_domctl_sched_credit2 { - uint16_t weight; - } credit2; - struct xen_domctl_sched_rtds { - uint32_t period; - uint32_t budget; - } rtds; + struct xen_domctl_sched_credit credit; + struct xen_domctl_sched_credit2 credit2; + struct xen_domctl_sched_rtds rtds; + struct { + XEN_GUEST_HANDLE_64(xen_domctl_schedparam_vcpu_t) vcpus; + /* + * IN: Number of elements in vcpus array. + * OUT: Number of processed elements of vcpus array. + */ + uint32_t nr_vcpus; + uint32_t padding; + } v; } u; }; -typedef struct xen_domctl_scheduler_op xen_domctl_scheduler_op_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_scheduler_op_t); /* XEN_DOMCTL_setdomainhandle */ struct xen_domctl_setdomainhandle { xen_domain_handle_t handle; }; -typedef struct xen_domctl_setdomainhandle xen_domctl_setdomainhandle_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_setdomainhandle_t); /* XEN_DOMCTL_setdebugging */ struct xen_domctl_setdebugging { uint8_t enable; }; -typedef struct xen_domctl_setdebugging xen_domctl_setdebugging_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_setdebugging_t); /* XEN_DOMCTL_irq_permission */ @@ -415,8 +408,6 @@ struct xen_domctl_irq_permission { uint8_t pirq; uint8_t allow_access; /* flag to specify enable/disable of IRQ access */ }; -typedef struct xen_domctl_irq_permission xen_domctl_irq_permission_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_irq_permission_t); /* XEN_DOMCTL_iomem_permission */ @@ -425,8 +416,6 @@ struct xen_domctl_iomem_permission { uint64_aligned_t nr_mfns; /* number of pages in range (>0) */ uint8_t allow_access; /* allow (!0) or deny (0) access to range? */ }; -typedef struct xen_domctl_iomem_permission xen_domctl_iomem_permission_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_iomem_permission_t); /* XEN_DOMCTL_ioport_permission */ @@ -435,42 +424,34 @@ struct xen_domctl_ioport_permission { uint32_t nr_ports; /* size of port range */ uint8_t allow_access; /* allow or deny access to range? */ }; -typedef struct xen_domctl_ioport_permission xen_domctl_ioport_permission_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_ioport_permission_t); /* XEN_DOMCTL_hypercall_init */ struct xen_domctl_hypercall_init { uint64_aligned_t gmfn; /* GMFN to be initialised */ }; -typedef struct xen_domctl_hypercall_init xen_domctl_hypercall_init_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_hypercall_init_t); /* XEN_DOMCTL_settimeoffset */ struct xen_domctl_settimeoffset { - int32_t time_offset_seconds; /* applied to domain wallclock time */ + int64_aligned_t time_offset_seconds; /* applied to domain wallclock time */ }; -typedef struct xen_domctl_settimeoffset xen_domctl_settimeoffset_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_settimeoffset_t); /* XEN_DOMCTL_gethvmcontext */ /* XEN_DOMCTL_sethvmcontext */ -typedef struct xen_domctl_hvmcontext { +struct xen_domctl_hvmcontext { uint32_t size; /* IN/OUT: size of buffer / bytes filled */ XEN_GUEST_HANDLE_64(uint8) buffer; /* IN/OUT: data, or call * gethvmcontext with NULL * buffer to get size req'd */ -} xen_domctl_hvmcontext_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_hvmcontext_t); +}; /* XEN_DOMCTL_set_address_size */ /* XEN_DOMCTL_get_address_size */ -typedef struct xen_domctl_address_size { +struct xen_domctl_address_size { uint32_t size; -} xen_domctl_address_size_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_address_size_t); +}; /* XEN_DOMCTL_sendtrigger */ @@ -483,19 +464,40 @@ struct xen_domctl_sendtrigger { uint32_t trigger; /* IN */ uint32_t vcpu; /* IN */ }; -typedef struct xen_domctl_sendtrigger xen_domctl_sendtrigger_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_sendtrigger_t); -/* Assign PCI device to HVM guest. Sets up IOMMU structures. */ +/* Assign a device to a guest. Sets up IOMMU structures. */ /* XEN_DOMCTL_assign_device */ -/* XEN_DOMCTL_test_assign_device */ -/* XEN_DOMCTL_deassign_device */ +/* + * XEN_DOMCTL_test_assign_device: Pass DOMID_INVALID to find out whether the + * given device is assigned to any DomU at all. Pass a specific domain ID to + * find out whether the given device can be assigned to that domain. + */ +/* + * XEN_DOMCTL_deassign_device: The behavior of this DOMCTL differs + * between the different type of device: + * - PCI device (XEN_DOMCTL_DEV_PCI) will be reassigned to DOM0 + * - DT device (XEN_DOMCTL_DEV_DT) will left unassigned. DOM0 + * will have to call XEN_DOMCTL_assign_device in order to use the + * device. + */ +#define XEN_DOMCTL_DEV_PCI 0 +#define XEN_DOMCTL_DEV_DT 1 struct xen_domctl_assign_device { - uint32_t machine_sbdf; /* machine PCI ID of assigned device */ + /* IN */ + uint32_t dev; /* XEN_DOMCTL_DEV_* */ + uint32_t flags; +#define XEN_DOMCTL_DEV_RDM_RELAXED 1 /* assign only */ + union { + struct { + uint32_t machine_sbdf; /* machine PCI ID of assigned device */ + } pci; + struct { + uint32_t size; /* Length of the path */ + XEN_GUEST_HANDLE_64(char) path; /* path to the device tree node */ + } dt; + } u; }; -typedef struct xen_domctl_assign_device xen_domctl_assign_device_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_assign_device_t); /* Retrieve sibling devices infomation of machine_sbdf */ /* XEN_DOMCTL_get_device_group */ @@ -505,22 +507,20 @@ struct xen_domctl_get_device_group { uint32_t num_sdevs; /* OUT */ XEN_GUEST_HANDLE_64(uint32) sdev_array; /* OUT */ }; -typedef struct xen_domctl_get_device_group xen_domctl_get_device_group_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_get_device_group_t); /* Pass-through interrupts: bind real irq -> hvm devfn. */ /* XEN_DOMCTL_bind_pt_irq */ /* XEN_DOMCTL_unbind_pt_irq */ -typedef enum pt_irq_type_e { +enum pt_irq_type { PT_IRQ_TYPE_PCI, PT_IRQ_TYPE_ISA, PT_IRQ_TYPE_MSI, PT_IRQ_TYPE_MSI_TRANSLATE, -} pt_irq_type_t; + PT_IRQ_TYPE_SPI, /* ARM: valid range 32-1019 */ +}; struct xen_domctl_bind_pt_irq { uint32_t machine_irq; - pt_irq_type_t irq_type; - uint32_t hvm_domid; + uint32_t irq_type; /* enum pt_irq_type */ union { struct { @@ -534,16 +534,32 @@ struct xen_domctl_bind_pt_irq { struct { uint8_t gvec; uint32_t gflags; +#define XEN_DOMCTL_VMSI_X86_DEST_ID_MASK 0x0000ff +#define XEN_DOMCTL_VMSI_X86_RH_MASK 0x000100 +#define XEN_DOMCTL_VMSI_X86_DM_MASK 0x000200 +#define XEN_DOMCTL_VMSI_X86_DELIV_MASK 0x007000 +#define XEN_DOMCTL_VMSI_X86_TRIG_MASK 0x008000 +#define XEN_DOMCTL_VMSI_X86_UNMASKED 0x010000 + uint64_aligned_t gtable; } msi; + struct { + uint16_t spi; + } spi; } u; }; -typedef struct xen_domctl_bind_pt_irq xen_domctl_bind_pt_irq_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_bind_pt_irq_t); /* Bind machine I/O address range -> HVM address range. */ /* XEN_DOMCTL_memory_mapping */ +/* Returns + - zero success, everything done + - -E2BIG passed in nr_mfns value too large for the implementation + - positive partial success for the first <result> page frames (with + <result> less than nr_mfns), requiring re-invocation by the + caller after updating inputs + - negative error; other than -E2BIG +*/ #define DPCI_ADD_MAPPING 1 #define DPCI_REMOVE_MAPPING 0 struct xen_domctl_memory_mapping { @@ -553,8 +569,6 @@ struct xen_domctl_memory_mapping { uint32_t add_mapping; /* add or remove mapping */ uint32_t padding; /* padding for 64-bit aligned structure */ }; -typedef struct xen_domctl_memory_mapping xen_domctl_memory_mapping_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_memory_mapping_t); /* Bind machine I/O port range -> HVM I/O port range. */ @@ -565,8 +579,6 @@ struct xen_domctl_ioport_mapping { uint32_t nr_ports; /* size of port range */ uint32_t add_mapping; /* add or remove mapping */ }; -typedef struct xen_domctl_ioport_mapping xen_domctl_ioport_mapping_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_ioport_mapping_t); /* @@ -585,8 +597,6 @@ struct xen_domctl_pin_mem_cacheattr { uint64_aligned_t start, end; uint32_t type; /* XEN_DOMCTL_MEM_CACHEATTR_* */ }; -typedef struct xen_domctl_pin_mem_cacheattr xen_domctl_pin_mem_cacheattr_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_pin_mem_cacheattr_t); /* XEN_DOMCTL_set_ext_vcpucontext */ @@ -618,8 +628,6 @@ struct xen_domctl_ext_vcpucontext { #endif #endif }; -typedef struct xen_domctl_ext_vcpucontext xen_domctl_ext_vcpucontext_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_ext_vcpucontext_t); /* * Set the target domain for a domain @@ -628,8 +636,6 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_ext_vcpucontext_t); struct xen_domctl_set_target { domid_t target; }; -typedef struct xen_domctl_set_target xen_domctl_set_target_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_set_target_t); #if defined(__i386__) || defined(__x86_64__) # define XEN_CPUID_INPUT_UNUSED 0xFFFFFFFF @@ -641,8 +647,6 @@ struct xen_domctl_cpuid { uint32_t ecx; uint32_t edx; }; -typedef struct xen_domctl_cpuid xen_domctl_cpuid_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_cpuid_t); #endif /* @@ -665,8 +669,6 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_cpuid_t); struct xen_domctl_subscribe { uint32_t port; /* IN */ }; -typedef struct xen_domctl_subscribe xen_domctl_subscribe_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_subscribe_t); /* * Define the maximum machine address size which should be allocated @@ -687,41 +689,34 @@ struct xen_domctl_debug_op { uint32_t op; /* IN */ uint32_t vcpu; /* IN */ }; -typedef struct xen_domctl_debug_op xen_domctl_debug_op_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_debug_op_t); /* * Request a particular record from the HVM context */ /* XEN_DOMCTL_gethvmcontext_partial */ -typedef struct xen_domctl_hvmcontext_partial { +struct xen_domctl_hvmcontext_partial { uint32_t type; /* IN: Type of record required */ uint32_t instance; /* IN: Instance of that type */ + uint64_aligned_t bufsz; /* IN: size of buffer */ XEN_GUEST_HANDLE_64(uint8) buffer; /* OUT: buffer to write record into */ -} xen_domctl_hvmcontext_partial_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_hvmcontext_partial_t); +}; /* XEN_DOMCTL_disable_migrate */ -typedef struct xen_domctl_disable_migrate { +struct xen_domctl_disable_migrate { uint32_t disable; /* IN: 1: disable migration and restore */ -} xen_domctl_disable_migrate_t; +}; /* XEN_DOMCTL_gettscinfo */ /* XEN_DOMCTL_settscinfo */ -struct xen_guest_tsc_info { +struct xen_domctl_tsc_info { + /* IN/OUT */ uint32_t tsc_mode; uint32_t gtsc_khz; uint32_t incarnation; uint32_t pad; uint64_aligned_t elapsed_nsec; }; -typedef struct xen_guest_tsc_info xen_guest_tsc_info_t; -DEFINE_XEN_GUEST_HANDLE(xen_guest_tsc_info_t); -typedef struct xen_domctl_tsc_info { - XEN_GUEST_HANDLE_64(xen_guest_tsc_info_t) out_info; /* OUT */ - xen_guest_tsc_info_t info; /* IN */ -} xen_domctl_tsc_info_t; /* XEN_DOMCTL_gdbsx_guestmemio guest mem io */ struct xen_domctl_gdbsx_memio { @@ -750,10 +745,21 @@ struct xen_domctl_gdbsx_domstatus { }; /* - * Memory event operations + * VM event operations */ -/* XEN_DOMCTL_mem_event_op */ +/* XEN_DOMCTL_vm_event_op */ + +/* + * There are currently three rings available for VM events: + * sharing, monitor and paging. This hypercall allows one to + * control these rings (enable/disable), as well as to signal + * to the hypervisor to pull responses (resume) from the given + * ring. + */ +#define XEN_VM_EVENT_ENABLE 0 +#define XEN_VM_EVENT_DISABLE 1 +#define XEN_VM_EVENT_RESUME 2 /* * Domain memory paging @@ -762,42 +768,38 @@ struct xen_domctl_gdbsx_domstatus { * pager<->hypervisor interface. Use XENMEM_paging_op* * to perform per-page operations. * - * The XEN_DOMCTL_MEM_EVENT_OP_PAGING_ENABLE domctl returns several + * The XEN_VM_EVENT_PAGING_ENABLE domctl returns several * non-standard error codes to indicate why paging could not be enabled: * ENODEV - host lacks HAP support (EPT/NPT) or HAP is disabled in guest * EMLINK - guest has iommu passthrough enabled * EXDEV - guest has PoD enabled * EBUSY - guest has or had paging enabled, ring buffer still active */ -#define XEN_DOMCTL_MEM_EVENT_OP_PAGING 1 - -#define XEN_DOMCTL_MEM_EVENT_OP_PAGING_ENABLE 0 -#define XEN_DOMCTL_MEM_EVENT_OP_PAGING_DISABLE 1 +#define XEN_DOMCTL_VM_EVENT_OP_PAGING 1 /* - * Access permissions. + * Monitor helper. * * As with paging, use the domctl for teardown/setup of the * helper<->hypervisor interface. * - * There are HVM hypercalls to set the per-page access permissions of every - * page in a domain. When one of these permissions--independent, read, - * write, and execute--is violated, the VCPU is paused and a memory event - * is sent with what happened. (See public/mem_event.h) . + * The monitor interface can be used to register for various VM events. For + * example, there are HVM hypercalls to set the per-page access permissions + * of every page in a domain. When one of these permissions--independent, + * read, write, and execute--is violated, the VCPU is paused and a memory event + * is sent with what happened. The memory event handler can then resume the + * VCPU and redo the access with a XEN_VM_EVENT_RESUME option. * - * The memory event handler can then resume the VCPU and redo the access - * with a XENMEM_access_op_resume hypercall. + * See public/vm_event.h for the list of available events that can be + * subscribed to via the monitor interface. * - * The XEN_DOMCTL_MEM_EVENT_OP_ACCESS_ENABLE domctl returns several + * The XEN_VM_EVENT_MONITOR_* domctls returns * non-standard error codes to indicate why access could not be enabled: * ENODEV - host lacks HAP support (EPT/NPT) or HAP is disabled in guest * EBUSY - guest has or had access enabled, ring buffer still active + * */ -#define XEN_DOMCTL_MEM_EVENT_OP_ACCESS 2 - -#define XEN_DOMCTL_MEM_EVENT_OP_ACCESS_ENABLE 0 -#define XEN_DOMCTL_MEM_EVENT_OP_ACCESS_DISABLE 1 -#define XEN_DOMCTL_MEM_EVENT_OP_ACCESS_ENABLE_INTROSPECTION 2 +#define XEN_DOMCTL_VM_EVENT_OP_MONITOR 2 /* * Sharing ENOMEM helper. @@ -812,21 +814,16 @@ struct xen_domctl_gdbsx_domstatus { * Note that shring can be turned on (as per the domctl below) * *without* this ring being setup. */ -#define XEN_DOMCTL_MEM_EVENT_OP_SHARING 3 - -#define XEN_DOMCTL_MEM_EVENT_OP_SHARING_ENABLE 0 -#define XEN_DOMCTL_MEM_EVENT_OP_SHARING_DISABLE 1 +#define XEN_DOMCTL_VM_EVENT_OP_SHARING 3 /* Use for teardown/setup of helper<->hypervisor interface for paging, * access and sharing.*/ -struct xen_domctl_mem_event_op { - uint32_t op; /* XEN_DOMCTL_MEM_EVENT_OP_*_* */ - uint32_t mode; /* XEN_DOMCTL_MEM_EVENT_OP_* */ +struct xen_domctl_vm_event_op { + uint32_t op; /* XEN_VM_EVENT_* */ + uint32_t mode; /* XEN_DOMCTL_VM_EVENT_OP_* */ uint32_t port; /* OUT: event channel for ring */ }; -typedef struct xen_domctl_mem_event_op xen_domctl_mem_event_op_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_mem_event_op_t); /* * Memory sharing operations @@ -842,8 +839,6 @@ struct xen_domctl_mem_sharing_op { uint8_t enable; /* CONTROL */ } u; }; -typedef struct xen_domctl_mem_sharing_op xen_domctl_mem_sharing_op_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_mem_sharing_op_t); struct xen_domctl_audit_p2m { /* OUT error counts */ @@ -851,14 +846,10 @@ struct xen_domctl_audit_p2m { uint64_t m2p_bad; uint64_t p2m_bad; }; -typedef struct xen_domctl_audit_p2m xen_domctl_audit_p2m_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_audit_p2m_t); struct xen_domctl_set_virq_handler { uint32_t virq; /* IN */ }; -typedef struct xen_domctl_set_virq_handler xen_domctl_set_virq_handler_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_set_virq_handler_t); #if defined(__i386__) || defined(__x86_64__) /* XEN_DOMCTL_setvcpuextstate */ @@ -881,8 +872,6 @@ struct xen_domctl_vcpuextstate { uint64_aligned_t size; XEN_GUEST_HANDLE_64(uint64) buffer; }; -typedef struct xen_domctl_vcpuextstate xen_domctl_vcpuextstate_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_vcpuextstate_t); #endif /* XEN_DOMCTL_set_access_required: sets whether a memory event listener @@ -892,14 +881,10 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_vcpuextstate_t); struct xen_domctl_set_access_required { uint8_t access_required; }; -typedef struct xen_domctl_set_access_required xen_domctl_set_access_required_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_set_access_required_t); struct xen_domctl_set_broken_page_p2m { uint64_aligned_t pfn; }; -typedef struct xen_domctl_set_broken_page_p2m xen_domctl_set_broken_page_p2m_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_set_broken_page_p2m_t); /* * XEN_DOMCTL_set_max_evtchn: sets the maximum event channel port @@ -909,8 +894,6 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_set_broken_page_p2m_t); struct xen_domctl_set_max_evtchn { uint32_t max_port; }; -typedef struct xen_domctl_set_max_evtchn xen_domctl_set_max_evtchn_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_set_max_evtchn_t); /* * ARM: Clean and invalidate caches associated with given region of @@ -920,8 +903,6 @@ struct xen_domctl_cacheflush { /* IN: page range to flush. */ xen_pfn_t start_pfn, nr_pfns; }; -typedef struct xen_domctl_cacheflush xen_domctl_cacheflush_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_cacheflush_t); #if defined(__i386__) || defined(__x86_64__) struct xen_domctl_vcpu_msr { @@ -954,36 +935,42 @@ struct xen_domctl_vcpu_msrs { uint32_t msr_count; /* IN/OUT */ XEN_GUEST_HANDLE_64(xen_domctl_vcpu_msr_t) msrs; /* IN/OUT */ }; -typedef struct xen_domctl_vcpu_msrs xen_domctl_vcpu_msrs_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_vcpu_msrs_t); #endif -/* - * Use in XEN_DOMCTL_setvnumainfo to set - * vNUMA domain topology. - */ +/* XEN_DOMCTL_setvnumainfo: specifies a virtual NUMA topology for the guest */ struct xen_domctl_vnuma { + /* IN: number of vNUMA nodes to setup. Shall be greater than 0 */ uint32_t nr_vnodes; + /* IN: number of memory ranges to setup */ uint32_t nr_vmemranges; + /* + * IN: number of vCPUs of the domain (used as size of the vcpu_to_vnode + * array declared below). Shall be equal to the domain's max_vcpus. + */ uint32_t nr_vcpus; - uint32_t pad; + uint32_t pad; /* must be zero */ + + /* + * IN: array for specifying the distances of the vNUMA nodes + * between each others. Shall have nr_vnodes*nr_vnodes elements. + */ XEN_GUEST_HANDLE_64(uint) vdistance; + /* + * IN: array for specifying to what vNUMA node each vCPU belongs. + * Shall have nr_vcpus elements. + */ XEN_GUEST_HANDLE_64(uint) vcpu_to_vnode; - /* - * vnodes to physical NUMA nodes mask. - * This kept on per-domain basis for - * interested consumers, such as numa aware ballooning. + * IN: array for specifying on what physical NUMA node each vNUMA + * node is placed. Shall have nr_vnodes elements. */ XEN_GUEST_HANDLE_64(uint) vnode_to_pnode; - /* - * memory rages for each vNUMA node + * IN: array for specifying the memory ranges. Shall have + * nr_vmemranges elements. */ XEN_GUEST_HANDLE_64(xen_vmemrange_t) vmemrange; }; -typedef struct xen_domctl_vnuma xen_domctl_vnuma_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_vnuma_t); struct xen_domctl_psr_cmt_op { #define XEN_DOMCTL_PSR_CMT_OP_DETACH 0 @@ -992,8 +979,127 @@ struct xen_domctl_psr_cmt_op { uint32_t cmd; uint32_t data; }; -typedef struct xen_domctl_psr_cmt_op xen_domctl_psr_cmt_op_t; -DEFINE_XEN_GUEST_HANDLE(xen_domctl_psr_cmt_op_t); + +/* XEN_DOMCTL_MONITOR_* + * + * Enable/disable monitoring various VM events. + * This domctl configures what events will be reported to helper apps + * via the ring buffer "MONITOR". The ring has to be first enabled + * with the domctl XEN_DOMCTL_VM_EVENT_OP_MONITOR. + * + * GET_CAPABILITIES can be used to determine which of these features is + * available on a given platform. + * + * NOTICE: mem_access events are also delivered via the "MONITOR" ring buffer; + * however, enabling/disabling those events is performed with the use of + * memory_op hypercalls! + */ +#define XEN_DOMCTL_MONITOR_OP_ENABLE 0 +#define XEN_DOMCTL_MONITOR_OP_DISABLE 1 +#define XEN_DOMCTL_MONITOR_OP_GET_CAPABILITIES 2 +#define XEN_DOMCTL_MONITOR_OP_EMULATE_EACH_REP 3 + +#define XEN_DOMCTL_MONITOR_EVENT_WRITE_CTRLREG 0 +#define XEN_DOMCTL_MONITOR_EVENT_MOV_TO_MSR 1 +#define XEN_DOMCTL_MONITOR_EVENT_SINGLESTEP 2 +#define XEN_DOMCTL_MONITOR_EVENT_SOFTWARE_BREAKPOINT 3 +#define XEN_DOMCTL_MONITOR_EVENT_GUEST_REQUEST 4 +#define XEN_DOMCTL_MONITOR_EVENT_DEBUG_EXCEPTION 5 +#define XEN_DOMCTL_MONITOR_EVENT_CPUID 6 +#define XEN_DOMCTL_MONITOR_EVENT_PRIVILEGED_CALL 7 +#define XEN_DOMCTL_MONITOR_EVENT_INTERRUPT 8 +#define XEN_DOMCTL_MONITOR_EVENT_DESC_ACCESS 9 +#define XEN_DOMCTL_MONITOR_EVENT_EMUL_UNIMPLEMENTED 10 + +struct xen_domctl_monitor_op { + uint32_t op; /* XEN_DOMCTL_MONITOR_OP_* */ + + /* + * When used with ENABLE/DISABLE this has to be set to + * the requested XEN_DOMCTL_MONITOR_EVENT_* value. + * With GET_CAPABILITIES this field returns a bitmap of + * events supported by the platform, in the format + * (1 << XEN_DOMCTL_MONITOR_EVENT_*). + */ + uint32_t event; + + /* + * Further options when issuing XEN_DOMCTL_MONITOR_OP_ENABLE. + */ + union { + struct { + /* Which control register */ + uint8_t index; + /* Pause vCPU until response */ + uint8_t sync; + /* Send event only on a change of value */ + uint8_t onchangeonly; + /* Allignment padding */ + uint8_t pad1; + uint32_t pad2; + /* + * Send event only if the changed bit in the control register + * is not masked. + */ + uint64_aligned_t bitmask; + } mov_to_cr; + + struct { + uint32_t msr; + } mov_to_msr; + + struct { + /* Pause vCPU until response */ + uint8_t sync; + uint8_t allow_userspace; + } guest_request; + + struct { + /* Pause vCPU until response */ + uint8_t sync; + } debug_exception; + } u; +}; + +struct xen_domctl_psr_cat_op { +#define XEN_DOMCTL_PSR_CAT_OP_SET_L3_CBM 0 +#define XEN_DOMCTL_PSR_CAT_OP_GET_L3_CBM 1 +#define XEN_DOMCTL_PSR_CAT_OP_SET_L3_CODE 2 +#define XEN_DOMCTL_PSR_CAT_OP_SET_L3_DATA 3 +#define XEN_DOMCTL_PSR_CAT_OP_GET_L3_CODE 4 +#define XEN_DOMCTL_PSR_CAT_OP_GET_L3_DATA 5 +#define XEN_DOMCTL_PSR_CAT_OP_SET_L2_CBM 6 +#define XEN_DOMCTL_PSR_CAT_OP_GET_L2_CBM 7 + uint32_t cmd; /* IN: XEN_DOMCTL_PSR_CAT_OP_* */ + uint32_t target; /* IN */ + uint64_t data; /* IN/OUT */ +}; + +struct xen_domctl_set_gnttab_limits { + uint32_t grant_frames; /* IN */ + uint32_t maptrack_frames; /* IN */ +}; + +/* XEN_DOMCTL_vuart_op */ +struct xen_domctl_vuart_op { +#define XEN_DOMCTL_VUART_OP_INIT 0 + uint32_t cmd; /* XEN_DOMCTL_VUART_OP_* */ +#define XEN_DOMCTL_VUART_TYPE_VPL011 0 + uint32_t type; /* IN - type of vuart. + * Currently only vpl011 supported. + */ + uint64_aligned_t gfn; /* IN - guest gfn to be used as a + * ring buffer. + */ + domid_t console_domid; /* IN - domid of domain running the + * backend console. + */ + uint8_t pad[2]; + evtchn_port_t evtchn; /* OUT - remote port of the event + * channel used for sending + * ring buffer events. + */ +}; struct xen_domctl { uint32_t cmd; @@ -1003,8 +1109,8 @@ struct xen_domctl { #define XEN_DOMCTL_unpausedomain 4 #define XEN_DOMCTL_getdomaininfo 5 #define XEN_DOMCTL_getmemlist 6 -#define XEN_DOMCTL_getpageframeinfo 7 -#define XEN_DOMCTL_getpageframeinfo2 8 +/* #define XEN_DOMCTL_getpageframeinfo 7 Obsolete - use getpageframeinfo3 */ +/* #define XEN_DOMCTL_getpageframeinfo2 8 Obsolete - use getpageframeinfo3 */ #define XEN_DOMCTL_setvcpuaffinity 9 #define XEN_DOMCTL_shadow_op 10 #define XEN_DOMCTL_max_mem 11 @@ -1049,7 +1155,7 @@ struct xen_domctl { #define XEN_DOMCTL_suppress_spurious_page_faults 53 #define XEN_DOMCTL_debug_op 54 #define XEN_DOMCTL_gethvmcontext_partial 55 -#define XEN_DOMCTL_mem_event_op 56 +#define XEN_DOMCTL_vm_event_op 56 #define XEN_DOMCTL_mem_sharing_op 57 #define XEN_DOMCTL_disable_migrate 58 #define XEN_DOMCTL_gettscinfo 59 @@ -1069,7 +1175,11 @@ struct xen_domctl { #define XEN_DOMCTL_set_vcpu_msrs 73 #define XEN_DOMCTL_setvnumainfo 74 #define XEN_DOMCTL_psr_cmt_op 75 -#define XEN_DOMCTL_arm_configure_domain 76 +#define XEN_DOMCTL_monitor_op 77 +#define XEN_DOMCTL_psr_cat_op 78 +#define XEN_DOMCTL_soft_reset 79 +#define XEN_DOMCTL_set_gnttab_limits 80 +#define XEN_DOMCTL_vuart_op 81 #define XEN_DOMCTL_gdbsx_guestmemio 1000 #define XEN_DOMCTL_gdbsx_pausevcpu 1001 #define XEN_DOMCTL_gdbsx_unpausevcpu 1002 @@ -1078,13 +1188,8 @@ struct xen_domctl { domid_t domain; union { struct xen_domctl_createdomain createdomain; -#if defined(__arm__) || defined(__aarch64__) - struct xen_domctl_arm_configuredomain configuredomain; -#endif struct xen_domctl_getdomaininfo getdomaininfo; struct xen_domctl_getmemlist getmemlist; - struct xen_domctl_getpageframeinfo getpageframeinfo; - struct xen_domctl_getpageframeinfo2 getpageframeinfo2; struct xen_domctl_getpageframeinfo3 getpageframeinfo3; struct xen_domctl_nodeaffinity nodeaffinity; struct xen_domctl_vcpuaffinity vcpuaffinity; @@ -1117,7 +1222,7 @@ struct xen_domctl { struct xen_domctl_set_target set_target; struct xen_domctl_subscribe subscribe; struct xen_domctl_debug_op debug_op; - struct xen_domctl_mem_event_op mem_event_op; + struct xen_domctl_vm_event_op vm_event_op; struct xen_domctl_mem_sharing_op mem_sharing_op; #if defined(__i386__) || defined(__x86_64__) struct xen_domctl_cpuid cpuid; @@ -1135,6 +1240,10 @@ struct xen_domctl { struct xen_domctl_gdbsx_domstatus gdbsx_domstatus; struct xen_domctl_vnuma vnuma; struct xen_domctl_psr_cmt_op psr_cmt_op; + struct xen_domctl_monitor_op monitor_op; + struct xen_domctl_psr_cat_op psr_cat_op; + struct xen_domctl_set_gnttab_limits set_gnttab_limits; + struct xen_domctl_vuart_op vuart_op; uint8_t pad[128]; } u; }; diff --git a/include/xen/elfnote.h b/include/xen/elfnote.h index 353985f..936aa65 100644 --- a/include/xen/elfnote.h +++ b/include/xen/elfnote.h @@ -173,7 +173,9 @@ * The (non-default) location the initial phys-to-machine map should be * placed at by the hypervisor (Dom0) or the tools (DomU). * The kernel must be prepared for this mapping to be established using - * large pages, despite such otherwise not being available to guests. + * large pages, despite such otherwise not being available to guests. Note + * that these large pages may be misaligned in PFN space (they'll obviously + * be aligned in MFN and virtual address spaces). * The kernel must also be able to handle the page table pages used for * this mapping not being accessible through the initial mapping. * (Only x86-64 supports this at present.) diff --git a/include/xen/errno.h b/include/xen/errno.h new file mode 100644 index 0000000..305c112 --- /dev/null +++ b/include/xen/errno.h @@ -0,0 +1,124 @@ +/* + * There are two expected ways of including this header. + * + * 1) The "default" case (expected from tools etc). + * + * Simply #include <public/errno.h> + * + * In this circumstance, normal header guards apply and the includer shall get + * an enumeration in the XEN_xxx namespace, appropriate for C or assembly. + * + * 2) The special case where the includer provides a XEN_ERRNO() in scope. + * + * In this case, no inclusion guards apply and the caller is responsible for + * their XEN_ERRNO() being appropriate in the included context. The header + * will unilaterally #undef XEN_ERRNO(). + */ + +#ifndef XEN_ERRNO + +/* + * Includer has not provided a custom XEN_ERRNO(). Arrange for normal header + * guards, an automatic enum (for C code) and constants in the XEN_xxx + * namespace. + */ +#ifndef __XEN_PUBLIC_ERRNO_H__ +#define __XEN_PUBLIC_ERRNO_H__ + +#define XEN_ERRNO_DEFAULT_INCLUDE + +#ifndef __ASSEMBLY__ + +#define XEN_ERRNO(name, value) XEN_##name = value, +enum xen_errno { + +#elif __XEN_INTERFACE_VERSION__ < 0x00040700 + +#define XEN_ERRNO(name, value) .equ XEN_##name, value + +#endif /* __ASSEMBLY__ */ + +#endif /* __XEN_PUBLIC_ERRNO_H__ */ +#endif /* !XEN_ERRNO */ + +/* ` enum neg_errnoval { [ -Efoo for each Efoo in the list below ] } */ +/* ` enum errnoval { */ + +#ifdef XEN_ERRNO + +/* + * Values originating from x86 Linux. Please consider using respective + * values when adding new definitions here. + * + * The set of identifiers to be added here shouldn't extend beyond what + * POSIX mandates (see e.g. + * http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html) + * with the exception that we support some optional (XSR) values + * specified there (but no new ones should be added). + */ + +XEN_ERRNO(EPERM, 1) /* Operation not permitted */ +XEN_ERRNO(ENOENT, 2) /* No such file or directory */ +XEN_ERRNO(ESRCH, 3) /* No such process */ +#ifdef __XEN__ /* Internal only, should never be exposed to the guest. */ +XEN_ERRNO(EINTR, 4) /* Interrupted system call */ +#endif +XEN_ERRNO(EIO, 5) /* I/O error */ +XEN_ERRNO(ENXIO, 6) /* No such device or address */ +XEN_ERRNO(E2BIG, 7) /* Arg list too long */ +XEN_ERRNO(ENOEXEC, 8) /* Exec format error */ +XEN_ERRNO(EBADF, 9) /* Bad file number */ +XEN_ERRNO(ECHILD, 10) /* No child processes */ +XEN_ERRNO(EAGAIN, 11) /* Try again */ +XEN_ERRNO(EWOULDBLOCK, 11) /* Operation would block. Aliases EAGAIN */ +XEN_ERRNO(ENOMEM, 12) /* Out of memory */ +XEN_ERRNO(EACCES, 13) /* Permission denied */ +XEN_ERRNO(EFAULT, 14) /* Bad address */ +XEN_ERRNO(EBUSY, 16) /* Device or resource busy */ +XEN_ERRNO(EEXIST, 17) /* File exists */ +XEN_ERRNO(EXDEV, 18) /* Cross-device link */ +XEN_ERRNO(ENODEV, 19) /* No such device */ +XEN_ERRNO(EISDIR, 21) /* Is a directory */ +XEN_ERRNO(EINVAL, 22) /* Invalid argument */ +XEN_ERRNO(ENFILE, 23) /* File table overflow */ +XEN_ERRNO(EMFILE, 24) /* Too many open files */ +XEN_ERRNO(ENOSPC, 28) /* No space left on device */ +XEN_ERRNO(EROFS, 30) /* Read-only file system */ +XEN_ERRNO(EMLINK, 31) /* Too many links */ +XEN_ERRNO(EDOM, 33) /* Math argument out of domain of func */ +XEN_ERRNO(ERANGE, 34) /* Math result not representable */ +XEN_ERRNO(EDEADLK, 35) /* Resource deadlock would occur */ +XEN_ERRNO(EDEADLOCK, 35) /* Resource deadlock would occur. Aliases EDEADLK */ +XEN_ERRNO(ENAMETOOLONG, 36) /* File name too long */ +XEN_ERRNO(ENOLCK, 37) /* No record locks available */ +XEN_ERRNO(ENOSYS, 38) /* Function not implemented */ +XEN_ERRNO(ENOTEMPTY, 39) /* Directory not empty */ +XEN_ERRNO(ENODATA, 61) /* No data available */ +XEN_ERRNO(ETIME, 62) /* Timer expired */ +XEN_ERRNO(EBADMSG, 74) /* Not a data message */ +XEN_ERRNO(EOVERFLOW, 75) /* Value too large for defined data type */ +XEN_ERRNO(EILSEQ, 84) /* Illegal byte sequence */ +#ifdef __XEN__ /* Internal only, should never be exposed to the guest. */ +XEN_ERRNO(ERESTART, 85) /* Interrupted system call should be restarted */ +#endif +XEN_ERRNO(ENOTSOCK, 88) /* Socket operation on non-socket */ +XEN_ERRNO(EOPNOTSUPP, 95) /* Operation not supported on transport endpoint */ +XEN_ERRNO(EADDRINUSE, 98) /* Address already in use */ +XEN_ERRNO(EADDRNOTAVAIL, 99) /* Cannot assign requested address */ +XEN_ERRNO(ENOBUFS, 105) /* No buffer space available */ +XEN_ERRNO(EISCONN, 106) /* Transport endpoint is already connected */ +XEN_ERRNO(ENOTCONN, 107) /* Transport endpoint is not connected */ +XEN_ERRNO(ETIMEDOUT, 110) /* Connection timed out */ + +#undef XEN_ERRNO +#endif /* XEN_ERRNO */ +/* ` } */ + +/* Clean up from a default include. Close the enum (for C). */ +#ifdef XEN_ERRNO_DEFAULT_INCLUDE +#undef XEN_ERRNO_DEFAULT_INCLUDE +#ifndef __ASSEMBLY__ +}; +#endif + +#endif /* XEN_ERRNO_DEFAULT_INCLUDE */ diff --git a/include/xen/event_channel.h b/include/xen/event_channel.h index 05e531d..44c549d 100644 --- a/include/xen/event_channel.h +++ b/include/xen/event_channel.h @@ -85,7 +85,7 @@ DEFINE_XEN_GUEST_HANDLE(evtchn_port_t); * is allocated in <dom> and returned as <port>. * NOTES: * 1. If the caller is unprivileged then <dom> must be DOMID_SELF. - * 2. <rdom> may be DOMID_SELF, allowing loopback connections. + * 2. <remote_dom> may be DOMID_SELF, allowing loopback connections. */ struct evtchn_alloc_unbound { /* IN parameters */ diff --git a/include/xen/features.h b/include/xen/features.h index 16d92aa..2110b04 100644 --- a/include/xen/features.h +++ b/include/xen/features.h @@ -99,6 +99,9 @@ #define XENFEAT_grant_map_identity 12 */ +/* Guest can use XENMEMF_vnode to specify virtual node for memory op. */ +#define XENFEAT_memory_op_vnode_supported 13 + #define XENFEAT_NR_SUBMAPS 1 #endif /* __XEN_PUBLIC_FEATURES_H__ */ diff --git a/include/xen/gcov.h b/include/xen/gcov.h deleted file mode 100644 index 1b29b48..0000000 --- a/include/xen/gcov.h +++ /dev/null @@ -1,115 +0,0 @@ -/****************************************************************************** - * gcov.h - * - * Coverage structures exported by Xen. - * Structure is different from Gcc one. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Copyright (c) 2013, Citrix Systems R&D Ltd. - */ - -#ifndef __XEN_PUBLIC_GCOV_H__ -#define __XEN_PUBLIC_GCOV_H__ __XEN_PUBLIC_GCOV_H__ - -#define XENCOV_COUNTERS 5 -#define XENCOV_TAG_BASE 0x58544300u -#define XENCOV_TAG_FILE (XENCOV_TAG_BASE+0x46u) -#define XENCOV_TAG_FUNC (XENCOV_TAG_BASE+0x66u) -#define XENCOV_TAG_COUNTER(n) (XENCOV_TAG_BASE+0x30u+((n)&0xfu)) -#define XENCOV_TAG_END (XENCOV_TAG_BASE+0x2eu) -#define XENCOV_IS_TAG_COUNTER(n) \ - ((n) >= XENCOV_TAG_COUNTER(0) && (n) < XENCOV_TAG_COUNTER(XENCOV_COUNTERS)) -#define XENCOV_COUNTER_NUM(n) ((n)-XENCOV_TAG_COUNTER(0)) - -/* - * The main structure for the blob is - * BLOB := FILE.. END - * FILE := TAG_FILE VERSION STAMP FILENAME COUNTERS FUNCTIONS - * FILENAME := LEN characters - * characters are padded to 32 bit - * LEN := 32 bit value - * COUNTERS := TAG_COUNTER(n) NUM COUNTER.. - * NUM := 32 bit valie - * COUNTER := 64 bit value - * FUNCTIONS := TAG_FUNC NUM FUNCTION.. - * FUNCTION := IDENT CHECKSUM NUM_COUNTERS - * - * All tagged structures are aligned to 8 bytes - */ - -/** - * File information - * Prefixed with XENCOV_TAG_FILE and a string with filename - * Aligned to 8 bytes - */ -struct xencov_file -{ - uint32_t tag; /* XENCOV_TAG_FILE */ - uint32_t version; - uint32_t stamp; - uint32_t fn_len; - char filename[1]; -}; - - -/** - * Counters information - * Prefixed with XENCOV_TAG_COUNTER(n) where n is 0..(XENCOV_COUNTERS-1) - * Aligned to 8 bytes - */ -struct xencov_counter -{ - uint32_t tag; /* XENCOV_TAG_COUNTER(n) */ - uint32_t num; - uint64_t values[1]; -}; - -/** - * Information for each function - * Number of counter is equal to the number of counter structures got before - */ -struct xencov_function -{ - uint32_t ident; - uint32_t checksum; - uint32_t num_counters[1]; -}; - -/** - * Information for all functions - * Aligned to 8 bytes - */ -struct xencov_functions -{ - uint32_t tag; /* XENCOV_TAG_FUNC */ - uint32_t num; - struct xencov_function xencov_function[1]; -}; - -/** - * Terminator - */ -struct xencov_end -{ - uint32_t tag; /* XENCOV_TAG_END */ -}; - -#endif /* __XEN_PUBLIC_GCOV_H__ */ - diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h index 20d4e77..018036e 100644 --- a/include/xen/grant_table.h +++ b/include/xen/grant_table.h @@ -43,7 +43,7 @@ * table are identified by grant references. A grant reference is an * integer, which indexes into the grant table. It acts as a * capability which the grantee can use to perform operations on the - * granter’s memory. + * granter's memory. * * This capability-based system allows shared-memory communications * between unprivileged domains. A grant reference also encapsulates @@ -134,8 +134,10 @@ struct grant_entry_v1 { /* The domain being granted foreign privileges. [GST] */ domid_t domid; /* - * GTF_permit_access: Frame that @domid is allowed to map and access. [GST] - * GTF_accept_transfer: Frame whose ownership transferred by @domid. [XEN] + * GTF_permit_access: GFN that @domid is allowed to map and access. [GST] + * GTF_accept_transfer: GFN that @domid is allowed to transfer into. [GST] + * GTF_transfer_completed: MFN whose ownership transferred by @domid + * (non-translated guests only). [XEN] */ uint32_t frame; }; @@ -321,7 +323,7 @@ typedef uint32_t grant_handle_t; /* * GNTTABOP_map_grant_ref: Map the grant entry (<dom>,<ref>) for access * by devices and/or host CPUs. If successful, <handle> is a tracking number - * that must be presented later to destroy the mapping(s). On error, <handle> + * that must be presented later to destroy the mapping(s). On error, <status> * is a negative status code. * NOTES: * 1. If GNTMAP_device_map is specified then <dev_bus_addr> is the address @@ -409,12 +411,13 @@ typedef struct gnttab_dump_table gnttab_dump_table_t; DEFINE_XEN_GUEST_HANDLE(gnttab_dump_table_t); /* - * GNTTABOP_transfer_grant_ref: Transfer <frame> to a foreign domain. The - * foreign domain has previously registered its interest in the transfer via - * <domid, ref>. + * GNTTABOP_transfer: Transfer <frame> to a foreign domain. The foreign domain + * has previously registered its interest in the transfer via <domid, ref>. * * Note that, even if the transfer fails, the specified page no longer belongs * to the calling domain *unless* the error is GNTST_bad_page. + * + * Note further that only PV guests can use this operation. */ struct gnttab_transfer { /* IN parameters. */ @@ -453,7 +456,7 @@ DEFINE_XEN_GUEST_HANDLE(gnttab_transfer_t); struct gnttab_copy { /* IN parameters. */ - struct { + struct gnttab_copy_ptr { union { grant_ref_t ref; xen_pfn_t gmfn; diff --git a/include/xen/hvm/dm_op.h b/include/xen/hvm/dm_op.h new file mode 100644 index 0000000..6bbab5f --- /dev/null +++ b/include/xen/hvm/dm_op.h @@ -0,0 +1,417 @@ +/* + * Copyright (c) 2016, Citrix Systems Inc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __XEN_PUBLIC_HVM_DM_OP_H__ +#define __XEN_PUBLIC_HVM_DM_OP_H__ + +#include "../xen.h" + +#if defined(__XEN__) || defined(__XEN_TOOLS__) + +#include "../event_channel.h" + +#ifndef uint64_aligned_t +#define uint64_aligned_t uint64_t +#endif + +/* + * IOREQ Servers + * + * The interface between an I/O emulator an Xen is called an IOREQ Server. + * A domain supports a single 'legacy' IOREQ Server which is instantiated if + * parameter... + * + * HVM_PARAM_IOREQ_PFN is read (to get the gfn containing the synchronous + * ioreq structures), or... + * HVM_PARAM_BUFIOREQ_PFN is read (to get the gfn containing the buffered + * ioreq ring), or... + * HVM_PARAM_BUFIOREQ_EVTCHN is read (to get the event channel that Xen uses + * to request buffered I/O emulation). + * + * The following hypercalls facilitate the creation of IOREQ Servers for + * 'secondary' emulators which are invoked to implement port I/O, memory, or + * PCI config space ranges which they explicitly register. + */ + +typedef uint16_t ioservid_t; + +/* + * XEN_DMOP_create_ioreq_server: Instantiate a new IOREQ Server for a + * secondary emulator. + * + * The <id> handed back is unique for target domain. The valur of + * <handle_bufioreq> should be one of HVM_IOREQSRV_BUFIOREQ_* defined in + * hvm_op.h. If the value is HVM_IOREQSRV_BUFIOREQ_OFF then the buffered + * ioreq ring will not be allocated and hence all emulation requests to + * this server will be synchronous. + */ +#define XEN_DMOP_create_ioreq_server 1 + +struct xen_dm_op_create_ioreq_server { + /* IN - should server handle buffered ioreqs */ + uint8_t handle_bufioreq; + uint8_t pad[3]; + /* OUT - server id */ + ioservid_t id; +}; + +/* + * XEN_DMOP_get_ioreq_server_info: Get all the information necessary to + * access IOREQ Server <id>. + * + * The emulator needs to map the synchronous ioreq structures and buffered + * ioreq ring (if it exists) that Xen uses to request emulation. These are + * hosted in the target domain's gmfns <ioreq_gfn> and <bufioreq_gfn> + * respectively. In addition, if the IOREQ Server is handling buffered + * emulation requests, the emulator needs to bind to event channel + * <bufioreq_port> to listen for them. (The event channels used for + * synchronous emulation requests are specified in the per-CPU ioreq + * structures in <ioreq_gfn>). + * If the IOREQ Server is not handling buffered emulation requests then the + * values handed back in <bufioreq_gfn> and <bufioreq_port> will both be 0. + */ +#define XEN_DMOP_get_ioreq_server_info 2 + +struct xen_dm_op_get_ioreq_server_info { + /* IN - server id */ + ioservid_t id; + uint16_t pad; + /* OUT - buffered ioreq port */ + evtchn_port_t bufioreq_port; + /* OUT - sync ioreq gfn */ + uint64_aligned_t ioreq_gfn; + /* OUT - buffered ioreq gfn */ + uint64_aligned_t bufioreq_gfn; +}; + +/* + * XEN_DMOP_map_io_range_to_ioreq_server: Register an I/O range for + * emulation by the client of + * IOREQ Server <id>. + * XEN_DMOP_unmap_io_range_from_ioreq_server: Deregister an I/O range + * previously registered for + * emulation by the client of + * IOREQ Server <id>. + * + * There are three types of I/O that can be emulated: port I/O, memory + * accesses and PCI config space accesses. The <type> field denotes which + * type of range* the <start> and <end> (inclusive) fields are specifying. + * PCI config space ranges are specified by segment/bus/device/function + * values which should be encoded using the DMOP_PCI_SBDF helper macro + * below. + * + * NOTE: unless an emulation request falls entirely within a range mapped + * by a secondary emulator, it will not be passed to that emulator. + */ +#define XEN_DMOP_map_io_range_to_ioreq_server 3 +#define XEN_DMOP_unmap_io_range_from_ioreq_server 4 + +struct xen_dm_op_ioreq_server_range { + /* IN - server id */ + ioservid_t id; + uint16_t pad; + /* IN - type of range */ + uint32_t type; +# define XEN_DMOP_IO_RANGE_PORT 0 /* I/O port range */ +# define XEN_DMOP_IO_RANGE_MEMORY 1 /* MMIO range */ +# define XEN_DMOP_IO_RANGE_PCI 2 /* PCI segment/bus/dev/func range */ + /* IN - inclusive start and end of range */ + uint64_aligned_t start, end; +}; + +#define XEN_DMOP_PCI_SBDF(s,b,d,f) \ + ((((s) & 0xffff) << 16) | \ + (((b) & 0xff) << 8) | \ + (((d) & 0x1f) << 3) | \ + ((f) & 0x07)) + +/* + * XEN_DMOP_set_ioreq_server_state: Enable or disable the IOREQ Server <id> + * + * The IOREQ Server will not be passed any emulation requests until it is + * in the enabled state. + * Note that the contents of the ioreq_gfn and bufioreq_gfn (see + * XEN_DMOP_get_ioreq_server_info) are not meaningful until the IOREQ Server + * is in the enabled state. + */ +#define XEN_DMOP_set_ioreq_server_state 5 + +struct xen_dm_op_set_ioreq_server_state { + /* IN - server id */ + ioservid_t id; + /* IN - enabled? */ + uint8_t enabled; + uint8_t pad; +}; + +/* + * XEN_DMOP_destroy_ioreq_server: Destroy the IOREQ Server <id>. + * + * Any registered I/O ranges will be automatically deregistered. + */ +#define XEN_DMOP_destroy_ioreq_server 6 + +struct xen_dm_op_destroy_ioreq_server { + /* IN - server id */ + ioservid_t id; + uint16_t pad; +}; + +/* + * XEN_DMOP_track_dirty_vram: Track modifications to the specified pfn + * range. + * + * NOTE: The bitmap passed back to the caller is passed in a + * secondary buffer. + */ +#define XEN_DMOP_track_dirty_vram 7 + +struct xen_dm_op_track_dirty_vram { + /* IN - number of pages to be tracked */ + uint32_t nr; + uint32_t pad; + /* IN - first pfn to track */ + uint64_aligned_t first_pfn; +}; + +/* + * XEN_DMOP_set_pci_intx_level: Set the logical level of one of a domain's + * PCI INTx pins. + */ +#define XEN_DMOP_set_pci_intx_level 8 + +struct xen_dm_op_set_pci_intx_level { + /* IN - PCI INTx identification (domain:bus:device:intx) */ + uint16_t domain; + uint8_t bus, device, intx; + /* IN - Level: 0 -> deasserted, 1 -> asserted */ + uint8_t level; +}; + +/* + * XEN_DMOP_set_isa_irq_level: Set the logical level of a one of a domain's + * ISA IRQ lines. + */ +#define XEN_DMOP_set_isa_irq_level 9 + +struct xen_dm_op_set_isa_irq_level { + /* IN - ISA IRQ (0-15) */ + uint8_t isa_irq; + /* IN - Level: 0 -> deasserted, 1 -> asserted */ + uint8_t level; +}; + +/* + * XEN_DMOP_set_pci_link_route: Map a PCI INTx line to an IRQ line. + */ +#define XEN_DMOP_set_pci_link_route 10 + +struct xen_dm_op_set_pci_link_route { + /* PCI INTx line (0-3) */ + uint8_t link; + /* ISA IRQ (1-15) or 0 -> disable link */ + uint8_t isa_irq; +}; + +/* + * XEN_DMOP_modified_memory: Notify that a set of pages were modified by + * an emulator. + * + * DMOP buf 1 contains an array of xen_dm_op_modified_memory_extent with + * @nr_extents entries. + * + * On error, @nr_extents will contain the index+1 of the extent that + * had the error. It is not defined if or which pages may have been + * marked as dirty, in this event. + */ +#define XEN_DMOP_modified_memory 11 + +struct xen_dm_op_modified_memory { + /* + * IN - Number of extents to be processed + * OUT -returns n+1 for failing extent + */ + uint32_t nr_extents; + /* IN/OUT - Must be set to 0 */ + uint32_t opaque; +}; + +struct xen_dm_op_modified_memory_extent { + /* IN - number of contiguous pages modified */ + uint32_t nr; + uint32_t pad; + /* IN - first pfn modified */ + uint64_aligned_t first_pfn; +}; + +/* + * XEN_DMOP_set_mem_type: Notify that a region of memory is to be treated + * in a specific way. (See definition of + * hvmmem_type_t). + * + * NOTE: In the event of a continuation (return code -ERESTART), the + * @first_pfn is set to the value of the pfn of the remaining + * region and @nr reduced to the size of the remaining region. + */ +#define XEN_DMOP_set_mem_type 12 + +struct xen_dm_op_set_mem_type { + /* IN - number of contiguous pages */ + uint32_t nr; + /* IN - new hvmmem_type_t of region */ + uint16_t mem_type; + uint16_t pad; + /* IN - first pfn in region */ + uint64_aligned_t first_pfn; +}; + +/* + * XEN_DMOP_inject_event: Inject an event into a VCPU, which will + * get taken up when it is next scheduled. + * + * Note that the caller should know enough of the state of the CPU before + * injecting, to know what the effect of injecting the event will be. + */ +#define XEN_DMOP_inject_event 13 + +struct xen_dm_op_inject_event { + /* IN - index of vCPU */ + uint32_t vcpuid; + /* IN - interrupt vector */ + uint8_t vector; + /* IN - event type (DMOP_EVENT_* ) */ + uint8_t type; +/* NB. This enumeration precisely matches hvm.h:X86_EVENTTYPE_* */ +# define XEN_DMOP_EVENT_ext_int 0 /* external interrupt */ +# define XEN_DMOP_EVENT_nmi 2 /* nmi */ +# define XEN_DMOP_EVENT_hw_exc 3 /* hardware exception */ +# define XEN_DMOP_EVENT_sw_int 4 /* software interrupt (CD nn) */ +# define XEN_DMOP_EVENT_pri_sw_exc 5 /* ICEBP (F1) */ +# define XEN_DMOP_EVENT_sw_exc 6 /* INT3 (CC), INTO (CE) */ + /* IN - instruction length */ + uint8_t insn_len; + uint8_t pad0; + /* IN - error code (or ~0 to skip) */ + uint32_t error_code; + uint32_t pad1; + /* IN - CR2 for page faults */ + uint64_aligned_t cr2; +}; + +/* + * XEN_DMOP_inject_msi: Inject an MSI for an emulated device. + */ +#define XEN_DMOP_inject_msi 14 + +struct xen_dm_op_inject_msi { + /* IN - MSI data (lower 32 bits) */ + uint32_t data; + uint32_t pad; + /* IN - MSI address (0xfeexxxxx) */ + uint64_aligned_t addr; +}; + +/* + * XEN_DMOP_map_mem_type_to_ioreq_server : map or unmap the IOREQ Server <id> + * to specific memory type <type> + * for specific accesses <flags> + * + * For now, flags only accept the value of XEN_DMOP_IOREQ_MEM_ACCESS_WRITE, + * which means only write operations are to be forwarded to an ioreq server. + * Support for the emulation of read operations can be added when an ioreq + * server has such requirement in future. + */ +#define XEN_DMOP_map_mem_type_to_ioreq_server 15 + +struct xen_dm_op_map_mem_type_to_ioreq_server { + ioservid_t id; /* IN - ioreq server id */ + uint16_t type; /* IN - memory type */ + uint32_t flags; /* IN - types of accesses to be forwarded to the + ioreq server. flags with 0 means to unmap the + ioreq server */ + +#define XEN_DMOP_IOREQ_MEM_ACCESS_READ (1u << 0) +#define XEN_DMOP_IOREQ_MEM_ACCESS_WRITE (1u << 1) + + uint64_t opaque; /* IN/OUT - only used for hypercall continuation, + has to be set to zero by the caller */ +}; + +struct xen_dm_op { + uint32_t op; + uint32_t pad; + union { + struct xen_dm_op_create_ioreq_server create_ioreq_server; + struct xen_dm_op_get_ioreq_server_info get_ioreq_server_info; + struct xen_dm_op_ioreq_server_range map_io_range_to_ioreq_server; + struct xen_dm_op_ioreq_server_range unmap_io_range_from_ioreq_server; + struct xen_dm_op_set_ioreq_server_state set_ioreq_server_state; + struct xen_dm_op_destroy_ioreq_server destroy_ioreq_server; + struct xen_dm_op_track_dirty_vram track_dirty_vram; + struct xen_dm_op_set_pci_intx_level set_pci_intx_level; + struct xen_dm_op_set_isa_irq_level set_isa_irq_level; + struct xen_dm_op_set_pci_link_route set_pci_link_route; + struct xen_dm_op_modified_memory modified_memory; + struct xen_dm_op_set_mem_type set_mem_type; + struct xen_dm_op_inject_event inject_event; + struct xen_dm_op_inject_msi inject_msi; + struct xen_dm_op_map_mem_type_to_ioreq_server + map_mem_type_to_ioreq_server; + } u; +}; + +#endif /* __XEN__ || __XEN_TOOLS__ */ + +struct xen_dm_op_buf { + XEN_GUEST_HANDLE(void) h; + xen_ulong_t size; +}; +typedef struct xen_dm_op_buf xen_dm_op_buf_t; +DEFINE_XEN_GUEST_HANDLE(xen_dm_op_buf_t); + +/* ` enum neg_errnoval + * ` HYPERVISOR_dm_op(domid_t domid, + * ` unsigned int nr_bufs, + * ` xen_dm_op_buf_t bufs[]) + * ` + * + * @domid is the domain the hypercall operates on. + * @nr_bufs is the number of buffers in the @bufs array. + * @bufs points to an array of buffers where @bufs[0] contains a struct + * xen_dm_op, describing the specific device model operation and its + * parameters. + * @bufs[1..] may be referenced in the parameters for the purposes of + * passing extra information to or from the domain. + */ + +#endif /* __XEN_PUBLIC_HVM_DM_OP_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/xen/hvm/e820.h b/include/xen/hvm/e820.h index 5bdc227..4c42f33 100644 --- a/include/xen/hvm/e820.h +++ b/include/xen/hvm/e820.h @@ -1,4 +1,3 @@ - /* * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -17,11 +16,15 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2006, Keir Fraser */ #ifndef __XEN_PUBLIC_HVM_E820_H__ #define __XEN_PUBLIC_HVM_E820_H__ +#include "../xen.h" + /* E820 location in HVM virtual address space. */ #define HVM_E820_PAGE 0x00090000 #define HVM_E820_NR_OFFSET 0x000001E8 @@ -29,6 +32,7 @@ #define HVM_BELOW_4G_RAM_END 0xF0000000 #define HVM_BELOW_4G_MMIO_START HVM_BELOW_4G_RAM_END -#define HVM_BELOW_4G_MMIO_LENGTH ((1ULL << 32) - HVM_BELOW_4G_MMIO_START) +#define HVM_BELOW_4G_MMIO_LENGTH ((xen_mk_ullong(1) << 32) - \ + HVM_BELOW_4G_MMIO_START) #endif /* __XEN_PUBLIC_HVM_E820_H__ */ diff --git a/include/xen/hvm/hvm_info_table.h b/include/xen/hvm/hvm_info_table.h index 36085fa..08c252e 100644 --- a/include/xen/hvm/hvm_info_table.h +++ b/include/xen/hvm/hvm_info_table.h @@ -20,6 +20,8 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2006, Keir Fraser */ #ifndef __XEN_PUBLIC_HVM_HVM_INFO_TABLE_H__ @@ -32,6 +34,14 @@ /* Maximum we can support with current vLAPIC ID mapping. */ #define HVM_MAX_VCPUS 128 +/* + * In some cases SMP HVM guests may require knowledge of Xen's idea of vCPU ids + * for their vCPUs. For example, HYPERVISOR_vcpu_op and some EVTCHNOP_* + * hypercalls take vcpu id as a parameter. It is valid for HVM guests to assume + * that Xen's vCPU id always equals to ACPI (not APIC!) id in MADT table which + * is always present for SMP guests. + */ + struct hvm_info_table { char signature[8]; /* "HVM INFO" */ uint32_t length; diff --git a/include/xen/hvm/hvm_op.h b/include/xen/hvm/hvm_op.h index cde3571..0bdafdf 100644 --- a/include/xen/hvm/hvm_op.h +++ b/include/xen/hvm/hvm_op.h @@ -16,6 +16,8 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2007, Keir Fraser */ #ifndef __XEN_PUBLIC_HVM_HVM_OP_H__ @@ -36,6 +38,8 @@ struct xen_hvm_param { typedef struct xen_hvm_param xen_hvm_param_t; DEFINE_XEN_GUEST_HANDLE(xen_hvm_param_t); +#if __XEN_INTERFACE_VERSION__ < 0x00040900 + /* Set the logical level of one of a domain's PCI INTx wires. */ #define HVMOP_set_pci_intx_level 2 struct xen_hvm_set_pci_intx_level { @@ -74,6 +78,8 @@ struct xen_hvm_set_pci_link_route { typedef struct xen_hvm_set_pci_link_route xen_hvm_set_pci_link_route_t; DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_pci_link_route_t); +#endif /* __XEN_INTERFACE_VERSION__ < 0x00040900 */ + /* Flushes all VCPU TLBs: @arg must be NULL. */ #define HVMOP_flush_tlbs 5 @@ -81,58 +87,21 @@ typedef enum { HVMMEM_ram_rw, /* Normal read/write guest RAM */ HVMMEM_ram_ro, /* Read-only; writes are discarded */ HVMMEM_mmio_dm, /* Reads and write go to the device model */ - HVMMEM_mmio_write_dm /* Read-only; writes go to the device model */ +#if __XEN_INTERFACE_VERSION__ < 0x00040700 + HVMMEM_mmio_write_dm, /* Read-only; writes go to the device model */ +#else + HVMMEM_unused, /* Placeholder; setting memory to this type + will fail for code after 4.7.0 */ +#endif + HVMMEM_ioreq_server /* Memory type claimed by an ioreq server; type + changes to this value are only allowed after + an ioreq server has claimed its ownership. + Only pages with HVMMEM_ram_rw are allowed to + change to this type; conversely, pages with + this type are only allowed to be changed back + to HVMMEM_ram_rw. */ } hvmmem_type_t; -/* Following tools-only interfaces may change in future. */ -#if defined(__XEN__) || defined(__XEN_TOOLS__) - -/* Track dirty VRAM. */ -#define HVMOP_track_dirty_vram 6 -struct xen_hvm_track_dirty_vram { - /* Domain to be tracked. */ - domid_t domid; - /* Number of pages to track. */ - uint32_t nr; - /* First pfn to track. */ - uint64_aligned_t first_pfn; - /* OUT variable. */ - /* Dirty bitmap buffer. */ - XEN_GUEST_HANDLE_64(uint8) dirty_bitmap; -}; -typedef struct xen_hvm_track_dirty_vram xen_hvm_track_dirty_vram_t; -DEFINE_XEN_GUEST_HANDLE(xen_hvm_track_dirty_vram_t); - -/* Notify that some pages got modified by the Device Model. */ -#define HVMOP_modified_memory 7 -struct xen_hvm_modified_memory { - /* Domain to be updated. */ - domid_t domid; - /* Number of pages. */ - uint32_t nr; - /* First pfn. */ - uint64_aligned_t first_pfn; -}; -typedef struct xen_hvm_modified_memory xen_hvm_modified_memory_t; -DEFINE_XEN_GUEST_HANDLE(xen_hvm_modified_memory_t); - -#define HVMOP_set_mem_type 8 -/* Notify that a region of memory is to be treated in a specific way. */ -struct xen_hvm_set_mem_type { - /* Domain to be updated. */ - domid_t domid; - /* Memory type */ - uint16_t hvmmem_type; - /* Number of pages. */ - uint32_t nr; - /* First pfn. */ - uint64_aligned_t first_pfn; -}; -typedef struct xen_hvm_set_mem_type xen_hvm_set_mem_type_t; -DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_mem_type_t); - -#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */ - /* Hint from PV drivers for pagetable destruction. */ #define HVMOP_pagetable_dying 9 struct xen_hvm_pagetable_dying { @@ -170,38 +139,6 @@ DEFINE_XEN_GUEST_HANDLE(xen_hvm_xentrace_t); /* Deprecated by XENMEM_access_op_get_access */ #define HVMOP_get_mem_access 13 -#define HVMOP_inject_trap 14 -/* Inject a trap into a VCPU, which will get taken up on the next - * scheduling of it. Note that the caller should know enough of the - * state of the CPU before injecting, to know what the effect of - * injecting the trap will be. - */ -struct xen_hvm_inject_trap { - /* Domain to be queried. */ - domid_t domid; - /* VCPU */ - uint32_t vcpuid; - /* Vector number */ - uint32_t vector; - /* Trap type (HVMOP_TRAP_*) */ - uint32_t type; -/* NB. This enumeration precisely matches hvm.h:X86_EVENTTYPE_* */ -# define HVMOP_TRAP_ext_int 0 /* external interrupt */ -# define HVMOP_TRAP_nmi 2 /* nmi */ -# define HVMOP_TRAP_hw_exc 3 /* hardware exception */ -# define HVMOP_TRAP_sw_int 4 /* software interrupt (CD nn) */ -# define HVMOP_TRAP_pri_sw_exc 5 /* ICEBP (F1) */ -# define HVMOP_TRAP_sw_exc 6 /* INT3 (CC), INTO (CE) */ - /* Error code, or ~0u to skip */ - uint32_t error_code; - /* Intruction length */ - uint32_t insn_len; - /* CR2 for page faults */ - uint64_aligned_t cr2; -}; -typedef struct xen_hvm_inject_trap xen_hvm_inject_trap_t; -DEFINE_XEN_GUEST_HANDLE(xen_hvm_inject_trap_t); - #endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */ #define HVMOP_get_mem_type 15 @@ -221,152 +158,18 @@ DEFINE_XEN_GUEST_HANDLE(xen_hvm_get_mem_type_t); /* Following tools-only interfaces may change in future. */ #if defined(__XEN__) || defined(__XEN_TOOLS__) -/* MSI injection for emulated devices */ -#define HVMOP_inject_msi 16 -struct xen_hvm_inject_msi { - /* Domain to be injected */ - domid_t domid; - /* Data -- lower 32 bits */ - uint32_t data; - /* Address (0xfeexxxxx) */ - uint64_t addr; -}; -typedef struct xen_hvm_inject_msi xen_hvm_inject_msi_t; -DEFINE_XEN_GUEST_HANDLE(xen_hvm_inject_msi_t); - /* - * IOREQ Servers - * - * The interface between an I/O emulator an Xen is called an IOREQ Server. - * A domain supports a single 'legacy' IOREQ Server which is instantiated if - * parameter... - * - * HVM_PARAM_IOREQ_PFN is read (to get the gmfn containing the synchronous - * ioreq structures), or... - * HVM_PARAM_BUFIOREQ_PFN is read (to get the gmfn containing the buffered - * ioreq ring), or... - * HVM_PARAM_BUFIOREQ_EVTCHN is read (to get the event channel that Xen uses - * to request buffered I/O emulation). - * - * The following hypercalls facilitate the creation of IOREQ Servers for - * 'secondary' emulators which are invoked to implement port I/O, memory, or - * PCI config space ranges which they explicitly register. + * Definitions relating to DMOP_create_ioreq_server. (Defined here for + * backwards compatibility). */ -typedef uint16_t ioservid_t; - +#define HVM_IOREQSRV_BUFIOREQ_OFF 0 +#define HVM_IOREQSRV_BUFIOREQ_LEGACY 1 /* - * HVMOP_create_ioreq_server: Instantiate a new IOREQ Server for a secondary - * emulator servicing domain <domid>. - * - * The <id> handed back is unique for <domid>. If <handle_bufioreq> is zero - * the buffered ioreq ring will not be allocated and hence all emulation - * requestes to this server will be synchronous. + * Use this when read_pointer gets updated atomically and + * the pointer pair gets read atomically: */ -#define HVMOP_create_ioreq_server 17 -struct xen_hvm_create_ioreq_server { - domid_t domid; /* IN - domain to be serviced */ - uint8_t handle_bufioreq; /* IN - should server handle buffered ioreqs */ - ioservid_t id; /* OUT - server id */ -}; -typedef struct xen_hvm_create_ioreq_server xen_hvm_create_ioreq_server_t; -DEFINE_XEN_GUEST_HANDLE(xen_hvm_create_ioreq_server_t); - -/* - * HVMOP_get_ioreq_server_info: Get all the information necessary to access - * IOREQ Server <id>. - * - * The emulator needs to map the synchronous ioreq structures and buffered - * ioreq ring (if it exists) that Xen uses to request emulation. These are - * hosted in domain <domid>'s gmfns <ioreq_pfn> and <bufioreq_pfn> - * respectively. In addition, if the IOREQ Server is handling buffered - * emulation requests, the emulator needs to bind to event channel - * <bufioreq_port> to listen for them. (The event channels used for - * synchronous emulation requests are specified in the per-CPU ioreq - * structures in <ioreq_pfn>). - * If the IOREQ Server is not handling buffered emulation requests then the - * values handed back in <bufioreq_pfn> and <bufioreq_port> will both be 0. - */ -#define HVMOP_get_ioreq_server_info 18 -struct xen_hvm_get_ioreq_server_info { - domid_t domid; /* IN - domain to be serviced */ - ioservid_t id; /* IN - server id */ - evtchn_port_t bufioreq_port; /* OUT - buffered ioreq port */ - uint64_aligned_t ioreq_pfn; /* OUT - sync ioreq pfn */ - uint64_aligned_t bufioreq_pfn; /* OUT - buffered ioreq pfn */ -}; -typedef struct xen_hvm_get_ioreq_server_info xen_hvm_get_ioreq_server_info_t; -DEFINE_XEN_GUEST_HANDLE(xen_hvm_get_ioreq_server_info_t); - -/* - * HVM_map_io_range_to_ioreq_server: Register an I/O range of domain <domid> - * for emulation by the client of IOREQ - * Server <id> - * HVM_unmap_io_range_from_ioreq_server: Deregister an I/O range of <domid> - * for emulation by the client of IOREQ - * Server <id> - * - * There are three types of I/O that can be emulated: port I/O, memory accesses - * and PCI config space accesses. The <type> field denotes which type of range - * the <start> and <end> (inclusive) fields are specifying. - * PCI config space ranges are specified by segment/bus/device/function values - * which should be encoded using the HVMOP_PCI_SBDF helper macro below. - * - * NOTE: unless an emulation request falls entirely within a range mapped - * by a secondary emulator, it will not be passed to that emulator. - */ -#define HVMOP_map_io_range_to_ioreq_server 19 -#define HVMOP_unmap_io_range_from_ioreq_server 20 -struct xen_hvm_io_range { - domid_t domid; /* IN - domain to be serviced */ - ioservid_t id; /* IN - server id */ - uint32_t type; /* IN - type of range */ -# define HVMOP_IO_RANGE_PORT 0 /* I/O port range */ -# define HVMOP_IO_RANGE_MEMORY 1 /* MMIO range */ -# define HVMOP_IO_RANGE_PCI 2 /* PCI segment/bus/dev/func range */ - uint64_aligned_t start, end; /* IN - inclusive start and end of range */ -}; -typedef struct xen_hvm_io_range xen_hvm_io_range_t; -DEFINE_XEN_GUEST_HANDLE(xen_hvm_io_range_t); - -#define HVMOP_PCI_SBDF(s,b,d,f) \ - ((((s) & 0xffff) << 16) | \ - (((b) & 0xff) << 8) | \ - (((d) & 0x1f) << 3) | \ - ((f) & 0x07)) - -/* - * HVMOP_destroy_ioreq_server: Destroy the IOREQ Server <id> servicing domain - * <domid>. - * - * Any registered I/O ranges will be automatically deregistered. - */ -#define HVMOP_destroy_ioreq_server 21 -struct xen_hvm_destroy_ioreq_server { - domid_t domid; /* IN - domain to be serviced */ - ioservid_t id; /* IN - server id */ -}; -typedef struct xen_hvm_destroy_ioreq_server xen_hvm_destroy_ioreq_server_t; -DEFINE_XEN_GUEST_HANDLE(xen_hvm_destroy_ioreq_server_t); - -/* - * HVMOP_set_ioreq_server_state: Enable or disable the IOREQ Server <id> servicing - * domain <domid>. - * - * The IOREQ Server will not be passed any emulation requests until it is in the - * enabled state. - * Note that the contents of the ioreq_pfn and bufioreq_fn (see - * HVMOP_get_ioreq_server_info) are not meaningful until the IOREQ Server is in - * the enabled state. - */ -#define HVMOP_set_ioreq_server_state 22 -struct xen_hvm_set_ioreq_server_state { - domid_t domid; /* IN - domain to be serviced */ - ioservid_t id; /* IN - server id */ - uint8_t enabled; /* IN - enabled? */ -}; -typedef struct xen_hvm_set_ioreq_server_state xen_hvm_set_ioreq_server_state_t; -DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_ioreq_server_state_t); +#define HVM_IOREQSRV_BUFIOREQ_ATOMIC 2 #endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */ @@ -389,6 +192,97 @@ DEFINE_XEN_GUEST_HANDLE(xen_hvm_evtchn_upcall_vector_t); #endif /* defined(__i386__) || defined(__x86_64__) */ +#define HVMOP_guest_request_vm_event 24 + +/* HVMOP_altp2m: perform altp2m state operations */ +#define HVMOP_altp2m 25 + +#define HVMOP_ALTP2M_INTERFACE_VERSION 0x00000001 + +struct xen_hvm_altp2m_domain_state { + /* IN or OUT variable on/off */ + uint8_t state; +}; +typedef struct xen_hvm_altp2m_domain_state xen_hvm_altp2m_domain_state_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_domain_state_t); + +struct xen_hvm_altp2m_vcpu_enable_notify { + uint32_t vcpu_id; + uint32_t pad; + /* #VE info area gfn */ + uint64_t gfn; +}; +typedef struct xen_hvm_altp2m_vcpu_enable_notify xen_hvm_altp2m_vcpu_enable_notify_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_vcpu_enable_notify_t); + +struct xen_hvm_altp2m_view { + /* IN/OUT variable */ + uint16_t view; + /* Create view only: default access type + * NOTE: currently ignored */ + uint16_t hvmmem_default_access; /* xenmem_access_t */ +}; +typedef struct xen_hvm_altp2m_view xen_hvm_altp2m_view_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_view_t); + +struct xen_hvm_altp2m_set_mem_access { + /* view */ + uint16_t view; + /* Memory type */ + uint16_t hvmmem_access; /* xenmem_access_t */ + uint32_t pad; + /* gfn */ + uint64_t gfn; +}; +typedef struct xen_hvm_altp2m_set_mem_access xen_hvm_altp2m_set_mem_access_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_set_mem_access_t); + +struct xen_hvm_altp2m_change_gfn { + /* view */ + uint16_t view; + uint16_t pad1; + uint32_t pad2; + /* old gfn */ + uint64_t old_gfn; + /* new gfn, INVALID_GFN (~0UL) means revert */ + uint64_t new_gfn; +}; +typedef struct xen_hvm_altp2m_change_gfn xen_hvm_altp2m_change_gfn_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_change_gfn_t); + +struct xen_hvm_altp2m_op { + uint32_t version; /* HVMOP_ALTP2M_INTERFACE_VERSION */ + uint32_t cmd; +/* Get/set the altp2m state for a domain */ +#define HVMOP_altp2m_get_domain_state 1 +#define HVMOP_altp2m_set_domain_state 2 +/* Set the current VCPU to receive altp2m event notifications */ +#define HVMOP_altp2m_vcpu_enable_notify 3 +/* Create a new view */ +#define HVMOP_altp2m_create_p2m 4 +/* Destroy a view */ +#define HVMOP_altp2m_destroy_p2m 5 +/* Switch view for an entire domain */ +#define HVMOP_altp2m_switch_p2m 6 +/* Notify that a page of memory is to have specific access types */ +#define HVMOP_altp2m_set_mem_access 7 +/* Change a p2m entry to have a different gfn->mfn mapping */ +#define HVMOP_altp2m_change_gfn 8 + domid_t domain; + uint16_t pad1; + uint32_t pad2; + union { + struct xen_hvm_altp2m_domain_state domain_state; + struct xen_hvm_altp2m_vcpu_enable_notify enable_notify; + struct xen_hvm_altp2m_view view; + struct xen_hvm_altp2m_set_mem_access set_mem_access; + struct xen_hvm_altp2m_change_gfn change_gfn; + uint8_t pad[64]; + } u; +}; +typedef struct xen_hvm_altp2m_op xen_hvm_altp2m_op_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_op_t); + #endif /* __XEN_PUBLIC_HVM_HVM_OP_H__ */ /* diff --git a/include/xen/hvm/hvm_vcpu.h b/include/xen/hvm/hvm_vcpu.h new file mode 100644 index 0000000..d21abf1 --- /dev/null +++ b/include/xen/hvm/hvm_vcpu.h @@ -0,0 +1,144 @@ +/* + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2015, Roger Pau Monne <roger.pau@xxxxxxxxxx> + */ + +#ifndef __XEN_PUBLIC_HVM_HVM_VCPU_H__ +#define __XEN_PUBLIC_HVM_HVM_VCPU_H__ + +#include "../xen.h" + +struct vcpu_hvm_x86_32 { + uint32_t eax; + uint32_t ecx; + uint32_t edx; + uint32_t ebx; + uint32_t esp; + uint32_t ebp; + uint32_t esi; + uint32_t edi; + uint32_t eip; + uint32_t eflags; + + uint32_t cr0; + uint32_t cr3; + uint32_t cr4; + + uint32_t pad1; + + /* + * EFER should only be used to set the NXE bit (if required) + * when starting a vCPU in 32bit mode with paging enabled or + * to set the LME/LMA bits in order to start the vCPU in + * compatibility mode. + */ + uint64_t efer; + + uint32_t cs_base; + uint32_t ds_base; + uint32_t ss_base; + uint32_t es_base; + uint32_t tr_base; + uint32_t cs_limit; + uint32_t ds_limit; + uint32_t ss_limit; + uint32_t es_limit; + uint32_t tr_limit; + uint16_t cs_ar; + uint16_t ds_ar; + uint16_t ss_ar; + uint16_t es_ar; + uint16_t tr_ar; + + uint16_t pad2[3]; +}; + +/* + * The layout of the _ar fields of the segment registers is the + * following: + * + * Bits [0,3]: type (bits 40-43). + * Bit 4: s (descriptor type, bit 44). + * Bit [5,6]: dpl (descriptor privilege level, bits 45-46). + * Bit 7: p (segment-present, bit 47). + * Bit 8: avl (available for system software, bit 52). + * Bit 9: l (64-bit code segment, bit 53). + * Bit 10: db (meaning depends on the segment, bit 54). + * Bit 11: g (granularity, bit 55) + * Bits [12,15]: unused, must be blank. + * + * A more complete description of the meaning of this fields can be + * obtained from the Intel SDM, Volume 3, section 3.4.5. + */ + +struct vcpu_hvm_x86_64 { + uint64_t rax; + uint64_t rcx; + uint64_t rdx; + uint64_t rbx; + uint64_t rsp; + uint64_t rbp; + uint64_t rsi; + uint64_t rdi; + uint64_t rip; + uint64_t rflags; + + uint64_t cr0; + uint64_t cr3; + uint64_t cr4; + uint64_t efer; + + /* + * Using VCPU_HVM_MODE_64B implies that the vCPU is launched + * directly in long mode, so the cached parts of the segment + * registers get set to match that environment. + * + * If the user wants to launch the vCPU in compatibility mode + * the 32-bit structure should be used instead. + */ +}; + +struct vcpu_hvm_context { +#define VCPU_HVM_MODE_32B 0 /* 32bit fields of the structure will be used. */ +#define VCPU_HVM_MODE_64B 1 /* 64bit fields of the structure will be used. */ + uint32_t mode; + + uint32_t pad; + + /* CPU registers. */ + union { + struct vcpu_hvm_x86_32 x86_32; + struct vcpu_hvm_x86_64 x86_64; + } cpu_regs; +}; +typedef struct vcpu_hvm_context vcpu_hvm_context_t; +DEFINE_XEN_GUEST_HANDLE(vcpu_hvm_context_t); + +#endif /* __XEN_PUBLIC_HVM_HVM_VCPU_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/xen/hvm/hvm_xs_strings.h b/include/xen/hvm/hvm_xs_strings.h index 8aec935..fea1dd4 100644 --- a/include/xen/hvm/hvm_xs_strings.h +++ b/include/xen/hvm/hvm_xs_strings.h @@ -20,6 +20,8 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2013, Citrix Systems */ #ifndef __XEN_PUBLIC_HVM_HVM_XS_STRINGS_H__ @@ -69,6 +71,7 @@ #define HVM_XS_SYSTEM_SERIAL_NUMBER "bios-strings/system-serial-number" #define HVM_XS_ENCLOSURE_MANUFACTURER "bios-strings/enclosure-manufacturer" #define HVM_XS_ENCLOSURE_SERIAL_NUMBER "bios-strings/enclosure-serial-number" +#define HVM_XS_ENCLOSURE_ASSET_TAG "bios-strings/enclosure-asset-tag" #define HVM_XS_BATTERY_MANUFACTURER "bios-strings/battery-manufacturer" #define HVM_XS_BATTERY_DEVICE_NAME "bios-strings/battery-device-name" diff --git a/include/xen/hvm/ioreq.h b/include/xen/hvm/ioreq.h index 5b5fedf..d309d12 100644 --- a/include/xen/hvm/ioreq.h +++ b/include/xen/hvm/ioreq.h @@ -83,8 +83,17 @@ typedef struct buf_ioreq buf_ioreq_t; #define IOREQ_BUFFER_SLOT_NUM 511 /* 8 bytes each, plus 2 4-byte indexes */ struct buffered_iopage { - unsigned int read_pointer; - unsigned int write_pointer; +#ifdef __XEN__ + union bufioreq_pointers { + struct { +#endif + uint32_t read_pointer; + uint32_t write_pointer; +#ifdef __XEN__ + }; + uint64_t full; + } ptrs; +#endif buf_ioreq_t buf_ioreq[IOREQ_BUFFER_SLOT_NUM]; }; /* NB. Size of this structure must be no greater than one page. */ typedef struct buffered_iopage buffered_iopage_t; @@ -94,14 +103,19 @@ typedef struct buffered_iopage buffered_iopage_t; * version number in HVM_PARAM_ACPI_IOPORTS_LOCATION. */ -/* Version 0 (default): Traditional Xen locations. */ +/* + * Version 0 (default): Traditional (obsolete) Xen locations. + * + * These are now only used for compatibility with VMs migrated + * from older Xen versions. + */ #define ACPI_PM1A_EVT_BLK_ADDRESS_V0 0x1f40 #define ACPI_PM1A_CNT_BLK_ADDRESS_V0 (ACPI_PM1A_EVT_BLK_ADDRESS_V0 + 0x04) #define ACPI_PM_TMR_BLK_ADDRESS_V0 (ACPI_PM1A_EVT_BLK_ADDRESS_V0 + 0x08) #define ACPI_GPE0_BLK_ADDRESS_V0 (ACPI_PM_TMR_BLK_ADDRESS_V0 + 0x20) #define ACPI_GPE0_BLK_LEN_V0 0x08 -/* Version 1: Locations preferred by modern Qemu. */ +/* Version 1: Locations preferred by modern Qemu (including Qemu-trad). */ #define ACPI_PM1A_EVT_BLK_ADDRESS_V1 0xb000 #define ACPI_PM1A_CNT_BLK_ADDRESS_V1 (ACPI_PM1A_EVT_BLK_ADDRESS_V1 + 0x04) #define ACPI_PM_TMR_BLK_ADDRESS_V1 (ACPI_PM1A_EVT_BLK_ADDRESS_V1 + 0x08) diff --git a/include/xen/hvm/params.h b/include/xen/hvm/params.h index a2d43bc..2ec2e7c 100644 --- a/include/xen/hvm/params.h +++ b/include/xen/hvm/params.h @@ -16,6 +16,8 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2007, Keir Fraser */ #ifndef __XEN_PUBLIC_HVM_PARAMS_H__ @@ -27,18 +29,47 @@ * Parameter space for HVMOP_{set,get}_param. */ +#define HVM_PARAM_CALLBACK_IRQ 0 +#define HVM_PARAM_CALLBACK_IRQ_TYPE_MASK xen_mk_ullong(0xFF00000000000000) /* * How should CPU0 event-channel notifications be delivered? - * val[63:56] == 0: val[55:0] is a delivery GSI (Global System Interrupt). - * val[63:56] == 1: val[55:0] is a delivery PCI INTx line, as follows: - * Domain = val[47:32], Bus = val[31:16], - * DevFn = val[15: 8], IntX = val[ 1: 0] - * val[63:56] == 2: val[7:0] is a vector number, check for - * XENFEAT_hvm_callback_vector to know if this delivery - * method is available. + * * If val == 0 then CPU0 event-channel notifications are not delivered. + * If val != 0, val[63:56] encodes the type, as follows: + */ + +#define HVM_PARAM_CALLBACK_TYPE_GSI 0 +/* + * val[55:0] is a delivery GSI. GSI 0 cannot be used, as it aliases val == 0, + * and disables all notifications. + */ + +#define HVM_PARAM_CALLBACK_TYPE_PCI_INTX 1 +/* + * val[55:0] is a delivery PCI INTx line: + * Domain = val[47:32], Bus = val[31:16] DevFn = val[15:8], IntX = val[1:0] */ -#define HVM_PARAM_CALLBACK_IRQ 0 + +#if defined(__i386__) || defined(__x86_64__) +#define HVM_PARAM_CALLBACK_TYPE_VECTOR 2 +/* + * val[7:0] is a vector number. Check for XENFEAT_hvm_callback_vector to know + * if this delivery method is available. + */ +#elif defined(__arm__) || defined(__aarch64__) +#define HVM_PARAM_CALLBACK_TYPE_PPI 2 +/* + * val[55:16] needs to be zero. + * val[15:8] is interrupt flag of the PPI used by event-channel: + * bit 8: the PPI is edge(1) or level(0) triggered + * bit 9: the PPI is active low(1) or high(0) + * val[7:0] is a PPI number used by event-channel. + * This is only used by ARM/ARM64 and masking/eoi the interrupt associated to + * the notification is handled by the interrupt controller. + */ +#define HVM_PARAM_CALLBACK_TYPE_PPI_FLAG_MASK 0xFF00 +#define HVM_PARAM_CALLBACK_TYPE_PPI_FLAG_LOW_LEVEL 2 +#endif /* * These are not used by Xen. They are here for convenience of HVM-guest @@ -96,11 +127,26 @@ #define _HVMPV_reference_tsc 3 #define HVMPV_reference_tsc (1 << _HVMPV_reference_tsc) +/* Use Hypercall for remote TLB flush */ +#define _HVMPV_hcall_remote_tlb_flush 4 +#define HVMPV_hcall_remote_tlb_flush (1 << _HVMPV_hcall_remote_tlb_flush) + +/* Use APIC assist */ +#define _HVMPV_apic_assist 5 +#define HVMPV_apic_assist (1 << _HVMPV_apic_assist) + +/* Enable crash MSRs */ +#define _HVMPV_crash_ctl 6 +#define HVMPV_crash_ctl (1 << _HVMPV_crash_ctl) + #define HVMPV_feature_mask \ - (HVMPV_base_freq | \ - HVMPV_no_freq | \ - HVMPV_time_ref_count | \ - HVMPV_reference_tsc) + (HVMPV_base_freq | \ + HVMPV_no_freq | \ + HVMPV_time_ref_count | \ + HVMPV_reference_tsc | \ + HVMPV_hcall_remote_tlb_flush | \ + HVMPV_apic_assist | \ + HVMPV_crash_ctl) #endif @@ -162,8 +208,7 @@ */ #define HVM_PARAM_ACPI_IOPORTS_LOCATION 19 -/* Enable blocking memory events, async or sync (pause vcpu until response) - * onchangeonly indicates messages only on a change of value */ +/* Deprecated */ #define HVM_PARAM_MEMORY_EVENT_CR0 20 #define HVM_PARAM_MEMORY_EVENT_CR3 21 #define HVM_PARAM_MEMORY_EVENT_CR4 22 @@ -171,18 +216,12 @@ #define HVM_PARAM_MEMORY_EVENT_SINGLE_STEP 25 #define HVM_PARAM_MEMORY_EVENT_MSR 30 -#define HVMPME_MODE_MASK (3 << 0) -#define HVMPME_mode_disabled 0 -#define HVMPME_mode_async 1 -#define HVMPME_mode_sync 2 -#define HVMPME_onchangeonly (1 << 2) - /* Boolean: Enable nestedhvm (hvm only) */ #define HVM_PARAM_NESTEDHVM 24 /* Params for the mem event rings */ #define HVM_PARAM_PAGING_RING_PFN 27 -#define HVM_PARAM_ACCESS_RING_PFN 28 +#define HVM_PARAM_MONITOR_RING_PFN 28 #define HVM_PARAM_SHARING_RING_PFN 29 /* SHUTDOWN_* action in case of a triple fault */ @@ -194,6 +233,52 @@ /* Location of the VM Generation ID in guest physical address space. */ #define HVM_PARAM_VM_GENERATION_ID_ADDR 34 -#define HVM_NR_PARAMS 35 +/* + * Set mode for altp2m: + * disabled: don't activate altp2m (default) + * mixed: allow access to all altp2m ops for both in-guest and external tools + * external: allow access to external privileged tools only + * limited: guest only has limited access (ie. control VMFUNC and #VE) + */ +#define HVM_PARAM_ALTP2M 35 +#define XEN_ALTP2M_disabled 0 +#define XEN_ALTP2M_mixed 1 +#define XEN_ALTP2M_external 2 +#define XEN_ALTP2M_limited 3 + +/* + * Size of the x87 FPU FIP/FDP registers that the hypervisor needs to + * save/restore. This is a workaround for a hardware limitation that + * does not allow the full FIP/FDP and FCS/FDS to be restored. + * + * Valid values are: + * + * 8: save/restore 64-bit FIP/FDP and clear FCS/FDS (default if CPU + * has FPCSDS feature). + * + * 4: save/restore 32-bit FIP/FDP, FCS/FDS, and clear upper 32-bits of + * FIP/FDP. + * + * 0: allow hypervisor to choose based on the value of FIP/FDP + * (default if CPU does not have FPCSDS). + * + * If FPCSDS (bit 13 in CPUID leaf 0x7, subleaf 0x0) is set, the CPU + * never saves FCS/FDS and this parameter should be left at the + * default of 8. + */ +#define HVM_PARAM_X87_FIP_WIDTH 36 + +/* + * TSS (and its size) used on Intel when CR0.PE=0. The address occupies + * the low 32 bits, while the size is in the high 32 ones. + */ +#define HVM_PARAM_VM86_TSS_SIZED 37 + +/* Enable MCA capabilities. */ +#define HVM_PARAM_MCA_CAP 38 +#define XEN_HVM_MCA_CAP_LMCE (xen_mk_ullong(1) << 0) +#define XEN_HVM_MCA_CAP_MASK XEN_HVM_MCA_CAP_LMCE + +#define HVM_NR_PARAMS 39 #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */ diff --git a/include/xen/hvm/save.h b/include/xen/hvm/save.h index cc8b5fd..0bd240d 100644 --- a/include/xen/hvm/save.h +++ b/include/xen/hvm/save.h @@ -63,13 +63,15 @@ struct hvm_save_descriptor { #ifdef __XEN__ # define DECLARE_HVM_SAVE_TYPE_COMPAT(_x, _code, _type, _ctype, _fix) \ - static inline int __HVM_SAVE_FIX_COMPAT_##_x(void *h) { return _fix(h); } \ - struct __HVM_SAVE_TYPE_##_x { _type t; char c[_code]; char cpt[2];}; \ + static inline int __HVM_SAVE_FIX_COMPAT_##_x(void *h, uint32_t size) \ + { return _fix(h, size); } \ + struct __HVM_SAVE_TYPE_##_x { _type t; char c[_code]; char cpt[2];}; \ struct __HVM_SAVE_TYPE_COMPAT_##_x { _ctype t; } # include <xen/lib.h> /* BUG() */ # define DECLARE_HVM_SAVE_TYPE(_x, _code, _type) \ - static inline int __HVM_SAVE_FIX_COMPAT_##_x(void *h) { BUG(); return -1; } \ + static inline int __HVM_SAVE_FIX_COMPAT_##_x(void *h, uint32_t size) \ + { BUG(); return -1; } \ struct __HVM_SAVE_TYPE_##_x { _type t; char c[_code]; char cpt[1];}; \ struct __HVM_SAVE_TYPE_COMPAT_##_x { _type t; } #else @@ -89,7 +91,7 @@ struct hvm_save_descriptor { # define HVM_SAVE_LENGTH_COMPAT(_x) (sizeof (HVM_SAVE_TYPE_COMPAT(_x))) # define HVM_SAVE_HAS_COMPAT(_x) (sizeof (((struct __HVM_SAVE_TYPE_##_x *)(0))->cpt)-1) -# define HVM_SAVE_FIX_COMPAT(_x, _dst) __HVM_SAVE_FIX_COMPAT_##_x(_dst) +# define HVM_SAVE_FIX_COMPAT(_x, _dst, _size) __HVM_SAVE_FIX_COMPAT_##_x(_dst, _size) #endif /* diff --git a/include/xen/io/9pfs.h b/include/xen/io/9pfs.h new file mode 100644 index 0000000..4bfd5d4 --- /dev/null +++ b/include/xen/io/9pfs.h @@ -0,0 +1,49 @@ +/* + * 9pfs.h -- Xen 9PFS transport + * + * Refer to docs/misc/9pfs.markdown for the specification + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (C) 2017 Stefano Stabellini <stefano@xxxxxxxxxxx> + */ + +#ifndef __XEN_PUBLIC_IO_9PFS_H__ +#define __XEN_PUBLIC_IO_9PFS_H__ + +#include "../grant_table.h" +#include "ring.h" + +/* + * See docs/misc/9pfs.markdown in xen.git for the full specification: + * https://xenbits.xen.org/docs/unstable/misc/9pfs.html + */ +DEFINE_XEN_FLEX_RING_AND_INTF(xen_9pfs); + +#endif + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/xen/io/blkif.h b/include/xen/io/blkif.h index 6baf7fb..15a71e3 100644 --- a/include/xen/io/blkif.h +++ b/include/xen/io/blkif.h @@ -89,8 +89,22 @@ * Values: string * * A free formatted string providing sufficient information for the - * backend driver to open the backing device. (e.g. the path to the - * file or block device representing the backing store.) + * hotplug script to attach the device and provide a suitable + * handler (ie: a block device) for blkback to use. + * + * physical-device + * Values: "MAJOR:MINOR" + * Notes: 11 + * + * MAJOR and MINOR are the major number and minor number of the + * backing device respectively. + * + * physical-device-path + * Values: path string + * + * A string that contains the absolute path to the disk image. On + * NetBSD and Linux this is always a block device, while on FreeBSD + * it can be either a block device or a regular file. * * type * Values: "file", "phy", "tap" @@ -202,10 +216,9 @@ * Default Value: 1 * * This optional property, set by the toolstack, instructs the backend - * to offer discard to the frontend. If the property is missing the - * backend should offer discard if the backing storage actually supports - * it. This optional property, set by the toolstack, requests that the - * backend offer, or not offer, discard to the frontend. + * to offer (or not to offer) discard to the frontend. If the property + * is missing the backend should offer discard if the backing storage + * actually supports it. * * discard-alignment * Values: <uint32_t> @@ -385,6 +398,55 @@ * than RING_SIZE * BLKIF_MAX_SEGMENTS_PER_REQUEST. *(10) The discard-secure property may be present and will be set to 1 if the * backing device supports secure discard. + *(11) Only used by Linux and NetBSD. + */ + +/* + * Multiple hardware queues/rings: + * If supported, the backend will write the key "multi-queue-max-queues" to + * the directory for that vbd, and set its value to the maximum supported + * number of queues. + * Frontends that are aware of this feature and wish to use it can write the + * key "multi-queue-num-queues" with the number they wish to use, which must be + * greater than zero, and no more than the value reported by the backend in + * "multi-queue-max-queues". + * + * For frontends requesting just one queue, the usual event-channel and + * ring-ref keys are written as before, simplifying the backend processing + * to avoid distinguishing between a frontend that doesn't understand the + * multi-queue feature, and one that does, but requested only one queue. + * + * Frontends requesting two or more queues must not write the toplevel + * event-channel and ring-ref keys, instead writing those keys under sub-keys + * having the name "queue-N" where N is the integer ID of the queue/ring for + * which those keys belong. Queues are indexed from zero. + * For example, a frontend with two queues must write the following set of + * queue-related keys: + * + * /local/domain/1/device/vbd/0/multi-queue-num-queues = "2" + * /local/domain/1/device/vbd/0/queue-0 = "" + * /local/domain/1/device/vbd/0/queue-0/ring-ref = "<ring-ref#0>" + * /local/domain/1/device/vbd/0/queue-0/event-channel = "<evtchn#0>" + * /local/domain/1/device/vbd/0/queue-1 = "" + * /local/domain/1/device/vbd/0/queue-1/ring-ref = "<ring-ref#1>" + * /local/domain/1/device/vbd/0/queue-1/event-channel = "<evtchn#1>" + * + * It is also possible to use multiple queues/rings together with + * feature multi-page ring buffer. + * For example, a frontend requests two queues/rings and the size of each ring + * buffer is two pages must write the following set of related keys: + * + * /local/domain/1/device/vbd/0/multi-queue-num-queues = "2" + * /local/domain/1/device/vbd/0/ring-page-order = "1" + * /local/domain/1/device/vbd/0/queue-0 = "" + * /local/domain/1/device/vbd/0/queue-0/ring-ref0 = "<ring-ref#0>" + * /local/domain/1/device/vbd/0/queue-0/ring-ref1 = "<ring-ref#1>" + * /local/domain/1/device/vbd/0/queue-0/event-channel = "<evtchn#0>" + * /local/domain/1/device/vbd/0/queue-1 = "" + * /local/domain/1/device/vbd/0/queue-1/ring-ref0 = "<ring-ref#2>" + * /local/domain/1/device/vbd/0/queue-1/ring-ref1 = "<ring-ref#3>" + * /local/domain/1/device/vbd/0/queue-1/event-channel = "<evtchn#1>" + * */ /* diff --git a/include/xen/io/console.h b/include/xen/io/console.h index e2cd97f..0f0711f 100644 --- a/include/xen/io/console.h +++ b/include/xen/io/console.h @@ -27,6 +27,8 @@ #ifndef __XEN_PUBLIC_IO_CONSOLE_H__ #define __XEN_PUBLIC_IO_CONSOLE_H__ +#include "ring.h" + typedef uint32_t XENCONS_RING_IDX; #define MASK_XENCONS_IDX(idx, ring) ((idx) & (sizeof(ring)-1)) @@ -38,6 +40,10 @@ struct xencons_interface { XENCONS_RING_IDX out_cons, out_prod; }; +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +DEFINE_XEN_FLEX_RING(xencons); +#endif + #endif /* __XEN_PUBLIC_IO_CONSOLE_H__ */ /* diff --git a/include/xen/io/displif.h b/include/xen/io/displif.h new file mode 100644 index 0000000..8a94f1f --- /dev/null +++ b/include/xen/io/displif.h @@ -0,0 +1,864 @@ +/****************************************************************************** + * displif.h + * + * Unified display device I/O interface for Xen guest OSes. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (C) 2016-2017 EPAM Systems Inc. + * + * Authors: Oleksandr Andrushchenko <oleksandr_andrushchenko@xxxxxxxx> + * Oleksandr Grytsov <oleksandr_grytsov@xxxxxxxx> + */ + +#ifndef __XEN_PUBLIC_IO_DISPLIF_H__ +#define __XEN_PUBLIC_IO_DISPLIF_H__ + +#include "ring.h" +#include "../grant_table.h" + +/* + ****************************************************************************** + * Protocol version + ****************************************************************************** + */ +#define XENDISPL_PROTOCOL_VERSION "1" + +/* + ****************************************************************************** + * Main features provided by the protocol + ****************************************************************************** + * This protocol aims to provide a unified protocol which fits more + * sophisticated use-cases than a framebuffer device can handle. At the + * moment basic functionality is supported with the intention to be extended: + * o multiple dynamically allocated/destroyed framebuffers + * o buffers of arbitrary sizes + * o buffer allocation at either back or front end + * o better configuration options including multiple display support + * + * Note: existing fbif can be used together with displif running at the + * same time, e.g. on Linux one provides framebuffer and another DRM/KMS + * + * Note: display resolution (XenStore's "resolution" property) defines + * visible area of the virtual display. At the same time resolution of + * the display and frame buffers may differ: buffers can be smaller, equal + * or bigger than the visible area. This is to enable use-cases, where backend + * may do some post-processing of the display and frame buffers supplied, + * e.g. those buffers can be just a part of the final composition. + * + ****************************************************************************** + * Direction of improvements + ****************************************************************************** + * Future extensions to the existing protocol may include: + * o display/connector cloning + * o allocation of objects other than display buffers + * o plane/overlay support + * o scaling support + * o rotation support + * + ****************************************************************************** + * Feature and Parameter Negotiation + ****************************************************************************** + * + * Front->back notifications: when enqueuing a new request, sending a + * notification can be made conditional on xendispl_req (i.e., the generic + * hold-off mechanism provided by the ring macros). Backends must set + * xendispl_req appropriately (e.g., using RING_FINAL_CHECK_FOR_REQUESTS()). + * + * Back->front notifications: when enqueuing a new response, sending a + * notification can be made conditional on xendispl_resp (i.e., the generic + * hold-off mechanism provided by the ring macros). Frontends must set + * xendispl_resp appropriately (e.g., using RING_FINAL_CHECK_FOR_RESPONSES()). + * + * The two halves of a para-virtual display driver utilize nodes within + * XenStore to communicate capabilities and to negotiate operating parameters. + * This section enumerates these nodes which reside in the respective front and + * backend portions of XenStore, following the XenBus convention. + * + * All data in XenStore is stored as strings. Nodes specifying numeric + * values are encoded in decimal. Integer value ranges listed below are + * expressed as fixed sized integer types capable of storing the conversion + * of a properly formated node string, without loss of information. + * + ****************************************************************************** + * Example configuration + ****************************************************************************** + * + * Note: depending on the use-case backend can expose more display connectors + * than the underlying HW physically has by employing SW graphics compositors + * + * This is an example of backend and frontend configuration: + * + *--------------------------------- Backend ----------------------------------- + * + * /local/domain/0/backend/vdispl/1/0/frontend-id = "1" + * /local/domain/0/backend/vdispl/1/0/frontend = "/local/domain/1/device/vdispl/0" + * /local/domain/0/backend/vdispl/1/0/state = "4" + * /local/domain/0/backend/vdispl/1/0/versions = "1,2" + * + *--------------------------------- Frontend ---------------------------------- + * + * /local/domain/1/device/vdispl/0/backend-id = "0" + * /local/domain/1/device/vdispl/0/backend = "/local/domain/0/backend/vdispl/1/0" + * /local/domain/1/device/vdispl/0/state = "4" + * /local/domain/1/device/vdispl/0/version = "1" + * /local/domain/1/device/vdispl/0/be-alloc = "1" + * + *-------------------------- Connector 0 configuration ------------------------ + * + * /local/domain/1/device/vdispl/0/0/resolution = "1920x1080" + * /local/domain/1/device/vdispl/0/0/req-ring-ref = "2832" + * /local/domain/1/device/vdispl/0/0/req-event-channel = "15" + * /local/domain/1/device/vdispl/0/0/evt-ring-ref = "387" + * /local/domain/1/device/vdispl/0/0/evt-event-channel = "16" + * + *-------------------------- Connector 1 configuration ------------------------ + * + * /local/domain/1/device/vdispl/0/1/resolution = "800x600" + * /local/domain/1/device/vdispl/0/1/req-ring-ref = "2833" + * /local/domain/1/device/vdispl/0/1/req-event-channel = "17" + * /local/domain/1/device/vdispl/0/1/evt-ring-ref = "388" + * /local/domain/1/device/vdispl/0/1/evt-event-channel = "18" + * + ****************************************************************************** + * Backend XenBus Nodes + ****************************************************************************** + * + *----------------------------- Protocol version ------------------------------ + * + * versions + * Values: <string> + * + * List of XENDISPL_LIST_SEPARATOR separated protocol versions supported + * by the backend. For example "1,2,3". + * + ****************************************************************************** + * Frontend XenBus Nodes + ****************************************************************************** + * + *-------------------------------- Addressing --------------------------------- + * + * dom-id + * Values: <uint16_t> + * + * Domain identifier. + * + * dev-id + * Values: <uint16_t> + * + * Device identifier. + * + * conn-idx + * Values: <uint8_t> + * + * Zero based contigous index of the connector. + * /local/domain/<dom-id>/device/vdispl/<dev-id>/<conn-idx>/... + * + *----------------------------- Protocol version ------------------------------ + * + * version + * Values: <string> + * + * Protocol version, chosen among the ones supported by the backend. + * + *------------------------- Backend buffer allocation ------------------------- + * + * be-alloc + * Values: "0", "1" + * + * If value is set to "1", then backend can be a buffer provider/allocator + * for this domain during XENDISPL_OP_DBUF_CREATE operation (see below + * for negotiation). + * If value is not "1" or omitted frontend must allocate buffers itself. + * + *----------------------------- Connector settings ---------------------------- + * + * resolution + * Values: <width, uint32_t>x<height, uint32_t> + * + * Width and height of the connector in pixels separated by + * XENDISPL_RESOLUTION_SEPARATOR. This defines visible area of the + * display. + * + *------------------ Connector Request Transport Parameters ------------------- + * + * This communication path is used to deliver requests from frontend to backend + * and get the corresponding responses from backend to frontend, + * set up per connector. + * + * req-event-channel + * Values: <uint32_t> + * + * The identifier of the Xen connector's control event channel + * used to signal activity in the ring buffer. + * + * req-ring-ref + * Values: <uint32_t> + * + * The Xen grant reference granting permission for the backend to map + * a sole page of connector's control ring buffer. + * + *------------------- Connector Event Transport Parameters -------------------- + * + * This communication path is used to deliver asynchronous events from backend + * to frontend, set up per connector. + * + * evt-event-channel + * Values: <uint32_t> + * + * The identifier of the Xen connector's event channel + * used to signal activity in the ring buffer. + * + * evt-ring-ref + * Values: <uint32_t> + * + * The Xen grant reference granting permission for the backend to map + * a sole page of connector's event ring buffer. + */ + +/* + ****************************************************************************** + * STATE DIAGRAMS + ****************************************************************************** + * + * Tool stack creates front and back state nodes with initial state + * XenbusStateInitialising. + * Tool stack creates and sets up frontend display configuration + * nodes per domain. + * + *-------------------------------- Normal flow -------------------------------- + * + * Front Back + * ================================= ===================================== + * XenbusStateInitialising XenbusStateInitialising + * o Query backend device identification + * data. + * o Open and validate backend device. + * | + * | + * V + * XenbusStateInitWait + * + * o Query frontend configuration + * o Allocate and initialize + * event channels per configured + * connector. + * o Publish transport parameters + * that will be in effect during + * this connection. + * | + * | + * V + * XenbusStateInitialised + * + * o Query frontend transport parameters. + * o Connect to the event channels. + * | + * | + * V + * XenbusStateConnected + * + * o Create and initialize OS + * virtual display connectors + * as per configuration. + * | + * | + * V + * XenbusStateConnected + * + * XenbusStateUnknown + * XenbusStateClosed + * XenbusStateClosing + * o Remove virtual display device + * o Remove event channels + * | + * | + * V + * XenbusStateClosed + * + *------------------------------- Recovery flow ------------------------------- + * + * In case of frontend unrecoverable errors backend handles that as + * if frontend goes into the XenbusStateClosed state. + * + * In case of backend unrecoverable errors frontend tries removing + * the virtualized device. If this is possible at the moment of error, + * then frontend goes into the XenbusStateInitialising state and is ready for + * new connection with backend. If the virtualized device is still in use and + * cannot be removed, then frontend goes into the XenbusStateReconfiguring state + * until either the virtualized device is removed or backend initiates a new + * connection. On the virtualized device removal frontend goes into the + * XenbusStateInitialising state. + * + * Note on XenbusStateReconfiguring state of the frontend: if backend has + * unrecoverable errors then frontend cannot send requests to the backend + * and thus cannot provide functionality of the virtualized device anymore. + * After backend is back to normal the virtualized device may still hold some + * state: configuration in use, allocated buffers, client application state etc. + * In most cases, this will require frontend to implement complex recovery + * reconnect logic. Instead, by going into XenbusStateReconfiguring state, + * frontend will make sure no new clients of the virtualized device are + * accepted, allow existing client(s) to exit gracefully by signaling error + * state etc. + * Once all the clients are gone frontend can reinitialize the virtualized + * device and get into XenbusStateInitialising state again signaling the + * backend that a new connection can be made. + * + * There are multiple conditions possible under which frontend will go from + * XenbusStateReconfiguring into XenbusStateInitialising, some of them are OS + * specific. For example: + * 1. The underlying OS framework may provide callbacks to signal that the last + * client of the virtualized device has gone and the device can be removed + * 2. Frontend can schedule a deferred work (timer/tasklet/workqueue) + * to periodically check if this is the right time to re-try removal of + * the virtualized device. + * 3. By any other means. + * + ****************************************************************************** + * REQUEST CODES + ****************************************************************************** + * Request codes [0; 15] are reserved and must not be used + */ + +#define XENDISPL_OP_DBUF_CREATE 0x10 +#define XENDISPL_OP_DBUF_DESTROY 0x11 +#define XENDISPL_OP_FB_ATTACH 0x12 +#define XENDISPL_OP_FB_DETACH 0x13 +#define XENDISPL_OP_SET_CONFIG 0x14 +#define XENDISPL_OP_PG_FLIP 0x15 + +/* + ****************************************************************************** + * EVENT CODES + ****************************************************************************** + */ +#define XENDISPL_EVT_PG_FLIP 0x00 + +/* + ****************************************************************************** + * XENSTORE FIELD AND PATH NAME STRINGS, HELPERS + ****************************************************************************** + */ +#define XENDISPL_DRIVER_NAME "vdispl" + +#define XENDISPL_LIST_SEPARATOR "," +#define XENDISPL_RESOLUTION_SEPARATOR "x" + +#define XENDISPL_FIELD_BE_VERSIONS "versions" +#define XENDISPL_FIELD_FE_VERSION "version" +#define XENDISPL_FIELD_REQ_RING_REF "req-ring-ref" +#define XENDISPL_FIELD_REQ_CHANNEL "req-event-channel" +#define XENDISPL_FIELD_EVT_RING_REF "evt-ring-ref" +#define XENDISPL_FIELD_EVT_CHANNEL "evt-event-channel" +#define XENDISPL_FIELD_RESOLUTION "resolution" +#define XENDISPL_FIELD_BE_ALLOC "be-alloc" + +/* + ****************************************************************************** + * STATUS RETURN CODES + ****************************************************************************** + * + * Status return code is zero on success and -XEN_EXX on failure. + * + ****************************************************************************** + * Assumptions + ****************************************************************************** + * o usage of grant reference 0 as invalid grant reference: + * grant reference 0 is valid, but never exposed to a PV driver, + * because of the fact it is already in use/reserved by the PV console. + * o all references in this document to page sizes must be treated + * as pages of size XEN_PAGE_SIZE unless otherwise noted. + * + ****************************************************************************** + * Description of the protocol between frontend and backend driver + ****************************************************************************** + * + * The two halves of a Para-virtual display driver communicate with + * each other using shared pages and event channels. + * Shared page contains a ring with request/response packets. + * + * All reserved fields in the structures below must be 0. + * Display buffers's cookie of value 0 is treated as invalid. + * Framebuffer's cookie of value 0 is treated as invalid. + * + * For all request/response/event packets that use cookies: + * dbuf_cookie - uint64_t, unique to guest domain value used by the backend + * to map remote display buffer to its local one + * fb_cookie - uint64_t, unique to guest domain value used by the backend + * to map remote framebuffer to its local one + * + *---------------------------------- Requests --------------------------------- + * + * All requests/responses, which are not connector specific, must be sent over + * control ring of the connector which has the index value of 0: + * /local/domain/<dom-id>/device/vdispl/<dev-id>/0/req-ring-ref + * + * All request packets have the same length (64 octets) + * All request packets have common header: + * 0 1 2 3 octet + * +----------------+----------------+----------------+----------------+ + * | id | operation | reserved | 4 + * +----------------+----------------+----------------+----------------+ + * | reserved | 8 + * +----------------+----------------+----------------+----------------+ + * id - uint16_t, private guest value, echoed in response + * operation - uint8_t, operation code, XENDISPL_OP_??? + * + * Request dbuf creation - request creation of a display buffer. + * 0 1 2 3 octet + * +----------------+----------------+----------------+----------------+ + * | id |_OP_DBUF_CREATE | reserved | 4 + * +----------------+----------------+----------------+----------------+ + * | reserved | 8 + * +----------------+----------------+----------------+----------------+ + * | dbuf_cookie low 32-bit | 12 + * +----------------+----------------+----------------+----------------+ + * | dbuf_cookie high 32-bit | 16 + * +----------------+----------------+----------------+----------------+ + * | width | 20 + * +----------------+----------------+----------------+----------------+ + * | height | 24 + * +----------------+----------------+----------------+----------------+ + * | bpp | 28 + * +----------------+----------------+----------------+----------------+ + * | buffer_sz | 32 + * +----------------+----------------+----------------+----------------+ + * | flags | 36 + * +----------------+----------------+----------------+----------------+ + * | gref_directory | 40 + * +----------------+----------------+----------------+----------------+ + * | reserved | 44 + * +----------------+----------------+----------------+----------------+ + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| + * +----------------+----------------+----------------+----------------+ + * | reserved | 64 + * +----------------+----------------+----------------+----------------+ + * + * Must be sent over control ring of the connector which has the index + * value of 0: + * /local/domain/<dom-id>/device/vdispl/<dev-id>/0/req-ring-ref + * All unused bits in flags field must be set to 0. + * + * An attempt to create multiple display buffers with the same dbuf_cookie is + * an error. dbuf_cookie can be re-used after destroying the corresponding + * display buffer. + * + * Width and height of the display buffers can be smaller, equal or bigger + * than the connector's resolution. Depth/pixel format of the individual + * buffers can differ as well. + * + * width - uint32_t, width in pixels + * height - uint32_t, height in pixels + * bpp - uint32_t, bits per pixel + * buffer_sz - uint32_t, buffer size to be allocated, octets + * flags - uint32_t, flags of the operation + * o XENDISPL_DBUF_FLG_REQ_ALLOC - if set, then backend is requested + * to allocate the buffer with the parameters provided in this request. + * Page directory is handled as follows: + * Frontend on request: + * o allocates pages for the directory (gref_directory, + * gref_dir_next_page(s) + * o grants permissions for the pages of the directory to the backend + * o sets gref_dir_next_page fields + * Backend on response: + * o grants permissions for the pages of the buffer allocated to + * the frontend + * o fills in page directory with grant references + * (gref[] in struct xendispl_page_directory) + * gref_directory - grant_ref_t, a reference to the first shared page + * describing shared buffer references. At least one page exists. If shared + * buffer size (buffer_sz) exceeds what can be addressed by this single page, + * then reference to the next page must be supplied (see gref_dir_next_page + * below) + */ + +#define XENDISPL_DBUF_FLG_REQ_ALLOC (1 << 0) + +struct xendispl_dbuf_create_req { + uint64_t dbuf_cookie; + uint32_t width; + uint32_t height; + uint32_t bpp; + uint32_t buffer_sz; + uint32_t flags; + grant_ref_t gref_directory; +}; + +/* + * Shared page for XENDISPL_OP_DBUF_CREATE buffer descriptor (gref_directory in + * the request) employs a list of pages, describing all pages of the shared + * data buffer: + * 0 1 2 3 octet + * +----------------+----------------+----------------+----------------+ + * | gref_dir_next_page | 4 + * +----------------+----------------+----------------+----------------+ + * | gref[0] | 8 + * +----------------+----------------+----------------+----------------+ + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| + * +----------------+----------------+----------------+----------------+ + * | gref[i] | i*4+8 + * +----------------+----------------+----------------+----------------+ + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| + * +----------------+----------------+----------------+----------------+ + * | gref[N - 1] | N*4+8 + * +----------------+----------------+----------------+----------------+ + * + * gref_dir_next_page - grant_ref_t, reference to the next page describing + * page directory. Must be 0 if there are no more pages in the list. + * gref[i] - grant_ref_t, reference to a shared page of the buffer + * allocated at XENDISPL_OP_DBUF_CREATE + * + * Number of grant_ref_t entries in the whole page directory is not + * passed, but instead can be calculated as: + * num_grefs_total = (XENDISPL_OP_DBUF_CREATE.buffer_sz + XEN_PAGE_SIZE - 1) / + * XEN_PAGE_SIZE + */ + +struct xendispl_page_directory { + grant_ref_t gref_dir_next_page; + grant_ref_t gref[1]; /* Variable length */ +}; + +/* + * Request dbuf destruction - destroy a previously allocated display buffer: + * 0 1 2 3 octet + * +----------------+----------------+----------------+----------------+ + * | id |_OP_DBUF_DESTROY| reserved | 4 + * +----------------+----------------+----------------+----------------+ + * | reserved | 8 + * +----------------+----------------+----------------+----------------+ + * | dbuf_cookie low 32-bit | 12 + * +----------------+----------------+----------------+----------------+ + * | dbuf_cookie high 32-bit | 16 + * +----------------+----------------+----------------+----------------+ + * | reserved | 20 + * +----------------+----------------+----------------+----------------+ + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| + * +----------------+----------------+----------------+----------------+ + * | reserved | 64 + * +----------------+----------------+----------------+----------------+ + * + * Must be sent over control ring of the connector which has the index + * value of 0: + * /local/domain/<dom-id>/device/vdispl/<dev-id>/0/req-ring-ref + */ + +struct xendispl_dbuf_destroy_req { + uint64_t dbuf_cookie; +}; + +/* + * Request framebuffer attachment - request attachment of a framebuffer to + * previously created display buffer. + * 0 1 2 3 octet + * +----------------+----------------+----------------+----------------+ + * | id | _OP_FB_ATTACH | reserved | 4 + * +----------------+----------------+----------------+----------------+ + * | reserved | 8 + * +----------------+----------------+----------------+----------------+ + * | dbuf_cookie low 32-bit | 12 + * +----------------+----------------+----------------+----------------+ + * | dbuf_cookie high 32-bit | 16 + * +----------------+----------------+----------------+----------------+ + * | fb_cookie low 32-bit | 20 + * +----------------+----------------+----------------+----------------+ + * | fb_cookie high 32-bit | 24 + * +----------------+----------------+----------------+----------------+ + * | width | 28 + * +----------------+----------------+----------------+----------------+ + * | height | 32 + * +----------------+----------------+----------------+----------------+ + * | pixel_format | 36 + * +----------------+----------------+----------------+----------------+ + * | reserved | 40 + * +----------------+----------------+----------------+----------------+ + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| + * +----------------+----------------+----------------+----------------+ + * | reserved | 64 + * +----------------+----------------+----------------+----------------+ + * + * Must be sent over control ring of the connector which has the index + * value of 0: + * /local/domain/<dom-id>/device/vdispl/<dev-id>/0/req-ring-ref + * Width and height can be smaller, equal or bigger than the connector's + * resolution. + * + * An attempt to create multiple frame buffers with the same fb_cookie is + * an error. fb_cookie can be re-used after destroying the corresponding + * frame buffer. + * + * width - uint32_t, width in pixels + * height - uint32_t, height in pixels + * pixel_format - uint32_t, pixel format of the framebuffer, FOURCC code + */ + +struct xendispl_fb_attach_req { + uint64_t dbuf_cookie; + uint64_t fb_cookie; + uint32_t width; + uint32_t height; + uint32_t pixel_format; +}; + +/* + * Request framebuffer detach - detach a previously + * attached framebuffer from the display buffer in request: + * 0 1 2 3 octet + * +----------------+----------------+----------------+----------------+ + * | id | _OP_FB_DETACH | reserved | 4 + * +----------------+----------------+----------------+----------------+ + * | reserved | 8 + * +----------------+----------------+----------------+----------------+ + * | fb_cookie low 32-bit | 12 + * +----------------+----------------+----------------+----------------+ + * | fb_cookie high 32-bit | 16 + * +----------------+----------------+----------------+----------------+ + * | reserved | 20 + * +----------------+----------------+----------------+----------------+ + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| + * +----------------+----------------+----------------+----------------+ + * | reserved | 64 + * +----------------+----------------+----------------+----------------+ + * + * Must be sent over control ring of the connector which has the index + * value of 0: + * /local/domain/<dom-id>/device/vdispl/<dev-id>/0/req-ring-ref + */ + +struct xendispl_fb_detach_req { + uint64_t fb_cookie; +}; + +/* + * Request configuration set/reset - request to set or reset + * the configuration/mode of the display: + * 0 1 2 3 octet + * +----------------+----------------+----------------+----------------+ + * | id | _OP_SET_CONFIG | reserved | 4 + * +----------------+----------------+----------------+----------------+ + * | reserved | 8 + * +----------------+----------------+----------------+----------------+ + * | fb_cookie low 32-bit | 12 + * +----------------+----------------+----------------+----------------+ + * | fb_cookie high 32-bit | 16 + * +----------------+----------------+----------------+----------------+ + * | x | 20 + * +----------------+----------------+----------------+----------------+ + * | y | 24 + * +----------------+----------------+----------------+----------------+ + * | width | 28 + * +----------------+----------------+----------------+----------------+ + * | height | 32 + * +----------------+----------------+----------------+----------------+ + * | bpp | 40 + * +----------------+----------------+----------------+----------------+ + * | reserved | 44 + * +----------------+----------------+----------------+----------------+ + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| + * +----------------+----------------+----------------+----------------+ + * | reserved | 64 + * +----------------+----------------+----------------+----------------+ + * + * Pass all zeros to reset, otherwise command is treated as + * configuration set. + * Framebuffer's cookie defines which framebuffer/dbuf must be + * displayed while enabling display (applying configuration). + * x, y, width and height are bound by the connector's resolution and must not + * exceed it. + * + * x - uint32_t, starting position in pixels by X axis + * y - uint32_t, starting position in pixels by Y axis + * width - uint32_t, width in pixels + * height - uint32_t, height in pixels + * bpp - uint32_t, bits per pixel + */ + +struct xendispl_set_config_req { + uint64_t fb_cookie; + uint32_t x; + uint32_t y; + uint32_t width; + uint32_t height; + uint32_t bpp; +}; + +/* + * Request page flip - request to flip a page identified by the framebuffer + * cookie: + * 0 1 2 3 octet + * +----------------+----------------+----------------+----------------+ + * | id | _OP_PG_FLIP | reserved | 4 + * +----------------+----------------+----------------+----------------+ + * | reserved | 8 + * +----------------+----------------+----------------+----------------+ + * | fb_cookie low 32-bit | 12 + * +----------------+----------------+----------------+----------------+ + * | fb_cookie high 32-bit | 16 + * +----------------+----------------+----------------+----------------+ + * | reserved | 20 + * +----------------+----------------+----------------+----------------+ + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| + * +----------------+----------------+----------------+----------------+ + * | reserved | 64 + * +----------------+----------------+----------------+----------------+ + */ + +struct xendispl_page_flip_req { + uint64_t fb_cookie; +}; + +/* + *---------------------------------- Responses -------------------------------- + * + * All response packets have the same length (64 octets) + * + * All response packets have common header: + * 0 1 2 3 octet + * +----------------+----------------+----------------+----------------+ + * | id | reserved | 4 + * +----------------+----------------+----------------+----------------+ + * | status | 8 + * +----------------+----------------+----------------+----------------+ + * | reserved | 12 + * +----------------+----------------+----------------+----------------+ + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| + * +----------------+----------------+----------------+----------------+ + * | reserved | 64 + * +----------------+----------------+----------------+----------------+ + * + * id - uint16_t, private guest value, echoed from request + * status - int32_t, response status, zero on success and -XEN_EXX on failure + * + *----------------------------------- Events ---------------------------------- + * + * Events are sent via a shared page allocated by the front and propagated by + * evt-event-channel/evt-ring-ref XenStore entries + * All event packets have the same length (64 octets) + * All event packets have common header: + * 0 1 2 3 octet + * +----------------+----------------+----------------+----------------+ + * | id | type | reserved | 4 + * +----------------+----------------+----------------+----------------+ + * | reserved | 8 + * +----------------+----------------+----------------+----------------+ + * + * id - uint16_t, event id, may be used by front + * type - uint8_t, type of the event + * + * + * Page flip complete event - event from back to front on page flip completed: + * 0 1 2 3 octet + * +----------------+----------------+----------------+----------------+ + * | id | _EVT_PG_FLIP | reserved | 4 + * +----------------+----------------+----------------+----------------+ + * | reserved | 8 + * +----------------+----------------+----------------+----------------+ + * | fb_cookie low 32-bit | 12 + * +----------------+----------------+----------------+----------------+ + * | fb_cookie high 32-bit | 16 + * +----------------+----------------+----------------+----------------+ + * | reserved | 20 + * +----------------+----------------+----------------+----------------+ + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| + * +----------------+----------------+----------------+----------------+ + * | reserved | 64 + * +----------------+----------------+----------------+----------------+ + */ + +struct xendispl_pg_flip_evt { + uint64_t fb_cookie; +}; + +struct xendispl_req { + uint16_t id; + uint8_t operation; + uint8_t reserved[5]; + union { + struct xendispl_dbuf_create_req dbuf_create; + struct xendispl_dbuf_destroy_req dbuf_destroy; + struct xendispl_fb_attach_req fb_attach; + struct xendispl_fb_detach_req fb_detach; + struct xendispl_set_config_req set_config; + struct xendispl_page_flip_req pg_flip; + uint8_t reserved[56]; + } op; +}; + +struct xendispl_resp { + uint16_t id; + uint8_t operation; + uint8_t reserved; + int32_t status; + uint8_t reserved1[56]; +}; + +struct xendispl_evt { + uint16_t id; + uint8_t type; + uint8_t reserved[5]; + union { + struct xendispl_pg_flip_evt pg_flip; + uint8_t reserved[56]; + } op; +}; + +DEFINE_RING_TYPES(xen_displif, struct xendispl_req, struct xendispl_resp); + +/* + ****************************************************************************** + * Back to front events delivery + ****************************************************************************** + * In order to deliver asynchronous events from back to front a shared page is + * allocated by front and its granted reference propagated to back via + * XenStore entries (evt-ring-ref/evt-event-channel). + * This page has a common header used by both front and back to synchronize + * access and control event's ring buffer, while back being a producer of the + * events and front being a consumer. The rest of the page after the header + * is used for event packets. + * + * Upon reception of an event(s) front may confirm its reception + * for either each event, group of events or none. + */ + +struct xendispl_event_page { + uint32_t in_cons; + uint32_t in_prod; + uint8_t reserved[56]; +}; + +#define XENDISPL_EVENT_PAGE_SIZE 4096 +#define XENDISPL_IN_RING_OFFS (sizeof(struct xendispl_event_page)) +#define XENDISPL_IN_RING_SIZE (XENDISPL_EVENT_PAGE_SIZE - XENDISPL_IN_RING_OFFS) +#define XENDISPL_IN_RING_LEN (XENDISPL_IN_RING_SIZE / sizeof(struct xendispl_evt)) +#define XENDISPL_IN_RING(page) \ + ((struct xendispl_evt *)((char *)(page) + XENDISPL_IN_RING_OFFS)) +#define XENDISPL_IN_RING_REF(page, idx) \ + (XENDISPL_IN_RING((page))[(idx) % XENDISPL_IN_RING_LEN]) + +#endif /* __XEN_PUBLIC_IO_DISPLIF_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/xen/io/kbdif.h b/include/xen/io/kbdif.h index 2d2aebd..3ce54e9 100644 --- a/include/xen/io/kbdif.h +++ b/include/xen/io/kbdif.h @@ -26,46 +26,449 @@ #ifndef __XEN_PUBLIC_IO_KBDIF_H__ #define __XEN_PUBLIC_IO_KBDIF_H__ -/* In events (backend -> frontend) */ +/* + ***************************************************************************** + * Feature and Parameter Negotiation + ***************************************************************************** + * + * The two halves of a para-virtual driver utilize nodes within + * XenStore to communicate capabilities and to negotiate operating parameters. + * This section enumerates these nodes which reside in the respective front and + * backend portions of XenStore, following XenBus convention. + * + * All data in XenStore is stored as strings. Nodes specifying numeric + * values are encoded in decimal. Integer value ranges listed below are + * expressed as fixed sized integer types capable of storing the conversion + * of a properly formated node string, without loss of information. + * + ***************************************************************************** + * Backend XenBus Nodes + ***************************************************************************** + * + *---------------------------- Features supported ---------------------------- + * + * Capable backend advertises supported features by publishing + * corresponding entries in XenStore and puts 1 as the value of the entry. + * If a feature is not supported then 0 must be set or feature entry omitted. + * + * feature-abs-pointer + * Values: <uint> + * + * Backends, which support reporting of absolute coordinates for pointer + * device should set this to 1. + * + * feature-multi-touch + * Values: <uint> + * + * Backends, which support reporting of multi-touch events + * should set this to 1. + * + * feature-raw-pointer + * Values: <uint> + * + * Backends, which support reporting raw (unscaled) absolute coordinates + * for pointer devices should set this to 1. Raw (unscaled) values have + * a range of [0, 0x7fff]. + * + *------------------------- Pointer Device Parameters ------------------------ + * + * width + * Values: <uint> + * + * Maximum X coordinate (width) to be used by the frontend + * while reporting input events, pixels, [0; UINT32_MAX]. + * + * height + * Values: <uint> + * + * Maximum Y coordinate (height) to be used by the frontend + * while reporting input events, pixels, [0; UINT32_MAX]. + * + ***************************************************************************** + * Frontend XenBus Nodes + ***************************************************************************** + * + *------------------------------ Feature request ----------------------------- + * + * Capable frontend requests features from backend via setting corresponding + * entries to 1 in XenStore. Requests for features not advertised as supported + * by the backend have no effect. + * + * request-abs-pointer + * Values: <uint> + * + * Request backend to report absolute pointer coordinates + * (XENKBD_TYPE_POS) instead of relative ones (XENKBD_TYPE_MOTION). + * + * request-multi-touch + * Values: <uint> + * + * Request backend to report multi-touch events. + * + * request-raw-pointer + * Values: <uint> + * + * Request backend to report raw unscaled absolute pointer coordinates. + * This option is only valid if request-abs-pointer is also set. + * Raw unscaled coordinates have the range [0, 0x7fff] + * + *----------------------- Request Transport Parameters ----------------------- + * + * event-channel + * Values: <uint> + * + * The identifier of the Xen event channel used to signal activity + * in the ring buffer. + * + * page-gref + * Values: <uint> + * + * The Xen grant reference granting permission for the backend to map + * a sole page in a single page sized event ring buffer. + * + * page-ref + * Values: <uint> + * + * OBSOLETE, not recommended for use. + * PFN of the shared page. + * + *----------------------- Multi-touch Device Parameters ----------------------- + * + * multi-touch-num-contacts + * Values: <uint> + * + * Number of simultaneous touches reported. + * + * multi-touch-width + * Values: <uint> + * + * Width of the touch area to be used by the frontend + * while reporting input events, pixels, [0; UINT32_MAX]. + * + * multi-touch-height + * Values: <uint> + * + * Height of the touch area to be used by the frontend + * while reporting input events, pixels, [0; UINT32_MAX]. + */ /* - * Frontends should ignore unknown in events. + * EVENT CODES. + */ + +#define XENKBD_TYPE_MOTION 1 +#define XENKBD_TYPE_RESERVED 2 +#define XENKBD_TYPE_KEY 3 +#define XENKBD_TYPE_POS 4 +#define XENKBD_TYPE_MTOUCH 5 + +/* Multi-touch event sub-codes */ + +#define XENKBD_MT_EV_DOWN 0 +#define XENKBD_MT_EV_UP 1 +#define XENKBD_MT_EV_MOTION 2 +#define XENKBD_MT_EV_SYN 3 +#define XENKBD_MT_EV_SHAPE 4 +#define XENKBD_MT_EV_ORIENT 5 + +/* + * CONSTANTS, XENSTORE FIELD AND PATH NAME STRINGS, HELPERS. */ -/* Pointer movement event */ -#define XENKBD_TYPE_MOTION 1 -/* Event type 2 currently not used */ -/* Key event (includes pointer buttons) */ -#define XENKBD_TYPE_KEY 3 +#define XENKBD_DRIVER_NAME "vkbd" + +#define XENKBD_FIELD_FEAT_ABS_POINTER "feature-abs-pointer" +#define XENKBD_FIELD_FEAT_MTOUCH "feature-multi-touch" +#define XENKBD_FIELD_REQ_ABS_POINTER "request-abs-pointer" +#define XENKBD_FIELD_REQ_MTOUCH "request-multi-touch" +#define XENKBD_FIELD_RING_GREF "page-gref" +#define XENKBD_FIELD_EVT_CHANNEL "event-channel" +#define XENKBD_FIELD_WIDTH "width" +#define XENKBD_FIELD_HEIGHT "height" +#define XENKBD_FIELD_MT_WIDTH "multi-touch-width" +#define XENKBD_FIELD_MT_HEIGHT "multi-touch-height" +#define XENKBD_FIELD_MT_NUM_CONTACTS "multi-touch-num-contacts" + +/* OBSOLETE, not recommended for use */ +#define XENKBD_FIELD_RING_REF "page-ref" + /* - * Pointer position event - * Capable backend sets feature-abs-pointer in xenstore. - * Frontend requests ot instead of XENKBD_TYPE_MOTION by setting - * request-abs-update in xenstore. + ***************************************************************************** + * Description of the protocol between frontend and backend driver. + ***************************************************************************** + * + * The two halves of a Para-virtual driver communicate with + * each other using a shared page and an event channel. + * Shared page contains a ring with event structures. + * + * All reserved fields in the structures below must be 0. + * + ***************************************************************************** + * Backend to frontend events + ***************************************************************************** + * + * Frontends should ignore unknown in events. + * All event packets have the same length (40 octets) + * All event packets have common header: + * + * 0 octet + * +-----------------+ + * | type | + * +-----------------+ + * type - uint8_t, event code, XENKBD_TYPE_??? + * + * + * Pointer relative movement event + * 0 1 2 3 octet + * +----------------+----------------+----------------+----------------+ + * | _TYPE_MOTION | reserved | 4 + * +----------------+----------------+----------------+----------------+ + * | rel_x | 8 + * +----------------+----------------+----------------+----------------+ + * | rel_y | 12 + * +----------------+----------------+----------------+----------------+ + * | rel_z | 16 + * +----------------+----------------+----------------+----------------+ + * | reserved | 20 + * +----------------+----------------+----------------+----------------+ + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| + * +----------------+----------------+----------------+----------------+ + * | reserved | 40 + * +----------------+----------------+----------------+----------------+ + * + * rel_x - int32_t, relative X motion + * rel_y - int32_t, relative Y motion + * rel_z - int32_t, relative Z motion (wheel) */ -#define XENKBD_TYPE_POS 4 struct xenkbd_motion { - uint8_t type; /* XENKBD_TYPE_MOTION */ - int32_t rel_x; /* relative X motion */ - int32_t rel_y; /* relative Y motion */ - int32_t rel_z; /* relative Z motion (wheel) */ + uint8_t type; + int32_t rel_x; + int32_t rel_y; + int32_t rel_z; }; +/* + * Key event (includes pointer buttons) + * 0 1 2 3 octet + * +----------------+----------------+----------------+----------------+ + * | _TYPE_KEY | pressed | reserved | 4 + * +----------------+----------------+----------------+----------------+ + * | keycode | 8 + * +----------------+----------------+----------------+----------------+ + * | reserved | 12 + * +----------------+----------------+----------------+----------------+ + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| + * +----------------+----------------+----------------+----------------+ + * | reserved | 40 + * +----------------+----------------+----------------+----------------+ + * + * pressed - uint8_t, 1 if pressed; 0 otherwise + * keycode - uint32_t, KEY_* from linux/input.h + */ + struct xenkbd_key { - uint8_t type; /* XENKBD_TYPE_KEY */ - uint8_t pressed; /* 1 if pressed; 0 otherwise */ - uint32_t keycode; /* KEY_* from linux/input.h */ + uint8_t type; + uint8_t pressed; + uint32_t keycode; }; +/* + * Pointer absolute position event + * 0 1 2 3 octet + * +----------------+----------------+----------------+----------------+ + * | _TYPE_POS | reserved | 4 + * +----------------+----------------+----------------+----------------+ + * | abs_x | 8 + * +----------------+----------------+----------------+----------------+ + * | abs_y | 12 + * +----------------+----------------+----------------+----------------+ + * | rel_z | 16 + * +----------------+----------------+----------------+----------------+ + * | reserved | 20 + * +----------------+----------------+----------------+----------------+ + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| + * +----------------+----------------+----------------+----------------+ + * | reserved | 40 + * +----------------+----------------+----------------+----------------+ + * + * abs_x - int32_t, absolute X position (in FB pixels) + * abs_y - int32_t, absolute Y position (in FB pixels) + * rel_z - int32_t, relative Z motion (wheel) + */ + struct xenkbd_position { - uint8_t type; /* XENKBD_TYPE_POS */ - int32_t abs_x; /* absolute X position (in FB pixels) */ - int32_t abs_y; /* absolute Y position (in FB pixels) */ - int32_t rel_z; /* relative Z motion (wheel) */ + uint8_t type; + int32_t abs_x; + int32_t abs_y; + int32_t rel_z; +}; + +/* + * Multi-touch event and its sub-types + * + * All multi-touch event packets have common header: + * + * 0 1 2 3 octet + * +----------------+----------------+----------------+----------------+ + * | _TYPE_MTOUCH | event_type | contact_id | reserved | 4 + * +----------------+----------------+----------------+----------------+ + * | reserved | 8 + * +----------------+----------------+----------------+----------------+ + * + * event_type - unt8_t, multi-touch event sub-type, XENKBD_MT_EV_??? + * contact_id - unt8_t, ID of the contact + * + * Touch interactions can consist of one or more contacts. + * For each contact, a series of events is generated, starting + * with a down event, followed by zero or more motion events, + * and ending with an up event. Events relating to the same + * contact point can be identified by the ID of the sequence: contact ID. + * Contact ID may be reused after XENKBD_MT_EV_UP event and + * is in the [0; XENKBD_FIELD_NUM_CONTACTS - 1] range. + * + * For further information please refer to documentation on Wayland [1], + * Linux [2] and Windows [3] multi-touch support. + * + * [1] https://cgit.freedesktop.org/wayland/wayland/tree/protocol/wayland.xml + * [2] https://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt + * [3] https://msdn.microsoft.com/en-us/library/jj151564(v=vs.85).aspx + * + * + * Multi-touch down event - sent when a new touch is made: touch is assigned + * a unique contact ID, sent with this and consequent events related + * to this touch. + * 0 1 2 3 octet + * +----------------+----------------+----------------+----------------+ + * | _TYPE_MTOUCH | _MT_EV_DOWN | contact_id | reserved | 4 + * +----------------+----------------+----------------+----------------+ + * | reserved | 8 + * +----------------+----------------+----------------+----------------+ + * | abs_x | 12 + * +----------------+----------------+----------------+----------------+ + * | abs_y | 16 + * +----------------+----------------+----------------+----------------+ + * | reserved | 20 + * +----------------+----------------+----------------+----------------+ + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| + * +----------------+----------------+----------------+----------------+ + * | reserved | 40 + * +----------------+----------------+----------------+----------------+ + * + * abs_x - int32_t, absolute X position, in pixels + * abs_y - int32_t, absolute Y position, in pixels + * + * Multi-touch contact release event + * 0 1 2 3 octet + * +----------------+----------------+----------------+----------------+ + * | _TYPE_MTOUCH | _MT_EV_UP | contact_id | reserved | 4 + * +----------------+----------------+----------------+----------------+ + * | reserved | 8 + * +----------------+----------------+----------------+----------------+ + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| + * +----------------+----------------+----------------+----------------+ + * | reserved | 40 + * +----------------+----------------+----------------+----------------+ + * + * Multi-touch motion event + * 0 1 2 3 octet + * +----------------+----------------+----------------+----------------+ + * | _TYPE_MTOUCH | _MT_EV_MOTION | contact_id | reserved | 4 + * +----------------+----------------+----------------+----------------+ + * | reserved | 8 + * +----------------+----------------+----------------+----------------+ + * | abs_x | 12 + * +----------------+----------------+----------------+----------------+ + * | abs_y | 16 + * +----------------+----------------+----------------+----------------+ + * | reserved | 20 + * +----------------+----------------+----------------+----------------+ + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| + * +----------------+----------------+----------------+----------------+ + * | reserved | 40 + * +----------------+----------------+----------------+----------------+ + * + * abs_x - int32_t, absolute X position, in pixels, + * abs_y - int32_t, absolute Y position, in pixels, + * + * Multi-touch input synchronization event - shows end of a set of events + * which logically belong together. + * 0 1 2 3 octet + * +----------------+----------------+----------------+----------------+ + * | _TYPE_MTOUCH | _MT_EV_SYN | contact_id | reserved | 4 + * +----------------+----------------+----------------+----------------+ + * | reserved | 8 + * +----------------+----------------+----------------+----------------+ + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| + * +----------------+----------------+----------------+----------------+ + * | reserved | 40 + * +----------------+----------------+----------------+----------------+ + * + * Multi-touch shape event - touch point's shape has changed its shape. + * Shape is approximated by an ellipse through the major and minor axis + * lengths: major is the longer diameter of the ellipse and minor is the + * shorter one. Center of the ellipse is reported via + * XENKBD_MT_EV_DOWN/XENKBD_MT_EV_MOTION events. + * 0 1 2 3 octet + * +----------------+----------------+----------------+----------------+ + * | _TYPE_MTOUCH | _MT_EV_SHAPE | contact_id | reserved | 4 + * +----------------+----------------+----------------+----------------+ + * | reserved | 8 + * +----------------+----------------+----------------+----------------+ + * | major | 12 + * +----------------+----------------+----------------+----------------+ + * | minor | 16 + * +----------------+----------------+----------------+----------------+ + * | reserved | 20 + * +----------------+----------------+----------------+----------------+ + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| + * +----------------+----------------+----------------+----------------+ + * | reserved | 40 + * +----------------+----------------+----------------+----------------+ + * + * major - unt32_t, length of the major axis, pixels + * minor - unt32_t, length of the minor axis, pixels + * + * Multi-touch orientation event - touch point's shape has changed + * its orientation: calculated as a clockwise angle between the major axis + * of the ellipse and positive Y axis in degrees, [-180; +180]. + * 0 1 2 3 octet + * +----------------+----------------+----------------+----------------+ + * | _TYPE_MTOUCH | _MT_EV_ORIENT | contact_id | reserved | 4 + * +----------------+----------------+----------------+----------------+ + * | reserved | 8 + * +----------------+----------------+----------------+----------------+ + * | orientation | reserved | 12 + * +----------------+----------------+----------------+----------------+ + * | reserved | 16 + * +----------------+----------------+----------------+----------------+ + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| + * +----------------+----------------+----------------+----------------+ + * | reserved | 40 + * +----------------+----------------+----------------+----------------+ + * + * orientation - int16_t, clockwise angle of the major axis + */ + +struct xenkbd_mtouch { + uint8_t type; /* XENKBD_TYPE_MTOUCH */ + uint8_t event_type; /* XENKBD_MT_EV_??? */ + uint8_t contact_id; + uint8_t reserved[5]; /* reserved for the future use */ + union { + struct { + int32_t abs_x; /* absolute X position, pixels */ + int32_t abs_y; /* absolute Y position, pixels */ + } pos; + struct { + uint32_t major; /* length of the major axis, pixels */ + uint32_t minor; /* length of the minor axis, pixels */ + } shape; + int16_t orientation; /* clockwise angle of the major axis */ + } u; }; #define XENKBD_IN_EVENT_SIZE 40 @@ -76,15 +479,26 @@ union xenkbd_in_event struct xenkbd_motion motion; struct xenkbd_key key; struct xenkbd_position pos; + struct xenkbd_mtouch mtouch; char pad[XENKBD_IN_EVENT_SIZE]; }; -/* Out events (frontend -> backend) */ - /* + ***************************************************************************** + * Frontend to backend events + ***************************************************************************** + * * Out events may be sent only when requested by backend, and receipt * of an unknown out event is an error. * No out events currently defined. + + * All event packets have the same length (40 octets) + * All event packets have common header: + * 0 octet + * +-----------------+ + * | type | + * +-----------------+ + * type - uint8_t, event code */ #define XENKBD_OUT_EVENT_SIZE 40 @@ -95,7 +509,11 @@ union xenkbd_out_event char pad[XENKBD_OUT_EVENT_SIZE]; }; -/* shared page */ +/* + ***************************************************************************** + * Shared page + ***************************************************************************** + */ #define XENKBD_IN_RING_SIZE 2048 #define XENKBD_IN_RING_LEN (XENKBD_IN_RING_SIZE / XENKBD_IN_EVENT_SIZE) @@ -119,7 +537,7 @@ struct xenkbd_page uint32_t out_cons, out_prod; }; -#endif +#endif /* __XEN_PUBLIC_IO_KBDIF_H__ */ /* * Local variables: diff --git a/include/xen/io/libxenvchan.h b/include/xen/io/libxenvchan.h index 5c3d3d4..44284f4 100644 --- a/include/xen/io/libxenvchan.h +++ b/include/xen/io/libxenvchan.h @@ -10,19 +10,23 @@ * * @section LICENSE * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * * @section DESCRIPTION * diff --git a/include/xen/io/netif.h b/include/xen/io/netif.h index 61e9aea..ca00614 100644 --- a/include/xen/io/netif.h +++ b/include/xen/io/netif.h @@ -1,8 +1,8 @@ /****************************************************************************** * netif.h - * + * * Unified network-device I/O interface for Xen guest OSes. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the @@ -136,14 +136,684 @@ */ /* - * This is the 'wire' format for packets: - * Request 1: netif_tx_request -- NETTXF_* (any flags) - * [Request 2: netif_tx_extra] (only if request 1 has NETTXF_extra_info) - * [Request 3: netif_tx_extra] (only if request 2 has XEN_NETIF_EXTRA_MORE) - * Request 4: netif_tx_request -- NETTXF_more_data - * Request 5: netif_tx_request -- NETTXF_more_data + * "feature-multicast-control" and "feature-dynamic-multicast-control" + * advertise the capability to filter ethernet multicast packets in the + * backend. If the frontend wishes to take advantage of this feature then + * it may set "request-multicast-control". If the backend only advertises + * "feature-multicast-control" then "request-multicast-control" must be set + * before the frontend moves into the connected state. The backend will + * sample the value on this state transition and any subsequent change in + * value will have no effect. However, if the backend also advertises + * "feature-dynamic-multicast-control" then "request-multicast-control" + * may be set by the frontend at any time. In this case, the backend will + * watch the value and re-sample on watch events. + * + * If the sampled value of "request-multicast-control" is set then the + * backend transmit side should no longer flood multicast packets to the + * frontend, it should instead drop any multicast packet that does not + * match in a filter list. + * The list is amended by the frontend by sending dummy transmit requests + * containing XEN_NETIF_EXTRA_TYPE_MCAST_{ADD,DEL} extra-info fragments as + * specified below. + * Note that the filter list may be amended even if the sampled value of + * "request-multicast-control" is not set, however the filter should only + * be applied if it is set. + */ + +/* + * Control ring + * ============ + * + * Some features, such as hashing (detailed below), require a + * significant amount of out-of-band data to be passed from frontend to + * backend. Use of xenstore is not suitable for large quantities of data + * because of quota limitations and so a dedicated 'control ring' is used. + * The ability of the backend to use a control ring is advertised by + * setting: + * + * /local/domain/X/backend/<domid>/<vif>/feature-ctrl-ring = "1" + * + * The frontend provides a control ring to the backend by setting: + * + * /local/domain/<domid>/device/vif/<vif>/ctrl-ring-ref = <gref> + * /local/domain/<domid>/device/vif/<vif>/event-channel-ctrl = <port> + * + * where <gref> is the grant reference of the shared page used to + * implement the control ring and <port> is an event channel to be used + * as a mailbox interrupt. These keys must be set before the frontend + * moves into the connected state. + * + * The control ring uses a fixed request/response message size and is + * balanced (i.e. one request to one response), so operationally it is much + * the same as a transmit or receive ring. + * Note that there is no requirement that responses are issued in the same + * order as requests. + */ + +/* + * Hash types + * ========== + * + * For the purposes of the definitions below, 'Packet[]' is an array of + * octets containing an IP packet without options, 'Array[X..Y]' means a + * sub-array of 'Array' containing bytes X thru Y inclusive, and '+' is + * used to indicate concatenation of arrays. + */ + +/* + * A hash calculated over an IP version 4 header as follows: + * + * Buffer[0..8] = Packet[12..15] (source address) + + * Packet[16..19] (destination address) + * + * Result = Hash(Buffer, 8) + */ +#define _XEN_NETIF_CTRL_HASH_TYPE_IPV4 0 +#define XEN_NETIF_CTRL_HASH_TYPE_IPV4 \ + (1 << _XEN_NETIF_CTRL_HASH_TYPE_IPV4) + +/* + * A hash calculated over an IP version 4 header and TCP header as + * follows: + * + * Buffer[0..12] = Packet[12..15] (source address) + + * Packet[16..19] (destination address) + + * Packet[20..21] (source port) + + * Packet[22..23] (destination port) + * + * Result = Hash(Buffer, 12) + */ +#define _XEN_NETIF_CTRL_HASH_TYPE_IPV4_TCP 1 +#define XEN_NETIF_CTRL_HASH_TYPE_IPV4_TCP \ + (1 << _XEN_NETIF_CTRL_HASH_TYPE_IPV4_TCP) + +/* + * A hash calculated over an IP version 6 header as follows: + * + * Buffer[0..32] = Packet[8..23] (source address ) + + * Packet[24..39] (destination address) + * + * Result = Hash(Buffer, 32) + */ +#define _XEN_NETIF_CTRL_HASH_TYPE_IPV6 2 +#define XEN_NETIF_CTRL_HASH_TYPE_IPV6 \ + (1 << _XEN_NETIF_CTRL_HASH_TYPE_IPV6) + +/* + * A hash calculated over an IP version 6 header and TCP header as + * follows: + * + * Buffer[0..36] = Packet[8..23] (source address) + + * Packet[24..39] (destination address) + + * Packet[40..41] (source port) + + * Packet[42..43] (destination port) + * + * Result = Hash(Buffer, 36) + */ +#define _XEN_NETIF_CTRL_HASH_TYPE_IPV6_TCP 3 +#define XEN_NETIF_CTRL_HASH_TYPE_IPV6_TCP \ + (1 << _XEN_NETIF_CTRL_HASH_TYPE_IPV6_TCP) + +/* + * Hash algorithms + * =============== + */ + +#define XEN_NETIF_CTRL_HASH_ALGORITHM_NONE 0 + +/* + * Toeplitz hash: + */ + +#define XEN_NETIF_CTRL_HASH_ALGORITHM_TOEPLITZ 1 + +/* + * This algorithm uses a 'key' as well as the data buffer itself. + * (Buffer[] and Key[] are treated as shift-registers where the MSB of + * Buffer/Key[0] is considered 'left-most' and the LSB of Buffer/Key[N-1] + * is the 'right-most'). + * + * Value = 0 + * For number of bits in Buffer[] + * If (left-most bit of Buffer[] is 1) + * Value ^= left-most 32 bits of Key[] + * Key[] << 1 + * Buffer[] << 1 + * + * The code below is provided for convenience where an operating system + * does not already provide an implementation. + */ +#ifdef XEN_NETIF_DEFINE_TOEPLITZ +static uint32_t xen_netif_toeplitz_hash(const uint8_t *key, + unsigned int keylen, + const uint8_t *buf, + unsigned int buflen) +{ + unsigned int keyi, bufi; + uint64_t prefix = 0; + uint64_t hash = 0; + + /* Pre-load prefix with the first 8 bytes of the key */ + for (keyi = 0; keyi < 8; keyi++) { + prefix <<= 8; + prefix |= (keyi < keylen) ? key[keyi] : 0; + } + + for (bufi = 0; bufi < buflen; bufi++) { + uint8_t byte = buf[bufi]; + unsigned int bit; + + for (bit = 0; bit < 8; bit++) { + if (byte & 0x80) + hash ^= prefix; + prefix <<= 1; + byte <<=1; + } + + /* + * 'prefix' has now been left-shifted by 8, so + * OR in the next byte. + */ + prefix |= (keyi < keylen) ? key[keyi] : 0; + keyi++; + } + + /* The valid part of the hash is in the upper 32 bits. */ + return hash >> 32; +} +#endif /* XEN_NETIF_DEFINE_TOEPLITZ */ + +/* + * Control requests (struct xen_netif_ctrl_request) + * ================================================ + * + * All requests have the following format: + * + * 0 1 2 3 4 5 6 7 octet + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * | id | type | data[0] | + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * | data[1] | data[2] | + * +-----+-----+-----+-----+-----------------------+ + * + * id: the request identifier, echoed in response. + * type: the type of request (see below) + * data[]: any data associated with the request (determined by type) + */ + +struct xen_netif_ctrl_request { + uint16_t id; + uint16_t type; + +#define XEN_NETIF_CTRL_TYPE_INVALID 0 +#define XEN_NETIF_CTRL_TYPE_GET_HASH_FLAGS 1 +#define XEN_NETIF_CTRL_TYPE_SET_HASH_FLAGS 2 +#define XEN_NETIF_CTRL_TYPE_SET_HASH_KEY 3 +#define XEN_NETIF_CTRL_TYPE_GET_HASH_MAPPING_SIZE 4 +#define XEN_NETIF_CTRL_TYPE_SET_HASH_MAPPING_SIZE 5 +#define XEN_NETIF_CTRL_TYPE_SET_HASH_MAPPING 6 +#define XEN_NETIF_CTRL_TYPE_SET_HASH_ALGORITHM 7 + + uint32_t data[3]; +}; + +/* + * Control responses (struct xen_netif_ctrl_response) + * ================================================== + * + * All responses have the following format: + * + * 0 1 2 3 4 5 6 7 octet + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * | id | type | status | + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * | data | + * +-----+-----+-----+-----+ + * + * id: the corresponding request identifier + * type: the type of the corresponding request + * status: the status of request processing + * data: any data associated with the response (determined by type and + * status) + */ + +struct xen_netif_ctrl_response { + uint16_t id; + uint16_t type; + uint32_t status; + +#define XEN_NETIF_CTRL_STATUS_SUCCESS 0 +#define XEN_NETIF_CTRL_STATUS_NOT_SUPPORTED 1 +#define XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER 2 +#define XEN_NETIF_CTRL_STATUS_BUFFER_OVERFLOW 3 + + uint32_t data; +}; + +/* + * Control messages + * ================ + * + * XEN_NETIF_CTRL_TYPE_SET_HASH_ALGORITHM + * -------------------------------------- + * + * This is sent by the frontend to set the desired hash algorithm. + * + * Request: + * + * type = XEN_NETIF_CTRL_TYPE_SET_HASH_ALGORITHM + * data[0] = a XEN_NETIF_CTRL_HASH_ALGORITHM_* value + * data[1] = 0 + * data[2] = 0 + * + * Response: + * + * status = XEN_NETIF_CTRL_STATUS_NOT_SUPPORTED - Operation not + * supported + * XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER - The algorithm is not + * supported + * XEN_NETIF_CTRL_STATUS_SUCCESS - Operation successful + * + * NOTE: Setting data[0] to XEN_NETIF_CTRL_HASH_ALGORITHM_NONE disables + * hashing and the backend is free to choose how it steers packets + * to queues (which is the default behaviour). + * + * XEN_NETIF_CTRL_TYPE_GET_HASH_FLAGS + * ---------------------------------- + * + * This is sent by the frontend to query the types of hash supported by + * the backend. + * + * Request: + * + * type = XEN_NETIF_CTRL_TYPE_GET_HASH_FLAGS + * data[0] = 0 + * data[1] = 0 + * data[2] = 0 + * + * Response: + * + * status = XEN_NETIF_CTRL_STATUS_NOT_SUPPORTED - Operation not supported + * XEN_NETIF_CTRL_STATUS_SUCCESS - Operation successful + * data = supported hash types (if operation was successful) + * + * NOTE: A valid hash algorithm must be selected before this operation can + * succeed. + * + * XEN_NETIF_CTRL_TYPE_SET_HASH_FLAGS + * ---------------------------------- + * + * This is sent by the frontend to set the types of hash that the backend + * should calculate. (See above for hash type definitions). + * Note that the 'maximal' type of hash should always be chosen. For + * example, if the frontend sets both IPV4 and IPV4_TCP hash types then + * the latter hash type should be calculated for any TCP packet and the + * former only calculated for non-TCP packets. + * + * Request: + * + * type = XEN_NETIF_CTRL_TYPE_SET_HASH_FLAGS + * data[0] = bitwise OR of XEN_NETIF_CTRL_HASH_TYPE_* values + * data[1] = 0 + * data[2] = 0 + * + * Response: + * + * status = XEN_NETIF_CTRL_STATUS_NOT_SUPPORTED - Operation not + * supported + * XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER - One or more flag + * value is invalid or + * unsupported + * XEN_NETIF_CTRL_STATUS_SUCCESS - Operation successful + * data = 0 + * + * NOTE: A valid hash algorithm must be selected before this operation can + * succeed. + * Also, setting data[0] to zero disables hashing and the backend + * is free to choose how it steers packets to queues. + * + * XEN_NETIF_CTRL_TYPE_SET_HASH_KEY + * -------------------------------- + * + * This is sent by the frontend to set the key of the hash if the algorithm + * requires it. (See hash algorithms above). + * + * Request: + * + * type = XEN_NETIF_CTRL_TYPE_SET_HASH_KEY + * data[0] = grant reference of page containing the key (assumed to + * start at beginning of grant) + * data[1] = size of key in octets + * data[2] = 0 + * + * Response: + * + * status = XEN_NETIF_CTRL_STATUS_NOT_SUPPORTED - Operation not + * supported + * XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER - Key size is invalid + * XEN_NETIF_CTRL_STATUS_BUFFER_OVERFLOW - Key size is larger + * than the backend + * supports + * XEN_NETIF_CTRL_STATUS_SUCCESS - Operation successful + * data = 0 + * + * NOTE: Any key octets not specified are assumed to be zero (the key + * is assumed to be empty by default) and specifying a new key + * invalidates any previous key, hence specifying a key size of + * zero will clear the key (which ensures that the calculated hash + * will always be zero). + * The maximum size of key is algorithm and backend specific, but + * is also limited by the single grant reference. + * The grant reference may be read-only and must remain valid until + * the response has been processed. + * + * XEN_NETIF_CTRL_TYPE_GET_HASH_MAPPING_SIZE + * ----------------------------------------- + * + * This is sent by the frontend to query the maximum size of mapping + * table supported by the backend. The size is specified in terms of + * table entries. + * + * Request: + * + * type = XEN_NETIF_CTRL_TYPE_GET_HASH_MAPPING_SIZE + * data[0] = 0 + * data[1] = 0 + * data[2] = 0 + * + * Response: + * + * status = XEN_NETIF_CTRL_STATUS_NOT_SUPPORTED - Operation not supported + * XEN_NETIF_CTRL_STATUS_SUCCESS - Operation successful + * data = maximum number of entries allowed in the mapping table + * (if operation was successful) or zero if a mapping table is + * not supported (i.e. hash mapping is done only by modular + * arithmetic). + * + * XEN_NETIF_CTRL_TYPE_SET_HASH_MAPPING_SIZE + * ------------------------------------- + * + * This is sent by the frontend to set the actual size of the mapping + * table to be used by the backend. The size is specified in terms of + * table entries. + * Any previous table is invalidated by this message and any new table + * is assumed to be zero filled. + * + * Request: + * + * type = XEN_NETIF_CTRL_TYPE_SET_HASH_MAPPING_SIZE + * data[0] = number of entries in mapping table + * data[1] = 0 + * data[2] = 0 + * + * Response: + * + * status = XEN_NETIF_CTRL_STATUS_NOT_SUPPORTED - Operation not + * supported + * XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER - Table size is invalid + * XEN_NETIF_CTRL_STATUS_SUCCESS - Operation successful + * data = 0 + * + * NOTE: Setting data[0] to 0 means that hash mapping should be done + * using modular arithmetic. + * + * XEN_NETIF_CTRL_TYPE_SET_HASH_MAPPING + * ------------------------------------ + * + * This is sent by the frontend to set the content of the table mapping + * hash value to queue number. The backend should calculate the hash from + * the packet header, use it as an index into the table (modulo the size + * of the table) and then steer the packet to the queue number found at + * that index. + * + * Request: + * + * type = XEN_NETIF_CTRL_TYPE_SET_HASH_MAPPING + * data[0] = grant reference of page containing the mapping (sub-)table + * (assumed to start at beginning of grant) + * data[1] = size of (sub-)table in entries + * data[2] = offset, in entries, of sub-table within overall table + * + * Response: + * + * status = XEN_NETIF_CTRL_STATUS_NOT_SUPPORTED - Operation not + * supported + * XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER - Table size or content + * is invalid + * XEN_NETIF_CTRL_STATUS_BUFFER_OVERFLOW - Table size is larger + * than the backend + * supports + * XEN_NETIF_CTRL_STATUS_SUCCESS - Operation successful + * data = 0 + * + * NOTE: The overall table has the following format: + * + * 0 1 2 3 4 5 6 7 octet + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * | mapping[0] | mapping[1] | + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * | . | + * | . | + * | . | + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * | mapping[N-2] | mapping[N-1] | + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * + * where N is specified by a XEN_NETIF_CTRL_TYPE_SET_HASH_MAPPING_SIZE + * message and each mapping must specifies a queue between 0 and + * "multi-queue-num-queues" (see above). + * The backend may support a mapping table larger than can be + * mapped by a single grant reference. Thus sub-tables within a + * larger table can be individually set by sending multiple messages + * with differing offset values. Specifying a new sub-table does not + * invalidate any table data outside that range. + * The grant reference may be read-only and must remain valid until + * the response has been processed. + */ + +DEFINE_RING_TYPES(xen_netif_ctrl, + struct xen_netif_ctrl_request, + struct xen_netif_ctrl_response); + +/* + * Guest transmit + * ============== + * + * This is the 'wire' format for transmit (frontend -> backend) packets: + * + * Fragment 1: netif_tx_request_t - flags = NETTXF_* + * size = total packet size + * [Extra 1: netif_extra_info_t] - (only if fragment 1 flags include + * NETTXF_extra_info) + * ... + * [Extra N: netif_extra_info_t] - (only if extra N-1 flags include + * XEN_NETIF_EXTRA_MORE) + * ... + * Fragment N: netif_tx_request_t - (only if fragment N-1 flags include + * NETTXF_more_data - flags on preceding + * extras are not relevant here) + * flags = 0 + * size = fragment size + * + * NOTE: + * + * This format slightly is different from that used for receive + * (backend -> frontend) packets. Specifically, in a multi-fragment + * packet the actual size of fragment 1 can only be determined by + * subtracting the sizes of fragments 2..N from the total packet size. + * + * Ring slot size is 12 octets, however not all request/response + * structs use the full size. + * + * tx request data (netif_tx_request_t) + * ------------------------------------ + * + * 0 1 2 3 4 5 6 7 octet + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * | grant ref | offset | flags | + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * | id | size | + * +-----+-----+-----+-----+ + * + * grant ref: Reference to buffer page. + * offset: Offset within buffer page. + * flags: NETTXF_*. + * id: request identifier, echoed in response. + * size: packet size in bytes. + * + * tx response (netif_tx_response_t) + * --------------------------------- + * + * 0 1 2 3 4 5 6 7 octet + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * | id | status | unused | + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * | unused | + * +-----+-----+-----+-----+ + * + * id: reflects id in transmit request + * status: NETIF_RSP_* + * + * Guest receive + * ============= + * + * This is the 'wire' format for receive (backend -> frontend) packets: + * + * Fragment 1: netif_rx_request_t - flags = NETRXF_* + * size = fragment size + * [Extra 1: netif_extra_info_t] - (only if fragment 1 flags include + * NETRXF_extra_info) + * ... + * [Extra N: netif_extra_info_t] - (only if extra N-1 flags include + * XEN_NETIF_EXTRA_MORE) * ... - * Request N: netif_tx_request -- 0 + * Fragment N: netif_rx_request_t - (only if fragment N-1 flags include + * NETRXF_more_data - flags on preceding + * extras are not relevant here) + * flags = 0 + * size = fragment size + * + * NOTE: + * + * This format slightly is different from that used for transmit + * (frontend -> backend) packets. Specifically, in a multi-fragment + * packet the size of the packet can only be determined by summing the + * sizes of fragments 1..N. + * + * Ring slot size is 8 octets. + * + * rx request (netif_rx_request_t) + * ------------------------------- + * + * 0 1 2 3 4 5 6 7 octet + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * | id | pad | gref | + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * + * id: request identifier, echoed in response. + * gref: reference to incoming granted frame. + * + * rx response (netif_rx_response_t) + * --------------------------------- + * + * 0 1 2 3 4 5 6 7 octet + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * | id | offset | flags | status | + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * + * id: reflects id in receive request + * offset: offset in page of start of received packet + * flags: NETRXF_* + * status: -ve: NETIF_RSP_*; +ve: Rx'ed pkt size. + * + * NOTE: Historically, to support GSO on the frontend receive side, Linux + * netfront does not make use of the rx response id (because, as + * described below, extra info structures overlay the id field). + * Instead it assumes that responses always appear in the same ring + * slot as their corresponding request. Thus, to maintain + * compatibility, backends must make sure this is the case. + * + * Extra Info + * ========== + * + * Can be present if initial request or response has NET{T,R}XF_extra_info, + * or previous extra request has XEN_NETIF_EXTRA_MORE. + * + * The struct therefore needs to fit into either a tx or rx slot and + * is therefore limited to 8 octets. + * + * NOTE: Because extra info data overlays the usual request/response + * structures, there is no id information in the opposite direction. + * So, if an extra info overlays an rx response the frontend can + * assume that it is in the same ring slot as the request that was + * consumed to make the slot available, and the backend must ensure + * this assumption is true. + * + * extra info (netif_extra_info_t) + * ------------------------------- + * + * General format: + * + * 0 1 2 3 4 5 6 7 octet + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * |type |flags| type specific data | + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * | padding for tx | + * +-----+-----+-----+-----+ + * + * type: XEN_NETIF_EXTRA_TYPE_* + * flags: XEN_NETIF_EXTRA_FLAG_* + * padding for tx: present only in the tx case due to 8 octet limit + * from rx case. Not shown in type specific entries + * below. + * + * XEN_NETIF_EXTRA_TYPE_GSO: + * + * 0 1 2 3 4 5 6 7 octet + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * |type |flags| size |type | pad | features | + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * + * type: Must be XEN_NETIF_EXTRA_TYPE_GSO + * flags: XEN_NETIF_EXTRA_FLAG_* + * size: Maximum payload size of each segment. For example, + * for TCP this is just the path MSS. + * type: XEN_NETIF_GSO_TYPE_*: This determines the protocol of + * the packet and any extra features required to segment the + * packet properly. + * features: EN_NETIF_GSO_FEAT_*: This specifies any extra GSO + * features required to process this packet, such as ECN + * support for TCPv4. + * + * XEN_NETIF_EXTRA_TYPE_MCAST_{ADD,DEL}: + * + * 0 1 2 3 4 5 6 7 octet + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * |type |flags| addr | + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * + * type: Must be XEN_NETIF_EXTRA_TYPE_MCAST_{ADD,DEL} + * flags: XEN_NETIF_EXTRA_FLAG_* + * addr: address to add/remove + * + * XEN_NETIF_EXTRA_TYPE_HASH: + * + * A backend that supports teoplitz hashing is assumed to accept + * this type of extra info in transmit packets. + * A frontend that enables hashing is assumed to accept + * this type of extra info in receive packets. + * + * 0 1 2 3 4 5 6 7 octet + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * |type |flags|htype| alg |LSB ---- value ---- MSB| + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * + * type: Must be XEN_NETIF_EXTRA_TYPE_HASH + * flags: XEN_NETIF_EXTRA_FLAG_* + * htype: Hash type (one of _XEN_NETIF_CTRL_HASH_TYPE_* - see above) + * alg: The algorithm used to calculate the hash (one of + * XEN_NETIF_CTRL_HASH_TYPE_ALGORITHM_* - see above) + * value: Hash value */ /* Protocol checksum field is blank in the packet (hardware offload)? */ @@ -164,11 +834,11 @@ #define XEN_NETIF_MAX_TX_SIZE 0xFFFF struct netif_tx_request { - grant_ref_t gref; /* Reference to buffer page */ - uint16_t offset; /* Offset within buffer page */ - uint16_t flags; /* NETTXF_* */ - uint16_t id; /* Echoed in response message. */ - uint16_t size; /* Packet size in bytes. */ + grant_ref_t gref; + uint16_t offset; + uint16_t flags; + uint16_t id; + uint16_t size; }; typedef struct netif_tx_request netif_tx_request_t; @@ -177,9 +847,10 @@ typedef struct netif_tx_request netif_tx_request_t; #define XEN_NETIF_EXTRA_TYPE_GSO (1) /* u.gso */ #define XEN_NETIF_EXTRA_TYPE_MCAST_ADD (2) /* u.mcast */ #define XEN_NETIF_EXTRA_TYPE_MCAST_DEL (3) /* u.mcast */ -#define XEN_NETIF_EXTRA_TYPE_MAX (4) +#define XEN_NETIF_EXTRA_TYPE_HASH (4) /* u.hash */ +#define XEN_NETIF_EXTRA_TYPE_MAX (5) -/* netif_extra_info flags. */ +/* netif_extra_info_t flags. */ #define _XEN_NETIF_EXTRA_FLAG_MORE (0) #define XEN_NETIF_EXTRA_FLAG_MORE (1U<<_XEN_NETIF_EXTRA_FLAG_MORE) @@ -189,55 +860,27 @@ typedef struct netif_tx_request netif_tx_request_t; #define XEN_NETIF_GSO_TYPE_TCPV6 (2) /* - * This structure needs to fit within both netif_tx_request and - * netif_rx_response for compatibility. + * This structure needs to fit within both netif_tx_request_t and + * netif_rx_response_t for compatibility. */ struct netif_extra_info { - uint8_t type; /* XEN_NETIF_EXTRA_TYPE_* */ - uint8_t flags; /* XEN_NETIF_EXTRA_FLAG_* */ - + uint8_t type; + uint8_t flags; union { - /* - * XEN_NETIF_EXTRA_TYPE_GSO: - */ struct { - /* - * Maximum payload size of each segment. For example, for TCP this - * is just the path MSS. - */ uint16_t size; - - /* - * GSO type. This determines the protocol of the packet and any - * extra features required to segment the packet properly. - */ - uint8_t type; /* XEN_NETIF_GSO_TYPE_* */ - - /* Future expansion. */ + uint8_t type; uint8_t pad; - - /* - * GSO features. This specifies any extra GSO features required - * to process this packet, such as ECN support for TCPv4. - */ - uint16_t features; /* XEN_NETIF_GSO_FEAT_* */ + uint16_t features; } gso; - - /* - * XEN_NETIF_EXTRA_TYPE_MCAST_{ADD,DEL}: - * Backend advertises availability via 'feature-multicast-control' - * xenbus node containing value '1'. - * Frontend requests this feature by advertising - * 'request-multicast-control' xenbus node containing value '1'. - * If multicast control is requested then multicast flooding is - * disabled and the frontend must explicitly register its interest - * in multicast groups using dummy transmit requests containing - * MCAST_{ADD,DEL} extra-info fragments. - */ struct { - uint8_t addr[6]; /* Address to add/remove. */ + uint8_t addr[6]; } mcast; - + struct { + uint8_t type; + uint8_t algorithm; + uint8_t value[4]; + } hash; uint16_t pad[3]; } u; }; @@ -245,13 +888,14 @@ typedef struct netif_extra_info netif_extra_info_t; struct netif_tx_response { uint16_t id; - int16_t status; /* NETIF_RSP_* */ + int16_t status; }; typedef struct netif_tx_response netif_tx_response_t; struct netif_rx_request { uint16_t id; /* Echoed in response message. */ - grant_ref_t gref; /* Reference to incoming granted frame */ + uint16_t pad; + grant_ref_t gref; }; typedef struct netif_rx_request netif_rx_request_t; @@ -271,11 +915,15 @@ typedef struct netif_rx_request netif_rx_request_t; #define _NETRXF_extra_info (3) #define NETRXF_extra_info (1U<<_NETRXF_extra_info) +/* Packet has GSO prefix. Deprecated but included for compatibility */ +#define _NETRXF_gso_prefix (4) +#define NETRXF_gso_prefix (1U<<_NETRXF_gso_prefix) + struct netif_rx_response { uint16_t id; - uint16_t offset; /* Offset in page of start of received packet */ - uint16_t flags; /* NETRXF_* */ - int16_t status; /* -ve: NETIF_RSP_* ; +ve: Rx'ed pkt size. */ + uint16_t offset; + uint16_t flags; + int16_t status; }; typedef struct netif_rx_response netif_rx_response_t; @@ -289,7 +937,7 @@ DEFINE_RING_TYPES(netif_rx, struct netif_rx_request, struct netif_rx_response); #define NETIF_RSP_DROPPED -2 #define NETIF_RSP_ERROR -1 #define NETIF_RSP_OKAY 0 -/* No response: used for auxiliary requests (e.g., netif_tx_extra). */ +/* No response: used for auxiliary requests (e.g., netif_extra_info_t). */ #define NETIF_RSP_NULL 1 #endif diff --git a/include/xen/io/protocols.h b/include/xen/io/protocols.h index 80b196b..40a9b30 100644 --- a/include/xen/io/protocols.h +++ b/include/xen/io/protocols.h @@ -18,6 +18,8 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2008, Keir Fraser */ #ifndef __XEN_PROTOCOLS_H__ diff --git a/include/xen/io/pvcalls.h b/include/xen/io/pvcalls.h new file mode 100644 index 0000000..cb81712 --- /dev/null +++ b/include/xen/io/pvcalls.h @@ -0,0 +1,153 @@ +/* + * pvcalls.h -- Xen PV Calls Protocol + * + * Refer to docs/misc/pvcalls.markdown for the specification + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (C) 2017 Stefano Stabellini <stefano@xxxxxxxxxxx> + */ + +#ifndef __XEN_PUBLIC_IO_PVCALLS_H__ +#define __XEN_PUBLIC_IO_PVCALLS_H__ + +#include "../grant_table.h" +#include "ring.h" + +/* + * See docs/misc/pvcalls.markdown in xen.git for the full specification: + * https://xenbits.xen.org/docs/unstable/misc/pvcalls.html + */ +struct pvcalls_data_intf { + RING_IDX in_cons, in_prod, in_error; + + uint8_t pad1[52]; + + RING_IDX out_cons, out_prod, out_error; + + uint8_t pad2[52]; + + RING_IDX ring_order; + grant_ref_t ref[]; +}; +DEFINE_XEN_FLEX_RING(pvcalls); + +#define PVCALLS_SOCKET 0 +#define PVCALLS_CONNECT 1 +#define PVCALLS_RELEASE 2 +#define PVCALLS_BIND 3 +#define PVCALLS_LISTEN 4 +#define PVCALLS_ACCEPT 5 +#define PVCALLS_POLL 6 + +struct xen_pvcalls_request { + uint32_t req_id; /* private to guest, echoed in response */ + uint32_t cmd; /* command to execute */ + union { + struct xen_pvcalls_socket { + uint64_t id; + uint32_t domain; + uint32_t type; + uint32_t protocol; + } socket; + struct xen_pvcalls_connect { + uint64_t id; + uint8_t addr[28]; + uint32_t len; + uint32_t flags; + grant_ref_t ref; + uint32_t evtchn; + } connect; + struct xen_pvcalls_release { + uint64_t id; + uint8_t reuse; + } release; + struct xen_pvcalls_bind { + uint64_t id; + uint8_t addr[28]; + uint32_t len; + } bind; + struct xen_pvcalls_listen { + uint64_t id; + uint32_t backlog; + } listen; + struct xen_pvcalls_accept { + uint64_t id; + uint64_t id_new; + grant_ref_t ref; + uint32_t evtchn; + } accept; + struct xen_pvcalls_poll { + uint64_t id; + } poll; + /* dummy member to force sizeof(struct xen_pvcalls_request) + * to match across archs */ + struct xen_pvcalls_dummy { + uint8_t dummy[56]; + } dummy; + } u; +}; + +struct xen_pvcalls_response { + uint32_t req_id; + uint32_t cmd; + int32_t ret; + uint32_t pad; + union { + struct _xen_pvcalls_socket { + uint64_t id; + } socket; + struct _xen_pvcalls_connect { + uint64_t id; + } connect; + struct _xen_pvcalls_release { + uint64_t id; + } release; + struct _xen_pvcalls_bind { + uint64_t id; + } bind; + struct _xen_pvcalls_listen { + uint64_t id; + } listen; + struct _xen_pvcalls_accept { + uint64_t id; + } accept; + struct _xen_pvcalls_poll { + uint64_t id; + } poll; + struct _xen_pvcalls_dummy { + uint8_t dummy[8]; + } dummy; + } u; +}; + +DEFINE_RING_TYPES(xen_pvcalls, struct xen_pvcalls_request, + struct xen_pvcalls_response); + +#endif + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/xen/io/ring.h b/include/xen/io/ring.h index 73e13d7..30342fc 100644 --- a/include/xen/io/ring.h +++ b/include/xen/io/ring.h @@ -27,6 +27,21 @@ #ifndef __XEN_PUBLIC_IO_RING_H__ #define __XEN_PUBLIC_IO_RING_H__ +/* + * When #include'ing this header, you need to provide the following + * declaration upfront: + * - standard integers types (uint8_t, uint16_t, etc) + * They are provided by stdint.h of the standard headers. + * + * In addition, if you intend to use the FLEX macros, you also need to + * provide the following, before invoking the FLEX macros: + * - size_t + * - memcpy + * - grant_ref_t + * These declarations are provided by string.h of the standard headers, + * and grant_table.h from the Xen public headers. + */ + #include "../xen-compat.h" #if __XEN_INTERFACE_VERSION__ < 0x00030208 @@ -111,7 +126,7 @@ struct __name##_sring { \ uint8_t msg; \ } tapif_user; \ uint8_t pvt_pad[4]; \ - } private; \ + } pvt; \ uint8_t __pad[44]; \ union __name##_sring_entry ring[1]; /* variable-length */ \ }; \ @@ -156,7 +171,7 @@ typedef struct __name##_back_ring __name##_back_ring_t #define SHARED_RING_INIT(_s) do { \ (_s)->req_prod = (_s)->rsp_prod = 0; \ (_s)->req_event = (_s)->rsp_event = 1; \ - (void)memset((_s)->private.pvt_pad, 0, sizeof((_s)->private.pvt_pad)); \ + (void)memset((_s)->pvt.pvt_pad, 0, sizeof((_s)->pvt.pvt_pad)); \ (void)memset((_s)->__pad, 0, sizeof((_s)->__pad)); \ } while(0) @@ -212,6 +227,20 @@ typedef struct __name##_back_ring __name##_back_ring_t #define RING_GET_REQUEST(_r, _idx) \ (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].req)) +/* + * Get a local copy of a request. + * + * Use this in preference to RING_GET_REQUEST() so all processing is + * done on a local copy that cannot be modified by the other end. + * + * Note that https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145 may cause this + * to be ineffective where _req is a struct which consists of only bitfields. + */ +#define RING_COPY_REQUEST(_r, _idx, _req) do { \ + /* Use volatile to force the copy into _req. */ \ + *(_req) = *(volatile typeof(_req))RING_GET_REQUEST(_r, _idx); \ +} while (0) + #define RING_GET_RESPONSE(_r, _idx) \ (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].rsp)) @@ -299,6 +328,149 @@ typedef struct __name##_back_ring __name##_back_ring_t (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r); \ } while (0) + +/* + * DEFINE_XEN_FLEX_RING_AND_INTF defines two monodirectional rings and + * functions to check if there is data on the ring, and to read and + * write to them. + * + * DEFINE_XEN_FLEX_RING is similar to DEFINE_XEN_FLEX_RING_AND_INTF, but + * does not define the indexes page. As different protocols can have + * extensions to the basic format, this macro allow them to define their + * own struct. + * + * XEN_FLEX_RING_SIZE + * Convenience macro to calculate the size of one of the two rings + * from the overall order. + * + * $NAME_mask + * Function to apply the size mask to an index, to reduce the index + * within the range [0-size]. + * + * $NAME_read_packet + * Function to read data from the ring. The amount of data to read is + * specified by the "size" argument. + * + * $NAME_write_packet + * Function to write data to the ring. The amount of data to write is + * specified by the "size" argument. + * + * $NAME_get_ring_ptr + * Convenience function that returns a pointer to read/write to the + * ring at the right location. + * + * $NAME_data_intf + * Indexes page, shared between frontend and backend. It also + * contains the array of grant refs. + * + * $NAME_queued + * Function to calculate how many bytes are currently on the ring, + * ready to be read. It can also be used to calculate how much free + * space is currently on the ring (XEN_FLEX_RING_SIZE() - + * $NAME_queued()). + */ + +#ifndef XEN_PAGE_SHIFT +/* The PAGE_SIZE for ring protocols and hypercall interfaces is always + * 4K, regardless of the architecture, and page granularity chosen by + * operating systems. + */ +#define XEN_PAGE_SHIFT 12 +#endif +#define XEN_FLEX_RING_SIZE(order) \ + (1UL << ((order) + XEN_PAGE_SHIFT - 1)) + +#define DEFINE_XEN_FLEX_RING(name) \ +static inline RING_IDX name##_mask(RING_IDX idx, RING_IDX ring_size) \ +{ \ + return idx & (ring_size - 1); \ +} \ + \ +static inline unsigned char *name##_get_ring_ptr(unsigned char *buf, \ + RING_IDX idx, \ + RING_IDX ring_size) \ +{ \ + return buf + name##_mask(idx, ring_size); \ +} \ + \ +static inline void name##_read_packet(void *opaque, \ + const unsigned char *buf, \ + size_t size, \ + RING_IDX masked_prod, \ + RING_IDX *masked_cons, \ + RING_IDX ring_size) \ +{ \ + if (*masked_cons < masked_prod || \ + size <= ring_size - *masked_cons) { \ + memcpy(opaque, buf + *masked_cons, size); \ + } else { \ + memcpy(opaque, buf + *masked_cons, ring_size - *masked_cons); \ + memcpy((unsigned char *)opaque + ring_size - *masked_cons, buf, \ + size - (ring_size - *masked_cons)); \ + } \ + *masked_cons = name##_mask(*masked_cons + size, ring_size); \ +} \ + \ +static inline void name##_write_packet(unsigned char *buf, \ + const void *opaque, \ + size_t size, \ + RING_IDX *masked_prod, \ + RING_IDX masked_cons, \ + RING_IDX ring_size) \ +{ \ + if (*masked_prod < masked_cons || \ + size <= ring_size - *masked_prod) { \ + memcpy(buf + *masked_prod, opaque, size); \ + } else { \ + memcpy(buf + *masked_prod, opaque, ring_size - *masked_prod); \ + memcpy(buf, (unsigned char *)opaque + (ring_size - *masked_prod), \ + size - (ring_size - *masked_prod)); \ + } \ + *masked_prod = name##_mask(*masked_prod + size, ring_size); \ +} \ + \ +static inline RING_IDX name##_queued(RING_IDX prod, \ + RING_IDX cons, \ + RING_IDX ring_size) \ +{ \ + RING_IDX size; \ + \ + if (prod == cons) \ + return 0; \ + \ + prod = name##_mask(prod, ring_size); \ + cons = name##_mask(cons, ring_size); \ + \ + if (prod == cons) \ + return ring_size; \ + \ + if (prod > cons) \ + size = prod - cons; \ + else \ + size = ring_size - (cons - prod); \ + return size; \ +} \ + \ +struct name##_data { \ + unsigned char *in; /* half of the allocation */ \ + unsigned char *out; /* half of the allocation */ \ +} + +#define DEFINE_XEN_FLEX_RING_AND_INTF(name) \ +struct name##_data_intf { \ + RING_IDX in_cons, in_prod; \ + \ + uint8_t pad1[56]; \ + \ + RING_IDX out_cons, out_prod; \ + \ + uint8_t pad2[56]; \ + \ + RING_IDX ring_order; \ + grant_ref_t ref[]; \ +}; \ +DEFINE_XEN_FLEX_RING(name) + #endif /* __XEN_PUBLIC_IO_RING_H__ */ /* diff --git a/include/xen/io/sndif.h b/include/xen/io/sndif.h new file mode 100644 index 0000000..c5c1978 --- /dev/null +++ b/include/xen/io/sndif.h @@ -0,0 +1,803 @@ +/****************************************************************************** + * sndif.h + * + * Unified sound-device I/O interface for Xen guest OSes. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (C) 2013-2015 GlobalLogic Inc. + * Copyright (C) 2016-2017 EPAM Systems Inc. + * + * Authors: Oleksandr Andrushchenko <oleksandr_andrushchenko@xxxxxxxx> + * Oleksandr Grytsov <oleksandr_grytsov@xxxxxxxx> + * Oleksandr Dmytryshyn <oleksandr.dmytryshyn@xxxxxxxxxxxxxxx> + * Iurii Konovalenko <iurii.konovalenko@xxxxxxxxxxxxxxx> + */ + +#ifndef __XEN_PUBLIC_IO_SNDIF_H__ +#define __XEN_PUBLIC_IO_SNDIF_H__ + +#include "ring.h" +#include "../grant_table.h" + +/* + ****************************************************************************** + * Feature and Parameter Negotiation + ****************************************************************************** + * + * Front->back notifications: when enqueuing a new request, sending a + * notification can be made conditional on xensnd_req (i.e., the generic + * hold-off mechanism provided by the ring macros). Backends must set + * xensnd_req appropriately (e.g., using RING_FINAL_CHECK_FOR_REQUESTS()). + * + * Back->front notifications: when enqueuing a new response, sending a + * notification can be made conditional on xensnd_resp (i.e., the generic + * hold-off mechanism provided by the ring macros). Frontends must set + * xensnd_resp appropriately (e.g., using RING_FINAL_CHECK_FOR_RESPONSES()). + * + * The two halves of a para-virtual sound card driver utilize nodes within + * XenStore to communicate capabilities and to negotiate operating parameters. + * This section enumerates these nodes which reside in the respective front and + * backend portions of XenStore, following the XenBus convention. + * + * All data in XenStore is stored as strings. Nodes specifying numeric + * values are encoded in decimal. Integer value ranges listed below are + * expressed as fixed sized integer types capable of storing the conversion + * of a properly formated node string, without loss of information. + * + ****************************************************************************** + * Example configuration + ****************************************************************************** + * + * Note: depending on the use-case backend can expose more sound cards and + * PCM devices/streams than the underlying HW physically has by employing + * SW mixers, configuring virtual sound streams, channels etc. + * + * This is an example of backend and frontend configuration: + * + *--------------------------------- Backend ----------------------------------- + * + * /local/domain/0/backend/vsnd/1/0/frontend-id = "1" + * /local/domain/0/backend/vsnd/1/0/frontend = "/local/domain/1/device/vsnd/0" + * /local/domain/0/backend/vsnd/1/0/state = "4" + * /local/domain/0/backend/vsnd/1/0/versions = "1,2" + * + *--------------------------------- Frontend ---------------------------------- + * + * /local/domain/1/device/vsnd/0/backend-id = "0" + * /local/domain/1/device/vsnd/0/backend = "/local/domain/0/backend/vsnd/1/0" + * /local/domain/1/device/vsnd/0/state = "4" + * /local/domain/1/device/vsnd/0/version = "1" + * + *----------------------------- Card configuration ---------------------------- + * + * /local/domain/1/device/vsnd/0/short-name = "Card short name" + * /local/domain/1/device/vsnd/0/long-name = "Card long name" + * /local/domain/1/device/vsnd/0/sample-rates = "8000,32000,44100,48000,96000" + * /local/domain/1/device/vsnd/0/sample-formats = "s8,u8,s16_le,s16_be" + * /local/domain/1/device/vsnd/0/buffer-size = "262144" + * + *------------------------------- PCM device 0 -------------------------------- + * + * /local/domain/1/device/vsnd/0/0/name = "General analog" + * /local/domain/1/device/vsnd/0/0/channels-max = "5" + * + *----------------------------- Stream 0, playback ---------------------------- + * + * /local/domain/1/device/vsnd/0/0/0/type = "p" + * /local/domain/1/device/vsnd/0/0/0/sample-formats = "s8,u8" + * /local/domain/1/device/vsnd/0/0/0/unique-id = "0" + * + * /local/domain/1/device/vsnd/0/0/0/ring-ref = "386" + * /local/domain/1/device/vsnd/0/0/0/event-channel = "15" + * + *------------------------------ Stream 1, capture ---------------------------- + * + * /local/domain/1/device/vsnd/0/0/1/type = "c" + * /local/domain/1/device/vsnd/0/0/1/channels-max = "2" + * /local/domain/1/device/vsnd/0/0/1/unique-id = "1" + * + * /local/domain/1/device/vsnd/0/0/1/ring-ref = "384" + * /local/domain/1/device/vsnd/0/0/1/event-channel = "13" + * + *------------------------------- PCM device 1 -------------------------------- + * + * /local/domain/1/device/vsnd/0/1/name = "HDMI-0" + * /local/domain/1/device/vsnd/0/1/sample-rates = "8000,32000,44100" + * + *------------------------------ Stream 0, capture ---------------------------- + * + * /local/domain/1/device/vsnd/0/1/0/type = "c" + * /local/domain/1/device/vsnd/0/1/0/unique-id = "2" + * + * /local/domain/1/device/vsnd/0/1/0/ring-ref = "387" + * /local/domain/1/device/vsnd/0/1/0/event-channel = "151" + * + *------------------------------- PCM device 2 -------------------------------- + * + * /local/domain/1/device/vsnd/0/2/name = "SPDIF" + * + *----------------------------- Stream 0, playback ---------------------------- + * + * /local/domain/1/device/vsnd/0/2/0/type = "p" + * /local/domain/1/device/vsnd/0/2/0/unique-id = "3" + * + * /local/domain/1/device/vsnd/0/2/0/ring-ref = "389" + * /local/domain/1/device/vsnd/0/2/0/event-channel = "152" + * + ****************************************************************************** + * Backend XenBus Nodes + ****************************************************************************** + * + *----------------------------- Protocol version ------------------------------ + * + * versions + * Values: <string> + * + * List of XENSND_LIST_SEPARATOR separated protocol versions supported + * by the backend. For example "1,2,3". + * + ****************************************************************************** + * Frontend XenBus Nodes + ****************************************************************************** + * + *-------------------------------- Addressing --------------------------------- + * + * dom-id + * Values: <uint16_t> + * + * Domain identifier. + * + * dev-id + * Values: <uint16_t> + * + * Device identifier. + * + * pcm-dev-idx + * Values: <uint8_t> + * + * Zero based contigous index of the PCM device. + * + * stream-idx + * Values: <uint8_t> + * + * Zero based contigous index of the stream of the PCM device. + * + * The following pattern is used for addressing: + * /local/domain/<dom-id>/device/vsnd/<dev-id>/<pcm-dev-idx>/<stream-idx>/... + * + *----------------------------- Protocol version ------------------------------ + * + * version + * Values: <string> + * + * Protocol version, chosen among the ones supported by the backend. + * + *------------------------------- PCM settings -------------------------------- + * + * Every virtualized sound frontend has a set of PCM devices and streams, each + * could be individually configured. Part of the PCM configuration can be + * defined at higher level of the hierarchy and be fully or partially re-used + * by the underlying layers. These configuration values are: + * o number of channels (min/max) + * o supported sample rates + * o supported sample formats. + * E.g. one can define these values for the whole card, device or stream. + * Every underlying layer in turn can re-define some or all of them to better + * fit its needs. For example, card may define number of channels to be + * in [1; 8] range, and some particular stream may be limited to [1; 2] only. + * The rule is that the underlying layer must be a subset of the upper layer + * range. + * + * channels-min + * Values: <uint8_t> + * + * The minimum amount of channels that is supported, [1; channels-max]. + * Optional, if not set or omitted a value of 1 is used. + * + * channels-max + * Values: <uint8_t> + * + * The maximum amount of channels that is supported. + * Must be at least <channels-min>. + * + * sample-rates + * Values: <list of uint32_t> + * + * List of supported sample rates separated by XENSND_LIST_SEPARATOR. + * Sample rates are expressed as a list of decimal values w/o any + * ordering requirement. + * + * sample-formats + * Values: <list of XENSND_PCM_FORMAT_XXX_STR> + * + * List of supported sample formats separated by XENSND_LIST_SEPARATOR. + * Items must not exceed XENSND_SAMPLE_FORMAT_MAX_LEN length. + * + * buffer-size + * Values: <uint32_t> + * + * The maximum size in octets of the buffer to allocate per stream. + * + *----------------------- Virtual sound card settings ------------------------- + * short-name + * Values: <char[32]> + * + * Short name of the virtual sound card. Optional. + * + * long-name + * Values: <char[80]> + * + * Long name of the virtual sound card. Optional. + * + *----------------------------- Device settings ------------------------------- + * name + * Values: <char[80]> + * + * Name of the sound device within the virtual sound card. Optional. + * + *----------------------------- Stream settings ------------------------------- + * + * type + * Values: "p", "c" + * + * Stream type: "p" - playback stream, "c" - capture stream + * + * If both capture and playback are needed then two streams need to be + * defined under the same device. + * + * unique-id + * Values: <uint32_t> + * + * After stream initialization it is assigned a unique ID (within the front + * driver), so every stream of the frontend can be identified by the + * backend by this ID. This is not equal to stream-idx as the later is + * zero based within the device, but this index is contigous within the + * driver. + * + *-------------------- Stream Request Transport Parameters -------------------- + * + * event-channel + * Values: <uint32_t> + * + * The identifier of the Xen event channel used to signal activity + * in the ring buffer. + * + * ring-ref + * Values: <uint32_t> + * + * The Xen grant reference granting permission for the backend to map + * a sole page in a single page sized ring buffer. + * + ****************************************************************************** + * STATE DIAGRAMS + ****************************************************************************** + * + * Tool stack creates front and back state nodes with initial state + * XenbusStateInitialising. + * Tool stack creates and sets up frontend sound configuration nodes per domain. + * + * Front Back + * ================================= ===================================== + * XenbusStateInitialising XenbusStateInitialising + * o Query backend device identification + * data. + * o Open and validate backend device. + * | + * | + * V + * XenbusStateInitWait + * + * o Query frontend configuration + * o Allocate and initialize + * event channels per configured + * playback/capture stream. + * o Publish transport parameters + * that will be in effect during + * this connection. + * | + * | + * V + * XenbusStateInitialised + * + * o Query frontend transport parameters. + * o Connect to the event channels. + * | + * | + * V + * XenbusStateConnected + * + * o Create and initialize OS + * virtual sound device instances + * as per configuration. + * | + * | + * V + * XenbusStateConnected + * + * XenbusStateUnknown + * XenbusStateClosed + * XenbusStateClosing + * o Remove virtual sound device + * o Remove event channels + * | + * | + * V + * XenbusStateClosed + * + *------------------------------- Recovery flow ------------------------------- + * + * In case of frontend unrecoverable errors backend handles that as + * if frontend goes into the XenbusStateClosed state. + * + * In case of backend unrecoverable errors frontend tries removing + * the virtualized device. If this is possible at the moment of error, + * then frontend goes into the XenbusStateInitialising state and is ready for + * new connection with backend. If the virtualized device is still in use and + * cannot be removed, then frontend goes into the XenbusStateReconfiguring state + * until either the virtualized device removed or backend initiates a new + * connection. On the virtualized device removal frontend goes into the + * XenbusStateInitialising state. + * + * Note on XenbusStateReconfiguring state of the frontend: if backend has + * unrecoverable errors then frontend cannot send requests to the backend + * and thus cannot provide functionality of the virtualized device anymore. + * After backend is back to normal the virtualized device may still hold some + * state: configuration in use, allocated buffers, client application state etc. + * So, in most cases, this will require frontend to implement complex recovery + * reconnect logic. Instead, by going into XenbusStateReconfiguring state, + * frontend will make sure no new clients of the virtualized device are + * accepted, allow existing client(s) to exit gracefully by signaling error + * state etc. + * Once all the clients are gone frontend can reinitialize the virtualized + * device and get into XenbusStateInitialising state again signaling the + * backend that a new connection can be made. + * + * There are multiple conditions possible under which frontend will go from + * XenbusStateReconfiguring into XenbusStateInitialising, some of them are OS + * specific. For example: + * 1. The underlying OS framework may provide callbacks to signal that the last + * client of the virtualized device has gone and the device can be removed + * 2. Frontend can schedule a deferred work (timer/tasklet/workqueue) + * to periodically check if this is the right time to re-try removal of + * the virtualized device. + * 3. By any other means. + * + ****************************************************************************** + * PCM FORMATS + ****************************************************************************** + * + * XENSND_PCM_FORMAT_<format>[_<endian>] + * + * format: <S/U/F><bits> or <name> + * S - signed, U - unsigned, F - float + * bits - 8, 16, 24, 32 + * name - MU_LAW, GSM, etc. + * + * endian: <LE/BE>, may be absent + * LE - Little endian, BE - Big endian + */ +#define XENSND_PCM_FORMAT_S8 0 +#define XENSND_PCM_FORMAT_U8 1 +#define XENSND_PCM_FORMAT_S16_LE 2 +#define XENSND_PCM_FORMAT_S16_BE 3 +#define XENSND_PCM_FORMAT_U16_LE 4 +#define XENSND_PCM_FORMAT_U16_BE 5 +#define XENSND_PCM_FORMAT_S24_LE 6 +#define XENSND_PCM_FORMAT_S24_BE 7 +#define XENSND_PCM_FORMAT_U24_LE 8 +#define XENSND_PCM_FORMAT_U24_BE 9 +#define XENSND_PCM_FORMAT_S32_LE 10 +#define XENSND_PCM_FORMAT_S32_BE 11 +#define XENSND_PCM_FORMAT_U32_LE 12 +#define XENSND_PCM_FORMAT_U32_BE 13 +#define XENSND_PCM_FORMAT_F32_LE 14 /* 4-byte float, IEEE-754 32-bit, */ +#define XENSND_PCM_FORMAT_F32_BE 15 /* range -1.0 to 1.0 */ +#define XENSND_PCM_FORMAT_F64_LE 16 /* 8-byte float, IEEE-754 64-bit, */ +#define XENSND_PCM_FORMAT_F64_BE 17 /* range -1.0 to 1.0 */ +#define XENSND_PCM_FORMAT_IEC958_SUBFRAME_LE 18 +#define XENSND_PCM_FORMAT_IEC958_SUBFRAME_BE 19 +#define XENSND_PCM_FORMAT_MU_LAW 20 +#define XENSND_PCM_FORMAT_A_LAW 21 +#define XENSND_PCM_FORMAT_IMA_ADPCM 22 +#define XENSND_PCM_FORMAT_MPEG 23 +#define XENSND_PCM_FORMAT_GSM 24 + +/* + ****************************************************************************** + * REQUEST CODES + ****************************************************************************** + */ +#define XENSND_OP_OPEN 0 +#define XENSND_OP_CLOSE 1 +#define XENSND_OP_READ 2 +#define XENSND_OP_WRITE 3 +#define XENSND_OP_SET_VOLUME 4 +#define XENSND_OP_GET_VOLUME 5 +#define XENSND_OP_MUTE 6 +#define XENSND_OP_UNMUTE 7 + +/* + ****************************************************************************** + * XENSTORE FIELD AND PATH NAME STRINGS, HELPERS + ****************************************************************************** + */ +#define XENSND_DRIVER_NAME "vsnd" + +#define XENSND_LIST_SEPARATOR "," +/* Field names */ +#define XENSND_FIELD_BE_VERSIONS "versions" +#define XENSND_FIELD_FE_VERSION "version" +#define XENSND_FIELD_VCARD_SHORT_NAME "short-name" +#define XENSND_FIELD_VCARD_LONG_NAME "long-name" +#define XENSND_FIELD_RING_REF "ring-ref" +#define XENSND_FIELD_EVT_CHNL "event-channel" +#define XENSND_FIELD_DEVICE_NAME "name" +#define XENSND_FIELD_TYPE "type" +#define XENSND_FIELD_STREAM_UNIQUE_ID "unique-id" +#define XENSND_FIELD_CHANNELS_MIN "channels-min" +#define XENSND_FIELD_CHANNELS_MAX "channels-max" +#define XENSND_FIELD_SAMPLE_RATES "sample-rates" +#define XENSND_FIELD_SAMPLE_FORMATS "sample-formats" +#define XENSND_FIELD_BUFFER_SIZE "buffer-size" + +/* Stream type field values. */ +#define XENSND_STREAM_TYPE_PLAYBACK "p" +#define XENSND_STREAM_TYPE_CAPTURE "c" +/* Sample rate max string length */ +#define XENSND_SAMPLE_RATE_MAX_LEN 11 +/* Sample format field values */ +#define XENSND_SAMPLE_FORMAT_MAX_LEN 24 + +#define XENSND_PCM_FORMAT_S8_STR "s8" +#define XENSND_PCM_FORMAT_U8_STR "u8" +#define XENSND_PCM_FORMAT_S16_LE_STR "s16_le" +#define XENSND_PCM_FORMAT_S16_BE_STR "s16_be" +#define XENSND_PCM_FORMAT_U16_LE_STR "u16_le" +#define XENSND_PCM_FORMAT_U16_BE_STR "u16_be" +#define XENSND_PCM_FORMAT_S24_LE_STR "s24_le" +#define XENSND_PCM_FORMAT_S24_BE_STR "s24_be" +#define XENSND_PCM_FORMAT_U24_LE_STR "u24_le" +#define XENSND_PCM_FORMAT_U24_BE_STR "u24_be" +#define XENSND_PCM_FORMAT_S32_LE_STR "s32_le" +#define XENSND_PCM_FORMAT_S32_BE_STR "s32_be" +#define XENSND_PCM_FORMAT_U32_LE_STR "u32_le" +#define XENSND_PCM_FORMAT_U32_BE_STR "u32_be" +#define XENSND_PCM_FORMAT_F32_LE_STR "float_le" +#define XENSND_PCM_FORMAT_F32_BE_STR "float_be" +#define XENSND_PCM_FORMAT_F64_LE_STR "float64_le" +#define XENSND_PCM_FORMAT_F64_BE_STR "float64_be" +#define XENSND_PCM_FORMAT_IEC958_SUBFRAME_LE_STR "iec958_subframe_le" +#define XENSND_PCM_FORMAT_IEC958_SUBFRAME_BE_STR "iec958_subframe_be" +#define XENSND_PCM_FORMAT_MU_LAW_STR "mu_law" +#define XENSND_PCM_FORMAT_A_LAW_STR "a_law" +#define XENSND_PCM_FORMAT_IMA_ADPCM_STR "ima_adpcm" +#define XENSND_PCM_FORMAT_MPEG_STR "mpeg" +#define XENSND_PCM_FORMAT_GSM_STR "gsm" + + +/* + ****************************************************************************** + * STATUS RETURN CODES + ****************************************************************************** + * + * Status return code is zero on success and -XEN_EXX on failure. + * + ****************************************************************************** + * Assumptions + ****************************************************************************** + * o usage of grant reference 0 as invalid grant reference: + * grant reference 0 is valid, but never exposed to a PV driver, + * because of the fact it is already in use/reserved by the PV console. + * o all references in this document to page sizes must be treated + * as pages of size XEN_PAGE_SIZE unless otherwise noted. + * + ****************************************************************************** + * Description of the protocol between frontend and backend driver + ****************************************************************************** + * + * The two halves of a Para-virtual sound driver communicate with + * each other using shared pages and event channels. + * Shared page contains a ring with request/response packets. + * + * Packets, used for input/output operations, e.g. read/write, set/get volume, + * etc., provide offset/length fields in order to allow asynchronous protocol + * operation with buffer space sharing: part of the buffer allocated at + * XENSND_OP_OPEN can be used for audio samples and part, for example, + * for volume control. + * + * All reserved fields in the structures below must be 0. + * + *---------------------------------- Requests --------------------------------- + * + * All request packets have the same length (32 octets) + * All request packets have common header: + * 0 1 2 3 octet + * +----------------+----------------+----------------+----------------+ + * | id | operation | reserved | 4 + * +----------------+----------------+----------------+----------------+ + * | reserved | 8 + * +----------------+----------------+----------------+----------------+ + * id - uint16_t, private guest value, echoed in response + * operation - uint8_t, operation code, XENSND_OP_??? + * + * For all packets which use offset and length: + * offset - uint32_t, read or write data offset within the shared buffer, + * passed with XENSND_OP_OPEN request, octets, + * [0; XENSND_OP_OPEN.buffer_sz - 1]. + * length - uint32_t, read or write data length, octets + * + * Request open - open a PCM stream for playback or capture: + * + * 0 1 2 3 octet + * +----------------+----------------+----------------+----------------+ + * | id | XENSND_OP_OPEN | reserved | 4 + * +----------------+----------------+----------------+----------------+ + * | reserved | 8 + * +----------------+----------------+----------------+----------------+ + * | pcm_rate | 12 + * +----------------+----------------+----------------+----------------+ + * | pcm_format | pcm_channels | reserved | 16 + * +----------------+----------------+----------------+----------------+ + * | buffer_sz | 20 + * +----------------+----------------+----------------+----------------+ + * | gref_directory | 24 + * +----------------+----------------+----------------+----------------+ + * | reserved | 28 + * +----------------+----------------+----------------+----------------+ + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| + * +----------------+----------------+----------------+----------------+ + * | reserved | 32 + * +----------------+----------------+----------------+----------------+ + * + * pcm_rate - uint32_t, stream data rate, Hz + * pcm_format - uint8_t, XENSND_PCM_FORMAT_XXX value + * pcm_channels - uint8_t, number of channels of this stream, + * [channels-min; channels-max] + * buffer_sz - uint32_t, buffer size to be allocated, octets + * gref_directory - grant_ref_t, a reference to the first shared page + * describing shared buffer references. At least one page exists. If shared + * buffer size (buffer_sz) exceeds what can be addressed by this single page, + * then reference to the next page must be supplied (see gref_dir_next_page + * below) + */ + +struct xensnd_open_req { + uint32_t pcm_rate; + uint8_t pcm_format; + uint8_t pcm_channels; + uint16_t reserved; + uint32_t buffer_sz; + grant_ref_t gref_directory; +}; + +/* + * Shared page for XENSND_OP_OPEN buffer descriptor (gref_directory in the + * request) employs a list of pages, describing all pages of the shared data + * buffer: + * 0 1 2 3 octet + * +----------------+----------------+----------------+----------------+ + * | gref_dir_next_page | 4 + * +----------------+----------------+----------------+----------------+ + * | gref[0] | 8 + * +----------------+----------------+----------------+----------------+ + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| + * +----------------+----------------+----------------+----------------+ + * | gref[i] | i*4+8 + * +----------------+----------------+----------------+----------------+ + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| + * +----------------+----------------+----------------+----------------+ + * | gref[N - 1] | N*4+8 + * +----------------+----------------+----------------+----------------+ + * + * gref_dir_next_page - grant_ref_t, reference to the next page describing + * page directory. Must be 0 if there are no more pages in the list. + * gref[i] - grant_ref_t, reference to a shared page of the buffer + * allocated at XENSND_OP_OPEN + * + * Number of grant_ref_t entries in the whole page directory is not + * passed, but instead can be calculated as: + * num_grefs_total = (XENSND_OP_OPEN.buffer_sz + XEN_PAGE_SIZE - 1) / + * XEN_PAGE_SIZE + */ + +struct xensnd_page_directory { + grant_ref_t gref_dir_next_page; + grant_ref_t gref[1]; /* Variable length */ +}; + +/* + * Request close - close an opened pcm stream: + * 0 1 2 3 octet + * +----------------+----------------+----------------+----------------+ + * | id | XENSND_OP_CLOSE| reserved | 4 + * +----------------+----------------+----------------+----------------+ + * | reserved | 8 + * +----------------+----------------+----------------+----------------+ + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| + * +----------------+----------------+----------------+----------------+ + * | reserved | 32 + * +----------------+----------------+----------------+----------------+ + * + * Request read/write - used for read (for capture) or write (for playback): + * 0 1 2 3 octet + * +----------------+----------------+----------------+----------------+ + * | id | operation | reserved | 4 + * +----------------+----------------+----------------+----------------+ + * | reserved | 8 + * +----------------+----------------+----------------+----------------+ + * | offset | 12 + * +----------------+----------------+----------------+----------------+ + * | length | 16 + * +----------------+----------------+----------------+----------------+ + * | reserved | 20 + * +----------------+----------------+----------------+----------------+ + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| + * +----------------+----------------+----------------+----------------+ + * | reserved | 32 + * +----------------+----------------+----------------+----------------+ + * + * operation - XENSND_OP_READ for read or XENSND_OP_WRITE for write + */ + +struct xensnd_rw_req { + uint32_t offset; + uint32_t length; +}; + +/* + * Request set/get volume - set/get channels' volume of the stream given: + * 0 1 2 3 octet + * +----------------+----------------+----------------+----------------+ + * | id | operation | reserved | 4 + * +----------------+----------------+----------------+----------------+ + * | reserved | 8 + * +----------------+----------------+----------------+----------------+ + * | offset | 12 + * +----------------+----------------+----------------+----------------+ + * | length | 16 + * +----------------+----------------+----------------+----------------+ + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| + * +----------------+----------------+----------------+----------------+ + * | reserved | 32 + * +----------------+----------------+----------------+----------------+ + * + * operation - XENSND_OP_SET_VOLUME for volume set + * or XENSND_OP_GET_VOLUME for volume get + * Buffer passed with XENSND_OP_OPEN is used to exchange volume + * values: + * + * 0 1 2 3 octet + * +----------------+----------------+----------------+----------------+ + * | channel[0] | 4 + * +----------------+----------------+----------------+----------------+ + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| + * +----------------+----------------+----------------+----------------+ + * | channel[i] | i*4 + * +----------------+----------------+----------------+----------------+ + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| + * +----------------+----------------+----------------+----------------+ + * | channel[N - 1] | (N-1)*4 + * +----------------+----------------+----------------+----------------+ + * + * N = XENSND_OP_OPEN.pcm_channels + * i - uint8_t, index of a channel + * channel[i] - sint32_t, volume of i-th channel + * Volume is expressed as a signed value in steps of 0.001 dB, + * while 0 being 0 dB. + * + * Request mute/unmute - mute/unmute stream: + * 0 1 2 3 octet + * +----------------+----------------+----------------+----------------+ + * | id | operation | reserved | 4 + * +----------------+----------------+----------------+----------------+ + * | reserved | 8 + * +----------------+----------------+----------------+----------------+ + * | offset | 12 + * +----------------+----------------+----------------+----------------+ + * | length | 16 + * +----------------+----------------+----------------+----------------+ + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| + * +----------------+----------------+----------------+----------------+ + * | reserved | 32 + * +----------------+----------------+----------------+----------------+ + * + * operation - XENSND_OP_MUTE for mute or XENSND_OP_UNMUTE for unmute + * Buffer passed with XENSND_OP_OPEN is used to exchange mute/unmute + * values: + * + * 0 octet + * +----------------+----------------+----------------+----------------+ + * | channel[0] | 4 + * +----------------+----------------+----------------+----------------+ + * +/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| + * +----------------+----------------+----------------+----------------+ + * | channel[i] | i*4 + * +----------------+----------------+----------------+----------------+ + * +/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| + * +----------------+----------------+----------------+----------------+ + * | channel[N - 1] | (N-1)*4 + * +----------------+----------------+----------------+----------------+ + * + * N = XENSND_OP_OPEN.pcm_channels + * i - uint8_t, index of a channel + * channel[i] - uint8_t, non-zero if i-th channel needs to be muted/unmuted + * + *------------------------------------ N.B. ----------------------------------- + * + * The 'struct xensnd_rw_req' is also used for XENSND_OP_SET_VOLUME, + * XENSND_OP_GET_VOLUME, XENSND_OP_MUTE, XENSND_OP_UNMUTE. + */ + +/* + *---------------------------------- Responses -------------------------------- + * + * All response packets have the same length (32 octets) + * + * Response for all requests: + * 0 1 2 3 octet + * +----------------+----------------+----------------+----------------+ + * | id | operation | reserved | 4 + * +----------------+----------------+----------------+----------------+ + * | status | 8 + * +----------------+----------------+----------------+----------------+ + * | reserved | 12 + * +----------------+----------------+----------------+----------------+ + * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| + * +----------------+----------------+----------------+----------------+ + * | reserved | 32 + * +----------------+----------------+----------------+----------------+ + * + * id - uint16_t, copied from the request + * operation - uint8_t, XENSND_OP_* - copied from request + * status - int32_t, response status, zero on success and -XEN_EXX on failure + */ + +struct xensnd_req { + uint16_t id; + uint8_t operation; + uint8_t reserved[5]; + union { + struct xensnd_open_req open; + struct xensnd_rw_req rw; + uint8_t reserved[24]; + } op; +}; + +struct xensnd_resp { + uint16_t id; + uint8_t operation; + uint8_t reserved; + int32_t status; + uint8_t reserved1[24]; +}; + +DEFINE_RING_TYPES(xen_sndif, struct xensnd_req, struct xensnd_resp); + +#endif /* __XEN_PUBLIC_IO_SNDIF_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/xen/io/usbif.h b/include/xen/io/usbif.h index 0af2a38..c6a5863 100644 --- a/include/xen/io/usbif.h +++ b/include/xen/io/usbif.h @@ -31,6 +31,76 @@ #include "ring.h" #include "../grant_table.h" +/* + * Feature and Parameter Negotiation + * ================================= + * The two halves of a Xen pvUSB driver utilize nodes within the XenStore to + * communicate capabilities and to negotiate operating parameters. This + * section enumerates these nodes which reside in the respective front and + * backend portions of the XenStore, following the XenBus convention. + * + * Any specified default value is in effect if the corresponding XenBus node + * is not present in the XenStore. + * + * XenStore nodes in sections marked "PRIVATE" are solely for use by the + * driver side whose XenBus tree contains them. + * + ***************************************************************************** + * Backend XenBus Nodes + ***************************************************************************** + * + *------------------ Backend Device Identification (PRIVATE) ------------------ + * + * num-ports + * Values: unsigned [1...31] + * + * Number of ports for this (virtual) USB host connector. + * + * usb-ver + * Values: unsigned [1...2] + * + * USB version of this host connector: 1 = USB 1.1, 2 = USB 2.0. + * + * port/[1...31] + * Values: string + * + * Physical USB device connected to the given port, e.g. "3-1.5". + * + ***************************************************************************** + * Frontend XenBus Nodes + ***************************************************************************** + * + *----------------------- Request Transport Parameters ----------------------- + * + * event-channel + * Values: unsigned + * + * The identifier of the Xen event channel used to signal activity + * in the ring buffer. + * + * urb-ring-ref + * Values: unsigned + * + * The Xen grant reference granting permission for the backend to map + * the sole page in a single page sized ring buffer. This is the ring + * buffer for urb requests. + * + * conn-ring-ref + * Values: unsigned + * + * The Xen grant reference granting permission for the backend to map + * the sole page in a single page sized ring buffer. This is the ring + * buffer for connection/disconnection requests. + * + * protocol + * Values: string (XEN_IO_PROTO_ABI_*) + * Default Value: XEN_IO_PROTO_ABI_NATIVE + * + * The machine ABI rules governing the format of all ring request and + * response structures. + * + */ + enum usb_spec_version { USB_VER_UNKNOWN = 0, USB_VER_USB11, @@ -41,37 +111,66 @@ enum usb_spec_version { /* * USB pipe in usbif_request * - * bits 0-5 are specific bits for virtual USB driver. - * bits 7-31 are standard urb pipe. - * - * - port number(NEW): bits 0-4 - * (USB_MAXCHILDREN is 31) + * - port number: bits 0-4 + * (USB_MAXCHILDREN is 31) * - * - operation flag(NEW): bit 5 - * (0 = submit urb, - * 1 = unlink urb) + * - operation flag: bit 5 + * (0 = submit urb, + * 1 = unlink urb) * * - direction: bit 7 - * (0 = Host-to-Device [Out] - * 1 = Device-to-Host [In]) + * (0 = Host-to-Device [Out] + * 1 = Device-to-Host [In]) * * - device address: bits 8-14 * * - endpoint: bits 15-18 * - * - pipe type: bits 30-31 - * (00 = isochronous, 01 = interrupt, - * 10 = control, 11 = bulk) + * - pipe type: bits 30-31 + * (00 = isochronous, 01 = interrupt, + * 10 = control, 11 = bulk) */ -#define usbif_pipeportnum(pipe) ((pipe) & 0x1f) -#define usbif_setportnum_pipe(pipe, portnum) \ - ((pipe)|(portnum)) -#define usbif_pipeunlink(pipe) ((pipe) & 0x20) -#define usbif_pipesubmit(pipe) (!usbif_pipeunlink(pipe)) -#define usbif_setunlink_pipe(pipe) ((pipe)|(0x20)) +#define USBIF_PIPE_PORT_MASK 0x0000001f +#define USBIF_PIPE_UNLINK 0x00000020 +#define USBIF_PIPE_DIR 0x00000080 +#define USBIF_PIPE_DEV_MASK 0x0000007f +#define USBIF_PIPE_DEV_SHIFT 8 +#define USBIF_PIPE_EP_MASK 0x0000000f +#define USBIF_PIPE_EP_SHIFT 15 +#define USBIF_PIPE_TYPE_MASK 0x00000003 +#define USBIF_PIPE_TYPE_SHIFT 30 +#define USBIF_PIPE_TYPE_ISOC 0 +#define USBIF_PIPE_TYPE_INT 1 +#define USBIF_PIPE_TYPE_CTRL 2 +#define USBIF_PIPE_TYPE_BULK 3 + +#define usbif_pipeportnum(pipe) ((pipe) & USBIF_PIPE_PORT_MASK) +#define usbif_setportnum_pipe(pipe, portnum) ((pipe) | (portnum)) + +#define usbif_pipeunlink(pipe) ((pipe) & USBIF_PIPE_UNLINK) +#define usbif_pipesubmit(pipe) (!usbif_pipeunlink(pipe)) +#define usbif_setunlink_pipe(pipe) ((pipe) | USBIF_PIPE_UNLINK) + +#define usbif_pipein(pipe) ((pipe) & USBIF_PIPE_DIR) +#define usbif_pipeout(pipe) (!usbif_pipein(pipe)) + +#define usbif_pipedevice(pipe) \ + (((pipe) >> USBIF_PIPE_DEV_SHIFT) & USBIF_PIPE_DEV_MASK) + +#define usbif_pipeendpoint(pipe) \ + (((pipe) >> USBIF_PIPE_EP_SHIFT) & USBIF_PIPE_EP_MASK) + +#define usbif_pipetype(pipe) \ + (((pipe) >> USBIF_PIPE_TYPE_SHIFT) & USBIF_PIPE_TYPE_MASK) +#define usbif_pipeisoc(pipe) (usbif_pipetype(pipe) == USBIF_PIPE_TYPE_ISOC) +#define usbif_pipeint(pipe) (usbif_pipetype(pipe) == USBIF_PIPE_TYPE_INT) +#define usbif_pipectrl(pipe) (usbif_pipetype(pipe) == USBIF_PIPE_TYPE_CTRL) +#define usbif_pipebulk(pipe) (usbif_pipetype(pipe) == USBIF_PIPE_TYPE_BULK) #define USBIF_MAX_SEGMENTS_PER_REQUEST (16) +#define USBIF_MAX_PORTNR 31 +#define USBIF_RING_SIZE 4096 /* * RING for transferring urbs. @@ -89,6 +188,7 @@ struct usbif_urb_request { /* basic urb parameter */ uint32_t pipe; uint16_t transfer_flags; +#define USBIF_SHORT_NOT_OK 0x0001 uint16_t buffer_length; union { uint8_t ctrl[8]; /* setup_packet (Ctrl) */ @@ -127,7 +227,7 @@ struct usbif_urb_response { typedef struct usbif_urb_response usbif_urb_response_t; DEFINE_RING_TYPES(usbif_urb, struct usbif_urb_request, struct usbif_urb_response); -#define USB_URB_RING_SIZE __CONST_RING_SIZE(usbif_urb, PAGE_SIZE) +#define USB_URB_RING_SIZE __CONST_RING_SIZE(usbif_urb, USBIF_RING_SIZE) /* * RING for notifying connect/disconnect events to frontend @@ -141,10 +241,14 @@ struct usbif_conn_response { uint16_t id; /* request id */ uint8_t portnum; /* port number */ uint8_t speed; /* usb_device_speed */ +#define USBIF_SPEED_NONE 0 +#define USBIF_SPEED_LOW 1 +#define USBIF_SPEED_FULL 2 +#define USBIF_SPEED_HIGH 3 }; typedef struct usbif_conn_response usbif_conn_response_t; DEFINE_RING_TYPES(usbif_conn, struct usbif_conn_request, struct usbif_conn_response); -#define USB_CONN_RING_SIZE __CONST_RING_SIZE(usbif_conn, PAGE_SIZE) +#define USB_CONN_RING_SIZE __CONST_RING_SIZE(usbif_conn, USBIF_RING_SIZE) #endif /* __XEN_PUBLIC_IO_USBIF_H__ */ diff --git a/include/xen/io/vscsiif.h b/include/xen/io/vscsiif.h index 7a1db05..d0bd3b5 100644 --- a/include/xen/io/vscsiif.h +++ b/include/xen/io/vscsiif.h @@ -60,7 +60,7 @@ * * A string specifying the backend device: either a 4-tuple "h:c:t:l" * (host, controller, target, lun, all integers), or a WWN (e.g. - * "naa.60014054ac780582"). + * "naa.60014054ac780582:0"). * * v-dev * Values: string @@ -104,6 +104,75 @@ * response structures. */ +/* + * Xenstore format in practice + * =========================== + * + * The backend driver uses a single_host:many_devices notation to manage domU + * devices. Everything is stored in /local/domain/<backend_domid>/backend/vscsi/. + * The xenstore layout looks like this (dom0 is assumed to be the backend_domid): + * + * <domid>/<vhost>/feature-host = "0" + * <domid>/<vhost>/frontend = "/local/domain/<domid>/device/vscsi/0" + * <domid>/<vhost>/frontend-id = "<domid>" + * <domid>/<vhost>/online = "1" + * <domid>/<vhost>/state = "4" + * <domid>/<vhost>/vscsi-devs/dev-0/p-dev = "8:0:2:1" or "naa.wwn:lun" + * <domid>/<vhost>/vscsi-devs/dev-0/state = "4" + * <domid>/<vhost>/vscsi-devs/dev-0/v-dev = "0:0:0:0" + * <domid>/<vhost>/vscsi-devs/dev-1/p-dev = "8:0:2:2" + * <domid>/<vhost>/vscsi-devs/dev-1/state = "4" + * <domid>/<vhost>/vscsi-devs/dev-1/v-dev = "0:0:1:0" + * + * The frontend driver maintains its state in + * /local/domain/<domid>/device/vscsi/. + * + * <vhost>/backend = "/local/domain/0/backend/vscsi/<domid>/<vhost>" + * <vhost>/backend-id = "0" + * <vhost>/event-channel = "20" + * <vhost>/ring-ref = "43" + * <vhost>/state = "4" + * <vhost>/vscsi-devs/dev-0/state = "4" + * <vhost>/vscsi-devs/dev-1/state = "4" + * + * In addition to the entries for backend and frontend these flags are stored + * for the toolstack: + * + * <domid>/<vhost>/vscsi-devs/dev-1/p-devname = "/dev/$device" + * <domid>/<vhost>/libxl_ctrl_index = "0" + * + * + * Backend/frontend protocol + * ========================= + * + * To create a vhost along with a device: + * <domid>/<vhost>/feature-host = "0" + * <domid>/<vhost>/frontend = "/local/domain/<domid>/device/vscsi/0" + * <domid>/<vhost>/frontend-id = "<domid>" + * <domid>/<vhost>/online = "1" + * <domid>/<vhost>/state = "1" + * <domid>/<vhost>/vscsi-devs/dev-0/p-dev = "8:0:2:1" + * <domid>/<vhost>/vscsi-devs/dev-0/state = "1" + * <domid>/<vhost>/vscsi-devs/dev-0/v-dev = "0:0:0:0" + * Wait for <domid>/<vhost>/state + <domid>/<vhost>/vscsi-devs/dev-0/state become 4 + * + * To add another device to a vhost: + * <domid>/<vhost>/state = "7" + * <domid>/<vhost>/vscsi-devs/dev-1/p-dev = "8:0:2:2" + * <domid>/<vhost>/vscsi-devs/dev-1/state = "1" + * <domid>/<vhost>/vscsi-devs/dev-1/v-dev = "0:0:1:0" + * Wait for <domid>/<vhost>/state + <domid>/<vhost>/vscsi-devs/dev-1/state become 4 + * + * To remove a device from a vhost: + * <domid>/<vhost>/state = "7" + * <domid>/<vhost>/vscsi-devs/dev-1/state = "5" + * Wait for <domid>/<vhost>/state to become 4 + * Wait for <domid>/<vhost>/vscsi-devs/dev-1/state become 6 + * Remove <domid>/<vhost>/vscsi-devs/dev-1/{state,p-dev,v-dev,p-devname} + * Remove <domid>/<vhost>/vscsi-devs/dev-1/ + * + */ + /* Requests from the frontend to the backend */ /* @@ -179,6 +248,7 @@ */ #define VSCSIIF_MAX_COMMAND_SIZE 16 #define VSCSIIF_SENSE_BUFFERSIZE 96 +#define VSCSIIF_PAGE_SIZE 4096 struct scsiif_request_segment { grant_ref_t gref; @@ -187,7 +257,7 @@ struct scsiif_request_segment { }; typedef struct scsiif_request_segment vscsiif_segment_t; -#define VSCSIIF_SG_PER_PAGE (PAGE_SIZE / sizeof(struct scsiif_request_segment)) +#define VSCSIIF_SG_PER_PAGE (VSCSIIF_PAGE_SIZE / sizeof(struct scsiif_request_segment)) /* Size of one request is 252 bytes */ struct vscsiif_request { diff --git a/include/xen/io/xs_wire.h b/include/xen/io/xs_wire.h index 0a0cdbc..4dd6632 100644 --- a/include/xen/io/xs_wire.h +++ b/include/xen/io/xs_wire.h @@ -28,7 +28,8 @@ enum xsd_sockmsg_type { - XS_DEBUG, + XS_CONTROL, +#define XS_DEBUG XS_CONTROL XS_DIRECTORY, XS_READ, XS_GET_PERMS, @@ -48,8 +49,11 @@ enum xsd_sockmsg_type XS_IS_DOMAIN_INTRODUCED, XS_RESUME, XS_SET_TARGET, - XS_RESTRICT, - XS_RESET_WATCHES, + /* XS_RESTRICT has been removed */ + XS_RESET_WATCHES = XS_SET_TARGET + 2, + XS_DIRECTORY_PART, + + XS_TYPE_COUNT, /* Number of valid types. */ XS_INVALID = 0xffff /* Guaranteed to remain an invalid type */ }; diff --git a/include/xen/kexec.h b/include/xen/kexec.h index a6a0a88..74ea981 100644 --- a/include/xen/kexec.h +++ b/include/xen/kexec.h @@ -227,6 +227,20 @@ typedef struct xen_kexec_unload { } xen_kexec_unload_t; DEFINE_XEN_GUEST_HANDLE(xen_kexec_unload_t); +/* + * Figure out whether we have an image loaded. A return value of + * zero indicates no image loaded. A return value of one + * indicates an image is loaded. A negative return value + * indicates an error. + * + * Type must be one of KEXEC_TYPE_DEFAULT or KEXEC_TYPE_CRASH. + */ +#define KEXEC_CMD_kexec_status 6 +typedef struct xen_kexec_status { + uint8_t type; +} xen_kexec_status_t; +DEFINE_XEN_GUEST_HANDLE(xen_kexec_status_t); + #else /* __XEN_INTERFACE_VERSION__ < 0x00040400 */ #define KEXEC_CMD_kexec_load KEXEC_CMD_kexec_load_v1 diff --git a/include/xen/mem_event.h b/include/xen/mem_event.h deleted file mode 100644 index 599f9e8..0000000 --- a/include/xen/mem_event.h +++ /dev/null @@ -1,134 +0,0 @@ -/****************************************************************************** - * mem_event.h - * - * Memory event common structures. - * - * Copyright (c) 2009 by Citrix Systems, Inc. (Patrick Colp) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifndef _XEN_PUBLIC_MEM_EVENT_H -#define _XEN_PUBLIC_MEM_EVENT_H - -#include "xen.h" -#include "io/ring.h" - -/* Memory event flags */ -#define MEM_EVENT_FLAG_VCPU_PAUSED (1 << 0) -#define MEM_EVENT_FLAG_DROP_PAGE (1 << 1) -#define MEM_EVENT_FLAG_EVICT_FAIL (1 << 2) -#define MEM_EVENT_FLAG_FOREIGN (1 << 3) -#define MEM_EVENT_FLAG_DUMMY (1 << 4) -/* - * Emulate the fault-causing instruction (if set in the event response flags). - * This will allow the guest to continue execution without lifting the page - * access restrictions. - */ -#define MEM_EVENT_FLAG_EMULATE (1 << 5) -/* - * Same as MEM_EVENT_FLAG_EMULATE, but with write operations or operations - * potentially having side effects (like memory mapped or port I/O) disabled. - */ -#define MEM_EVENT_FLAG_EMULATE_NOWRITE (1 << 6) - -/* Reasons for the memory event request */ -#define MEM_EVENT_REASON_UNKNOWN 0 /* typical reason */ -#define MEM_EVENT_REASON_VIOLATION 1 /* access violation, GFN is address */ -#define MEM_EVENT_REASON_CR0 2 /* CR0 was hit: gfn is new CR0 value, gla is previous */ -#define MEM_EVENT_REASON_CR3 3 /* CR3 was hit: gfn is new CR3 value, gla is previous */ -#define MEM_EVENT_REASON_CR4 4 /* CR4 was hit: gfn is new CR4 value, gla is previous */ -#define MEM_EVENT_REASON_INT3 5 /* int3 was hit: gla/gfn are RIP */ -#define MEM_EVENT_REASON_SINGLESTEP 6 /* single step was invoked: gla/gfn are RIP */ -#define MEM_EVENT_REASON_MSR 7 /* MSR was hit: gfn is MSR value, gla is MSR address; - does NOT honour HVMPME_onchangeonly */ - -/* Using a custom struct (not hvm_hw_cpu) so as to not fill - * the mem_event ring buffer too quickly. */ -struct mem_event_regs_x86 { - uint64_t rax; - uint64_t rcx; - uint64_t rdx; - uint64_t rbx; - uint64_t rsp; - uint64_t rbp; - uint64_t rsi; - uint64_t rdi; - uint64_t r8; - uint64_t r9; - uint64_t r10; - uint64_t r11; - uint64_t r12; - uint64_t r13; - uint64_t r14; - uint64_t r15; - uint64_t rflags; - uint64_t dr7; - uint64_t rip; - uint64_t cr0; - uint64_t cr2; - uint64_t cr3; - uint64_t cr4; - uint64_t sysenter_cs; - uint64_t sysenter_esp; - uint64_t sysenter_eip; - uint64_t msr_efer; - uint64_t msr_star; - uint64_t msr_lstar; - uint64_t fs_base; - uint64_t gs_base; - uint32_t cs_arbytes; - uint32_t _pad; -}; - -typedef struct mem_event_st { - uint32_t flags; - uint32_t vcpu_id; - - uint64_t gfn; - uint64_t offset; - uint64_t gla; /* if gla_valid */ - - uint32_t p2mt; - - uint16_t access_r:1; - uint16_t access_w:1; - uint16_t access_x:1; - uint16_t gla_valid:1; - uint16_t fault_with_gla:1; - uint16_t fault_in_gpt:1; - uint16_t available:10; - - uint16_t reason; - struct mem_event_regs_x86 x86_regs; -} mem_event_request_t, mem_event_response_t; - -DEFINE_RING_TYPES(mem_event, mem_event_request_t, mem_event_response_t); - -#endif - -/* - * Local variables: - * mode: C - * c-file-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/include/xen/memory.h b/include/xen/memory.h index 595f953..29386df 100644 --- a/include/xen/memory.h +++ b/include/xen/memory.h @@ -28,6 +28,7 @@ #define __XEN_PUBLIC_MEMORY_H__ #include "xen.h" +#include "physdev.h" /* * Increase or decrease the specified domain's memory reservation. Returns the @@ -55,6 +56,8 @@ /* Flag to request allocation only from the node specified */ #define XENMEMF_exact_node_request (1<<17) #define XENMEMF_exact_node(n) (XENMEMF_node(n) | XENMEMF_exact_node_request) +/* Flag to indicate the node specified is virtual node */ +#define XENMEMF_vnode (1<<18) #endif struct xen_memory_reservation { @@ -99,6 +102,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_memory_reservation_t); * Returns zero on complete success, otherwise a negative error code. * On complete success then always @nr_exchanged == @in.nr_extents. * On partial success @nr_exchanged indicates how much work was done. + * + * Note that only PV guests can use this operation. */ #define XENMEM_exchange 11 struct xen_memory_exchange { @@ -217,6 +222,11 @@ DEFINE_XEN_GUEST_HANDLE(xen_machphys_mapping_t); #define XENMAPSPACE_gmfn_range 3 /* GMFN range, XENMEM_add_to_physmap only. */ #define XENMAPSPACE_gmfn_foreign 4 /* GMFN from another dom, * XENMEM_add_to_physmap_batch only. */ +#define XENMAPSPACE_dev_mmio 5 /* device mmio region + ARM only; the region is mapped in + Stage-2 using the Normal Memory + Inner/Outer Write-Back Cacheable + memory attribute. */ /* ` } */ /* @@ -255,7 +265,15 @@ struct xen_add_to_physmap_batch { /* Number of pages to go through */ uint16_t size; - domid_t foreign_domid; /* IFF gmfn_foreign */ + +#if __XEN_INTERFACE_VERSION__ < 0x00040700 + domid_t foreign_domid; /* IFF gmfn_foreign. Should be 0 for other spaces. */ +#else + union xen_add_to_physmap_batch_extra { + domid_t foreign_domid; /* gmfn_foreign */ + uint16_t res0; /* All the other spaces. Should be 0 */ + } u; +#endif /* Indexes into space being mapped. */ XEN_GUEST_HANDLE(xen_ulong_t) idxs; @@ -323,6 +341,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_memory_map_t); /* * Returns the real physical memory map. Passes the same structure as * XENMEM_memory_map. + * Specifying buffer as NULL will return the number of entries required + * to store the complete memory map. * arg == addr of xen_memory_map_t. */ #define XENMEM_machine_memory_map 10 @@ -372,23 +392,29 @@ typedef struct xen_pod_target xen_pod_target_t; #define XENMEM_paging_op_evict 1 #define XENMEM_paging_op_prep 2 -struct xen_mem_event_op { - uint8_t op; /* XENMEM_*_op_* */ +struct xen_mem_paging_op { + uint8_t op; /* XENMEM_paging_op_* */ domid_t domain; - /* PAGING_PREP IN: buffer to immediately fill page in */ uint64_aligned_t buffer; /* Other OPs */ uint64_aligned_t gfn; /* IN: gfn of page being operated on */ }; -typedef struct xen_mem_event_op xen_mem_event_op_t; -DEFINE_XEN_GUEST_HANDLE(xen_mem_event_op_t); +typedef struct xen_mem_paging_op xen_mem_paging_op_t; +DEFINE_XEN_GUEST_HANDLE(xen_mem_paging_op_t); #define XENMEM_access_op 21 -#define XENMEM_access_op_resume 0 -#define XENMEM_access_op_set_access 1 -#define XENMEM_access_op_get_access 2 +#define XENMEM_access_op_set_access 0 +#define XENMEM_access_op_get_access 1 +/* + * XENMEM_access_op_enable_emulate and XENMEM_access_op_disable_emulate are + * currently unused, but since they have been in use please do not reuse them. + * + * #define XENMEM_access_op_enable_emulate 2 + * #define XENMEM_access_op_disable_emulate 3 + */ +#define XENMEM_access_op_set_access_multi 4 typedef enum { XENMEM_access_n, @@ -421,7 +447,8 @@ struct xen_mem_access_op { uint8_t access; domid_t domid; /* - * Number of pages for set op + * Number of pages for set op (or size of pfn_list for + * XENMEM_access_op_set_access_multi) * Ignored on setting default access and other ops */ uint32_t nr; @@ -431,6 +458,16 @@ struct xen_mem_access_op { * ~0ull is used to set and get the default access for pages */ uint64_aligned_t pfn; + /* + * List of pfns to set access for + * Used only with XENMEM_access_op_set_access_multi + */ + XEN_GUEST_HANDLE(const_uint64) pfn_list; + /* + * Corresponding list of access settings for pfn_list + * Used only with XENMEM_access_op_set_access_multi + */ + XEN_GUEST_HANDLE(const_uint8) access_list; }; typedef struct xen_mem_access_op xen_mem_access_op_t; DEFINE_XEN_GUEST_HANDLE(xen_mem_access_op_t); @@ -439,12 +476,12 @@ DEFINE_XEN_GUEST_HANDLE(xen_mem_access_op_t); #define XENMEM_sharing_op_nominate_gfn 0 #define XENMEM_sharing_op_nominate_gref 1 #define XENMEM_sharing_op_share 2 -#define XENMEM_sharing_op_resume 3 -#define XENMEM_sharing_op_debug_gfn 4 -#define XENMEM_sharing_op_debug_mfn 5 -#define XENMEM_sharing_op_debug_gref 6 -#define XENMEM_sharing_op_add_physmap 7 -#define XENMEM_sharing_op_audit 8 +#define XENMEM_sharing_op_debug_gfn 3 +#define XENMEM_sharing_op_debug_mfn 4 +#define XENMEM_sharing_op_debug_gref 5 +#define XENMEM_sharing_op_add_physmap 6 +#define XENMEM_sharing_op_audit 7 +#define XENMEM_sharing_op_range_share 8 #define XENMEM_SHARING_OP_S_HANDLE_INVALID (-10) #define XENMEM_SHARING_OP_C_HANDLE_INVALID (-9) @@ -453,7 +490,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_mem_access_op_t); * for sharing utilities sitting as "filters" in IO backends * (e.g. memshr + blktap(2)). The IO backend is only exposed * to grant references, and this allows sharing of the grefs */ -#define XENMEM_SHARING_OP_FIELD_IS_GREF_FLAG (1ULL << 62) +#define XENMEM_SHARING_OP_FIELD_IS_GREF_FLAG (xen_mk_ullong(1) << 62) #define XENMEM_SHARING_OP_FIELD_MAKE_GREF(field, val) \ (field) = (XENMEM_SHARING_OP_FIELD_IS_GREF_FLAG | val) @@ -480,7 +517,14 @@ struct xen_mem_sharing_op { uint64_aligned_t client_gfn; /* IN: the client gfn */ uint64_aligned_t client_handle; /* IN: handle to the client page */ domid_t client_domain; /* IN: the client domain id */ - } share; + } share; + struct mem_sharing_op_range { /* OP_RANGE_SHARE */ + uint64_aligned_t first_gfn; /* IN: the first gfn */ + uint64_aligned_t last_gfn; /* IN: the last gfn */ + uint64_aligned_t opaque; /* Must be set to 0 */ + domid_t client_domain; /* IN: the client domain id */ + uint16_t _pad[3]; /* Must be set to 0 */ + } range; struct mem_sharing_op_debug { /* OP_DEBUG_xxx */ union { uint64_aligned_t gfn; /* IN: gfn to debug */ @@ -518,9 +562,43 @@ DEFINE_XEN_GUEST_HANDLE(xen_mem_sharing_op_t); /* * XENMEM_claim_pages flags - the are no flags at this time. - * The zero value is appropiate. + * The zero value is appropriate. */ +/* + * With some legacy devices, certain guest-physical addresses cannot safely + * be used for other purposes, e.g. to map guest RAM. This hypercall + * enumerates those regions so the toolstack can avoid using them. + */ +#define XENMEM_reserved_device_memory_map 27 +struct xen_reserved_device_memory { + xen_pfn_t start_pfn; + xen_ulong_t nr_pages; +}; +typedef struct xen_reserved_device_memory xen_reserved_device_memory_t; +DEFINE_XEN_GUEST_HANDLE(xen_reserved_device_memory_t); + +struct xen_reserved_device_memory_map { +#define XENMEM_RDM_ALL 1 /* Request all regions (ignore dev union). */ + /* IN */ + uint32_t flags; + /* + * IN/OUT + * + * Gets set to the required number of entries when too low, + * signaled by error code -ERANGE. + */ + unsigned int nr_entries; + /* OUT */ + XEN_GUEST_HANDLE(xen_reserved_device_memory_t) buffer; + /* IN */ + union { + struct physdev_pci_device pci; + } dev; +}; +typedef struct xen_reserved_device_memory_map xen_reserved_device_memory_map_t; +DEFINE_XEN_GUEST_HANDLE(xen_reserved_device_memory_map_t); + #endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */ /* @@ -572,7 +650,7 @@ struct xen_vnuma_topology_info { typedef struct xen_vnuma_topology_info xen_vnuma_topology_info_t; DEFINE_XEN_GUEST_HANDLE(xen_vnuma_topology_info_t); -/* Next available subop number is 27 */ +/* Next available subop number is 28 */ #endif /* __XEN_PUBLIC_MEMORY_H__ */ diff --git a/include/xen/physdev.h b/include/xen/physdev.h index 2683719..0e54635 100644 --- a/include/xen/physdev.h +++ b/include/xen/physdev.h @@ -16,6 +16,8 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2006, Keir Fraser */ #ifndef __XEN_PUBLIC_PHYSDEV_H__ @@ -293,6 +295,11 @@ struct physdev_pci_device_add { uint8_t bus; uint8_t devfn; } physfn; + /* + * Optional parameters array. + * First element ([0]) is PXM domain associated with the device (if + * XEN_PCI_DEV_PXM is set) + */ #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L uint32_t optarr[]; #elif defined(__GNUC__) diff --git a/include/xen/platform.h b/include/xen/platform.h index 5c57615..94dbc3f 100644 --- a/include/xen/platform.h +++ b/include/xen/platform.h @@ -35,13 +35,28 @@ * Set clock such that it would read <secs,nsecs> after 00:00:00 UTC, * 1 January, 1970 if the current system time was <system_time>. */ -#define XENPF_settime 17 -struct xenpf_settime { +#define XENPF_settime32 17 +struct xenpf_settime32 { /* IN variables. */ uint32_t secs; uint32_t nsecs; uint64_t system_time; }; +#define XENPF_settime64 62 +struct xenpf_settime64 { + /* IN variables. */ + uint64_t secs; + uint32_t nsecs; + uint32_t mbz; + uint64_t system_time; +}; +#if __XEN_INTERFACE_VERSION__ < 0x00040600 +#define XENPF_settime XENPF_settime32 +#define xenpf_settime xenpf_settime32 +#else +#define XENPF_settime XENPF_settime64 +#define xenpf_settime xenpf_settime64 +#endif typedef struct xenpf_settime xenpf_settime_t; DEFINE_XEN_GUEST_HANDLE(xenpf_settime_t); @@ -126,6 +141,26 @@ DEFINE_XEN_GUEST_HANDLE(xenpf_platform_quirk_t); #define XEN_EFI_query_variable_info 9 #define XEN_EFI_query_capsule_capabilities 10 #define XEN_EFI_update_capsule 11 + +struct xenpf_efi_time { + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t hour; + uint8_t min; + uint8_t sec; + uint32_t ns; + int16_t tz; + uint8_t daylight; +}; + +struct xenpf_efi_guid { + uint32_t data1; + uint16_t data2; + uint16_t data3; + uint8_t data4[8]; +}; + struct xenpf_efi_runtime_call { uint32_t function; /* @@ -138,17 +173,7 @@ struct xenpf_efi_runtime_call { union { #define XEN_EFI_GET_TIME_SET_CLEARS_NS 0x00000001 struct { - struct xenpf_efi_time { - uint16_t year; - uint8_t month; - uint8_t day; - uint8_t hour; - uint8_t min; - uint8_t sec; - uint32_t ns; - int16_t tz; - uint8_t daylight; - } time; + struct xenpf_efi_time time; uint32_t resolution; uint32_t accuracy; } get_time; @@ -170,12 +195,7 @@ struct xenpf_efi_runtime_call { XEN_GUEST_HANDLE(void) name; /* UCS-2/UTF-16 string */ xen_ulong_t size; XEN_GUEST_HANDLE(void) data; - struct xenpf_efi_guid { - uint32_t data1; - uint16_t data2; - uint16_t data3; - uint8_t data4[8]; - } vendor_guid; + struct xenpf_efi_guid vendor_guid; } get_variable, set_variable; struct { @@ -220,6 +240,7 @@ DEFINE_XEN_GUEST_HANDLE(xenpf_efi_runtime_call_t); #define XEN_FW_EFI_MEM_INFO 3 #define XEN_FW_EFI_RT_VERSION 4 #define XEN_FW_EFI_PCI_ROM 5 +#define XEN_FW_EFI_APPLE_PROPERTIES 6 #define XEN_FW_KBD_SHIFT_FLAGS 5 struct xenpf_firmware_info { /* IN variables. */ @@ -279,6 +300,11 @@ struct xenpf_firmware_info { uint64_t address; xen_ulong_t size; } pci_rom; + struct { + /* OUT variables */ + uint64_t address; + xen_ulong_t size; + } apple_properties; } efi_info; /* XEN_FW_EFI_INFO */ /* Int16, Fn02: Get keyboard shift flags. */ @@ -540,6 +566,16 @@ DEFINE_XEN_GUEST_HANDLE(xenpf_core_parking_t); #define XEN_RESOURCE_OP_MSR_READ 0 #define XEN_RESOURCE_OP_MSR_WRITE 1 +/* + * Specially handled MSRs: + * - MSR_IA32_TSC + * READ: Returns the scaled system time(ns) instead of raw timestamp. In + * multiple entry case, if other MSR read is followed by a MSR_IA32_TSC + * read, then both reads are guaranteed to be performed atomically (with + * IRQ disabled). The return time indicates the point of reading that MSR. + * WRITE: Not supported. + */ + struct xenpf_resource_entry { union { uint32_t cmd; /* IN: XEN_RESOURCE_OP_* */ @@ -560,6 +596,24 @@ struct xenpf_resource_op { typedef struct xenpf_resource_op xenpf_resource_op_t; DEFINE_XEN_GUEST_HANDLE(xenpf_resource_op_t); +#define XENPF_get_symbol 63 +struct xenpf_symdata { + /* IN/OUT variables */ + uint32_t namelen; /* IN: size of name buffer */ + /* OUT: strlen(name) of hypervisor symbol (may be */ + /* larger than what's been copied to guest) */ + uint32_t symnum; /* IN: Symbol to read */ + /* OUT: Next available symbol. If same as IN then */ + /* we reached the end */ + + /* OUT variables */ + XEN_GUEST_HANDLE(char) name; + uint64_t address; + char type; +}; +typedef struct xenpf_symdata xenpf_symdata_t; +DEFINE_XEN_GUEST_HANDLE(xenpf_symdata_t); + /* * ` enum neg_errnoval * ` HYPERVISOR_platform_op(const struct xen_platform_op*); @@ -569,6 +623,8 @@ struct xen_platform_op { uint32_t interface_version; /* XENPF_INTERFACE_VERSION */ union { struct xenpf_settime settime; + struct xenpf_settime32 settime32; + struct xenpf_settime64 settime64; struct xenpf_add_memtype add_memtype; struct xenpf_del_memtype del_memtype; struct xenpf_read_memtype read_memtype; @@ -587,6 +643,7 @@ struct xen_platform_op { struct xenpf_mem_hotadd mem_add; struct xenpf_core_parking core_parking; struct xenpf_resource_op resource_op; + struct xenpf_symdata symdata; uint8_t pad[128]; } u; }; diff --git a/include/xen/pmu.h b/include/xen/pmu.h new file mode 100644 index 0000000..0e1312c --- /dev/null +++ b/include/xen/pmu.h @@ -0,0 +1,143 @@ +/* + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. + */ + +#ifndef __XEN_PUBLIC_PMU_H__ +#define __XEN_PUBLIC_PMU_H__ + +#include "xen.h" +#if defined(__i386__) || defined(__x86_64__) +#include "arch-x86/pmu.h" +#elif defined (__arm__) || defined (__aarch64__) +#include "arch-arm.h" +#else +#error "Unsupported architecture" +#endif + +#define XENPMU_VER_MAJ 0 +#define XENPMU_VER_MIN 1 + +/* + * ` enum neg_errnoval + * ` HYPERVISOR_xenpmu_op(enum xenpmu_op cmd, struct xenpmu_params *args); + * + * @cmd == XENPMU_* (PMU operation) + * @args == struct xenpmu_params + */ +/* ` enum xenpmu_op { */ +#define XENPMU_mode_get 0 /* Also used for getting PMU version */ +#define XENPMU_mode_set 1 +#define XENPMU_feature_get 2 +#define XENPMU_feature_set 3 +#define XENPMU_init 4 +#define XENPMU_finish 5 +#define XENPMU_lvtpc_set 6 +#define XENPMU_flush 7 /* Write cached MSR values to HW */ +/* ` } */ + +/* Parameters structure for HYPERVISOR_xenpmu_op call */ +struct xen_pmu_params { + /* IN/OUT parameters */ + struct { + uint32_t maj; + uint32_t min; + } version; + uint64_t val; + + /* IN parameters */ + uint32_t vcpu; + uint32_t pad; +}; +typedef struct xen_pmu_params xen_pmu_params_t; +DEFINE_XEN_GUEST_HANDLE(xen_pmu_params_t); + +/* PMU modes: + * - XENPMU_MODE_OFF: No PMU virtualization + * - XENPMU_MODE_SELF: Guests can profile themselves + * - XENPMU_MODE_HV: Guests can profile themselves, dom0 profiles + * itself and Xen + * - XENPMU_MODE_ALL: Only dom0 has access to VPMU and it profiles + * everyone: itself, the hypervisor and the guests. + */ +#define XENPMU_MODE_OFF 0 +#define XENPMU_MODE_SELF (1<<0) +#define XENPMU_MODE_HV (1<<1) +#define XENPMU_MODE_ALL (1<<2) + +/* + * PMU features: + * - XENPMU_FEATURE_INTEL_BTS: Intel BTS support (ignored on AMD) + * - XENPMU_FEATURE_IPC_ONLY: Restrict PMCs to the most minimum set possible. + * Instructions, cycles, and ref cycles. Can be + * used to calculate instructions-per-cycle (IPC) + * (ignored on AMD). + * - XENPMU_FEATURE_ARCH_ONLY: Restrict PMCs to the Intel Pre-Defined + * Architectural Performance Events exposed by + * cpuid and listed in the Intel developer's manual + * (ignored on AMD). + */ +#define XENPMU_FEATURE_INTEL_BTS (1<<0) +#define XENPMU_FEATURE_IPC_ONLY (1<<1) +#define XENPMU_FEATURE_ARCH_ONLY (1<<2) + +/* + * Shared PMU data between hypervisor and PV(H) domains. + * + * The hypervisor fills out this structure during PMU interrupt and sends an + * interrupt to appropriate VCPU. + * Architecture-independent fields of xen_pmu_data are WO for the hypervisor + * and RO for the guest but some fields in xen_pmu_arch can be writable + * by both the hypervisor and the guest (see arch-$arch/pmu.h). + */ +struct xen_pmu_data { + /* Interrupted VCPU */ + uint32_t vcpu_id; + + /* + * Physical processor on which the interrupt occurred. On non-privileged + * guests set to vcpu_id; + */ + uint32_t pcpu_id; + + /* + * Domain that was interrupted. On non-privileged guests set to DOMID_SELF. + * On privileged guests can be DOMID_SELF, DOMID_XEN, or, when in + * XENPMU_MODE_ALL mode, domain ID of another domain. + */ + domid_t domain_id; + + uint8_t pad[6]; + + /* Architecture-specific information */ + struct xen_pmu_arch pmu; +}; + +#endif /* __XEN_PUBLIC_PMU_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/xen/sched.h b/include/xen/sched.h index 4000ac9..811bd87 100644 --- a/include/xen/sched.h +++ b/include/xen/sched.h @@ -118,6 +118,18 @@ * With id != 0 and timeout != 0, poke watchdog timer and set new timeout. */ #define SCHEDOP_watchdog 6 + +/* + * Override the current vcpu affinity by pinning it to one physical cpu or + * undo this override restoring the previous affinity. + * @arg == pointer to sched_pin_override_t structure. + * + * A negative pcpu value will undo a previous pin override and restore the + * previous cpu affinity. + * This call is allowed for the hardware domain only and requires the cpu + * to be part of the domain's cpupool. + */ +#define SCHEDOP_pin_override 7 /* ` } */ struct sched_shutdown { @@ -148,6 +160,12 @@ struct sched_watchdog { typedef struct sched_watchdog sched_watchdog_t; DEFINE_XEN_GUEST_HANDLE(sched_watchdog_t); +struct sched_pin_override { + int32_t pcpu; +}; +typedef struct sched_pin_override sched_pin_override_t; +DEFINE_XEN_GUEST_HANDLE(sched_pin_override_t); + /* * Reason codes for SCHEDOP_shutdown. These may be interpreted by control * software to determine the appropriate action. For the most part, Xen does @@ -159,7 +177,16 @@ DEFINE_XEN_GUEST_HANDLE(sched_watchdog_t); #define SHUTDOWN_suspend 2 /* Clean up, save suspend info, kill. */ #define SHUTDOWN_crash 3 /* Tell controller we've crashed. */ #define SHUTDOWN_watchdog 4 /* Restart because watchdog time expired. */ -#define SHUTDOWN_MAX 4 /* Maximum valid shutdown reason. */ + +/* + * Domain asked to perform 'soft reset' for it. The expected behavior is to + * reset internal Xen state for the domain returning it to the point where it + * was created but leaving the domain's memory contents and vCPU contexts + * intact. This will allow the domain to start over and set up all Xen specific + * interfaces again. + */ +#define SHUTDOWN_soft_reset 5 +#define SHUTDOWN_MAX 5 /* Maximum valid shutdown reason. */ /* ` } */ #endif /* __XEN_PUBLIC_SCHED_H__ */ diff --git a/include/xen/sysctl.h b/include/xen/sysctl.h index 8552dc6..6140f1a 100644 --- a/include/xen/sysctl.h +++ b/include/xen/sysctl.h @@ -33,8 +33,10 @@ #include "xen.h" #include "domctl.h" +#include "physdev.h" +#include "tmem.h" -#define XEN_SYSCTL_INTERFACE_VERSION 0x0000000B +#define XEN_SYSCTL_INTERFACE_VERSION 0x00000010 /* * Read console content from Xen buffer ring. @@ -56,8 +58,6 @@ struct xen_sysctl_readconsole { /* IN: Size of buffer; OUT: Bytes written to buffer. */ uint32_t count; }; -typedef struct xen_sysctl_readconsole xen_sysctl_readconsole_t; -DEFINE_XEN_GUEST_HANDLE(xen_sysctl_readconsole_t); /* Get trace buffers machine base address */ /* XEN_SYSCTL_tbuf_op */ @@ -77,8 +77,6 @@ struct xen_sysctl_tbuf_op { uint64_aligned_t buffer_mfn; uint32_t size; /* Also an IN variable! */ }; -typedef struct xen_sysctl_tbuf_op xen_sysctl_tbuf_op_t; -DEFINE_XEN_GUEST_HANDLE(xen_sysctl_tbuf_op_t); /* * Get physical information about the host machine @@ -98,17 +96,14 @@ struct xen_sysctl_physinfo { uint32_t nr_nodes; /* # nodes currently online */ uint32_t max_node_id; /* Largest possible node ID on this host */ uint32_t cpu_khz; + uint32_t capabilities;/* XEN_SYSCTL_PHYSCAP_??? */ uint64_aligned_t total_pages; uint64_aligned_t free_pages; uint64_aligned_t scrub_pages; uint64_aligned_t outstanding_pages; + uint64_aligned_t max_mfn; /* Largest possible MFN on this host */ uint32_t hw_cap[8]; - - /* XEN_SYSCTL_PHYSCAP_??? */ - uint32_t capabilities; }; -typedef struct xen_sysctl_physinfo xen_sysctl_physinfo_t; -DEFINE_XEN_GUEST_HANDLE(xen_sysctl_physinfo_t); /* * Get the ID of the current scheduler. @@ -118,8 +113,6 @@ struct xen_sysctl_sched_id { /* OUT variable */ uint32_t sched_id; }; -typedef struct xen_sysctl_sched_id xen_sysctl_sched_id_t; -DEFINE_XEN_GUEST_HANDLE(xen_sysctl_sched_id_t); /* Interface for controlling Xen software performance counters. */ /* XEN_SYSCTL_perfc_op */ @@ -146,8 +139,6 @@ struct xen_sysctl_perfc_op { /* counter values (or NULL) */ XEN_GUEST_HANDLE_64(xen_sysctl_perfc_val_t) val; }; -typedef struct xen_sysctl_perfc_op xen_sysctl_perfc_op_t; -DEFINE_XEN_GUEST_HANDLE(xen_sysctl_perfc_op_t); /* XEN_SYSCTL_getdomaininfolist */ struct xen_sysctl_getdomaininfolist { @@ -158,8 +149,6 @@ struct xen_sysctl_getdomaininfolist { /* OUT variables. */ uint32_t num_domains; }; -typedef struct xen_sysctl_getdomaininfolist xen_sysctl_getdomaininfolist_t; -DEFINE_XEN_GUEST_HANDLE(xen_sysctl_getdomaininfolist_t); /* Inject debug keys into Xen. */ /* XEN_SYSCTL_debug_keys */ @@ -168,8 +157,6 @@ struct xen_sysctl_debug_keys { XEN_GUEST_HANDLE_64(char) keys; uint32_t nr_keys; }; -typedef struct xen_sysctl_debug_keys xen_sysctl_debug_keys_t; -DEFINE_XEN_GUEST_HANDLE(xen_sysctl_debug_keys_t); /* Get physical CPU information. */ /* XEN_SYSCTL_getcpuinfo */ @@ -185,8 +172,6 @@ struct xen_sysctl_getcpuinfo { /* OUT variables. */ uint32_t nr_cpus; }; -typedef struct xen_sysctl_getcpuinfo xen_sysctl_getcpuinfo_t; -DEFINE_XEN_GUEST_HANDLE(xen_sysctl_getcpuinfo_t); /* XEN_SYSCTL_availheap */ struct xen_sysctl_availheap { @@ -197,8 +182,6 @@ struct xen_sysctl_availheap { /* OUT variables. */ uint64_aligned_t avail_bytes;/* Bytes available in the specified region. */ }; -typedef struct xen_sysctl_availheap xen_sysctl_availheap_t; -DEFINE_XEN_GUEST_HANDLE(xen_sysctl_availheap_t); /* XEN_SYSCTL_get_pmstat */ struct pm_px_val { @@ -217,8 +200,6 @@ struct pm_px_stat { XEN_GUEST_HANDLE_64(uint64) trans_pt; /* Px transition table */ XEN_GUEST_HANDLE_64(pm_px_val_t) pt; }; -typedef struct pm_px_stat pm_px_stat_t; -DEFINE_XEN_GUEST_HANDLE(pm_px_stat_t); struct pm_cx_stat { uint32_t nr; /* entry nr in triggers & residencies, including C0 */ @@ -257,8 +238,6 @@ struct xen_sysctl_get_pmstat { /* other struct for tx, etc */ } u; }; -typedef struct xen_sysctl_get_pmstat xen_sysctl_get_pmstat_t; -DEFINE_XEN_GUEST_HANDLE(xen_sysctl_get_pmstat_t); /* XEN_SYSCTL_cpu_hotplug */ struct xen_sysctl_cpu_hotplug { @@ -268,8 +247,6 @@ struct xen_sysctl_cpu_hotplug { #define XEN_SYSCTL_CPU_HOTPLUG_OFFLINE 1 uint32_t op; /* hotplug opcode */ }; -typedef struct xen_sysctl_cpu_hotplug xen_sysctl_cpu_hotplug_t; -DEFINE_XEN_GUEST_HANDLE(xen_sysctl_cpu_hotplug_t); /* * Get/set xen power management, include @@ -279,7 +256,6 @@ DEFINE_XEN_GUEST_HANDLE(xen_sysctl_cpu_hotplug_t); struct xen_userspace { uint32_t scaling_setspeed; }; -typedef struct xen_userspace xen_userspace_t; struct xen_ondemand { uint32_t sampling_rate_max; @@ -288,7 +264,6 @@ struct xen_ondemand { uint32_t sampling_rate; uint32_t up_threshold; }; -typedef struct xen_ondemand xen_ondemand_t; /* * cpufreq para name of this structure named @@ -459,67 +434,76 @@ struct xen_sysctl_lockprof_op { /* profile information (or NULL) */ XEN_GUEST_HANDLE_64(xen_sysctl_lockprof_data_t) data; }; -typedef struct xen_sysctl_lockprof_op xen_sysctl_lockprof_op_t; -DEFINE_XEN_GUEST_HANDLE(xen_sysctl_lockprof_op_t); -/* XEN_SYSCTL_topologyinfo */ -#define INVALID_TOPOLOGY_ID (~0U) -struct xen_sysctl_topologyinfo { - /* - * IN: maximum addressable entry in the caller-provided arrays. - * OUT: largest cpu identifier in the system. - * If OUT is greater than IN then the arrays are truncated! - * If OUT is leass than IN then the array tails are not written by sysctl. - */ - uint32_t max_cpu_index; +/* XEN_SYSCTL_cputopoinfo */ +#define XEN_INVALID_CORE_ID (~0U) +#define XEN_INVALID_SOCKET_ID (~0U) +#define XEN_INVALID_NODE_ID (~0U) - /* - * If not NULL, these arrays are filled with core/socket/node identifier - * for each cpu. - * If a cpu has no core/socket/node information (e.g., cpu not present) - * then the sentinel value ~0u is written to each array. - * The number of array elements written by the sysctl is: - * min(@max_cpu_index_IN,@max_cpu_index_OUT)+1 - */ - XEN_GUEST_HANDLE_64(uint32) cpu_to_core; - XEN_GUEST_HANDLE_64(uint32) cpu_to_socket; - XEN_GUEST_HANDLE_64(uint32) cpu_to_node; +struct xen_sysctl_cputopo { + uint32_t core; + uint32_t socket; + uint32_t node; +}; +typedef struct xen_sysctl_cputopo xen_sysctl_cputopo_t; +DEFINE_XEN_GUEST_HANDLE(xen_sysctl_cputopo_t); + +/* + * IN: + * - a NULL 'cputopo' handle is a request for maximun 'num_cpus'. + * - otherwise it's the number of entries in 'cputopo' + * + * OUT: + * - If 'num_cpus' is less than the number Xen wants to write but the handle + * handle is not a NULL one, partial data gets returned and 'num_cpus' gets + * updated to reflect the intended number. + * - Otherwise, 'num_cpus' shall indicate the number of entries written, which + * may be less than the input value. + */ +struct xen_sysctl_cputopoinfo { + uint32_t num_cpus; + XEN_GUEST_HANDLE_64(xen_sysctl_cputopo_t) cputopo; }; -typedef struct xen_sysctl_topologyinfo xen_sysctl_topologyinfo_t; -DEFINE_XEN_GUEST_HANDLE(xen_sysctl_topologyinfo_t); /* XEN_SYSCTL_numainfo */ -#define INVALID_NUMAINFO_ID (~0U) +#define XEN_INVALID_MEM_SZ (~0U) +#define XEN_INVALID_NODE_DIST (~0U) + +struct xen_sysctl_meminfo { + uint64_t memsize; + uint64_t memfree; +}; +typedef struct xen_sysctl_meminfo xen_sysctl_meminfo_t; +DEFINE_XEN_GUEST_HANDLE(xen_sysctl_meminfo_t); + +/* + * IN: + * - Both 'meminfo' and 'distance' handles being null is a request + * for maximum value of 'num_nodes'. + * - Otherwise it's the number of entries in 'meminfo' and square root + * of number of entries in 'distance' (when corresponding handle is + * non-null) + * + * OUT: + * - If 'num_nodes' is less than the number Xen wants to write but either + * handle is not a NULL one, partial data gets returned and 'num_nodes' + * gets updated to reflect the intended number. + * - Otherwise, 'num_nodes' shall indicate the number of entries written, which + * may be less than the input value. + */ + struct xen_sysctl_numainfo { - /* - * IN: maximum addressable entry in the caller-provided arrays. - * OUT: largest node identifier in the system. - * If OUT is greater than IN then the arrays are truncated! - */ - uint32_t max_node_index; + uint32_t num_nodes; - /* NB. Entries are 0 if node is not present. */ - XEN_GUEST_HANDLE_64(uint64) node_to_memsize; - XEN_GUEST_HANDLE_64(uint64) node_to_memfree; + XEN_GUEST_HANDLE_64(xen_sysctl_meminfo_t) meminfo; /* - * Array, of size (max_node_index+1)^2, listing memory access distances - * between nodes. If an entry has no node distance information (e.g., node - * not present) then the value ~0u is written. - * - * Note that the array rows must be indexed by multiplying by the minimum - * of the caller-provided max_node_index and the returned value of - * max_node_index. That is, if the largest node index in the system is - * smaller than the caller can handle, a smaller 2-d array is constructed - * within the space provided by the caller. When this occurs, trailing - * space provided by the caller is not modified. If the largest node index - * in the system is larger than the caller can handle, then a 2-d array of - * the maximum size handleable by the caller is constructed. + * Distance between nodes 'i' and 'j' is stored in index 'i*N + j', + * where N is the number of nodes that will be returned in 'num_nodes' + * (i.e. not 'num_nodes' provided by the caller) */ - XEN_GUEST_HANDLE_64(uint32) node_to_node_distance; + XEN_GUEST_HANDLE_64(uint32) distance; }; -typedef struct xen_sysctl_numainfo xen_sysctl_numainfo_t; -DEFINE_XEN_GUEST_HANDLE(xen_sysctl_numainfo_t); /* XEN_SYSCTL_cpupool_op */ #define XEN_SYSCTL_CPUPOOL_OP_CREATE 1 /* C */ @@ -539,8 +523,42 @@ struct xen_sysctl_cpupool_op { uint32_t n_dom; /* OUT: I */ struct xenctl_bitmap cpumap; /* OUT: IF */ }; -typedef struct xen_sysctl_cpupool_op xen_sysctl_cpupool_op_t; -DEFINE_XEN_GUEST_HANDLE(xen_sysctl_cpupool_op_t); + +/* + * Error return values of cpupool operations: + * + * -EADDRINUSE: + * XEN_SYSCTL_CPUPOOL_OP_RMCPU: A vcpu is temporarily pinned to the cpu + * which is to be removed from a cpupool. + * -EADDRNOTAVAIL: + * XEN_SYSCTL_CPUPOOL_OP_ADDCPU, XEN_SYSCTL_CPUPOOL_OP_RMCPU: A previous + * request to remove a cpu from a cpupool was terminated with -EAGAIN + * and has not been retried using the same parameters. + * -EAGAIN: + * XEN_SYSCTL_CPUPOOL_OP_RMCPU: The cpu can't be removed from the cpupool + * as it is active in the hypervisor. A retry will succeed soon. + * -EBUSY: + * XEN_SYSCTL_CPUPOOL_OP_DESTROY, XEN_SYSCTL_CPUPOOL_OP_RMCPU: A cpupool + * can't be destroyed or the last cpu can't be removed as there is still + * a running domain in that cpupool. + * -EEXIST: + * XEN_SYSCTL_CPUPOOL_OP_CREATE: A cpupool_id was specified and is already + * existing. + * -EINVAL: + * XEN_SYSCTL_CPUPOOL_OP_ADDCPU, XEN_SYSCTL_CPUPOOL_OP_RMCPU: An illegal + * cpu was specified (cpu does not exist). + * XEN_SYSCTL_CPUPOOL_OP_MOVEDOMAIN: An illegal domain was specified + * (domain id illegal or not suitable for operation). + * -ENODEV: + * XEN_SYSCTL_CPUPOOL_OP_ADDCPU, XEN_SYSCTL_CPUPOOL_OP_RMCPU: The specified + * cpu is either not free (add) or not member of the specified cpupool + * (remove). + * -ENOENT: + * all: The cpupool with the specified cpupool_id doesn't exist. + * + * Some common error return values like -ENOMEM and -EFAULT are possible for + * all the operations. + */ #define ARINC653_MAX_DOMAINS_PER_SCHEDULE 64 /* @@ -570,18 +588,24 @@ struct xen_sysctl_arinc653_schedule { typedef struct xen_sysctl_arinc653_schedule xen_sysctl_arinc653_schedule_t; DEFINE_XEN_GUEST_HANDLE(xen_sysctl_arinc653_schedule_t); +/* + * Valid range for context switch rate limit (in microseconds). + * Applicable to Credit and Credit2 schedulers. + */ +#define XEN_SYSCTL_SCHED_RATELIMIT_MAX 500000 +#define XEN_SYSCTL_SCHED_RATELIMIT_MIN 100 + struct xen_sysctl_credit_schedule { /* Length of timeslice in milliseconds */ #define XEN_SYSCTL_CSCHED_TSLICE_MAX 1000 #define XEN_SYSCTL_CSCHED_TSLICE_MIN 1 unsigned tslice_ms; - /* Rate limit (minimum timeslice) in microseconds */ -#define XEN_SYSCTL_SCHED_RATELIMIT_MAX 500000 -#define XEN_SYSCTL_SCHED_RATELIMIT_MIN 100 unsigned ratelimit_us; }; -typedef struct xen_sysctl_credit_schedule xen_sysctl_credit_schedule_t; -DEFINE_XEN_GUEST_HANDLE(xen_sysctl_credit_schedule_t); + +struct xen_sysctl_credit2_schedule { + unsigned ratelimit_us; +}; /* XEN_SYSCTL_scheduler_op */ /* Set or get info? */ @@ -596,45 +620,41 @@ struct xen_sysctl_scheduler_op { XEN_GUEST_HANDLE_64(xen_sysctl_arinc653_schedule_t) schedule; } sched_arinc653; struct xen_sysctl_credit_schedule sched_credit; + struct xen_sysctl_credit2_schedule sched_credit2; } u; }; -typedef struct xen_sysctl_scheduler_op xen_sysctl_scheduler_op_t; -DEFINE_XEN_GUEST_HANDLE(xen_sysctl_scheduler_op_t); - -/* XEN_SYSCTL_coverage_op */ -/* - * Get total size of information, to help allocate - * the buffer. The pointer points to a 32 bit value. - */ -#define XEN_SYSCTL_COVERAGE_get_total_size 0 /* - * Read coverage information in a single run - * You must use a tool to split them. + * Output format of gcov data: + * + * XEN_GCOV_FORMAT_MAGIC XEN_GCOV_RECORD ... XEN_GCOV_RECORD + * + * That is, one magic number followed by 0 or more record. + * + * The magic number is stored as an uint32_t field. + * + * The record is packed and variable in length. It has the form: + * + * filename: a NULL terminated path name extracted from gcov, used to + * create the name of gcda file. + * size: a uint32_t field indicating the size of the payload, the + * unit is byte. + * payload: the actual payload, length is `size' bytes. + * + * Userspace tool will split the record to different files. */ -#define XEN_SYSCTL_COVERAGE_read 1 -/* - * Reset all the coverage counters to 0 - * No parameters. - */ -#define XEN_SYSCTL_COVERAGE_reset 2 +#define XEN_GCOV_FORMAT_MAGIC 0x58434f56 /* XCOV */ -/* - * Like XEN_SYSCTL_COVERAGE_read but reset also - * counters to 0 in a single call. - */ -#define XEN_SYSCTL_COVERAGE_read_and_reset 3 +#define XEN_SYSCTL_GCOV_get_size 0 /* Get total size of output data */ +#define XEN_SYSCTL_GCOV_read 1 /* Read output data */ +#define XEN_SYSCTL_GCOV_reset 2 /* Reset all counters */ -struct xen_sysctl_coverage_op { - uint32_t cmd; /* XEN_SYSCTL_COVERAGE_* */ - union { - uint32_t total_size; /* OUT */ - XEN_GUEST_HANDLE_64(uint8) raw_info; /* OUT */ - } u; +struct xen_sysctl_gcov_op { + uint32_t cmd; + uint32_t size; /* IN/OUT: size of the buffer */ + XEN_GUEST_HANDLE_64(char) buffer; /* OUT */ }; -typedef struct xen_sysctl_coverage_op xen_sysctl_coverage_op_t; -DEFINE_XEN_GUEST_HANDLE(xen_sysctl_coverage_op_t); #define XEN_SYSCTL_PSR_CMT_get_total_rmid 0 #define XEN_SYSCTL_PSR_CMT_get_l3_upscaling_factor 1 @@ -653,8 +673,377 @@ struct xen_sysctl_psr_cmt_op { } l3_cache; } u; }; -typedef struct xen_sysctl_psr_cmt_op xen_sysctl_psr_cmt_op_t; -DEFINE_XEN_GUEST_HANDLE(xen_sysctl_psr_cmt_op_t); + +/* XEN_SYSCTL_pcitopoinfo */ +#define XEN_INVALID_DEV (XEN_INVALID_NODE_ID - 1) +struct xen_sysctl_pcitopoinfo { + /* + * IN: Number of elements in 'pcitopo' and 'nodes' arrays. + * OUT: Number of processed elements of those arrays. + */ + uint32_t num_devs; + + /* IN: list of devices for which node IDs are requested. */ + XEN_GUEST_HANDLE_64(physdev_pci_device_t) devs; + + /* + * OUT: node identifier for each device. + * If information for a particular device is not available then + * corresponding entry will be set to XEN_INVALID_NODE_ID. If + * device is not known to the hypervisor then XEN_INVALID_DEV + * will be provided. + */ + XEN_GUEST_HANDLE_64(uint32) nodes; +}; + +#define XEN_SYSCTL_PSR_CAT_get_l3_info 0 +#define XEN_SYSCTL_PSR_CAT_get_l2_info 1 +struct xen_sysctl_psr_cat_op { + uint32_t cmd; /* IN: XEN_SYSCTL_PSR_CAT_* */ + uint32_t target; /* IN */ + union { + struct { + uint32_t cbm_len; /* OUT: CBM length */ + uint32_t cos_max; /* OUT: Maximum COS */ +#define XEN_SYSCTL_PSR_CAT_L3_CDP (1u << 0) + uint32_t flags; /* OUT: CAT flags */ + } cat_info; + } u; +}; + +#define XEN_SYSCTL_TMEM_OP_ALL_CLIENTS 0xFFFFU + +#define XEN_SYSCTL_TMEM_OP_THAW 0 +#define XEN_SYSCTL_TMEM_OP_FREEZE 1 +#define XEN_SYSCTL_TMEM_OP_FLUSH 2 +#define XEN_SYSCTL_TMEM_OP_DESTROY 3 +#define XEN_SYSCTL_TMEM_OP_LIST 4 +#define XEN_SYSCTL_TMEM_OP_GET_CLIENT_INFO 5 +#define XEN_SYSCTL_TMEM_OP_SET_CLIENT_INFO 6 +#define XEN_SYSCTL_TMEM_OP_GET_POOLS 7 +#define XEN_SYSCTL_TMEM_OP_QUERY_FREEABLE_MB 8 +#define XEN_SYSCTL_TMEM_OP_SET_POOLS 9 +#define XEN_SYSCTL_TMEM_OP_SAVE_BEGIN 10 +#define XEN_SYSCTL_TMEM_OP_SET_AUTH 11 +#define XEN_SYSCTL_TMEM_OP_SAVE_GET_NEXT_PAGE 19 +#define XEN_SYSCTL_TMEM_OP_SAVE_GET_NEXT_INV 20 +#define XEN_SYSCTL_TMEM_OP_SAVE_END 21 +#define XEN_SYSCTL_TMEM_OP_RESTORE_BEGIN 30 +#define XEN_SYSCTL_TMEM_OP_RESTORE_PUT_PAGE 32 +#define XEN_SYSCTL_TMEM_OP_RESTORE_FLUSH_PAGE 33 + +/* + * XEN_SYSCTL_TMEM_OP_SAVE_GET_NEXT_[PAGE|INV] override the 'buf' in + * xen_sysctl_tmem_op with this structure - sometimes with an extra + * page tackled on. + */ +struct tmem_handle { + uint32_t pool_id; + uint32_t index; + xen_tmem_oid_t oid; +}; + +/* + * XEN_SYSCTL_TMEM_OP_[GET,SAVE]_CLIENT uses the 'client' in + * xen_tmem_op with this structure, which is mostly used during migration. + */ +struct xen_tmem_client { + uint32_t version; /* If mismatched we will get XEN_EOPNOTSUPP. */ + uint32_t maxpools; /* If greater than what hypervisor supports, will get + XEN_ERANGE. */ + uint32_t nr_pools; /* Current amount of pools. Ignored on SET*/ + union { /* See TMEM_CLIENT_[COMPRESS,FROZEN] */ + uint32_t raw; + struct { + uint8_t frozen:1, + compress:1, + migrating:1; + } u; + } flags; + uint32_t weight; +}; +typedef struct xen_tmem_client xen_tmem_client_t; +DEFINE_XEN_GUEST_HANDLE(xen_tmem_client_t); + +/* + * XEN_SYSCTL_TMEM_OP_[GET|SET]_POOLS or XEN_SYSCTL_TMEM_OP_SET_AUTH + * uses the 'pool' array in * xen_sysctl_tmem_op with this structure. + * The XEN_SYSCTL_TMEM_OP_GET_POOLS hypercall will + * return the number of entries in 'pool' or a negative value + * if an error was encountered. + * The XEN_SYSCTL_TMEM_OP_SET_[AUTH|POOLS] will return the number of + * entries in 'pool' processed or a negative value if an error + * was encountered. + */ +struct xen_tmem_pool_info { + union { + uint32_t raw; + struct { + uint32_t persist:1, /* See TMEM_POOL_PERSIST. */ + shared:1, /* See TMEM_POOL_SHARED. */ + auth:1, /* See TMEM_POOL_AUTH. */ + rsv1:1, + pagebits:8, /* TMEM_POOL_PAGESIZE_[SHIFT,MASK]. */ + rsv2:12, + version:8; /* TMEM_POOL_VERSION_[SHIFT,MASK]. */ + } u; + } flags; + uint32_t id; /* Less than tmem_client.maxpools. */ + uint64_t n_pages; /* Zero on XEN_SYSCTL_TMEM_OP_SET_[AUTH|POOLS]. */ + uint64_aligned_t uuid[2]; +}; +typedef struct xen_tmem_pool_info xen_tmem_pool_info_t; +DEFINE_XEN_GUEST_HANDLE(xen_tmem_pool_info_t); + +struct xen_sysctl_tmem_op { + uint32_t cmd; /* IN: XEN_SYSCTL_TMEM_OP_* . */ + int32_t pool_id; /* IN: 0 by default unless _SAVE_*, RESTORE_* .*/ + uint32_t cli_id; /* IN: client id, 0 for XEN_SYSCTL_TMEM_QUERY_FREEABLE_MB + for all others can be the domain id or + XEN_SYSCTL_TMEM_OP_ALL_CLIENTS for all. */ + uint32_t len; /* IN: length of 'buf'. If not applicable to use 0. */ + uint32_t arg; /* IN: If not applicable to command use 0. */ + uint32_t pad; /* Padding so structure is the same under 32 and 64. */ + xen_tmem_oid_t oid; /* IN: If not applicable to command use 0s. */ + union { + XEN_GUEST_HANDLE_64(char) buf; /* IN/OUT: Buffer to save/restore */ + XEN_GUEST_HANDLE_64(xen_tmem_client_t) client; /* IN/OUT for */ + /* XEN_SYSCTL_TMEM_OP_[GET,SAVE]_CLIENT. */ + XEN_GUEST_HANDLE_64(xen_tmem_pool_info_t) pool; /* OUT for */ + /* XEN_SYSCTL_TMEM_OP_GET_POOLS. Must have 'len' */ + /* of them. */ + } u; +}; + +/* + * XEN_SYSCTL_get_cpu_levelling_caps (x86 specific) + * + * Return hardware capabilities concerning masking or faulting of the cpuid + * instruction for PV guests. + */ +struct xen_sysctl_cpu_levelling_caps { +#define XEN_SYSCTL_CPU_LEVELCAP_faulting (1ul << 0) /* CPUID faulting */ +#define XEN_SYSCTL_CPU_LEVELCAP_ecx (1ul << 1) /* 0x00000001.ecx */ +#define XEN_SYSCTL_CPU_LEVELCAP_edx (1ul << 2) /* 0x00000001.edx */ +#define XEN_SYSCTL_CPU_LEVELCAP_extd_ecx (1ul << 3) /* 0x80000001.ecx */ +#define XEN_SYSCTL_CPU_LEVELCAP_extd_edx (1ul << 4) /* 0x80000001.edx */ +#define XEN_SYSCTL_CPU_LEVELCAP_xsave_eax (1ul << 5) /* 0x0000000D:1.eax */ +#define XEN_SYSCTL_CPU_LEVELCAP_thermal_ecx (1ul << 6) /* 0x00000006.ecx */ +#define XEN_SYSCTL_CPU_LEVELCAP_l7s0_eax (1ul << 7) /* 0x00000007:0.eax */ +#define XEN_SYSCTL_CPU_LEVELCAP_l7s0_ebx (1ul << 8) /* 0x00000007:0.ebx */ + uint32_t caps; +}; + +/* + * XEN_SYSCTL_get_cpu_featureset (x86 specific) + * + * Return information about featuresets available on this host. + * - Raw: The real cpuid values. + * - Host: The values Xen is using, (after command line overrides, etc). + * - PV: Maximum set of features which can be given to a PV guest. + * - HVM: Maximum set of features which can be given to a HVM guest. + */ +struct xen_sysctl_cpu_featureset { +#define XEN_SYSCTL_cpu_featureset_raw 0 +#define XEN_SYSCTL_cpu_featureset_host 1 +#define XEN_SYSCTL_cpu_featureset_pv 2 +#define XEN_SYSCTL_cpu_featureset_hvm 3 + uint32_t index; /* IN: Which featureset to query? */ + uint32_t nr_features; /* IN/OUT: Number of entries in/written to + * 'features', or the maximum number of features if + * the guest handle is NULL. NB. All featuresets + * come from the same numberspace, so have the same + * maximum length. */ + XEN_GUEST_HANDLE_64(uint32) features; /* OUT: */ +}; + +/* + * XEN_SYSCTL_LIVEPATCH_op + * + * Refer to the docs/unstable/misc/livepatch.markdown + * for the design details of this hypercall. + * + * There are four sub-ops: + * XEN_SYSCTL_LIVEPATCH_UPLOAD (0) + * XEN_SYSCTL_LIVEPATCH_GET (1) + * XEN_SYSCTL_LIVEPATCH_LIST (2) + * XEN_SYSCTL_LIVEPATCH_ACTION (3) + * + * The normal sequence of sub-ops is to: + * 1) XEN_SYSCTL_LIVEPATCH_UPLOAD to upload the payload. If errors STOP. + * 2) XEN_SYSCTL_LIVEPATCH_GET to check the `->rc`. If -XEN_EAGAIN spin. + * If zero go to next step. + * 3) XEN_SYSCTL_LIVEPATCH_ACTION with LIVEPATCH_ACTION_APPLY to apply the patch. + * 4) XEN_SYSCTL_LIVEPATCH_GET to check the `->rc`. If in -XEN_EAGAIN spin. + * If zero exit with success. + */ + +#define LIVEPATCH_PAYLOAD_VERSION 1 +/* + * .livepatch.funcs structure layout defined in the `Payload format` + * section in the Live Patch design document. + * + * We guard this with __XEN__ as toolstacks SHOULD not use it. + */ +#ifdef __XEN__ +struct livepatch_func { + const char *name; /* Name of function to be patched. */ + void *new_addr; + void *old_addr; + uint32_t new_size; + uint32_t old_size; + uint8_t version; /* MUST be LIVEPATCH_PAYLOAD_VERSION. */ + uint8_t opaque[31]; +}; +typedef struct livepatch_func livepatch_func_t; +#endif + +/* + * Structure describing an ELF payload. Uniquely identifies the + * payload. Should be human readable. + * Recommended length is upto XEN_LIVEPATCH_NAME_SIZE. + * Includes the NUL terminator. + */ +#define XEN_LIVEPATCH_NAME_SIZE 128 +struct xen_livepatch_name { + XEN_GUEST_HANDLE_64(char) name; /* IN: pointer to name. */ + uint16_t size; /* IN: size of name. May be upto + XEN_LIVEPATCH_NAME_SIZE. */ + uint16_t pad[3]; /* IN: MUST be zero. */ +}; + +/* + * Upload a payload to the hypervisor. The payload is verified + * against basic checks and if there are any issues the proper return code + * will be returned. The payload is not applied at this time - that is + * controlled by XEN_SYSCTL_LIVEPATCH_ACTION. + * + * The return value is zero if the payload was succesfully uploaded. + * Otherwise an EXX return value is provided. Duplicate `name` are not + * supported. + * + * The payload at this point is verified against basic checks. + * + * The `payload` is the ELF payload as mentioned in the `Payload format` + * section in the Live Patch design document. + */ +#define XEN_SYSCTL_LIVEPATCH_UPLOAD 0 +struct xen_sysctl_livepatch_upload { + struct xen_livepatch_name name; /* IN, name of the patch. */ + uint64_t size; /* IN, size of the ELF file. */ + XEN_GUEST_HANDLE_64(uint8) payload; /* IN, the ELF file. */ +}; + +/* + * Retrieve an status of an specific payload. + * + * Upon completion the `struct xen_livepatch_status` is updated. + * + * The return value is zero on success and XEN_EXX on failure. This operation + * is synchronous and does not require preemption. + */ +#define XEN_SYSCTL_LIVEPATCH_GET 1 + +struct xen_livepatch_status { +#define LIVEPATCH_STATE_CHECKED 1 +#define LIVEPATCH_STATE_APPLIED 2 + uint32_t state; /* OUT: LIVEPATCH_STATE_*. */ + int32_t rc; /* OUT: 0 if no error, otherwise -XEN_EXX. */ +}; +typedef struct xen_livepatch_status xen_livepatch_status_t; +DEFINE_XEN_GUEST_HANDLE(xen_livepatch_status_t); + +struct xen_sysctl_livepatch_get { + struct xen_livepatch_name name; /* IN, name of the payload. */ + struct xen_livepatch_status status; /* IN/OUT, state of it. */ +}; + +/* + * Retrieve an array of abbreviated status and names of payloads that are + * loaded in the hypervisor. + * + * If the hypercall returns an positive number, it is the number (up to `nr`) + * of the payloads returned, along with `nr` updated with the number of remaining + * payloads, `version` updated (it may be the same across hypercalls. If it + * varies the data is stale and further calls could fail). The `status`, + * `name`, and `len`' are updated at their designed index value (`idx`) with + * the returned value of data. + * + * If the hypercall returns E2BIG the `nr` is too big and should be + * lowered. The upper limit of `nr` is left to the implemention. + * + * Note that due to the asynchronous nature of hypercalls the domain might have + * added or removed the number of payloads making this information stale. It is + * the responsibility of the toolstack to use the `version` field to check + * between each invocation. if the version differs it should discard the stale + * data and start from scratch. It is OK for the toolstack to use the new + * `version` field. + */ +#define XEN_SYSCTL_LIVEPATCH_LIST 2 +struct xen_sysctl_livepatch_list { + uint32_t version; /* OUT: Hypervisor stamps value. + If varies between calls, we are + * getting stale data. */ + uint32_t idx; /* IN: Index into hypervisor list. */ + uint32_t nr; /* IN: How many status, name, and len + should fill out. Can be zero to get + amount of payloads and version. + OUT: How many payloads left. */ + uint32_t pad; /* IN: Must be zero. */ + XEN_GUEST_HANDLE_64(xen_livepatch_status_t) status; /* OUT. Must have enough + space allocate for nr of them. */ + XEN_GUEST_HANDLE_64(char) name; /* OUT: Array of names. Each member + MUST XEN_LIVEPATCH_NAME_SIZE in size. + Must have nr of them. */ + XEN_GUEST_HANDLE_64(uint32) len; /* OUT: Array of lengths of name's. + Must have nr of them. */ +}; + +/* + * Perform an operation on the payload structure referenced by the `name` field. + * The operation request is asynchronous and the status should be retrieved + * by using either XEN_SYSCTL_LIVEPATCH_GET or XEN_SYSCTL_LIVEPATCH_LIST hypercall. + */ +#define XEN_SYSCTL_LIVEPATCH_ACTION 3 +struct xen_sysctl_livepatch_action { + struct xen_livepatch_name name; /* IN, name of the patch. */ +#define LIVEPATCH_ACTION_UNLOAD 1 +#define LIVEPATCH_ACTION_REVERT 2 +#define LIVEPATCH_ACTION_APPLY 3 +#define LIVEPATCH_ACTION_REPLACE 4 + uint32_t cmd; /* IN: LIVEPATCH_ACTION_*. */ + uint32_t timeout; /* IN: If zero then uses */ + /* hypervisor default. */ + /* Or upper bound of time (ns) */ + /* for operation to take. */ +}; + +struct xen_sysctl_livepatch_op { + uint32_t cmd; /* IN: XEN_SYSCTL_LIVEPATCH_*. */ + uint32_t pad; /* IN: Always zero. */ + union { + struct xen_sysctl_livepatch_upload upload; + struct xen_sysctl_livepatch_list list; + struct xen_sysctl_livepatch_get get; + struct xen_sysctl_livepatch_action action; + } u; +}; + +/* + * XEN_SYSCTL_set_parameter + * + * Change hypervisor parameters at runtime. + * The input string is parsed similar to the boot parameters. + * Parameters are a single string terminated by a NUL byte of max. size + * characters. Multiple settings can be specified by separating them + * with blanks. + */ + +struct xen_sysctl_set_parameter { + XEN_GUEST_HANDLE_64(char) params; /* IN: pointer to parameters. */ + uint16_t size; /* IN: size of parameters. */ + uint16_t pad[3]; /* IN: MUST be zero. */ +}; struct xen_sysctl { uint32_t cmd; @@ -672,18 +1061,26 @@ struct xen_sysctl { #define XEN_SYSCTL_pm_op 12 #define XEN_SYSCTL_page_offline_op 14 #define XEN_SYSCTL_lockprof_op 15 -#define XEN_SYSCTL_topologyinfo 16 +#define XEN_SYSCTL_cputopoinfo 16 #define XEN_SYSCTL_numainfo 17 #define XEN_SYSCTL_cpupool_op 18 #define XEN_SYSCTL_scheduler_op 19 -#define XEN_SYSCTL_coverage_op 20 +#define XEN_SYSCTL_gcov_op 20 #define XEN_SYSCTL_psr_cmt_op 21 +#define XEN_SYSCTL_pcitopoinfo 22 +#define XEN_SYSCTL_psr_cat_op 23 +#define XEN_SYSCTL_tmem_op 24 +#define XEN_SYSCTL_get_cpu_levelling_caps 25 +#define XEN_SYSCTL_get_cpu_featureset 26 +#define XEN_SYSCTL_livepatch_op 27 +#define XEN_SYSCTL_set_parameter 28 uint32_t interface_version; /* XEN_SYSCTL_INTERFACE_VERSION */ union { struct xen_sysctl_readconsole readconsole; struct xen_sysctl_tbuf_op tbuf_op; struct xen_sysctl_physinfo physinfo; - struct xen_sysctl_topologyinfo topologyinfo; + struct xen_sysctl_cputopoinfo cputopoinfo; + struct xen_sysctl_pcitopoinfo pcitopoinfo; struct xen_sysctl_numainfo numainfo; struct xen_sysctl_sched_id sched_id; struct xen_sysctl_perfc_op perfc_op; @@ -698,8 +1095,14 @@ struct xen_sysctl { struct xen_sysctl_lockprof_op lockprof_op; struct xen_sysctl_cpupool_op cpupool_op; struct xen_sysctl_scheduler_op scheduler_op; - struct xen_sysctl_coverage_op coverage_op; + struct xen_sysctl_gcov_op gcov_op; struct xen_sysctl_psr_cmt_op psr_cmt_op; + struct xen_sysctl_psr_cat_op psr_cat_op; + struct xen_sysctl_tmem_op tmem_op; + struct xen_sysctl_cpu_levelling_caps cpu_levelling_caps; + struct xen_sysctl_cpu_featureset cpu_featureset; + struct xen_sysctl_livepatch_op livepatch; + struct xen_sysctl_set_parameter set_parameter; uint8_t pad[128]; } u; }; diff --git a/include/xen/tmem.h b/include/xen/tmem.h index 4fd2fc6..aa0aafa 100644 --- a/include/xen/tmem.h +++ b/include/xen/tmem.h @@ -33,7 +33,11 @@ #define TMEM_SPEC_VERSION 1 /* Commands to HYPERVISOR_tmem_op() */ -#define TMEM_CONTROL 0 +#ifdef __XEN__ +#define TMEM_CONTROL 0 /* Now called XEN_SYSCTL_tmem_op */ +#else +#undef TMEM_CONTROL +#endif #define TMEM_NEW_POOL 1 #define TMEM_DESTROY_POOL 2 #define TMEM_PUT_PAGE 4 @@ -47,35 +51,9 @@ #define TMEM_XCHG 10 #endif -/* Privileged commands to HYPERVISOR_tmem_op() */ -#define TMEM_AUTH 101 -#define TMEM_RESTORE_NEW 102 - -/* Subops for HYPERVISOR_tmem_op(TMEM_CONTROL) */ -#define TMEMC_THAW 0 -#define TMEMC_FREEZE 1 -#define TMEMC_FLUSH 2 -#define TMEMC_DESTROY 3 -#define TMEMC_LIST 4 -#define TMEMC_SET_WEIGHT 5 -#define TMEMC_SET_CAP 6 -#define TMEMC_SET_COMPRESS 7 -#define TMEMC_QUERY_FREEABLE_MB 8 -#define TMEMC_SAVE_BEGIN 10 -#define TMEMC_SAVE_GET_VERSION 11 -#define TMEMC_SAVE_GET_MAXPOOLS 12 -#define TMEMC_SAVE_GET_CLIENT_WEIGHT 13 -#define TMEMC_SAVE_GET_CLIENT_CAP 14 -#define TMEMC_SAVE_GET_CLIENT_FLAGS 15 -#define TMEMC_SAVE_GET_POOL_FLAGS 16 -#define TMEMC_SAVE_GET_POOL_NPAGES 17 -#define TMEMC_SAVE_GET_POOL_UUID 18 -#define TMEMC_SAVE_GET_NEXT_PAGE 19 -#define TMEMC_SAVE_GET_NEXT_INV 20 -#define TMEMC_SAVE_END 21 -#define TMEMC_RESTORE_BEGIN 30 -#define TMEMC_RESTORE_PUT_PAGE 32 -#define TMEMC_RESTORE_FLUSH_PAGE 33 +/* Privileged commands now called via XEN_SYSCTL_tmem_op. */ +#define TMEM_AUTH 101 /* as XEN_SYSCTL_TMEM_OP_SET_AUTH. */ +#define TMEM_RESTORE_NEW 102 /* as XEN_SYSCTL_TMEM_OP_SET_POOL. */ /* Bits for HYPERVISOR_tmem_op(TMEM_NEW_POOL) */ #define TMEM_POOL_PERSIST 1 @@ -95,6 +73,11 @@ #define EFROZEN 1000 #define EEMPTY 1001 +struct xen_tmem_oid { + uint64_t oid[3]; +}; +typedef struct xen_tmem_oid xen_tmem_oid_t; +DEFINE_XEN_GUEST_HANDLE(xen_tmem_oid_t); #ifndef __ASSEMBLY__ #if __XEN_INTERFACE_VERSION__ < 0x00040400 @@ -109,18 +92,13 @@ struct tmem_op { uint64_t uuid[2]; uint32_t flags; uint32_t arg1; - } creat; /* for cmd == TMEM_NEW_POOL, TMEM_AUTH, TMEM_RESTORE_NEW */ - struct { - uint32_t subop; - uint32_t cli_id; - uint32_t arg1; - uint32_t arg2; - uint64_t oid[3]; - tmem_cli_va_t buf; - } ctrl; /* for cmd == TMEM_CONTROL */ + } creat; /* for cmd == TMEM_NEW_POOL. */ struct { - +#if __XEN_INTERFACE_VERSION__ < 0x00040600 uint64_t oid[3]; +#else + xen_tmem_oid_t oid; +#endif uint32_t index; uint32_t tmem_offset; uint32_t pfn_offset; @@ -131,12 +109,6 @@ struct tmem_op { }; typedef struct tmem_op tmem_op_t; DEFINE_XEN_GUEST_HANDLE(tmem_op_t); - -struct tmem_handle { - uint32_t pool_id; - uint32_t index; - uint64_t oid[3]; -}; #endif #endif /* __XEN_PUBLIC_TMEM_H__ */ diff --git a/include/xen/trace.h b/include/xen/trace.h index 5211ae7..3746bff 100644 --- a/include/xen/trace.h +++ b/include/xen/trace.h @@ -75,9 +75,10 @@ /* Per-scheduler IDs, to identify scheduler specific events */ #define TRC_SCHED_CSCHED 0 #define TRC_SCHED_CSCHED2 1 -#define TRC_SCHED_SEDF 2 +/* #define XEN_SCHEDULER_SEDF 2 (Removed) */ #define TRC_SCHED_ARINC653 3 #define TRC_SCHED_RTDS 4 +#define TRC_SCHED_SNULL 5 /* Per-scheduler tracing */ #define TRC_SCHED_CLASS_EVT(_c, _e) \ @@ -85,6 +86,9 @@ ((TRC_SCHED_##_c << TRC_SCHED_ID_SHIFT) & TRC_SCHED_ID_MASK) ) + \ (_e & TRC_SCHED_EVT_MASK) ) +/* Trace classes for DOM0 operations */ +#define TRC_DOM0_DOMOPS 0x00041000 /* Domains manipulations */ + /* Trace classes for Hardware */ #define TRC_HW_PM 0x00801000 /* Power management traces */ #define TRC_HW_IRQ 0x00802000 /* Traces relating to the handling of IRQs */ @@ -112,6 +116,10 @@ #define TRC_SCHED_SWITCH_INFPREV (TRC_SCHED_VERBOSE + 14) #define TRC_SCHED_SWITCH_INFNEXT (TRC_SCHED_VERBOSE + 15) #define TRC_SCHED_SHUTDOWN_CODE (TRC_SCHED_VERBOSE + 16) +#define TRC_SCHED_SWITCH_INFCONT (TRC_SCHED_VERBOSE + 17) + +#define TRC_DOM0_DOM_ADD (TRC_DOM0_DOMOPS + 1) +#define TRC_DOM0_DOM_REM (TRC_DOM0_DOMOPS + 2) #define TRC_MEM_PAGE_GRANT_MAP (TRC_MEM + 1) #define TRC_MEM_PAGE_GRANT_UNMAP (TRC_MEM + 2) diff --git a/include/xen/vcpu.h b/include/xen/vcpu.h index 898b89f..8a9e30d 100644 --- a/include/xen/vcpu.h +++ b/include/xen/vcpu.h @@ -41,8 +41,10 @@ * Initialise a VCPU. Each VCPU can be initialised only once. A * newly-initialised VCPU will not run until it is brought up by VCPUOP_up. * - * @extra_arg == pointer to vcpu_guest_context structure containing initial - * state for the VCPU. + * @extra_arg == For PV or ARM guests this is a pointer to a vcpu_guest_context + * structure containing the initial state for the VCPU. For x86 + * HVM based guests this is a pointer to a vcpu_hvm_context + * structure. */ #define VCPUOP_initialise 0 @@ -82,6 +84,12 @@ struct vcpu_runstate_info { /* When was current state entered (system time, ns)? */ uint64_t state_entry_time; /* + * Update indicator set in state_entry_time: + * When activated via VMASST_TYPE_runstate_update_flag, set during + * updates in guest memory mapped copy of vcpu_runstate_info. + */ +#define XEN_RUNSTATE_UPDATE (xen_mk_ullong(1) << 63) + /* * Time spent in each RUNSTATE_* (ns). The sum of these times is * guaranteed not to drift from system time. */ diff --git a/include/xen/version.h b/include/xen/version.h index 44f26b0..cb84565 100644 --- a/include/xen/version.h +++ b/include/xen/version.h @@ -30,7 +30,8 @@ #include "xen.h" -/* NB. All ops return zero on success, except XENVER_{version,pagesize} */ +/* NB. All ops return zero on success, except XENVER_{version,pagesize} + * XENVER_{version,pagesize,build_id} */ /* arg == NULL; returns major:minor (16:16). */ #define XENVER_version 0 @@ -77,12 +78,31 @@ typedef struct xen_feature_info xen_feature_info_t; /* arg == NULL; returns host memory page size. */ #define XENVER_pagesize 7 -/* arg == xen_domain_handle_t. */ +/* arg == xen_domain_handle_t. + * + * The toolstack fills it out for guest consumption. It is intended to hold + * the UUID of the guest. + */ #define XENVER_guest_handle 8 #define XENVER_commandline 9 typedef char xen_commandline_t[1024]; +/* + * Return value is the number of bytes written, or XEN_Exx on error. + * Calling with empty parameter returns the size of build_id. + */ +#define XENVER_build_id 10 +struct xen_build_id { + uint32_t len; /* IN: size of buf[]. */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + unsigned char buf[]; +#elif defined(__GNUC__) + unsigned char buf[1]; /* OUT: Variable length buffer with build_id. */ +#endif +}; +typedef struct xen_build_id xen_build_id_t; + #endif /* __XEN_PUBLIC_VERSION_H__ */ /* diff --git a/include/xen/vm_event.h b/include/xen/vm_event.h new file mode 100644 index 0000000..b531f71 --- /dev/null +++ b/include/xen/vm_event.h @@ -0,0 +1,378 @@ +/****************************************************************************** + * vm_event.h + * + * Memory event common structures. + * + * Copyright (c) 2009 by Citrix Systems, Inc. (Patrick Colp) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef _XEN_PUBLIC_VM_EVENT_H +#define _XEN_PUBLIC_VM_EVENT_H + +#include "xen.h" + +#define VM_EVENT_INTERFACE_VERSION 0x00000002 + +#if defined(__XEN__) || defined(__XEN_TOOLS__) + +#include "io/ring.h" + +/* + * Memory event flags + */ + +/* + * VCPU_PAUSED in a request signals that the vCPU triggering the event has been + * paused + * VCPU_PAUSED in a response signals to unpause the vCPU + */ +#define VM_EVENT_FLAG_VCPU_PAUSED (1 << 0) +/* Flags to aid debugging vm_event */ +#define VM_EVENT_FLAG_FOREIGN (1 << 1) +/* + * The following flags can be set in response to a mem_access event. + * + * Emulate the fault-causing instruction (if set in the event response flags). + * This will allow the guest to continue execution without lifting the page + * access restrictions. + */ +#define VM_EVENT_FLAG_EMULATE (1 << 2) +/* + * Same as VM_EVENT_FLAG_EMULATE, but with write operations or operations + * potentially having side effects (like memory mapped or port I/O) disabled. + */ +#define VM_EVENT_FLAG_EMULATE_NOWRITE (1 << 3) +/* + * Toggle singlestepping on vm_event response. + * Requires the vCPU to be paused already (synchronous events only). + */ +#define VM_EVENT_FLAG_TOGGLE_SINGLESTEP (1 << 4) +/* + * Data is being sent back to the hypervisor in the event response, to be + * returned by the read function when emulating an instruction. + * This flag is only useful when combined with VM_EVENT_FLAG_EMULATE + * and takes precedence if combined with VM_EVENT_FLAG_EMULATE_NOWRITE + * (i.e. if both VM_EVENT_FLAG_EMULATE_NOWRITE and + * VM_EVENT_FLAG_SET_EMUL_READ_DATA are set, only the latter will be honored). + */ +#define VM_EVENT_FLAG_SET_EMUL_READ_DATA (1 << 5) +/* + * Deny completion of the operation that triggered the event. + * Currently only useful for MSR and control-register write events. + * Requires the vCPU to be paused already (synchronous events only). + */ +#define VM_EVENT_FLAG_DENY (1 << 6) +/* + * This flag can be set in a request or a response + * + * On a request, indicates that the event occurred in the alternate p2m + * specified by the altp2m_idx request field. + * + * On a response, indicates that the VCPU should resume in the alternate p2m + * specified by the altp2m_idx response field if possible. + */ +#define VM_EVENT_FLAG_ALTERNATE_P2M (1 << 7) +/* + * Set the vCPU registers to the values in the vm_event response. + * At the moment x86-only, applies to EAX-EDX, ESP, EBP, ESI, EDI, R8-R15, + * EFLAGS, and EIP. + * Requires the vCPU to be paused already (synchronous events only). + */ +#define VM_EVENT_FLAG_SET_REGISTERS (1 << 8) +/* + * Instruction cache is being sent back to the hypervisor in the event response + * to be used by the emulator. This flag is only useful when combined with + * VM_EVENT_FLAG_EMULATE and does not take presedence if combined with + * VM_EVENT_FLAG_EMULATE_NOWRITE or VM_EVENT_FLAG_SET_EMUL_READ_DATA, (i.e. + * if any of those flags are set, only those will be honored). + */ +#define VM_EVENT_FLAG_SET_EMUL_INSN_DATA (1 << 9) +/* + * Have a one-shot VM_EVENT_REASON_INTERRUPT event sent for the first + * interrupt pending after resuming the VCPU. + */ +#define VM_EVENT_FLAG_GET_NEXT_INTERRUPT (1 << 10) + +/* + * Reasons for the vm event request + */ + +/* Default case */ +#define VM_EVENT_REASON_UNKNOWN 0 +/* Memory access violation */ +#define VM_EVENT_REASON_MEM_ACCESS 1 +/* Memory sharing event */ +#define VM_EVENT_REASON_MEM_SHARING 2 +/* Memory paging event */ +#define VM_EVENT_REASON_MEM_PAGING 3 +/* A control register was updated */ +#define VM_EVENT_REASON_WRITE_CTRLREG 4 +/* An MSR was updated. */ +#define VM_EVENT_REASON_MOV_TO_MSR 5 +/* Debug operation executed (e.g. int3) */ +#define VM_EVENT_REASON_SOFTWARE_BREAKPOINT 6 +/* Single-step (e.g. MTF) */ +#define VM_EVENT_REASON_SINGLESTEP 7 +/* An event has been requested via HVMOP_guest_request_vm_event. */ +#define VM_EVENT_REASON_GUEST_REQUEST 8 +/* A debug exception was caught */ +#define VM_EVENT_REASON_DEBUG_EXCEPTION 9 +/* CPUID executed */ +#define VM_EVENT_REASON_CPUID 10 +/* + * Privileged call executed (e.g. SMC). + * Note: event may be generated even if SMC condition check fails on some CPUs. + * As this behavior is CPU-specific, users are advised to not rely on it. + * These kinds of events will be filtered out in future versions. + */ +#define VM_EVENT_REASON_PRIVILEGED_CALL 11 +/* An interrupt has been delivered. */ +#define VM_EVENT_REASON_INTERRUPT 12 +/* A descriptor table register was accessed. */ +#define VM_EVENT_REASON_DESCRIPTOR_ACCESS 13 +/* Current instruction is not implemented by the emulator */ +#define VM_EVENT_REASON_EMUL_UNIMPLEMENTED 14 + +/* Supported values for the vm_event_write_ctrlreg index. */ +#define VM_EVENT_X86_CR0 0 +#define VM_EVENT_X86_CR3 1 +#define VM_EVENT_X86_CR4 2 +#define VM_EVENT_X86_XCR0 3 + +/* + * Using custom vCPU structs (i.e. not hvm_hw_cpu) for both x86 and ARM + * so as to not fill the vm_event ring buffer too quickly. + */ +struct vm_event_regs_x86 { + uint64_t rax; + uint64_t rcx; + uint64_t rdx; + uint64_t rbx; + uint64_t rsp; + uint64_t rbp; + uint64_t rsi; + uint64_t rdi; + uint64_t r8; + uint64_t r9; + uint64_t r10; + uint64_t r11; + uint64_t r12; + uint64_t r13; + uint64_t r14; + uint64_t r15; + uint64_t rflags; + uint64_t dr7; + uint64_t rip; + uint64_t cr0; + uint64_t cr2; + uint64_t cr3; + uint64_t cr4; + uint64_t sysenter_cs; + uint64_t sysenter_esp; + uint64_t sysenter_eip; + uint64_t msr_efer; + uint64_t msr_star; + uint64_t msr_lstar; + uint64_t fs_base; + uint64_t gs_base; + uint32_t cs_arbytes; + uint32_t _pad; +}; + +/* + * Only the register 'pc' can be set on a vm_event response using the + * VM_EVENT_FLAG_SET_REGISTERS flag. + */ +struct vm_event_regs_arm { + uint64_t ttbr0; + uint64_t ttbr1; + uint64_t ttbcr; + uint64_t pc; + uint32_t cpsr; + uint32_t _pad; +}; + +/* + * mem_access flag definitions + * + * These flags are set only as part of a mem_event request. + * + * R/W/X: Defines the type of violation that has triggered the event + * Multiple types can be set in a single violation! + * GLA_VALID: If the gla field holds a guest VA associated with the event + * FAULT_WITH_GLA: If the violation was triggered by accessing gla + * FAULT_IN_GPT: If the violation was triggered during translating gla + */ +#define MEM_ACCESS_R (1 << 0) +#define MEM_ACCESS_W (1 << 1) +#define MEM_ACCESS_X (1 << 2) +#define MEM_ACCESS_RWX (MEM_ACCESS_R | MEM_ACCESS_W | MEM_ACCESS_X) +#define MEM_ACCESS_RW (MEM_ACCESS_R | MEM_ACCESS_W) +#define MEM_ACCESS_RX (MEM_ACCESS_R | MEM_ACCESS_X) +#define MEM_ACCESS_WX (MEM_ACCESS_W | MEM_ACCESS_X) +#define MEM_ACCESS_GLA_VALID (1 << 3) +#define MEM_ACCESS_FAULT_WITH_GLA (1 << 4) +#define MEM_ACCESS_FAULT_IN_GPT (1 << 5) + +struct vm_event_mem_access { + uint64_t gfn; + uint64_t offset; + uint64_t gla; /* if flags has MEM_ACCESS_GLA_VALID set */ + uint32_t flags; /* MEM_ACCESS_* */ + uint32_t _pad; +}; + +struct vm_event_write_ctrlreg { + uint32_t index; + uint32_t _pad; + uint64_t new_value; + uint64_t old_value; +}; + +struct vm_event_singlestep { + uint64_t gfn; +}; + +struct vm_event_debug { + uint64_t gfn; + uint32_t insn_length; + uint8_t type; /* HVMOP_TRAP_* */ + uint8_t _pad[3]; +}; + +struct vm_event_mov_to_msr { + uint64_t msr; + uint64_t value; +}; + +#define VM_EVENT_DESC_IDTR 1 +#define VM_EVENT_DESC_GDTR 2 +#define VM_EVENT_DESC_LDTR 3 +#define VM_EVENT_DESC_TR 4 + +struct vm_event_desc_access { + union { + struct { + uint32_t instr_info; /* VMX: VMCS Instruction-Information */ + uint32_t _pad1; + uint64_t exit_qualification; /* VMX: VMCS Exit Qualification */ + } vmx; + struct { + uint64_t exitinfo; /* SVM: VMCB EXITINFO */ + uint64_t _pad2; + } svm; + } arch; + uint8_t descriptor; /* VM_EVENT_DESC_* */ + uint8_t is_write; + uint8_t _pad[6]; +}; + +struct vm_event_cpuid { + uint32_t insn_length; + uint32_t leaf; + uint32_t subleaf; + uint32_t _pad; +}; + +struct vm_event_interrupt_x86 { + uint32_t vector; + uint32_t type; + uint32_t error_code; + uint32_t _pad; + uint64_t cr2; +}; + +#define MEM_PAGING_DROP_PAGE (1 << 0) +#define MEM_PAGING_EVICT_FAIL (1 << 1) + +struct vm_event_paging { + uint64_t gfn; + uint32_t p2mt; + uint32_t flags; +}; + +struct vm_event_sharing { + uint64_t gfn; + uint32_t p2mt; + uint32_t _pad; +}; + +struct vm_event_emul_read_data { + uint32_t size; + /* The struct is used in a union with vm_event_regs_x86. */ + uint8_t data[sizeof(struct vm_event_regs_x86) - sizeof(uint32_t)]; +}; + +struct vm_event_emul_insn_data { + uint8_t data[16]; /* Has to be completely filled */ +}; + +typedef struct vm_event_st { + uint32_t version; /* VM_EVENT_INTERFACE_VERSION */ + uint32_t flags; /* VM_EVENT_FLAG_* */ + uint32_t reason; /* VM_EVENT_REASON_* */ + uint32_t vcpu_id; + uint16_t altp2m_idx; /* may be used during request and response */ + uint16_t _pad[3]; + + union { + struct vm_event_paging mem_paging; + struct vm_event_sharing mem_sharing; + struct vm_event_mem_access mem_access; + struct vm_event_write_ctrlreg write_ctrlreg; + struct vm_event_mov_to_msr mov_to_msr; + struct vm_event_desc_access desc_access; + struct vm_event_singlestep singlestep; + struct vm_event_debug software_breakpoint; + struct vm_event_debug debug_exception; + struct vm_event_cpuid cpuid; + union { + struct vm_event_interrupt_x86 x86; + } interrupt; + } u; + + union { + union { + struct vm_event_regs_x86 x86; + struct vm_event_regs_arm arm; + } regs; + + union { + struct vm_event_emul_read_data read; + struct vm_event_emul_insn_data insn; + } emul; + } data; +} vm_event_request_t, vm_event_response_t; + +DEFINE_RING_TYPES(vm_event, vm_event_request_t, vm_event_response_t); + +#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */ +#endif /* _XEN_PUBLIC_VM_EVENT_H */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/xen/xen-compat.h b/include/xen/xen-compat.h index 1e62dc1..b673653 100644 --- a/include/xen/xen-compat.h +++ b/include/xen/xen-compat.h @@ -27,7 +27,7 @@ #ifndef __XEN_PUBLIC_XEN_COMPAT_H__ #define __XEN_PUBLIC_XEN_COMPAT_H__ -#define __XEN_LATEST_INTERFACE_VERSION__ 0x00040600 +#define __XEN_LATEST_INTERFACE_VERSION__ 0x00040900 #if defined(__XEN__) || defined(__XEN_TOOLS__) /* Xen is built with matching headers and implements the latest interface. */ diff --git a/include/xen/xen.h b/include/xen/xen.h index a6a2092..2ac6b1e 100644 --- a/include/xen/xen.h +++ b/include/xen/xen.h @@ -52,6 +52,24 @@ DEFINE_XEN_GUEST_HANDLE(void); DEFINE_XEN_GUEST_HANDLE(uint64_t); DEFINE_XEN_GUEST_HANDLE(xen_pfn_t); DEFINE_XEN_GUEST_HANDLE(xen_ulong_t); + +/* Turn a plain number into a C unsigned (long (long)) constant. */ +#define __xen_mk_uint(x) x ## U +#define __xen_mk_ulong(x) x ## UL +#ifndef __xen_mk_ullong +# define __xen_mk_ullong(x) x ## ULL +#endif +#define xen_mk_uint(x) __xen_mk_uint(x) +#define xen_mk_ulong(x) __xen_mk_ulong(x) +#define xen_mk_ullong(x) __xen_mk_ullong(x) + +#else + +/* In assembly code we cannot use C numeric constant suffixes. */ +#define xen_mk_uint(x) x +#define xen_mk_ulong(x) x +#define xen_mk_ullong(x) x + #endif /* @@ -101,6 +119,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_ulong_t); #define __HYPERVISOR_kexec_op 37 #define __HYPERVISOR_tmem_op 38 #define __HYPERVISOR_xc_reserved_op 39 /* reserved for XenClient */ +#define __HYPERVISOR_xenpmu_op 40 +#define __HYPERVISOR_dm_op 41 /* Architecture-specific hypercall definitions. */ #define __HYPERVISOR_arch_0 48 @@ -160,6 +180,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_ulong_t); #define VIRQ_MEM_EVENT 10 /* G. (DOM0) A memory event has occured */ #define VIRQ_XC_RESERVED 11 /* G. Reserved for XenClient */ #define VIRQ_ENOMEM 12 /* G. (DOM0) Low on heap memory */ +#define VIRQ_XENPMU 13 /* V. PMC interrupt */ /* Architecture-specific VIRQ definitions. */ #define VIRQ_ARCH_0 16 @@ -449,13 +470,13 @@ DEFINE_XEN_GUEST_HANDLE(mmuext_op_t); /* When specifying UVMF_MULTI, also OR in a pointer to a CPU bitmap. */ /* UVMF_LOCAL is merely UVMF_MULTI with a NULL bitmap pointer. */ /* ` enum uvm_flags { */ -#define UVMF_NONE (0UL<<0) /* No flushing at all. */ -#define UVMF_TLB_FLUSH (1UL<<0) /* Flush entire TLB(s). */ -#define UVMF_INVLPG (2UL<<0) /* Flush only one entry. */ -#define UVMF_FLUSHTYPE_MASK (3UL<<0) -#define UVMF_MULTI (0UL<<2) /* Flush subset of TLBs. */ -#define UVMF_LOCAL (0UL<<2) /* Flush local TLB. */ -#define UVMF_ALL (1UL<<2) /* Flush all TLBs. */ +#define UVMF_NONE (xen_mk_ulong(0)<<0) /* No flushing at all. */ +#define UVMF_TLB_FLUSH (xen_mk_ulong(1)<<0) /* Flush entire TLB(s). */ +#define UVMF_INVLPG (xen_mk_ulong(2)<<0) /* Flush only one entry. */ +#define UVMF_FLUSHTYPE_MASK (xen_mk_ulong(3)<<0) +#define UVMF_MULTI (xen_mk_ulong(0)<<2) /* Flush subset of TLBs. */ +#define UVMF_LOCAL (xen_mk_ulong(0)<<2) /* Flush local TLB. */ +#define UVMF_ALL (xen_mk_ulong(1)<<2) /* Flush all TLBs. */ /* ` } */ /* @@ -486,17 +507,42 @@ DEFINE_XEN_GUEST_HANDLE(mmuext_op_t); /* x86/PAE guests: support PDPTs above 4GB. */ #define VMASST_TYPE_pae_extended_cr3 3 -#define MAX_VMASST_TYPE 3 +/* + * x86 guests: Sane behaviour for virtual iopl + * - virtual iopl updated from do_iret() hypercalls. + * - virtual iopl reported in bounce frames. + * - guest kernels assumed to be level 0 for the purpose of iopl checks. + */ +#define VMASST_TYPE_architectural_iopl 4 -#ifndef __ASSEMBLY__ +/* + * All guests: activate update indicator in vcpu_runstate_info + * Enable setting the XEN_RUNSTATE_UPDATE flag in guest memory mapped + * vcpu_runstate_info during updates of the runstate information. + */ +#define VMASST_TYPE_runstate_update_flag 5 -typedef uint16_t domid_t; +/* + * x86/64 guests: strictly hide M2P from user mode. + * This allows the guest to control respective hypervisor behavior: + * - when not set, L4 tables get created with the respective slot blank, + * and whenever the L4 table gets used as a kernel one the missing + * mapping gets inserted, + * - when set, L4 tables get created with the respective slot initialized + * as before, and whenever the L4 table gets used as a user one the + * mapping gets zapped. + */ +#define VMASST_TYPE_m2p_strict 32 + +#if __XEN_INTERFACE_VERSION__ < 0x00040600 +#define MAX_VMASST_TYPE 3 +#endif /* Domain ids >= DOMID_FIRST_RESERVED cannot be used for ordinary domains. */ -#define DOMID_FIRST_RESERVED (0x7FF0U) +#define DOMID_FIRST_RESERVED xen_mk_uint(0x7FF0) /* DOMID_SELF is used in certain contexts to refer to oneself. */ -#define DOMID_SELF (0x7FF0U) +#define DOMID_SELF xen_mk_uint(0x7FF0) /* * DOMID_IO is used to restrict page-table updates to mapping I/O memory. @@ -504,28 +550,37 @@ typedef uint16_t domid_t; * is useful to ensure that no mappings to the OS's own heap are accidentally * installed. (e.g., in Linux this could cause havoc as reference counts * aren't adjusted on the I/O-mapping code path). - * This only makes sense in MMUEXT_SET_FOREIGNDOM, but in that context can - * be specified by any calling domain. + * This only makes sense as HYPERVISOR_mmu_update()'s and + * HYPERVISOR_update_va_mapping_otherdomain()'s "foreigndom" argument. For + * HYPERVISOR_mmu_update() context it can be specified by any calling domain, + * otherwise it's only permitted if the caller is privileged. */ -#define DOMID_IO (0x7FF1U) +#define DOMID_IO xen_mk_uint(0x7FF1) /* * DOMID_XEN is used to allow privileged domains to map restricted parts of * Xen's heap space (e.g., the machine_to_phys table). - * This only makes sense in MMUEXT_SET_FOREIGNDOM, and is only permitted if - * the caller is privileged. + * This only makes sense as + * - HYPERVISOR_mmu_update()'s, HYPERVISOR_mmuext_op()'s, or + * HYPERVISOR_update_va_mapping_otherdomain()'s "foreigndom" argument, + * - with XENMAPSPACE_gmfn_foreign, + * and is only permitted if the caller is privileged. */ -#define DOMID_XEN (0x7FF2U) +#define DOMID_XEN xen_mk_uint(0x7FF2) /* * DOMID_COW is used as the owner of sharable pages */ -#define DOMID_COW (0x7FF3U) +#define DOMID_COW xen_mk_uint(0x7FF3) /* DOMID_INVALID is used to identify pages with unknown owner. */ -#define DOMID_INVALID (0x7FF4U) +#define DOMID_INVALID xen_mk_uint(0x7FF4) /* Idle domain. */ -#define DOMID_IDLE (0x7FFFU) +#define DOMID_IDLE xen_mk_uint(0x7FFF) + +#ifndef __ASSEMBLY__ + +typedef uint16_t domid_t; /* * Send an array of these to HYPERVISOR_mmu_update(). @@ -585,10 +640,18 @@ struct vcpu_time_info { */ uint32_t tsc_to_system_mul; int8_t tsc_shift; +#if __XEN_INTERFACE_VERSION__ > 0x040600 + uint8_t flags; + uint8_t pad1[2]; +#else int8_t pad1[3]; +#endif }; /* 32 bytes */ typedef struct vcpu_time_info vcpu_time_info_t; +#define XEN_PVCLOCK_TSC_STABLE_BIT (1 << 0) +#define XEN_PVCLOCK_GUEST_STOPPED (1 << 1) + struct vcpu_info { /* * 'evtchn_upcall_pending' is written non-zero by Xen to indicate @@ -682,6 +745,12 @@ struct shared_info { uint32_t wc_version; /* Version counter: see vcpu_time_info_t. */ uint32_t wc_sec; /* Secs 00:00:00 UTC, Jan 1, 1970. */ uint32_t wc_nsec; /* Nsecs 00:00:00 UTC, Jan 1, 1970. */ +#if !defined(__i386__) + uint32_t wc_sec_hi; +# define xen_wc_sec_hi wc_sec_hi +#elif !defined(__XEN__) && !defined(__XEN_TOOLS__) +# define xen_wc_sec_hi arch.wc_sec_hi +#endif struct arch_shared_info arch; @@ -698,24 +767,27 @@ typedef struct shared_info shared_info_t; * 3. This the order of bootstrap elements in the initial virtual region: * a. relocated kernel image * b. initial ram disk [mod_start, mod_len] + * (may be omitted) * c. list of allocated page frames [mfn_list, nr_pages] * (unless relocated due to XEN_ELFNOTE_INIT_P2M) - * d. start_info_t structure [register ESI (x86)] - * e. bootstrap page tables [pt_base and CR3 (x86)] - * f. bootstrap stack [register ESP (x86)] + * d. start_info_t structure [register rSI (x86)] + * in case of dom0 this page contains the console info, too + * e. unless dom0: xenstore ring page + * f. unless dom0: console ring page + * g. bootstrap page tables [pt_base and CR3 (x86)] + * h. bootstrap stack [register ESP (x86)] * 4. Bootstrap elements are packed together, but each is 4kB-aligned. - * 5. The initial ram disk may be omitted. - * 6. The list of page frames forms a contiguous 'pseudo-physical' memory + * 5. The list of page frames forms a contiguous 'pseudo-physical' memory * layout for the domain. In particular, the bootstrap virtual-memory * region is a 1:1 mapping to the first section of the pseudo-physical map. - * 7. All bootstrap elements are mapped read-writable for the guest OS. The + * 6. All bootstrap elements are mapped read-writable for the guest OS. The * only exception is the bootstrap page table, which is mapped read-only. - * 8. There is guaranteed to be at least 512kB padding after the final + * 7. There is guaranteed to be at least 512kB padding after the final * bootstrap element. If necessary, the bootstrap virtual region is * extended by an extra 4MB to ensure this. * * Note: Prior to 25833:bb85bbccb1c9. ("x86/32-on-64 adjust Dom0 initial page - * table layout") a bug caused the pt_base (3.e above) and cr3 to not point + * table layout") a bug caused the pt_base (3.g above) and cr3 to not point * to the start of the guest page tables (it was offset by two pages). * This only manifested itself on 32-on-64 dom0 kernels and not 32-on-64 domU * or 64-bit kernels of any colour. The page tables for a 32-on-64 dom0 got @@ -771,6 +843,8 @@ typedef struct start_info start_info_t; #define SIF_INITDOMAIN (1<<1) /* Is this the initial control domain? */ #define SIF_MULTIBOOT_MOD (1<<2) /* Is mod_start a multiboot module? */ #define SIF_MOD_START_PFN (1<<3) /* Is mod_start a PFN? */ +#define SIF_VIRT_P2M_4TOOLS (1<<4) /* Do Xen tools understand a virt. mapped */ + /* P->M making the 3 level tree obsolete? */ #define SIF_PM_MASK (0xFF<<8) /* reserve 1 byte for xen-pm options */ /* @@ -851,25 +925,19 @@ typedef struct dom0_vga_console_info { typedef uint8_t xen_domain_handle_t[16]; -/* Turn a plain number into a C unsigned long constant. */ -#define __mk_unsigned_long(x) x ## UL -#define mk_unsigned_long(x) __mk_unsigned_long(x) - __DEFINE_XEN_GUEST_HANDLE(uint8, uint8_t); __DEFINE_XEN_GUEST_HANDLE(uint16, uint16_t); __DEFINE_XEN_GUEST_HANDLE(uint32, uint32_t); __DEFINE_XEN_GUEST_HANDLE(uint64, uint64_t); -#else /* __ASSEMBLY__ */ - -/* In assembly code we cannot use C numeric constant suffixes. */ -#define mk_unsigned_long(x) x - #endif /* !__ASSEMBLY__ */ /* Default definitions for macros used by domctl/sysctl. */ #if defined(__XEN__) || defined(__XEN_TOOLS__) +#ifndef int64_aligned_t +#define int64_aligned_t int64_t +#endif #ifndef uint64_aligned_t #define uint64_aligned_t uint64_t #endif diff --git a/include/xen/xenoprof.h b/include/xen/xenoprof.h index 1c305c4..1955db1 100644 --- a/include/xen/xenoprof.h +++ b/include/xen/xenoprof.h @@ -68,7 +68,7 @@ struct event_log { }; /* PC value that indicates a special code */ -#define XENOPROF_ESCAPE_CODE (~0ULL) +#define XENOPROF_ESCAPE_CODE (~xen_mk_ullong(0)) /* Transient events for the xenoprof->oprofile cpu buf */ #define XENOPROF_TRACE_BEGIN 1 diff --git a/include/xen/xsm/flask_op.h b/include/xen/xsm/flask_op.h index 233de81..970ec07 100644 --- a/include/xen/xsm/flask_op.h +++ b/include/xen/xsm/flask_op.h @@ -25,6 +25,8 @@ #ifndef __FLASK_OP_H__ #define __FLASK_OP_H__ +#include "../event_channel.h" + #define XEN_FLASK_INTERFACE_VERSION 1 struct xen_flask_load { @@ -68,6 +70,7 @@ struct xen_flask_transition { uint32_t newsid; }; +#if __XEN_INTERFACE_VERSION__ < 0x00040800 struct xen_flask_userlist { /* IN: starting SID for list */ uint32_t start_sid; @@ -81,6 +84,7 @@ struct xen_flask_userlist { XEN_GUEST_HANDLE(uint32) sids; } u; }; +#endif struct xen_flask_boolean { /* IN/OUT: numeric identifier for boolean [GET/SET] @@ -148,6 +152,13 @@ struct xen_flask_relabel { uint32_t sid; }; +struct xen_flask_devicetree_label { + /* IN */ + uint32_t sid; + uint32_t length; + XEN_GUEST_HANDLE(char) path; +}; + struct xen_flask_op { uint32_t cmd; #define FLASK_LOAD 1 @@ -158,7 +169,7 @@ struct xen_flask_op { #define FLASK_ACCESS 6 #define FLASK_CREATE 7 #define FLASK_RELABEL 8 -#define FLASK_USER 9 +#define FLASK_USER 9 /* No longer implemented */ #define FLASK_POLICYVERS 10 #define FLASK_GETBOOL 11 #define FLASK_SETBOOL 12 @@ -174,6 +185,7 @@ struct xen_flask_op { #define FLASK_DEL_OCONTEXT 22 #define FLASK_GET_PEER_SID 23 #define FLASK_RELABEL_DOMAIN 24 +#define FLASK_DEVICETREE_LABEL 25 uint32_t interface_version; /* XEN_FLASK_INTERFACE_VERSION */ union { struct xen_flask_load load; @@ -183,7 +195,9 @@ struct xen_flask_op { struct xen_flask_access access; /* FLASK_CREATE, FLASK_RELABEL, FLASK_MEMBER */ struct xen_flask_transition transition; +#if __XEN_INTERFACE_VERSION__ < 0x00040800 struct xen_flask_userlist userlist; +#endif /* FLASK_GETBOOL, FLASK_SETBOOL */ struct xen_flask_boolean boolean; struct xen_flask_setavc_threshold setavc_threshold; @@ -193,6 +207,7 @@ struct xen_flask_op { struct xen_flask_ocontext ocontext; struct xen_flask_peersid peersid; struct xen_flask_relabel relabel; + struct xen_flask_devicetree_label devicetree_label; } u; }; typedef struct xen_flask_op xen_flask_op_t; -- 2.11.0 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |