318 changes: 318 additions & 0 deletions include/hw/xen/interface/hvm/params.h
@@ -0,0 +1,318 @@
/*
* 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) 2007, Keir Fraser
*/

#ifndef __XEN_PUBLIC_HVM_PARAMS_H__
#define __XEN_PUBLIC_HVM_PARAMS_H__

#include "hvm_op.h"

/* These parameters are deprecated and their meaning is undefined. */
#if defined(__XEN__) || defined(__XEN_TOOLS__)

#define HVM_PARAM_PAE_ENABLED 4
#define HVM_PARAM_DM_DOMAIN 13
#define HVM_PARAM_MEMORY_EVENT_CR0 20
#define HVM_PARAM_MEMORY_EVENT_CR3 21
#define HVM_PARAM_MEMORY_EVENT_CR4 22
#define HVM_PARAM_MEMORY_EVENT_INT3 23
#define HVM_PARAM_NESTEDHVM 24
#define HVM_PARAM_MEMORY_EVENT_SINGLE_STEP 25
#define HVM_PARAM_BUFIOREQ_EVTCHN 26
#define HVM_PARAM_MEMORY_EVENT_MSR 30

#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */

/*
* 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?
*
* 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]
*/

#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
* xenbus implementations.
*/
#define HVM_PARAM_STORE_PFN 1
#define HVM_PARAM_STORE_EVTCHN 2

#define HVM_PARAM_IOREQ_PFN 5

#define HVM_PARAM_BUFIOREQ_PFN 6

#if defined(__i386__) || defined(__x86_64__)

/*
* Viridian enlightenments
*
* (See http://download.microsoft.com/download/A/B/4/AB43A34E-BDD0-4FA6-BDEF-79EEF16E880B/Hypervisor%20Top%20Level%20Functional%20Specification%20v4.0.docx)
*
* To expose viridian enlightenments to the guest set this parameter
* to the desired feature mask. The base feature set must be present
* in any valid feature mask.
*/
#define HVM_PARAM_VIRIDIAN 9

/* Base+Freq viridian feature sets:
*
* - Hypercall MSRs (HV_X64_MSR_GUEST_OS_ID and HV_X64_MSR_HYPERCALL)
* - APIC access MSRs (HV_X64_MSR_EOI, HV_X64_MSR_ICR and HV_X64_MSR_TPR)
* - Virtual Processor index MSR (HV_X64_MSR_VP_INDEX)
* - Timer frequency MSRs (HV_X64_MSR_TSC_FREQUENCY and
* HV_X64_MSR_APIC_FREQUENCY)
*/
#define _HVMPV_base_freq 0
#define HVMPV_base_freq (1 << _HVMPV_base_freq)

/* Feature set modifications */

/* Disable timer frequency MSRs (HV_X64_MSR_TSC_FREQUENCY and
* HV_X64_MSR_APIC_FREQUENCY).
* This modification restores the viridian feature set to the
* original 'base' set exposed in releases prior to Xen 4.4.
*/
#define _HVMPV_no_freq 1
#define HVMPV_no_freq (1 << _HVMPV_no_freq)

/* Enable Partition Time Reference Counter (HV_X64_MSR_TIME_REF_COUNT) */
#define _HVMPV_time_ref_count 2
#define HVMPV_time_ref_count (1 << _HVMPV_time_ref_count)

/* Enable Reference TSC Page (HV_X64_MSR_REFERENCE_TSC) */
#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)

/* Enable SYNIC MSRs */
#define _HVMPV_synic 7
#define HVMPV_synic (1 << _HVMPV_synic)

/* Enable STIMER MSRs */
#define _HVMPV_stimer 8
#define HVMPV_stimer (1 << _HVMPV_stimer)

/* Use Synthetic Cluster IPI Hypercall */
#define _HVMPV_hcall_ipi 9
#define HVMPV_hcall_ipi (1 << _HVMPV_hcall_ipi)

/* Enable ExProcessorMasks */
#define _HVMPV_ex_processor_masks 10
#define HVMPV_ex_processor_masks (1 << _HVMPV_ex_processor_masks)

/* Allow more than 64 VPs */
#define _HVMPV_no_vp_limit 11
#define HVMPV_no_vp_limit (1 << _HVMPV_no_vp_limit)

/* Enable vCPU hotplug */
#define _HVMPV_cpu_hotplug 12
#define HVMPV_cpu_hotplug (1 << _HVMPV_cpu_hotplug)

#define HVMPV_feature_mask \
(HVMPV_base_freq | \
HVMPV_no_freq | \
HVMPV_time_ref_count | \
HVMPV_reference_tsc | \
HVMPV_hcall_remote_tlb_flush | \
HVMPV_apic_assist | \
HVMPV_crash_ctl | \
HVMPV_synic | \
HVMPV_stimer | \
HVMPV_hcall_ipi | \
HVMPV_ex_processor_masks | \
HVMPV_no_vp_limit | \
HVMPV_cpu_hotplug)

#endif

/*
* Set mode for virtual timers (currently x86 only):
* delay_for_missed_ticks (default):
* Do not advance a vcpu's time beyond the correct delivery time for
* interrupts that have been missed due to preemption. Deliver missed
* interrupts when the vcpu is rescheduled and advance the vcpu's virtual
* time stepwise for each one.
* no_delay_for_missed_ticks:
* As above, missed interrupts are delivered, but guest time always tracks
* wallclock (i.e., real) time while doing so.
* no_missed_ticks_pending:
* No missed interrupts are held pending. Instead, to ensure ticks are
* delivered at some non-zero rate, if we detect missed ticks then the
* internal tick alarm is not disabled if the VCPU is preempted during the
* next tick period.
* one_missed_tick_pending:
* Missed interrupts are collapsed together and delivered as one 'late tick'.
* Guest time always tracks wallclock (i.e., real) time.
*/
#define HVM_PARAM_TIMER_MODE 10
#define HVMPTM_delay_for_missed_ticks 0
#define HVMPTM_no_delay_for_missed_ticks 1
#define HVMPTM_no_missed_ticks_pending 2
#define HVMPTM_one_missed_tick_pending 3

/* Boolean: Enable virtual HPET (high-precision event timer)? (x86-only) */
#define HVM_PARAM_HPET_ENABLED 11

/* Identity-map page directory used by Intel EPT when CR0.PG=0. */
#define HVM_PARAM_IDENT_PT 12

/* ACPI S state: currently support S0 and S3 on x86. */
#define HVM_PARAM_ACPI_S_STATE 14

/* TSS used on Intel when CR0.PE=0. */
#define HVM_PARAM_VM86_TSS 15

/* Boolean: Enable aligning all periodic vpts to reduce interrupts */
#define HVM_PARAM_VPT_ALIGN 16

/* Console debug shared memory ring and event channel */
#define HVM_PARAM_CONSOLE_PFN 17
#define HVM_PARAM_CONSOLE_EVTCHN 18

/*
* Select location of ACPI PM1a and TMR control blocks. Currently two locations
* are supported, specified by version 0 or 1 in this parameter:
* - 0: default, use the old addresses
* PM1A_EVT == 0x1f40; PM1A_CNT == 0x1f44; PM_TMR == 0x1f48
* - 1: use the new default qemu addresses
* PM1A_EVT == 0xb000; PM1A_CNT == 0xb004; PM_TMR == 0xb008
* You can find these address definitions in <hvm/ioreq.h>
*/
#define HVM_PARAM_ACPI_IOPORTS_LOCATION 19

/* Params for the mem event rings */
#define HVM_PARAM_PAGING_RING_PFN 27
#define HVM_PARAM_MONITOR_RING_PFN 28
#define HVM_PARAM_SHARING_RING_PFN 29

/* SHUTDOWN_* action in case of a triple fault */
#define HVM_PARAM_TRIPLE_FAULT_REASON 31

#define HVM_PARAM_IOREQ_SERVER_PFN 32
#define HVM_PARAM_NR_IOREQ_SERVER_PAGES 33

/* Location of the VM Generation ID in guest physical address space. */
#define HVM_PARAM_VM_GENERATION_ID_ADDR 34

/*
* 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)
*
* Note that 'mixed' mode has not been evaluated for safety from a
* security perspective. Before using this mode in a
* security-critical environment, each subop should be evaluated for
* safety, with unsafe subops blacklisted in XSM.
*/
#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__ */
14 changes: 12 additions & 2 deletions include/hw/xen/interface/io/blkif.h
Expand Up @@ -118,7 +118,7 @@
*
* The underlying storage is not affected by the direct IO memory
* lifetime bug. See:
* http://lists.xen.org/archives/html/xen-devel/2012-12/msg01154.html
* https://lists.xen.org/archives/html/xen-devel/2012-12/msg01154.html
*
* Therefore this option gives the backend permission to use
* O_DIRECT, notwithstanding that bug.
Expand Down Expand Up @@ -341,7 +341,7 @@
* access (even when it should be read-only). If the frontend hits the
* maximum number of allowed persistently mapped grants, it can fallback
* to non persistent mode. This will cause a performance degradation,
* since the backend driver will still try to map those grants
* since the the backend driver will still try to map those grants
* persistently. Since the persistent grants protocol is compatible with
* the previous protocol, a frontend driver can choose to work in
* persistent mode even when the backend doesn't support it.
Expand Down Expand Up @@ -710,3 +710,13 @@ DEFINE_RING_TYPES(blkif, struct blkif_request, struct blkif_response);
#define VDISK_READONLY 0x4

#endif /* __XEN_PUBLIC_IO_BLKIF_H__ */

/*
* Local variables:
* mode: C
* c-file-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
10 changes: 10 additions & 0 deletions include/hw/xen/interface/io/console.h
Expand Up @@ -44,3 +44,13 @@ DEFINE_XEN_FLEX_RING(xencons);
#endif

#endif /* __XEN_PUBLIC_IO_CONSOLE_H__ */

/*
* Local variables:
* mode: C
* c-file-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
20 changes: 20 additions & 0 deletions include/hw/xen/interface/io/fbif.h
Expand Up @@ -153,4 +153,24 @@ struct xenfb_page
unsigned long pd[256];
};

/*
* Wart: xenkbd needs to know default resolution. Put it here until a
* better solution is found, but don't leak it to the backend.
*/
#ifdef __KERNEL__
#define XENFB_WIDTH 800
#define XENFB_HEIGHT 600
#define XENFB_DEPTH 32
#endif

#endif

/*
* Local variables:
* mode: C
* c-file-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
10 changes: 10 additions & 0 deletions include/hw/xen/interface/io/kbdif.h
Expand Up @@ -564,3 +564,13 @@ struct xenkbd_page
};

#endif /* __XEN_PUBLIC_IO_KBDIF_H__ */

/*
* Local variables:
* mode: C
* c-file-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
94 changes: 93 additions & 1 deletion include/hw/xen/interface/io/netif.h
Expand Up @@ -171,7 +171,7 @@
* The ability of the backend to use a control ring is advertised by
* setting:
*
* /local/domain/X/backend/<domid>/<vif>/feature-ctrl-ring = "1"
* /local/domain/X/backend/vif/<domid>/<vif>/feature-ctrl-ring = "1"
*
* The frontend provides a control ring to the backend by setting:
*
Expand All @@ -190,6 +190,32 @@
* order as requests.
*/

/*
* Link state
* ==========
*
* The backend can advertise its current link (carrier) state to the
* frontend using the /local/domain/X/backend/vif/<domid>/<vif>/carrier
* node. If this node is not present, then the frontend should assume that
* the link is up (for compatibility with backends that do not implement
* this feature). If this node is present, then a value of "0" should be
* interpreted by the frontend as the link being down (no carrier) and a
* value of "1" should be interpreted as the link being up (carrier
* present).
*/

/*
* MTU
* ===
*
* The toolstack may set a value of MTU for the frontend by setting the
* /local/domain/<domid>/device/vif/<vif>/mtu node with the MTU value in
* octets. If this node is absent the frontend should assume an MTU value
* of 1500 octets. A frontend is also at liberty to ignore this value so
* it is only suitable for informing the frontend that a packet payload
* >1500 octets is permitted.
*/

/*
* Hash types
* ==========
Expand Down Expand Up @@ -267,6 +293,62 @@

#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)
* ================================================
Expand Down Expand Up @@ -1008,3 +1090,13 @@ DEFINE_RING_TYPES(netif_rx, struct netif_rx_request, struct netif_rx_response);
#define NETIF_RSP_NULL 1

#endif

/*
* Local variables:
* mode: C
* c-file-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
99 changes: 60 additions & 39 deletions include/hw/xen/interface/io/ring.h
@@ -1,6 +1,6 @@
/******************************************************************************
* ring.h
*
*
* Shared producer-consumer ring macros.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
Expand Down Expand Up @@ -33,13 +33,6 @@
* - standard integers types (uint8_t, uint16_t, etc)
* They are provided by stdint.h of the standard headers.
*
* Before using the different macros, you need to provide the following
* macros:
* - xen_mb() a memory barrier
* - xen_rmb() a read memory barrier
* - xen_wmb() a write memory barrier
* Example of those can be found in xenctrl.h.
*
* In addition, if you intend to use the FLEX macros, you also need to
* provide the following, before invoking the FLEX macros:
* - size_t
Expand All @@ -49,6 +42,14 @@
* and grant_table.h from the Xen public headers.
*/

#include "../xen-compat.h"

#if __XEN_INTERFACE_VERSION__ < 0x00030208
#define xen_mb() mb()
#define xen_rmb() rmb()
#define xen_wmb() wmb()
#endif

typedef unsigned int RING_IDX;

/* Round a 32-bit unsigned constant down to the nearest power of two. */
Expand All @@ -61,12 +62,12 @@ typedef unsigned int RING_IDX;
/*
* Calculate size of a shared ring, given the total available space for the
* ring and indexes (_sz), and the name tag of the request/response structure.
* A ring contains as many entries as will fit, rounded down to the nearest
* A ring contains as many entries as will fit, rounded down to the nearest
* power of two (so we can mask with (size-1) to loop around).
*/
#define __CONST_RING_SIZE(_s, _sz) \
(__RD32(((_sz) - offsetof(struct _s##_sring, ring)) / \
sizeof_field(struct _s##_sring, ring[0])))
sizeof(((struct _s##_sring *)0)->ring[0])))
/*
* The same for passing in an actual pointer instead of a name tag.
*/
Expand All @@ -75,7 +76,7 @@ typedef unsigned int RING_IDX;

/*
* Macros to make the correct C datatypes for a new kind of ring.
*
*
* To make a new ring datatype, you need to have two message structures,
* let's say request_t, and response_t already defined.
*
Expand All @@ -85,7 +86,7 @@ typedef unsigned int RING_IDX;
*
* These expand out to give you a set of types, as you can see below.
* The most important of these are:
*
*
* mytag_sring_t - The shared ring.
* mytag_front_ring_t - The 'front' half of the ring.
* mytag_back_ring_t - The 'back' half of the ring.
Expand Down Expand Up @@ -153,15 +154,15 @@ typedef struct __name##_back_ring __name##_back_ring_t

/*
* Macros for manipulating rings.
*
* FRONT_RING_whatever works on the "front end" of a ring: here
*
* FRONT_RING_whatever works on the "front end" of a ring: here
* requests are pushed on to the ring and responses taken off it.
*
* BACK_RING_whatever works on the "back end" of a ring: here
*
* BACK_RING_whatever works on the "back end" of a ring: here
* requests are taken off the ring and responses put on.
*
* N.B. these macros do NO INTERLOCKS OR FLOW CONTROL.
* This is OK in 1-for-1 request-response situations where the
*
* N.B. these macros do NO INTERLOCKS OR FLOW CONTROL.
* This is OK in 1-for-1 request-response situations where the
* requestor (front end) never has more than RING_SIZE()-1
* outstanding requests.
*/
Expand All @@ -174,20 +175,24 @@ typedef struct __name##_back_ring __name##_back_ring_t
(void)memset((_s)->__pad, 0, sizeof((_s)->__pad)); \
} while(0)

#define FRONT_RING_INIT(_r, _s, __size) do { \
(_r)->req_prod_pvt = 0; \
(_r)->rsp_cons = 0; \
#define FRONT_RING_ATTACH(_r, _s, _i, __size) do { \
(_r)->req_prod_pvt = (_i); \
(_r)->rsp_cons = (_i); \
(_r)->nr_ents = __RING_SIZE(_s, __size); \
(_r)->sring = (_s); \
} while (0)

#define BACK_RING_INIT(_r, _s, __size) do { \
(_r)->rsp_prod_pvt = 0; \
(_r)->req_cons = 0; \
#define FRONT_RING_INIT(_r, _s, __size) FRONT_RING_ATTACH(_r, _s, 0, __size)

#define BACK_RING_ATTACH(_r, _s, _i, __size) do { \
(_r)->rsp_prod_pvt = (_i); \
(_r)->req_cons = (_i); \
(_r)->nr_ents = __RING_SIZE(_s, __size); \
(_r)->sring = (_s); \
} while (0)

#define BACK_RING_INIT(_r, _s, __size) BACK_RING_ATTACH(_r, _s, 0, __size)

/* How big is this ring? */
#define RING_SIZE(_r) \
((_r)->nr_ents)
Expand All @@ -206,33 +211,45 @@ typedef struct __name##_back_ring __name##_back_ring_t
#define RING_HAS_UNCONSUMED_RESPONSES(_r) \
((_r)->sring->rsp_prod - (_r)->rsp_cons)

#ifdef __GNUC__
#define RING_HAS_UNCONSUMED_REQUESTS(_r) ({ \
unsigned int req = (_r)->sring->req_prod - (_r)->req_cons; \
unsigned int rsp = RING_SIZE(_r) - \
((_r)->req_cons - (_r)->rsp_prod_pvt); \
req < rsp ? req : rsp; \
})
#else
/* Same as above, but without the nice GCC ({ ... }) syntax. */
#define RING_HAS_UNCONSUMED_REQUESTS(_r) \
((((_r)->sring->req_prod - (_r)->req_cons) < \
(RING_SIZE(_r) - ((_r)->req_cons - (_r)->rsp_prod_pvt))) ? \
((_r)->sring->req_prod - (_r)->req_cons) : \
(RING_SIZE(_r) - ((_r)->req_cons - (_r)->rsp_prod_pvt)))
#endif

/* Direct access to individual ring elements, by index. */
#define RING_GET_REQUEST(_r, _idx) \
(&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].req))

#define RING_GET_RESPONSE(_r, _idx) \
(&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].rsp))

/*
* Get a local copy of a request.
* Get a local copy of a request/response.
*
* Use this in preference to RING_GET_REQUEST() so all processing is
* Use this in preference to RING_GET_{REQUEST,RESPONSE}() 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.
* to be ineffective where dest 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); \
#define RING_COPY_(type, r, idx, dest) do { \
/* Use volatile to force the copy into dest. */ \
*(dest) = *(volatile __typeof__(dest))RING_GET_##type(r, idx); \
} while (0)

#define RING_GET_RESPONSE(_r, _idx) \
(&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].rsp))
#define RING_COPY_REQUEST(r, idx, req) RING_COPY_(REQUEST, r, idx, req)
#define RING_COPY_RESPONSE(r, idx, rsp) RING_COPY_(RESPONSE, r, idx, rsp)

/* Loop termination condition: Would the specified index overflow the ring? */
#define RING_REQUEST_CONS_OVERFLOW(_r, _cons) \
Expand All @@ -242,6 +259,10 @@ typedef struct __name##_back_ring __name##_back_ring_t
#define RING_REQUEST_PROD_OVERFLOW(_r, _prod) \
(((_prod) - (_r)->rsp_prod_pvt) > RING_SIZE(_r))

/* Ill-behaved backend determination: Can there be this many responses? */
#define RING_RESPONSE_PROD_OVERFLOW(_r, _prod) \
(((_prod) - (_r)->rsp_cons) > RING_SIZE(_r))

#define RING_PUSH_REQUESTS(_r) do { \
xen_wmb(); /* back sees requests /before/ updated producer index */ \
(_r)->sring->req_prod = (_r)->req_prod_pvt; \
Expand All @@ -254,26 +275,26 @@ typedef struct __name##_back_ring __name##_back_ring_t

/*
* Notification hold-off (req_event and rsp_event):
*
*
* When queueing requests or responses on a shared ring, it may not always be
* necessary to notify the remote end. For example, if requests are in flight
* in a backend, the front may be able to queue further requests without
* notifying the back (if the back checks for new requests when it queues
* responses).
*
*
* When enqueuing requests or responses:
*
*
* Use RING_PUSH_{REQUESTS,RESPONSES}_AND_CHECK_NOTIFY(). The second argument
* is a boolean return value. True indicates that the receiver requires an
* asynchronous notification.
*
*
* After dequeuing requests or responses (before sleeping the connection):
*
*
* Use RING_FINAL_CHECK_FOR_REQUESTS() or RING_FINAL_CHECK_FOR_RESPONSES().
* The second argument is a boolean return value. True indicates that there
* are pending messages on the ring (i.e., the connection should not be put
* to sleep).
*
*
* These macros will set the req_event/rsp_event field to trigger a
* notification on the very next message that is enqueued. If you want to
* create batches of work (i.e., only receive a notification after several
Expand Down
377 changes: 274 additions & 103 deletions include/hw/xen/interface/io/usbif.h

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions include/hw/xen/interface/io/xenbus.h
Expand Up @@ -68,3 +68,13 @@ enum xenbus_state {
typedef enum xenbus_state XenbusState;

#endif /* _XEN_PUBLIC_IO_XENBUS_H */

/*
* Local variables:
* mode: C
* c-file-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
153 changes: 153 additions & 0 deletions include/hw/xen/interface/io/xs_wire.h
@@ -0,0 +1,153 @@
/*
* Details of the "wire" protocol between Xen Store Daemon and client
* library or guest kernel.
*
* 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) 2005 Rusty Russell IBM Corporation
*/

#ifndef _XS_WIRE_H
#define _XS_WIRE_H

enum xsd_sockmsg_type
{
XS_CONTROL,
#define XS_DEBUG XS_CONTROL
XS_DIRECTORY,
XS_READ,
XS_GET_PERMS,
XS_WATCH,
XS_UNWATCH,
XS_TRANSACTION_START,
XS_TRANSACTION_END,
XS_INTRODUCE,
XS_RELEASE,
XS_GET_DOMAIN_PATH,
XS_WRITE,
XS_MKDIR,
XS_RM,
XS_SET_PERMS,
XS_WATCH_EVENT,
XS_ERROR,
XS_IS_DOMAIN_INTRODUCED,
XS_RESUME,
XS_SET_TARGET,
/* 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 */
};

#define XS_WRITE_NONE "NONE"
#define XS_WRITE_CREATE "CREATE"
#define XS_WRITE_CREATE_EXCL "CREATE|EXCL"

/* We hand errors as strings, for portability. */
struct xsd_errors
{
int errnum;
const char *errstring;
};
#ifdef EINVAL
#define XSD_ERROR(x) { x, #x }
/* LINTED: static unused */
static struct xsd_errors xsd_errors[]
#if defined(__GNUC__)
__attribute__((unused))
#endif
= {
XSD_ERROR(EINVAL),
XSD_ERROR(EACCES),
XSD_ERROR(EEXIST),
XSD_ERROR(EISDIR),
XSD_ERROR(ENOENT),
XSD_ERROR(ENOMEM),
XSD_ERROR(ENOSPC),
XSD_ERROR(EIO),
XSD_ERROR(ENOTEMPTY),
XSD_ERROR(ENOSYS),
XSD_ERROR(EROFS),
XSD_ERROR(EBUSY),
XSD_ERROR(EAGAIN),
XSD_ERROR(EISCONN),
XSD_ERROR(E2BIG)
};
#endif

struct xsd_sockmsg
{
uint32_t type; /* XS_??? */
uint32_t req_id;/* Request identifier, echoed in daemon's response. */
uint32_t tx_id; /* Transaction id (0 if not related to a transaction). */
uint32_t len; /* Length of data following this. */

/* Generally followed by nul-terminated string(s). */
};

enum xs_watch_type
{
XS_WATCH_PATH = 0,
XS_WATCH_TOKEN
};

/*
* `incontents 150 xenstore_struct XenStore wire protocol.
*
* Inter-domain shared memory communications. */
#define XENSTORE_RING_SIZE 1024
typedef uint32_t XENSTORE_RING_IDX;
#define MASK_XENSTORE_IDX(idx) ((idx) & (XENSTORE_RING_SIZE-1))
struct xenstore_domain_interface {
char req[XENSTORE_RING_SIZE]; /* Requests to xenstore daemon. */
char rsp[XENSTORE_RING_SIZE]; /* Replies and async watch events. */
XENSTORE_RING_IDX req_cons, req_prod;
XENSTORE_RING_IDX rsp_cons, rsp_prod;
uint32_t server_features; /* Bitmap of features supported by the server */
uint32_t connection;
};

/* Violating this is very bad. See docs/misc/xenstore.txt. */
#define XENSTORE_PAYLOAD_MAX 4096

/* Violating these just gets you an error back */
#define XENSTORE_ABS_PATH_MAX 3072
#define XENSTORE_REL_PATH_MAX 2048

/* The ability to reconnect a ring */
#define XENSTORE_SERVER_FEATURE_RECONNECTION 1

/* Valid values for the connection field */
#define XENSTORE_CONNECTED 0 /* the steady-state */
#define XENSTORE_RECONNECT 1 /* guest has initiated a reconnect */

#endif /* _XS_WIRE_H */

/*
* Local variables:
* mode: C
* c-file-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
754 changes: 754 additions & 0 deletions include/hw/xen/interface/memory.h

Large diffs are not rendered by default.

383 changes: 383 additions & 0 deletions include/hw/xen/interface/physdev.h
@@ -0,0 +1,383 @@
/*
* 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) 2006, Keir Fraser
*/

#ifndef __XEN_PUBLIC_PHYSDEV_H__
#define __XEN_PUBLIC_PHYSDEV_H__

#include "xen.h"

/*
* Prototype for this hypercall is:
* int physdev_op(int cmd, void *args)
* @cmd == PHYSDEVOP_??? (physdev operation).
* @args == Operation-specific extra arguments (NULL if none).
*/

/*
* Notify end-of-interrupt (EOI) for the specified IRQ.
* @arg == pointer to physdev_eoi structure.
*/
#define PHYSDEVOP_eoi 12
struct physdev_eoi {
/* IN */
uint32_t irq;
};
typedef struct physdev_eoi physdev_eoi_t;
DEFINE_XEN_GUEST_HANDLE(physdev_eoi_t);

/*
* Register a shared page for the hypervisor to indicate whether the guest
* must issue PHYSDEVOP_eoi. The semantics of PHYSDEVOP_eoi change slightly
* once the guest used this function in that the associated event channel
* will automatically get unmasked. The page registered is used as a bit
* array indexed by Xen's PIRQ value.
*/
#define PHYSDEVOP_pirq_eoi_gmfn_v1 17
/*
* Register a shared page for the hypervisor to indicate whether the
* guest must issue PHYSDEVOP_eoi. This hypercall is very similar to
* PHYSDEVOP_pirq_eoi_gmfn_v1 but it doesn't change the semantics of
* PHYSDEVOP_eoi. The page registered is used as a bit array indexed by
* Xen's PIRQ value.
*/
#define PHYSDEVOP_pirq_eoi_gmfn_v2 28
struct physdev_pirq_eoi_gmfn {
/* IN */
xen_pfn_t gmfn;
};
typedef struct physdev_pirq_eoi_gmfn physdev_pirq_eoi_gmfn_t;
DEFINE_XEN_GUEST_HANDLE(physdev_pirq_eoi_gmfn_t);

/*
* Query the status of an IRQ line.
* @arg == pointer to physdev_irq_status_query structure.
*/
#define PHYSDEVOP_irq_status_query 5
struct physdev_irq_status_query {
/* IN */
uint32_t irq;
/* OUT */
uint32_t flags; /* XENIRQSTAT_* */
};
typedef struct physdev_irq_status_query physdev_irq_status_query_t;
DEFINE_XEN_GUEST_HANDLE(physdev_irq_status_query_t);

/* Need to call PHYSDEVOP_eoi when the IRQ has been serviced? */
#define _XENIRQSTAT_needs_eoi (0)
#define XENIRQSTAT_needs_eoi (1U<<_XENIRQSTAT_needs_eoi)

/* IRQ shared by multiple guests? */
#define _XENIRQSTAT_shared (1)
#define XENIRQSTAT_shared (1U<<_XENIRQSTAT_shared)

/*
* Set the current VCPU's I/O privilege level.
* @arg == pointer to physdev_set_iopl structure.
*/
#define PHYSDEVOP_set_iopl 6
struct physdev_set_iopl {
/* IN */
uint32_t iopl;
};
typedef struct physdev_set_iopl physdev_set_iopl_t;
DEFINE_XEN_GUEST_HANDLE(physdev_set_iopl_t);

/*
* Set the current VCPU's I/O-port permissions bitmap.
* @arg == pointer to physdev_set_iobitmap structure.
*/
#define PHYSDEVOP_set_iobitmap 7
struct physdev_set_iobitmap {
/* IN */
#if __XEN_INTERFACE_VERSION__ >= 0x00030205
XEN_GUEST_HANDLE(uint8) bitmap;
#else
uint8_t *bitmap;
#endif
uint32_t nr_ports;
};
typedef struct physdev_set_iobitmap physdev_set_iobitmap_t;
DEFINE_XEN_GUEST_HANDLE(physdev_set_iobitmap_t);

/*
* Read or write an IO-APIC register.
* @arg == pointer to physdev_apic structure.
*/
#define PHYSDEVOP_apic_read 8
#define PHYSDEVOP_apic_write 9
struct physdev_apic {
/* IN */
unsigned long apic_physbase;
uint32_t reg;
/* IN or OUT */
uint32_t value;
};
typedef struct physdev_apic physdev_apic_t;
DEFINE_XEN_GUEST_HANDLE(physdev_apic_t);

/*
* Allocate or free a physical upcall vector for the specified IRQ line.
* @arg == pointer to physdev_irq structure.
*/
#define PHYSDEVOP_alloc_irq_vector 10
#define PHYSDEVOP_free_irq_vector 11
struct physdev_irq {
/* IN */
uint32_t irq;
/* IN or OUT */
uint32_t vector;
};
typedef struct physdev_irq physdev_irq_t;
DEFINE_XEN_GUEST_HANDLE(physdev_irq_t);

#define MAP_PIRQ_TYPE_MSI 0x0
#define MAP_PIRQ_TYPE_GSI 0x1
#define MAP_PIRQ_TYPE_UNKNOWN 0x2
#define MAP_PIRQ_TYPE_MSI_SEG 0x3
#define MAP_PIRQ_TYPE_MULTI_MSI 0x4

#define PHYSDEVOP_map_pirq 13
struct physdev_map_pirq {
domid_t domid;
/* IN */
int type;
/* IN (ignored for ..._MULTI_MSI) */
int index;
/* IN or OUT */
int pirq;
/* IN - high 16 bits hold segment for ..._MSI_SEG and ..._MULTI_MSI */
int bus;
/* IN */
int devfn;
/* IN (also OUT for ..._MULTI_MSI) */
int entry_nr;
/* IN */
uint64_t table_base;
};
typedef struct physdev_map_pirq physdev_map_pirq_t;
DEFINE_XEN_GUEST_HANDLE(physdev_map_pirq_t);

#define PHYSDEVOP_unmap_pirq 14
struct physdev_unmap_pirq {
domid_t domid;
/* IN */
int pirq;
};

typedef struct physdev_unmap_pirq physdev_unmap_pirq_t;
DEFINE_XEN_GUEST_HANDLE(physdev_unmap_pirq_t);

#define PHYSDEVOP_manage_pci_add 15
#define PHYSDEVOP_manage_pci_remove 16
struct physdev_manage_pci {
/* IN */
uint8_t bus;
uint8_t devfn;
};

typedef struct physdev_manage_pci physdev_manage_pci_t;
DEFINE_XEN_GUEST_HANDLE(physdev_manage_pci_t);

#define PHYSDEVOP_restore_msi 19
struct physdev_restore_msi {
/* IN */
uint8_t bus;
uint8_t devfn;
};
typedef struct physdev_restore_msi physdev_restore_msi_t;
DEFINE_XEN_GUEST_HANDLE(physdev_restore_msi_t);

#define PHYSDEVOP_manage_pci_add_ext 20
struct physdev_manage_pci_ext {
/* IN */
uint8_t bus;
uint8_t devfn;
unsigned is_extfn;
unsigned is_virtfn;
struct {
uint8_t bus;
uint8_t devfn;
} physfn;
};

typedef struct physdev_manage_pci_ext physdev_manage_pci_ext_t;
DEFINE_XEN_GUEST_HANDLE(physdev_manage_pci_ext_t);

/*
* Argument to physdev_op_compat() hypercall. Superceded by new physdev_op()
* hypercall since 0x00030202.
*/
struct physdev_op {
uint32_t cmd;
union {
physdev_irq_status_query_t irq_status_query;
physdev_set_iopl_t set_iopl;
physdev_set_iobitmap_t set_iobitmap;
physdev_apic_t apic_op;
physdev_irq_t irq_op;
} u;
};
typedef struct physdev_op physdev_op_t;
DEFINE_XEN_GUEST_HANDLE(physdev_op_t);

#define PHYSDEVOP_setup_gsi 21
struct physdev_setup_gsi {
int gsi;
/* IN */
uint8_t triggering;
/* IN */
uint8_t polarity;
/* IN */
};

typedef struct physdev_setup_gsi physdev_setup_gsi_t;
DEFINE_XEN_GUEST_HANDLE(physdev_setup_gsi_t);

/* leave PHYSDEVOP 22 free */

/* type is MAP_PIRQ_TYPE_GSI or MAP_PIRQ_TYPE_MSI
* the hypercall returns a free pirq */
#define PHYSDEVOP_get_free_pirq 23
struct physdev_get_free_pirq {
/* IN */
int type;
/* OUT */
uint32_t pirq;
};

typedef struct physdev_get_free_pirq physdev_get_free_pirq_t;
DEFINE_XEN_GUEST_HANDLE(physdev_get_free_pirq_t);

#define XEN_PCI_MMCFG_RESERVED 0x1

#define PHYSDEVOP_pci_mmcfg_reserved 24
struct physdev_pci_mmcfg_reserved {
uint64_t address;
uint16_t segment;
uint8_t start_bus;
uint8_t end_bus;
uint32_t flags;
};
typedef struct physdev_pci_mmcfg_reserved physdev_pci_mmcfg_reserved_t;
DEFINE_XEN_GUEST_HANDLE(physdev_pci_mmcfg_reserved_t);

#define XEN_PCI_DEV_EXTFN 0x1
#define XEN_PCI_DEV_VIRTFN 0x2
#define XEN_PCI_DEV_PXM 0x4

#define PHYSDEVOP_pci_device_add 25
struct physdev_pci_device_add {
/* IN */
uint16_t seg;
uint8_t bus;
uint8_t devfn;
uint32_t flags;
struct {
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)
*/
uint32_t optarr[XEN_FLEX_ARRAY_DIM];
};
typedef struct physdev_pci_device_add physdev_pci_device_add_t;
DEFINE_XEN_GUEST_HANDLE(physdev_pci_device_add_t);

#define PHYSDEVOP_pci_device_remove 26
#define PHYSDEVOP_restore_msi_ext 27
/*
* Dom0 should use these two to announce MMIO resources assigned to
* MSI-X capable devices won't (prepare) or may (release) change.
*/
#define PHYSDEVOP_prepare_msix 30
#define PHYSDEVOP_release_msix 31
struct physdev_pci_device {
/* IN */
uint16_t seg;
uint8_t bus;
uint8_t devfn;
};
typedef struct physdev_pci_device physdev_pci_device_t;
DEFINE_XEN_GUEST_HANDLE(physdev_pci_device_t);

#define PHYSDEVOP_DBGP_RESET_PREPARE 1
#define PHYSDEVOP_DBGP_RESET_DONE 2

#define PHYSDEVOP_DBGP_BUS_UNKNOWN 0
#define PHYSDEVOP_DBGP_BUS_PCI 1

#define PHYSDEVOP_dbgp_op 29
struct physdev_dbgp_op {
/* IN */
uint8_t op;
uint8_t bus;
union {
physdev_pci_device_t pci;
} u;
};
typedef struct physdev_dbgp_op physdev_dbgp_op_t;
DEFINE_XEN_GUEST_HANDLE(physdev_dbgp_op_t);

/*
* Notify that some PIRQ-bound event channels have been unmasked.
* ** This command is obsolete since interface version 0x00030202 and is **
* ** unsupported by newer versions of Xen. **
*/
#define PHYSDEVOP_IRQ_UNMASK_NOTIFY 4

#if __XEN_INTERFACE_VERSION__ < 0x00040600
/*
* These all-capitals physdev operation names are superceded by the new names
* (defined above) since interface version 0x00030202. The guard above was
* added post-4.5 only though and hence shouldn't check for 0x00030202.
*/
#define PHYSDEVOP_IRQ_STATUS_QUERY PHYSDEVOP_irq_status_query
#define PHYSDEVOP_SET_IOPL PHYSDEVOP_set_iopl
#define PHYSDEVOP_SET_IOBITMAP PHYSDEVOP_set_iobitmap
#define PHYSDEVOP_APIC_READ PHYSDEVOP_apic_read
#define PHYSDEVOP_APIC_WRITE PHYSDEVOP_apic_write
#define PHYSDEVOP_ASSIGN_VECTOR PHYSDEVOP_alloc_irq_vector
#define PHYSDEVOP_FREE_VECTOR PHYSDEVOP_free_irq_vector
#define PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY XENIRQSTAT_needs_eoi
#define PHYSDEVOP_IRQ_SHARED XENIRQSTAT_shared
#endif

#if __XEN_INTERFACE_VERSION__ < 0x00040200
#define PHYSDEVOP_pirq_eoi_gmfn PHYSDEVOP_pirq_eoi_gmfn_v1
#else
#define PHYSDEVOP_pirq_eoi_gmfn PHYSDEVOP_pirq_eoi_gmfn_v2
#endif

#endif /* __XEN_PUBLIC_PHYSDEV_H__ */

/*
* Local variables:
* mode: C
* c-file-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
202 changes: 202 additions & 0 deletions include/hw/xen/interface/sched.h
@@ -0,0 +1,202 @@
/******************************************************************************
* sched.h
*
* Scheduler state interactions
*
* 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) 2005, Keir Fraser <keir@xensource.com>
*/

#ifndef __XEN_PUBLIC_SCHED_H__
#define __XEN_PUBLIC_SCHED_H__

#include "event_channel.h"

/*
* `incontents 150 sched Guest Scheduler Operations
*
* The SCHEDOP interface provides mechanisms for a guest to interact
* with the scheduler, including yield, blocking and shutting itself
* down.
*/

/*
* The prototype for this hypercall is:
* ` long HYPERVISOR_sched_op(enum sched_op cmd, void *arg, ...)
*
* @cmd == SCHEDOP_??? (scheduler operation).
* @arg == Operation-specific extra argument(s), as described below.
* ... == Additional Operation-specific extra arguments, described below.
*
* Versions of Xen prior to 3.0.2 provided only the following legacy version
* of this hypercall, supporting only the commands yield, block and shutdown:
* long sched_op(int cmd, unsigned long arg)
* @cmd == SCHEDOP_??? (scheduler operation).
* @arg == 0 (SCHEDOP_yield and SCHEDOP_block)
* == SHUTDOWN_* code (SCHEDOP_shutdown)
*
* This legacy version is available to new guests as:
* ` long HYPERVISOR_sched_op_compat(enum sched_op cmd, unsigned long arg)
*/

/* ` enum sched_op { // SCHEDOP_* => struct sched_* */
/*
* Voluntarily yield the CPU.
* @arg == NULL.
*/
#define SCHEDOP_yield 0

/*
* Block execution of this VCPU until an event is received for processing.
* If called with event upcalls masked, this operation will atomically
* reenable event delivery and check for pending events before blocking the
* VCPU. This avoids a "wakeup waiting" race.
* @arg == NULL.
*/
#define SCHEDOP_block 1

/*
* Halt execution of this domain (all VCPUs) and notify the system controller.
* @arg == pointer to sched_shutdown_t structure.
*
* If the sched_shutdown_t reason is SHUTDOWN_suspend then
* x86 PV guests must also set RDX (EDX for 32-bit guests) to the MFN
* of the guest's start info page. RDX/EDX is the third hypercall
* argument.
*
* In addition, which reason is SHUTDOWN_suspend this hypercall
* returns 1 if suspend was cancelled or the domain was merely
* checkpointed, and 0 if it is resuming in a new domain.
*/
#define SCHEDOP_shutdown 2

/*
* Poll a set of event-channel ports. Return when one or more are pending. An
* optional timeout may be specified.
* @arg == pointer to sched_poll_t structure.
*/
#define SCHEDOP_poll 3

/*
* Declare a shutdown for another domain. The main use of this function is
* in interpreting shutdown requests and reasons for fully-virtualized
* domains. A para-virtualized domain may use SCHEDOP_shutdown directly.
* @arg == pointer to sched_remote_shutdown_t structure.
*/
#define SCHEDOP_remote_shutdown 4

/*
* Latch a shutdown code, so that when the domain later shuts down it
* reports this code to the control tools.
* @arg == sched_shutdown_t, as for SCHEDOP_shutdown.
*/
#define SCHEDOP_shutdown_code 5

/*
* Setup, poke and destroy a domain watchdog timer.
* @arg == pointer to sched_watchdog_t structure.
* With id == 0, setup a domain watchdog timer to cause domain shutdown
* after timeout, returns watchdog id.
* With id != 0 and timeout == 0, destroy domain watchdog timer.
* 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 {
unsigned int reason; /* SHUTDOWN_* => enum sched_shutdown_reason */
};
typedef struct sched_shutdown sched_shutdown_t;
DEFINE_XEN_GUEST_HANDLE(sched_shutdown_t);

struct sched_poll {
XEN_GUEST_HANDLE(evtchn_port_t) ports;
unsigned int nr_ports;
uint64_t timeout;
};
typedef struct sched_poll sched_poll_t;
DEFINE_XEN_GUEST_HANDLE(sched_poll_t);

struct sched_remote_shutdown {
domid_t domain_id; /* Remote domain ID */
unsigned int reason; /* SHUTDOWN_* => enum sched_shutdown_reason */
};
typedef struct sched_remote_shutdown sched_remote_shutdown_t;
DEFINE_XEN_GUEST_HANDLE(sched_remote_shutdown_t);

struct sched_watchdog {
uint32_t id; /* watchdog ID */
uint32_t timeout; /* timeout */
};
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
* not care about the shutdown code.
*/
/* ` enum sched_shutdown_reason { */
#define SHUTDOWN_poweroff 0 /* Domain exited normally. Clean up and kill. */
#define SHUTDOWN_reboot 1 /* Clean up, kill, and then restart. */
#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. */

/*
* 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__ */

/*
* Local variables:
* mode: C
* c-file-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
341 changes: 341 additions & 0 deletions include/hw/xen/interface/trace.h
@@ -0,0 +1,341 @@
/******************************************************************************
* include/public/trace.h
*
* 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.
*
* Mark Williamson, (C) 2004 Intel Research Cambridge
* Copyright (C) 2005 Bin Ren
*/

#ifndef __XEN_PUBLIC_TRACE_H__
#define __XEN_PUBLIC_TRACE_H__

#define TRACE_EXTRA_MAX 7
#define TRACE_EXTRA_SHIFT 28

/* Trace classes */
#define TRC_CLS_SHIFT 16
#define TRC_GEN 0x0001f000 /* General trace */
#define TRC_SCHED 0x0002f000 /* Xen Scheduler trace */
#define TRC_DOM0OP 0x0004f000 /* Xen DOM0 operation trace */
#define TRC_HVM 0x0008f000 /* Xen HVM trace */
#define TRC_MEM 0x0010f000 /* Xen memory trace */
#define TRC_PV 0x0020f000 /* Xen PV traces */
#define TRC_SHADOW 0x0040f000 /* Xen shadow tracing */
#define TRC_HW 0x0080f000 /* Xen hardware-related traces */
#define TRC_GUEST 0x0800f000 /* Guest-generated traces */
#define TRC_ALL 0x0ffff000
#define TRC_HD_TO_EVENT(x) ((x)&0x0fffffff)
#define TRC_HD_CYCLE_FLAG (1UL<<31)
#define TRC_HD_INCLUDES_CYCLE_COUNT(x) ( !!( (x) & TRC_HD_CYCLE_FLAG ) )
#define TRC_HD_EXTRA(x) (((x)>>TRACE_EXTRA_SHIFT)&TRACE_EXTRA_MAX)

/* Trace subclasses */
#define TRC_SUBCLS_SHIFT 12

/* trace subclasses for SVM */
#define TRC_HVM_ENTRYEXIT 0x00081000 /* VMENTRY and #VMEXIT */
#define TRC_HVM_HANDLER 0x00082000 /* various HVM handlers */
#define TRC_HVM_EMUL 0x00084000 /* emulated devices */

#define TRC_SCHED_MIN 0x00021000 /* Just runstate changes */
#define TRC_SCHED_CLASS 0x00022000 /* Scheduler-specific */
#define TRC_SCHED_VERBOSE 0x00028000 /* More inclusive scheduling */

/*
* The highest 3 bits of the last 12 bits of TRC_SCHED_CLASS above are
* reserved for encoding what scheduler produced the information. The
* actual event is encoded in the last 9 bits.
*
* This means we have 8 scheduling IDs available (which means at most 8
* schedulers generating events) and, in each scheduler, up to 512
* different events.
*/
#define TRC_SCHED_ID_BITS 3
#define TRC_SCHED_ID_SHIFT (TRC_SUBCLS_SHIFT - TRC_SCHED_ID_BITS)
#define TRC_SCHED_ID_MASK (((1UL<<TRC_SCHED_ID_BITS) - 1) << TRC_SCHED_ID_SHIFT)
#define TRC_SCHED_EVT_MASK (~(TRC_SCHED_ID_MASK))

/* Per-scheduler IDs, to identify scheduler specific events */
#define TRC_SCHED_CSCHED 0
#define TRC_SCHED_CSCHED2 1
/* #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) \
( ( TRC_SCHED_CLASS | \
((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 */

/* Trace events per class */
#define TRC_LOST_RECORDS (TRC_GEN + 1)
#define TRC_TRACE_WRAP_BUFFER (TRC_GEN + 2)
#define TRC_TRACE_CPU_CHANGE (TRC_GEN + 3)

#define TRC_SCHED_RUNSTATE_CHANGE (TRC_SCHED_MIN + 1)
#define TRC_SCHED_CONTINUE_RUNNING (TRC_SCHED_MIN + 2)
#define TRC_SCHED_DOM_ADD (TRC_SCHED_VERBOSE + 1)
#define TRC_SCHED_DOM_REM (TRC_SCHED_VERBOSE + 2)
#define TRC_SCHED_SLEEP (TRC_SCHED_VERBOSE + 3)
#define TRC_SCHED_WAKE (TRC_SCHED_VERBOSE + 4)
#define TRC_SCHED_YIELD (TRC_SCHED_VERBOSE + 5)
#define TRC_SCHED_BLOCK (TRC_SCHED_VERBOSE + 6)
#define TRC_SCHED_SHUTDOWN (TRC_SCHED_VERBOSE + 7)
#define TRC_SCHED_CTL (TRC_SCHED_VERBOSE + 8)
#define TRC_SCHED_ADJDOM (TRC_SCHED_VERBOSE + 9)
#define TRC_SCHED_SWITCH (TRC_SCHED_VERBOSE + 10)
#define TRC_SCHED_S_TIMER_FN (TRC_SCHED_VERBOSE + 11)
#define TRC_SCHED_T_TIMER_FN (TRC_SCHED_VERBOSE + 12)
#define TRC_SCHED_DOM_TIMER_FN (TRC_SCHED_VERBOSE + 13)
#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)
#define TRC_MEM_PAGE_GRANT_TRANSFER (TRC_MEM + 3)
#define TRC_MEM_SET_P2M_ENTRY (TRC_MEM + 4)
#define TRC_MEM_DECREASE_RESERVATION (TRC_MEM + 5)
#define TRC_MEM_POD_POPULATE (TRC_MEM + 16)
#define TRC_MEM_POD_ZERO_RECLAIM (TRC_MEM + 17)
#define TRC_MEM_POD_SUPERPAGE_SPLINTER (TRC_MEM + 18)

#define TRC_PV_ENTRY 0x00201000 /* Hypervisor entry points for PV guests. */
#define TRC_PV_SUBCALL 0x00202000 /* Sub-call in a multicall hypercall */

#define TRC_PV_HYPERCALL (TRC_PV_ENTRY + 1)
#define TRC_PV_TRAP (TRC_PV_ENTRY + 3)
#define TRC_PV_PAGE_FAULT (TRC_PV_ENTRY + 4)
#define TRC_PV_FORCED_INVALID_OP (TRC_PV_ENTRY + 5)
#define TRC_PV_EMULATE_PRIVOP (TRC_PV_ENTRY + 6)
#define TRC_PV_EMULATE_4GB (TRC_PV_ENTRY + 7)
#define TRC_PV_MATH_STATE_RESTORE (TRC_PV_ENTRY + 8)
#define TRC_PV_PAGING_FIXUP (TRC_PV_ENTRY + 9)
#define TRC_PV_GDT_LDT_MAPPING_FAULT (TRC_PV_ENTRY + 10)
#define TRC_PV_PTWR_EMULATION (TRC_PV_ENTRY + 11)
#define TRC_PV_PTWR_EMULATION_PAE (TRC_PV_ENTRY + 12)
#define TRC_PV_HYPERCALL_V2 (TRC_PV_ENTRY + 13)
#define TRC_PV_HYPERCALL_SUBCALL (TRC_PV_SUBCALL + 14)

/*
* TRC_PV_HYPERCALL_V2 format
*
* Only some of the hypercall argument are recorded. Bit fields A0 to
* A5 in the first extra word are set if the argument is present and
* the arguments themselves are packed sequentially in the following
* words.
*
* The TRC_64_FLAG bit is not set for these events (even if there are
* 64-bit arguments in the record).
*
* Word
* 0 bit 31 30|29 28|27 26|25 24|23 22|21 20|19 ... 0
* A5 |A4 |A3 |A2 |A1 |A0 |Hypercall op
* 1 First 32 bit (or low word of first 64 bit) arg in record
* 2 Second 32 bit (or high word of first 64 bit) arg in record
* ...
*
* A0-A5 bitfield values:
*
* 00b Argument not present
* 01b 32-bit argument present
* 10b 64-bit argument present
* 11b Reserved
*/
#define TRC_PV_HYPERCALL_V2_ARG_32(i) (0x1 << (20 + 2*(i)))
#define TRC_PV_HYPERCALL_V2_ARG_64(i) (0x2 << (20 + 2*(i)))
#define TRC_PV_HYPERCALL_V2_ARG_MASK (0xfff00000)

#define TRC_SHADOW_NOT_SHADOW (TRC_SHADOW + 1)
#define TRC_SHADOW_FAST_PROPAGATE (TRC_SHADOW + 2)
#define TRC_SHADOW_FAST_MMIO (TRC_SHADOW + 3)
#define TRC_SHADOW_FALSE_FAST_PATH (TRC_SHADOW + 4)
#define TRC_SHADOW_MMIO (TRC_SHADOW + 5)
#define TRC_SHADOW_FIXUP (TRC_SHADOW + 6)
#define TRC_SHADOW_DOMF_DYING (TRC_SHADOW + 7)
#define TRC_SHADOW_EMULATE (TRC_SHADOW + 8)
#define TRC_SHADOW_EMULATE_UNSHADOW_USER (TRC_SHADOW + 9)
#define TRC_SHADOW_EMULATE_UNSHADOW_EVTINJ (TRC_SHADOW + 10)
#define TRC_SHADOW_EMULATE_UNSHADOW_UNHANDLED (TRC_SHADOW + 11)
#define TRC_SHADOW_WRMAP_BF (TRC_SHADOW + 12)
#define TRC_SHADOW_PREALLOC_UNPIN (TRC_SHADOW + 13)
#define TRC_SHADOW_RESYNC_FULL (TRC_SHADOW + 14)
#define TRC_SHADOW_RESYNC_ONLY (TRC_SHADOW + 15)

/* trace events per subclass */
#define TRC_HVM_NESTEDFLAG (0x400)
#define TRC_HVM_VMENTRY (TRC_HVM_ENTRYEXIT + 0x01)
#define TRC_HVM_VMEXIT (TRC_HVM_ENTRYEXIT + 0x02)
#define TRC_HVM_VMEXIT64 (TRC_HVM_ENTRYEXIT + TRC_64_FLAG + 0x02)
#define TRC_HVM_PF_XEN (TRC_HVM_HANDLER + 0x01)
#define TRC_HVM_PF_XEN64 (TRC_HVM_HANDLER + TRC_64_FLAG + 0x01)
#define TRC_HVM_PF_INJECT (TRC_HVM_HANDLER + 0x02)
#define TRC_HVM_PF_INJECT64 (TRC_HVM_HANDLER + TRC_64_FLAG + 0x02)
#define TRC_HVM_INJ_EXC (TRC_HVM_HANDLER + 0x03)
#define TRC_HVM_INJ_VIRQ (TRC_HVM_HANDLER + 0x04)
#define TRC_HVM_REINJ_VIRQ (TRC_HVM_HANDLER + 0x05)
#define TRC_HVM_IO_READ (TRC_HVM_HANDLER + 0x06)
#define TRC_HVM_IO_WRITE (TRC_HVM_HANDLER + 0x07)
#define TRC_HVM_CR_READ (TRC_HVM_HANDLER + 0x08)
#define TRC_HVM_CR_READ64 (TRC_HVM_HANDLER + TRC_64_FLAG + 0x08)
#define TRC_HVM_CR_WRITE (TRC_HVM_HANDLER + 0x09)
#define TRC_HVM_CR_WRITE64 (TRC_HVM_HANDLER + TRC_64_FLAG + 0x09)
#define TRC_HVM_DR_READ (TRC_HVM_HANDLER + 0x0A)
#define TRC_HVM_DR_WRITE (TRC_HVM_HANDLER + 0x0B)
#define TRC_HVM_MSR_READ (TRC_HVM_HANDLER + 0x0C)
#define TRC_HVM_MSR_WRITE (TRC_HVM_HANDLER + 0x0D)
#define TRC_HVM_CPUID (TRC_HVM_HANDLER + 0x0E)
#define TRC_HVM_INTR (TRC_HVM_HANDLER + 0x0F)
#define TRC_HVM_NMI (TRC_HVM_HANDLER + 0x10)
#define TRC_HVM_SMI (TRC_HVM_HANDLER + 0x11)
#define TRC_HVM_VMMCALL (TRC_HVM_HANDLER + 0x12)
#define TRC_HVM_HLT (TRC_HVM_HANDLER + 0x13)
#define TRC_HVM_INVLPG (TRC_HVM_HANDLER + 0x14)
#define TRC_HVM_INVLPG64 (TRC_HVM_HANDLER + TRC_64_FLAG + 0x14)
#define TRC_HVM_MCE (TRC_HVM_HANDLER + 0x15)
#define TRC_HVM_IOPORT_READ (TRC_HVM_HANDLER + 0x16)
#define TRC_HVM_IOMEM_READ (TRC_HVM_HANDLER + 0x17)
#define TRC_HVM_CLTS (TRC_HVM_HANDLER + 0x18)
#define TRC_HVM_LMSW (TRC_HVM_HANDLER + 0x19)
#define TRC_HVM_LMSW64 (TRC_HVM_HANDLER + TRC_64_FLAG + 0x19)
#define TRC_HVM_RDTSC (TRC_HVM_HANDLER + 0x1a)
#define TRC_HVM_INTR_WINDOW (TRC_HVM_HANDLER + 0x20)
#define TRC_HVM_NPF (TRC_HVM_HANDLER + 0x21)
#define TRC_HVM_REALMODE_EMULATE (TRC_HVM_HANDLER + 0x22)
#define TRC_HVM_TRAP (TRC_HVM_HANDLER + 0x23)
#define TRC_HVM_TRAP_DEBUG (TRC_HVM_HANDLER + 0x24)
#define TRC_HVM_VLAPIC (TRC_HVM_HANDLER + 0x25)
#define TRC_HVM_XCR_READ64 (TRC_HVM_HANDLER + TRC_64_FLAG + 0x26)
#define TRC_HVM_XCR_WRITE64 (TRC_HVM_HANDLER + TRC_64_FLAG + 0x27)

#define TRC_HVM_IOPORT_WRITE (TRC_HVM_HANDLER + 0x216)
#define TRC_HVM_IOMEM_WRITE (TRC_HVM_HANDLER + 0x217)

/* Trace events for emulated devices */
#define TRC_HVM_EMUL_HPET_START_TIMER (TRC_HVM_EMUL + 0x1)
#define TRC_HVM_EMUL_PIT_START_TIMER (TRC_HVM_EMUL + 0x2)
#define TRC_HVM_EMUL_RTC_START_TIMER (TRC_HVM_EMUL + 0x3)
#define TRC_HVM_EMUL_LAPIC_START_TIMER (TRC_HVM_EMUL + 0x4)
#define TRC_HVM_EMUL_HPET_STOP_TIMER (TRC_HVM_EMUL + 0x5)
#define TRC_HVM_EMUL_PIT_STOP_TIMER (TRC_HVM_EMUL + 0x6)
#define TRC_HVM_EMUL_RTC_STOP_TIMER (TRC_HVM_EMUL + 0x7)
#define TRC_HVM_EMUL_LAPIC_STOP_TIMER (TRC_HVM_EMUL + 0x8)
#define TRC_HVM_EMUL_PIT_TIMER_CB (TRC_HVM_EMUL + 0x9)
#define TRC_HVM_EMUL_LAPIC_TIMER_CB (TRC_HVM_EMUL + 0xA)
#define TRC_HVM_EMUL_PIC_INT_OUTPUT (TRC_HVM_EMUL + 0xB)
#define TRC_HVM_EMUL_PIC_KICK (TRC_HVM_EMUL + 0xC)
#define TRC_HVM_EMUL_PIC_INTACK (TRC_HVM_EMUL + 0xD)
#define TRC_HVM_EMUL_PIC_POSEDGE (TRC_HVM_EMUL + 0xE)
#define TRC_HVM_EMUL_PIC_NEGEDGE (TRC_HVM_EMUL + 0xF)
#define TRC_HVM_EMUL_PIC_PEND_IRQ_CALL (TRC_HVM_EMUL + 0x10)
#define TRC_HVM_EMUL_LAPIC_PIC_INTR (TRC_HVM_EMUL + 0x11)

/* trace events for per class */
#define TRC_PM_FREQ_CHANGE (TRC_HW_PM + 0x01)
#define TRC_PM_IDLE_ENTRY (TRC_HW_PM + 0x02)
#define TRC_PM_IDLE_EXIT (TRC_HW_PM + 0x03)

/* Trace events for IRQs */
#define TRC_HW_IRQ_MOVE_CLEANUP_DELAY (TRC_HW_IRQ + 0x1)
#define TRC_HW_IRQ_MOVE_CLEANUP (TRC_HW_IRQ + 0x2)
#define TRC_HW_IRQ_BIND_VECTOR (TRC_HW_IRQ + 0x3)
#define TRC_HW_IRQ_CLEAR_VECTOR (TRC_HW_IRQ + 0x4)
#define TRC_HW_IRQ_MOVE_FINISH (TRC_HW_IRQ + 0x5)
#define TRC_HW_IRQ_ASSIGN_VECTOR (TRC_HW_IRQ + 0x6)
#define TRC_HW_IRQ_UNMAPPED_VECTOR (TRC_HW_IRQ + 0x7)
#define TRC_HW_IRQ_HANDLED (TRC_HW_IRQ + 0x8)

/*
* Event Flags
*
* Some events (e.g, TRC_PV_TRAP and TRC_HVM_IOMEM_READ) have multiple
* record formats. These event flags distinguish between the
* different formats.
*/
#define TRC_64_FLAG 0x100 /* Addresses are 64 bits (instead of 32 bits) */

/* This structure represents a single trace buffer record. */
struct t_rec {
uint32_t event:28;
uint32_t extra_u32:3; /* # entries in trailing extra_u32[] array */
uint32_t cycles_included:1; /* u.cycles or u.no_cycles? */
union {
struct {
uint32_t cycles_lo, cycles_hi; /* cycle counter timestamp */
uint32_t extra_u32[7]; /* event data items */
} cycles;
struct {
uint32_t extra_u32[7]; /* event data items */
} nocycles;
} u;
};

/*
* This structure contains the metadata for a single trace buffer. The head
* field, indexes into an array of struct t_rec's.
*/
struct t_buf {
/* Assume the data buffer size is X. X is generally not a power of 2.
* CONS and PROD are incremented modulo (2*X):
* 0 <= cons < 2*X
* 0 <= prod < 2*X
* This is done because addition modulo X breaks at 2^32 when X is not a
* power of 2:
* (((2^32 - 1) % X) + 1) % X != (2^32) % X
*/
uint32_t cons; /* Offset of next item to be consumed by control tools. */
uint32_t prod; /* Offset of next item to be produced by Xen. */
/* Records follow immediately after the meta-data header. */
};

/* Structure used to pass MFNs to the trace buffers back to trace consumers.
* Offset is an offset into the mapped structure where the mfn list will be held.
* MFNs will be at ((unsigned long *)(t_info))+(t_info->cpu_offset[cpu]).
*/
struct t_info {
uint16_t tbuf_size; /* Size in pages of each trace buffer */
uint16_t mfn_offset[]; /* Offset within t_info structure of the page list per cpu */
/* MFN lists immediately after the header */
};

#endif /* __XEN_PUBLIC_TRACE_H__ */

/*
* Local variables:
* mode: C
* c-file-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
248 changes: 248 additions & 0 deletions include/hw/xen/interface/vcpu.h
@@ -0,0 +1,248 @@
/******************************************************************************
* vcpu.h
*
* VCPU initialisation, query, and hotplug.
*
* 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) 2005, Keir Fraser <keir@xensource.com>
*/

#ifndef __XEN_PUBLIC_VCPU_H__
#define __XEN_PUBLIC_VCPU_H__

#include "xen.h"

/*
* Prototype for this hypercall is:
* long vcpu_op(int cmd, unsigned int vcpuid, void *extra_args)
* @cmd == VCPUOP_??? (VCPU operation).
* @vcpuid == VCPU to operate on.
* @extra_args == Operation-specific extra arguments (NULL if none).
*/

/*
* 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 == 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

/*
* Bring up a VCPU. This makes the VCPU runnable. This operation will fail
* if the VCPU has not been initialised (VCPUOP_initialise).
*/
#define VCPUOP_up 1

/*
* Bring down a VCPU (i.e., make it non-runnable).
* There are a few caveats that callers should observe:
* 1. This operation may return, and VCPU_is_up may return false, before the
* VCPU stops running (i.e., the command is asynchronous). It is a good
* idea to ensure that the VCPU has entered a non-critical loop before
* bringing it down. Alternatively, this operation is guaranteed
* synchronous if invoked by the VCPU itself.
* 2. After a VCPU is initialised, there is currently no way to drop all its
* references to domain memory. Even a VCPU that is down still holds
* memory references via its pagetable base pointer and GDT. It is good
* practise to move a VCPU onto an 'idle' or default page table, LDT and
* GDT before bringing it down.
*/
#define VCPUOP_down 2

/* Returns 1 if the given VCPU is up. */
#define VCPUOP_is_up 3

/*
* Return information about the state and running time of a VCPU.
* @extra_arg == pointer to vcpu_runstate_info structure.
*/
#define VCPUOP_get_runstate_info 4
struct vcpu_runstate_info {
/* VCPU's current state (RUNSTATE_*). */
int state;
/* 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.
*/
uint64_t time[4];
};
typedef struct vcpu_runstate_info vcpu_runstate_info_t;
DEFINE_XEN_GUEST_HANDLE(vcpu_runstate_info_t);

/* VCPU is currently running on a physical CPU. */
#define RUNSTATE_running 0

/* VCPU is runnable, but not currently scheduled on any physical CPU. */
#define RUNSTATE_runnable 1

/* VCPU is blocked (a.k.a. idle). It is therefore not runnable. */
#define RUNSTATE_blocked 2

/*
* VCPU is not runnable, but it is not blocked.
* This is a 'catch all' state for things like hotplug and pauses by the
* system administrator (or for critical sections in the hypervisor).
* RUNSTATE_blocked dominates this state (it is the preferred state).
*/
#define RUNSTATE_offline 3

/*
* Register a shared memory area from which the guest may obtain its own
* runstate information without needing to execute a hypercall.
* Notes:
* 1. The registered address may be virtual or physical or guest handle,
* depending on the platform. Virtual address or guest handle should be
* registered on x86 systems.
* 2. Only one shared area may be registered per VCPU. The shared area is
* updated by the hypervisor each time the VCPU is scheduled. Thus
* runstate.state will always be RUNSTATE_running and
* runstate.state_entry_time will indicate the system time at which the
* VCPU was last scheduled to run.
* @extra_arg == pointer to vcpu_register_runstate_memory_area structure.
*/
#define VCPUOP_register_runstate_memory_area 5
struct vcpu_register_runstate_memory_area {
union {
XEN_GUEST_HANDLE(vcpu_runstate_info_t) h;
struct vcpu_runstate_info *v;
uint64_t p;
} addr;
};
typedef struct vcpu_register_runstate_memory_area vcpu_register_runstate_memory_area_t;
DEFINE_XEN_GUEST_HANDLE(vcpu_register_runstate_memory_area_t);

/*
* Set or stop a VCPU's periodic timer. Every VCPU has one periodic timer
* which can be set via these commands. Periods smaller than one millisecond
* may not be supported.
*/
#define VCPUOP_set_periodic_timer 6 /* arg == vcpu_set_periodic_timer_t */
#define VCPUOP_stop_periodic_timer 7 /* arg == NULL */
struct vcpu_set_periodic_timer {
uint64_t period_ns;
};
typedef struct vcpu_set_periodic_timer vcpu_set_periodic_timer_t;
DEFINE_XEN_GUEST_HANDLE(vcpu_set_periodic_timer_t);

/*
* Set or stop a VCPU's single-shot timer. Every VCPU has one single-shot
* timer which can be set via these commands.
*/
#define VCPUOP_set_singleshot_timer 8 /* arg == vcpu_set_singleshot_timer_t */
#define VCPUOP_stop_singleshot_timer 9 /* arg == NULL */
struct vcpu_set_singleshot_timer {
uint64_t timeout_abs_ns; /* Absolute system time value in nanoseconds. */
uint32_t flags; /* VCPU_SSHOTTMR_??? */
};
typedef struct vcpu_set_singleshot_timer vcpu_set_singleshot_timer_t;
DEFINE_XEN_GUEST_HANDLE(vcpu_set_singleshot_timer_t);

/* Flags to VCPUOP_set_singleshot_timer. */
/* Require the timeout to be in the future (return -ETIME if it's passed). */
#define _VCPU_SSHOTTMR_future (0)
#define VCPU_SSHOTTMR_future (1U << _VCPU_SSHOTTMR_future)

/*
* Register a memory location in the guest address space for the
* vcpu_info structure. This allows the guest to place the vcpu_info
* structure in a convenient place, such as in a per-cpu data area.
* The pointer need not be page aligned, but the structure must not
* cross a page boundary.
*
* This may be called only once per vcpu.
*/
#define VCPUOP_register_vcpu_info 10 /* arg == vcpu_register_vcpu_info_t */
struct vcpu_register_vcpu_info {
uint64_t mfn; /* mfn of page to place vcpu_info */
uint32_t offset; /* offset within page */
uint32_t rsvd; /* unused */
};
typedef struct vcpu_register_vcpu_info vcpu_register_vcpu_info_t;
DEFINE_XEN_GUEST_HANDLE(vcpu_register_vcpu_info_t);

/* Send an NMI to the specified VCPU. @extra_arg == NULL. */
#define VCPUOP_send_nmi 11

/*
* Get the physical ID information for a pinned vcpu's underlying physical
* processor. The physical ID informmation is architecture-specific.
* On x86: id[31:0]=apic_id, id[63:32]=acpi_id.
* This command returns -EINVAL if it is not a valid operation for this VCPU.
*/
#define VCPUOP_get_physid 12 /* arg == vcpu_get_physid_t */
struct vcpu_get_physid {
uint64_t phys_id;
};
typedef struct vcpu_get_physid vcpu_get_physid_t;
DEFINE_XEN_GUEST_HANDLE(vcpu_get_physid_t);
#define xen_vcpu_physid_to_x86_apicid(physid) ((uint32_t)(physid))
#define xen_vcpu_physid_to_x86_acpiid(physid) ((uint32_t)((physid) >> 32))

/*
* Register a memory location to get a secondary copy of the vcpu time
* parameters. The master copy still exists as part of the vcpu shared
* memory area, and this secondary copy is updated whenever the master copy
* is updated (and using the same versioning scheme for synchronisation).
*
* The intent is that this copy may be mapped (RO) into userspace so
* that usermode can compute system time using the time info and the
* tsc. Usermode will see an array of vcpu_time_info structures, one
* for each vcpu, and choose the right one by an existing mechanism
* which allows it to get the current vcpu number (such as via a
* segment limit). It can then apply the normal algorithm to compute
* system time from the tsc.
*
* @extra_arg == pointer to vcpu_register_time_info_memory_area structure.
*/
#define VCPUOP_register_vcpu_time_memory_area 13
DEFINE_XEN_GUEST_HANDLE(vcpu_time_info_t);
struct vcpu_register_time_memory_area {
union {
XEN_GUEST_HANDLE(vcpu_time_info_t) h;
struct vcpu_time_info *v;
uint64_t p;
} addr;
};
typedef struct vcpu_register_time_memory_area vcpu_register_time_memory_area_t;
DEFINE_XEN_GUEST_HANDLE(vcpu_register_time_memory_area_t);

#endif /* __XEN_PUBLIC_VCPU_H__ */

/*
* Local variables:
* mode: C
* c-file-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
113 changes: 113 additions & 0 deletions include/hw/xen/interface/version.h
@@ -0,0 +1,113 @@
/******************************************************************************
* version.h
*
* Xen version, type, and compile information.
*
* 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) 2005, Nguyen Anh Quynh <aquynh@gmail.com>
* Copyright (c) 2005, Keir Fraser <keir@xensource.com>
*/

#ifndef __XEN_PUBLIC_VERSION_H__
#define __XEN_PUBLIC_VERSION_H__

#include "xen.h"

/* 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

/* arg == xen_extraversion_t. */
#define XENVER_extraversion 1
typedef char xen_extraversion_t[16];
#define XEN_EXTRAVERSION_LEN (sizeof(xen_extraversion_t))

/* arg == xen_compile_info_t. */
#define XENVER_compile_info 2
struct xen_compile_info {
char compiler[64];
char compile_by[16];
char compile_domain[32];
char compile_date[32];
};
typedef struct xen_compile_info xen_compile_info_t;

#define XENVER_capabilities 3
typedef char xen_capabilities_info_t[1024];
#define XEN_CAPABILITIES_INFO_LEN (sizeof(xen_capabilities_info_t))

#define XENVER_changeset 4
typedef char xen_changeset_info_t[64];
#define XEN_CHANGESET_INFO_LEN (sizeof(xen_changeset_info_t))

#define XENVER_platform_parameters 5
struct xen_platform_parameters {
xen_ulong_t virt_start;
};
typedef struct xen_platform_parameters xen_platform_parameters_t;

#define XENVER_get_features 6
struct xen_feature_info {
unsigned int submap_idx; /* IN: which 32-bit submap to return */
uint32_t submap; /* OUT: 32-bit submap */
};
typedef struct xen_feature_info xen_feature_info_t;

/* Declares the features reported by XENVER_get_features. */
#include "features.h"

/* arg == NULL; returns host memory page size. */
#define XENVER_pagesize 7

/* 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[]. */
unsigned char buf[XEN_FLEX_ARRAY_DIM];
/* OUT: Variable length buffer with build_id. */
};
typedef struct xen_build_id xen_build_id_t;

#endif /* __XEN_PUBLIC_VERSION_H__ */

/*
* Local variables:
* mode: C
* c-file-style: "BSD"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/
46 changes: 46 additions & 0 deletions include/hw/xen/interface/xen-compat.h
@@ -0,0 +1,46 @@
/******************************************************************************
* xen-compat.h
*
* Guest OS interface to Xen. Compatibility layer.
*
* 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) 2006, Christian Limpach
*/

#ifndef __XEN_PUBLIC_XEN_COMPAT_H__
#define __XEN_PUBLIC_XEN_COMPAT_H__

#define __XEN_LATEST_INTERFACE_VERSION__ 0x00040e00

#if defined(__XEN__) || defined(__XEN_TOOLS__)
/* Xen is built with matching headers and implements the latest interface. */
#define __XEN_INTERFACE_VERSION__ __XEN_LATEST_INTERFACE_VERSION__
#elif !defined(__XEN_INTERFACE_VERSION__)
/* Guests which do not specify a version get the legacy interface. */
#define __XEN_INTERFACE_VERSION__ 0x00000000
#endif

#if __XEN_INTERFACE_VERSION__ > __XEN_LATEST_INTERFACE_VERSION__
#error "These header files do not support the requested interface version."
#endif

#define COMPAT_FLEX_ARRAY_DIM XEN_FLEX_ARRAY_DIM

#endif /* __XEN_PUBLIC_XEN_COMPAT_H__ */
1,049 changes: 1,049 additions & 0 deletions include/hw/xen/interface/xen.h

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions include/hw/xen/xen-legacy-backend.h
Expand Up @@ -42,8 +42,7 @@ int xenstore_read_fe_uint64(struct XenLegacyDevice *xendev, const char *node,
void xen_be_check_state(struct XenLegacyDevice *xendev);

/* xen backend driver bits */
int xen_be_init(void);
void xen_be_register_common(void);
void xen_be_init(void);
int xen_be_register(const char *type, struct XenDevOps *ops);
int xen_be_set_state(struct XenLegacyDevice *xendev, enum xenbus_state state);
int xen_be_bind_evtchn(struct XenLegacyDevice *xendev);
Expand Down
21 changes: 16 additions & 5 deletions include/hw/xen/xen.h
@@ -1,19 +1,30 @@
#ifndef QEMU_HW_XEN_H
#define QEMU_HW_XEN_H

/*
* public xen header
* stuff needed outside xen-*.c, i.e. interfaces to qemu.
* must not depend on any xen headers being present in
* /usr/include/xen, so it can be included unconditionally.
*/
#ifndef QEMU_HW_XEN_H
#define QEMU_HW_XEN_H

/*
* As a temporary measure while the headers are being untangled, define
* __XEN_TOOLS__ here before any Xen headers are included. Otherwise, if
* the Xen toolstack library headers are later included, they will find
* some of the "internal" definitions missing and the build will fail. In
* later commits, we'll end up with a rule that the native libraries have
* to be included first, which will ensure that the libraries get the
* version of Xen libraries that they expect.
*/
#define __XEN_TOOLS__ 1

#include "exec/cpu-common.h"

/* xen-machine.c */
enum xen_mode {
XEN_EMULATE = 0, // xen emulation, using xenner (default)
XEN_ATTACH // attach to xen domain created by libxl
XEN_DISABLED = 0, /* xen support disabled (default) */
XEN_ATTACH, /* attach to xen domain created by libxl */
XEN_EMULATE, /* emulate Xen within QEMU */
};

extern uint32_t xen_domid;
Expand Down
2 changes: 2 additions & 0 deletions include/monitor/hmp.h
Expand Up @@ -114,6 +114,8 @@ void hmp_virtio_status(Monitor *mon, const QDict *qdict);
void hmp_virtio_queue_status(Monitor *mon, const QDict *qdict);
void hmp_vhost_queue_status(Monitor *mon, const QDict *qdict);
void hmp_virtio_queue_element(Monitor *mon, const QDict *qdict);
void hmp_xen_event_inject(Monitor *mon, const QDict *qdict);
void hmp_xen_event_list(Monitor *mon, const QDict *qdict);
void object_add_completion(ReadLineState *rs, int nb_args, const char *str);
void object_del_completion(ReadLineState *rs, int nb_args, const char *str);
void device_add_completion(ReadLineState *rs, int nb_args, const char *str);
Expand Down
4 changes: 4 additions & 0 deletions include/sysemu/kvm_int.h
Expand Up @@ -118,6 +118,10 @@ struct KVMState
struct KVMDirtyRingReaper reaper;
NotifyVmexitOption notify_vmexit;
uint32_t notify_window;
uint32_t xen_version;
uint32_t xen_caps;
uint16_t xen_gnttab_max_frames;
uint16_t xen_evtchn_max_pirq;
};

void kvm_memory_listener_register(KVMState *s, KVMMemoryListener *kml,
Expand Down
43 changes: 43 additions & 0 deletions include/sysemu/kvm_xen.h
@@ -0,0 +1,43 @@
/*
* Xen HVM emulation support in KVM
*
* Copyright © 2019 Oracle and/or its affiliates. All rights reserved.
* Copyright © 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*
*/

#ifndef QEMU_SYSEMU_KVM_XEN_H
#define QEMU_SYSEMU_KVM_XEN_H

/* The KVM API uses these to indicate "no GPA" or "no GFN" */
#define INVALID_GPA UINT64_MAX
#define INVALID_GFN UINT64_MAX

/* QEMU plays the rôle of dom0 for "interdomain" communication. */
#define DOMID_QEMU 0

int kvm_xen_soft_reset(void);
uint32_t kvm_xen_get_caps(void);
void *kvm_xen_get_vcpu_info_hva(uint32_t vcpu_id);
void kvm_xen_inject_vcpu_callback_vector(uint32_t vcpu_id, int type);
void kvm_xen_set_callback_asserted(void);
int kvm_xen_set_vcpu_virq(uint32_t vcpu_id, uint16_t virq, uint16_t port);
uint16_t kvm_xen_get_gnttab_max_frames(void);
uint16_t kvm_xen_get_evtchn_max_pirq(void);

#define kvm_xen_has_cap(cap) (!!(kvm_xen_get_caps() & \
KVM_XEN_HVM_CONFIG_ ## cap))

#define XEN_SPECIAL_AREA_ADDR 0xfeff8000UL
#define XEN_SPECIAL_AREA_SIZE 0x4000UL

#define XEN_SPECIALPAGE_CONSOLE 0
#define XEN_SPECIALPAGE_XENSTORE 1

#define XEN_SPECIAL_PFN(x) ((XEN_SPECIAL_AREA_ADDR >> TARGET_PAGE_BITS) + \
XEN_SPECIALPAGE_##x)

#endif /* QEMU_SYSEMU_KVM_XEN_H */
2 changes: 2 additions & 0 deletions meson.build
Expand Up @@ -2982,6 +2982,7 @@ if have_system
'hw/i2c',
'hw/i386',
'hw/i386/xen',
'hw/i386/kvm',
'hw/ide',
'hw/input',
'hw/intc',
Expand Down Expand Up @@ -3881,6 +3882,7 @@ if have_system
if xen.found()
summary_info += {'xen ctrl version': xen.version()}
endif
summary_info += {'Xen emulation': config_all.has_key('CONFIG_XEN_EMU')}
endif
summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
if config_all.has_key('CONFIG_TCG')
Expand Down
4 changes: 3 additions & 1 deletion qapi/machine.json
Expand Up @@ -155,14 +155,16 @@
#
# @default-ram-id: the default ID of initial RAM memory backend (since 5.2)
#
# @acpi: machine type supports ACPI (since 8.0)
#
# Since: 1.2
##
{ 'struct': 'MachineInfo',
'data': { 'name': 'str', '*alias': 'str',
'*is-default': 'bool', 'cpu-max': 'int',
'hotpluggable-cpus': 'bool', 'numa-mem-supported': 'bool',
'deprecated': 'bool', '*default-cpu-type': 'str',
'*default-ram-id': 'str' } }
'*default-ram-id': 'str', 'acpi': 'bool' } }

##
# @query-machines:
Expand Down
116 changes: 116 additions & 0 deletions qapi/misc-target.json
Expand Up @@ -380,3 +380,119 @@
#
##
{ 'command': 'query-sgx-capabilities', 'returns': 'SGXInfo', 'if': 'TARGET_I386' }


##
# @EvtchnPortType:
#
# An enumeration of Xen event channel port types.
#
# @closed: The port is unused.
#
# @unbound: The port is allocated and ready to be bound.
#
# @interdomain: The port is connected as an interdomain interrupt.
#
# @pirq: The port is bound to a physical IRQ (PIRQ).
#
# @virq: The port is bound to a virtual IRQ (VIRQ).
#
# @ipi: The post is an inter-processor interrupt (IPI).
#
# Since: 8.0
##
{ 'enum': 'EvtchnPortType',
'data': ['closed', 'unbound', 'interdomain', 'pirq', 'virq', 'ipi'],
'if': 'TARGET_I386' }

##
# @EvtchnInfo:
#
# Information about a Xen event channel port
#
# @port: the port number
#
# @vcpu: target vCPU for this port
#
# @type: the port type
#
# @remote-domain: remote domain for interdomain ports
#
# @target: remote port ID, or virq/pirq number
#
# @pending: port is currently active pending delivery
#
# @masked: port is masked
#
# Since: 8.0
##
{ 'struct': 'EvtchnInfo',
'data': {'port': 'uint16',
'vcpu': 'uint32',
'type': 'EvtchnPortType',
'remote-domain': 'str',
'target': 'uint16',
'pending': 'bool',
'masked': 'bool'},
'if': 'TARGET_I386' }


##
# @xen-event-list:
#
# Query the Xen event channels opened by the guest.
#
# Returns: list of open event channel ports.
#
# Since: 8.0
#
# Example:
#
# -> { "execute": "xen-event-list" }
# <- { "return": [
# {
# "pending": false,
# "port": 1,
# "vcpu": 1,
# "remote-domain": "qemu",
# "masked": false,
# "type": "interdomain",
# "target": 1
# },
# {
# "pending": false,
# "port": 2,
# "vcpu": 0,
# "remote-domain": "",
# "masked": false,
# "type": "virq",
# "target": 0
# }
# ]
# }
#
##
{ 'command': 'xen-event-list',
'returns': ['EvtchnInfo'],
'if': 'TARGET_I386' }

##
# @xen-event-inject:
#
# Inject a Xen event channel port (interrupt) to the guest.
#
# @port: The port number
#
# Returns: - Nothing on success.
#
# Since: 8.0
#
# Example:
#
# -> { "execute": "xen-event-inject", "arguments": { "port": 1 } }
# <- { "return": { } }
#
##
{ 'command': 'xen-event-inject',
'data': { 'port': 'uint32' },
'if': 'TARGET_I386' }
2 changes: 1 addition & 1 deletion softmmu/globals.c
Expand Up @@ -63,5 +63,5 @@ QemuUUID qemu_uuid;
bool qemu_uuid_set;

uint32_t xen_domid;
enum xen_mode xen_mode = XEN_EMULATE;
enum xen_mode xen_mode = XEN_DISABLED;
bool xen_domid_restrict;
2 changes: 1 addition & 1 deletion softmmu/vl.c
Expand Up @@ -3360,7 +3360,7 @@ void qemu_init(int argc, char **argv)
has_defaults = 0;
break;
case QEMU_OPTION_xen_domid:
if (!(accel_find("xen"))) {
if (!(accel_find("xen")) && !(accel_find("kvm"))) {
error_report("Option not supported for this target");
exit(1);
}
Expand Down
1 change: 1 addition & 0 deletions target/i386/cpu.c
Expand Up @@ -7209,6 +7209,7 @@ static Property x86_cpu_properties[] = {
* own cache information (see x86_cpu_load_def()).
*/
DEFINE_PROP_BOOL("legacy-cache", X86CPU, legacy_cache, true),
DEFINE_PROP_BOOL("xen-vapic", X86CPU, xen_vapic, false),

/*
* From "Requirements for Implementing the Microsoft
Expand Down
19 changes: 19 additions & 0 deletions target/i386/cpu.h
Expand Up @@ -26,6 +26,9 @@
#include "exec/cpu-defs.h"
#include "qapi/qapi-types-common.h"
#include "qemu/cpu-float.h"
#include "qemu/timer.h"

#define XEN_NR_VIRQS 24

/* The x86 has a strong memory model with some store-after-load re-ordering */
#define TCG_GUEST_DEFAULT_MO (TCG_MO_ALL & ~TCG_MO_ST_LD)
Expand Down Expand Up @@ -1799,6 +1802,20 @@ typedef struct CPUArchState {
#endif
#if defined(CONFIG_KVM)
struct kvm_nested_state *nested_state;
MemoryRegion *xen_vcpu_info_mr;
void *xen_vcpu_info_hva;
uint64_t xen_vcpu_info_gpa;
uint64_t xen_vcpu_info_default_gpa;
uint64_t xen_vcpu_time_info_gpa;
uint64_t xen_vcpu_runstate_gpa;
uint8_t xen_vcpu_callback_vector;
bool xen_callback_asserted;
uint16_t xen_virq[XEN_NR_VIRQS];
uint64_t xen_singleshot_timer_ns;
QEMUTimer *xen_singleshot_timer;
uint64_t xen_periodic_timer_period;
QEMUTimer *xen_periodic_timer;
QemuMutex xen_timers_lock;
#endif
#if defined(CONFIG_HVF)
HVFX86LazyFlags hvf_lflags;
Expand Down Expand Up @@ -1975,6 +1992,8 @@ struct ArchCPU {
int32_t thread_id;

int32_t hv_max_vps;

bool xen_vapic;
};


Expand Down