[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [edk2] [PATCH v3 02/19] OvmfPkg: Add public headers from Xen Project.



On 2014-10-17 10:03:45, Anthony PERARD wrote:
> This patch imports publics headers in order to use features from Xen
> like XenStore, PV Block... There is only the necessary header files and
> there are only a few modifications in order to facilitate future merge of
> more recent header (that would be necessary to access new features).
> 
> There is little modification compared to the original files:
> - Removed most of the unused part of the headers
> - Use of ZeroMem() instead of memset()
> - using #pragma pack(4) for IA32 compilation.

Usually EDK II uses pack(1) when concerned about structure layout. I'm
not saying you need to change this, but it does stand out.

> - Replace types to be more UEFI compliant using a script.
> 
> OVMF, when built for IA32 arch, uses the gcc switch -malign-double. This
> change the alignment of fields in some struct compare to what is
> espected by Xen and any backends. To fix the alignment, the #pragma pack(4)
> directive is used around the struct that need it.
> 
> Command to run to change types:
> find OvmfPkg/Include/IndustryStandard/Xen -type f -name '*.h' -exec sed
>   --regexp-extended --file=fix_type_in_xen_includes.sed --in-place {} \;

Did you intend to include fix_type_in_xen_includes.sed?

Maybe you could mention the source (url, version) for the files? Was
it a direct copy into OvmfPkg/Include/IndustryStandard/Xen before
using the script?

How easy do you think someone could 'update' the files from Xen based
on the information you provided here?

> This line is commented instead of been change as I'm not sure why it
> does not compile (when s/char/CHAR8/), and it does not seems necessary
> so far.
>   /* __DEFINE_XEN_GUEST_HANDLE(uchar, unsigned char); */

Could 'unsigned char' => 'UINT8' help?

-Jordan

>   in OvmfPkg/Include/IndustryStandard/Xen/arch-x86/xen.h
> 
> Avoid changing the 'long' that is not a type (with the first line).
> $ cat fix_type_in_xen_includes.sed
> /as long as/b
> 
> s/([^a-zA-Z0-9_]|^)uint8_t([^a-zA-Z0-9_]|$)/\1UINT8\2/g
> s/([^a-zA-Z0-9_]|^)uint16_t([^a-zA-Z0-9_]|$)/\1UINT16\2/g
> s/([^a-zA-Z0-9_]|^)uint32_t([^a-zA-Z0-9_]|$)/\1UINT32\2/g
> s/([^a-zA-Z0-9_]|^)uint64_t([^a-zA-Z0-9_]|$)/\1UINT64\2/g
> 
> s/([^a-zA-Z0-9_]|^)int8_t([^a-zA-Z0-9_]|$)/\1INT8\2/g
> s/([^a-zA-Z0-9_]|^)int16_t([^a-zA-Z0-9_]|$)/\1INT16\2/g
> s/([^a-zA-Z0-9_]|^)int32_t([^a-zA-Z0-9_]|$)/\1INT32\2/g
> s/([^a-zA-Z0-9_]|^)int64_t([^a-zA-Z0-9_]|$)/\1INT64\2/g
> 
> s/([^a-zA-Z0-9_]|^)void([^a-zA-Z0-9_]|$)/\1VOID\2/g
> s/([^a-zA-Z0-9_]|^)unsigned int([^a-zA-Z0-9_]|$)/\1UINT32\2/g
> s/([^a-zA-Z0-9_]|^)int([^a-zA-Z0-9_]|$)/\1INT32\2/g
> s/([^a-zA-Z0-9_]|^)char([^a-zA-Z0-9_]|$)/\1CHAR8\2/g
> s/([^a-zA-Z0-9_]|^)unsigned long([^a-zA-Z0-9_]|$)/\1UINTN\2/g
> s/([^a-zA-Z0-9_]|^)long([^a-zA-Z0-9_]|$)/\1INTN\2/g
> 
> License: This patch adds many files under the MIT licence.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Anthony PERARD <anthony.perard@xxxxxxxxxx>
> 
> ---
> Change in V3:
> - Remove unused header sched.h
> - moving xs_wire.h in a later patch, where it's first needed
> - moving io/blkif.h in a later patch (XenPvBlkDxe: Add BlockFront client)
> - moving event_channel.h in a later patch (XenBusDxe: Add Event Channel 
> Notify)
> - using #pragma pack(4) for IA32
> - headers trimed down, removed most of the unused struct/define/...
> ---
>  .../IndustryStandard/Xen/arch-x86/xen-x86_32.h     |  59 +++
>  .../IndustryStandard/Xen/arch-x86/xen-x86_64.h     |  59 +++
>  .../Include/IndustryStandard/Xen/arch-x86/xen.h    | 112 ++++++
>  OvmfPkg/Include/IndustryStandard/Xen/grant_table.h | 444 
> +++++++++++++++++++++
>  OvmfPkg/Include/IndustryStandard/Xen/hvm/hvm_op.h  |  37 ++
>  OvmfPkg/Include/IndustryStandard/Xen/hvm/params.h  | 150 +++++++
>  .../Include/IndustryStandard/Xen/io/protocols.h    |  40 ++
>  OvmfPkg/Include/IndustryStandard/Xen/io/ring.h     | 312 +++++++++++++++
>  OvmfPkg/Include/IndustryStandard/Xen/io/xenbus.h   |  80 ++++
>  OvmfPkg/Include/IndustryStandard/Xen/memory.h      |  94 +++++
>  OvmfPkg/Include/IndustryStandard/Xen/xen-compat.h  |  44 ++
>  OvmfPkg/Include/IndustryStandard/Xen/xen.h         | 341 ++++++++++++++++
>  12 files changed, 1772 insertions(+)
>  create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/arch-x86/xen-x86_32.h
>  create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/arch-x86/xen-x86_64.h
>  create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/arch-x86/xen.h
>  create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/grant_table.h
>  create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/hvm/hvm_op.h
>  create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/hvm/params.h
>  create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/io/protocols.h
>  create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/io/ring.h
>  create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/io/xenbus.h
>  create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/memory.h
>  create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/xen-compat.h
>  create mode 100644 OvmfPkg/Include/IndustryStandard/Xen/xen.h
> 
> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/arch-x86/xen-x86_32.h 
> b/OvmfPkg/Include/IndustryStandard/Xen/arch-x86/xen-x86_32.h
> new file mode 100644
> index 0000000..ed7e12b
> --- /dev/null
> +++ b/OvmfPkg/Include/IndustryStandard/Xen/arch-x86/xen-x86_32.h
> @@ -0,0 +1,59 @@
> +/******************************************************************************
> + * xen-x86_32.h
> + * 
> + * Guest OS interface to x86 32-bit 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
> + * 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) 2004-2007, K A Fraser
> + */
> +
> +#ifndef __XEN_PUBLIC_ARCH_X86_XEN_X86_32_H__
> +#define __XEN_PUBLIC_ARCH_X86_XEN_X86_32_H__
> +
> +/*
> + * Hypercall interface:
> + *  Input:  %ebx, %ecx, %edx, %esi, %edi, %ebp (arguments 1-6)
> + *  Output: %eax
> + * Access is via hypercall page (set up by guest loader or via a Xen MSR):
> + *  call hypercall_page + hypercall-number * 32
> + * Clobbered: Argument registers (e.g., 2-arg hypercall clobbers %ebx,%ecx)
> + */
> +
> +#ifndef __ASSEMBLY__
> +
> +struct arch_vcpu_info {
> +    UINTN cr2;
> +    UINTN pad[5]; /* sizeof(vcpu_info_t) == 64 */
> +};
> +typedef struct arch_vcpu_info arch_vcpu_info_t;
> +
> +#endif /* !__ASSEMBLY__ */
> +
> +#endif /* __XEN_PUBLIC_ARCH_X86_XEN_X86_32_H__ */
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * tab-width: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/arch-x86/xen-x86_64.h 
> b/OvmfPkg/Include/IndustryStandard/Xen/arch-x86/xen-x86_64.h
> new file mode 100644
> index 0000000..c5ef5d4
> --- /dev/null
> +++ b/OvmfPkg/Include/IndustryStandard/Xen/arch-x86/xen-x86_64.h
> @@ -0,0 +1,59 @@
> +/******************************************************************************
> + * xen-x86_64.h
> + * 
> + * Guest OS interface to x86 64-bit 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
> + * 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) 2004-2006, K A Fraser
> + */
> +
> +#ifndef __XEN_PUBLIC_ARCH_X86_XEN_X86_64_H__
> +#define __XEN_PUBLIC_ARCH_X86_XEN_X86_64_H__
> +
> +/*
> + * Hypercall interface:
> + *  Input:  %rdi, %rsi, %rdx, %r10, %r8, %r9 (arguments 1-6)
> + *  Output: %rax
> + * Access is via hypercall page (set up by guest loader or via a Xen MSR):
> + *  call hypercall_page + hypercall-number * 32
> + * Clobbered: argument registers (e.g., 2-arg hypercall clobbers %rdi,%rsi)
> + */
> +
> +#ifndef __ASSEMBLY__
> +
> +struct arch_vcpu_info {
> +    UINTN cr2;
> +    UINTN pad; /* sizeof(vcpu_info_t) == 64 */
> +};
> +typedef struct arch_vcpu_info arch_vcpu_info_t;
> +
> +#endif /* !__ASSEMBLY__ */
> +
> +#endif /* __XEN_PUBLIC_ARCH_X86_XEN_X86_64_H__ */
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * tab-width: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/arch-x86/xen.h 
> b/OvmfPkg/Include/IndustryStandard/Xen/arch-x86/xen.h
> new file mode 100644
> index 0000000..951d57b
> --- /dev/null
> +++ b/OvmfPkg/Include/IndustryStandard/Xen/arch-x86/xen.h
> @@ -0,0 +1,112 @@
> +/******************************************************************************
> + * arch-x86/xen.h
> + * 
> + * Guest OS 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
> + * 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) 2004-2006, K A Fraser
> + */
> +
> +#include "../xen.h"
> +
> +#ifndef __XEN_PUBLIC_ARCH_X86_XEN_H__
> +#define __XEN_PUBLIC_ARCH_X86_XEN_H__
> +
> +/* Structural guest handles introduced in 0x00030201. */
> +#if __XEN_INTERFACE_VERSION__ >= 0x00030201
> +#define ___DEFINE_XEN_GUEST_HANDLE(name, type) \
> +    typedef struct { type *p; } __guest_handle_ ## name
> +#else
> +#define ___DEFINE_XEN_GUEST_HANDLE(name, type) \
> +    typedef type * __guest_handle_ ## name
> +#endif
> +
> +/*
> + * XEN_GUEST_HANDLE represents a guest pointer, when passed as a field
> + * in a struct in memory.
> + * XEN_GUEST_HANDLE_PARAM represent a guest pointer, when passed as an
> + * hypercall argument.
> + * XEN_GUEST_HANDLE_PARAM and XEN_GUEST_HANDLE are the same on X86 but
> + * they might not be on other architectures.
> + */
> +#define __DEFINE_XEN_GUEST_HANDLE(name, type) \
> +    ___DEFINE_XEN_GUEST_HANDLE(name, type);   \
> +    ___DEFINE_XEN_GUEST_HANDLE(const_##name, const type)
> +#define DEFINE_XEN_GUEST_HANDLE(name)   __DEFINE_XEN_GUEST_HANDLE(name, name)
> +#define __XEN_GUEST_HANDLE(name)        __guest_handle_ ## name
> +#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__)
> +#include "xen-x86_32.h"
> +#elif defined(__x86_64__)
> +#include "xen-x86_64.h"
> +#endif
> +
> +#ifndef __ASSEMBLY__
> +typedef UINTN xen_pfn_t;
> +#define PRI_xen_pfn "lx"
> +#endif
> +
> +#define XEN_HAVE_PV_UPCALL_MASK 1
> +
> +/* Maximum number of virtual CPUs in legacy multi-processor guests. */
> +#define XEN_LEGACY_MAX_VCPUS 32
> +
> +#ifndef __ASSEMBLY__
> +
> +typedef UINTN xen_ulong_t;
> +#define PRI_xen_ulong "lx"
> +
> +typedef UINT64 tsc_timestamp_t; /* RDTSC timestamp */
> +
> +#ifdef __i386__
> +#pragma pack(4)
> +#endif
> +struct arch_shared_info {
> +    UINTN max_pfn;                  /* max pfn that appears in table */
> +    /* Frame containing list of mfns containing list of mfns containing p2m. 
> */
> +    xen_pfn_t     pfn_to_mfn_frame_list_list;
> +    UINTN nmi_reason;
> +    UINT64 pad[32];
> +};
> +typedef struct arch_shared_info arch_shared_info_t;
> +#ifdef __i386__
> +#pragma pack()
> +#endif
> +
> +#endif /* !__ASSEMBLY__ */
> +
> +#endif /* __XEN_PUBLIC_ARCH_X86_XEN_H__ */
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * tab-width: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/grant_table.h 
> b/OvmfPkg/Include/IndustryStandard/Xen/grant_table.h
> new file mode 100644
> index 0000000..8725931
> --- /dev/null
> +++ b/OvmfPkg/Include/IndustryStandard/Xen/grant_table.h
> @@ -0,0 +1,444 @@
> +/******************************************************************************
> + * grant_table.h
> + *
> + * Interface for granting foreign access to page frames, and receiving
> + * page-ownership transfers.
> + *
> + * 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) 2004, K A Fraser
> + */
> +
> +#ifndef __XEN_PUBLIC_GRANT_TABLE_H__
> +#define __XEN_PUBLIC_GRANT_TABLE_H__
> +
> +#include "xen.h"
> +
> +/*
> + * `incontents 150 gnttab Grant Tables
> + *
> + * Xen's grant tables provide a generic mechanism to memory sharing
> + * between domains. This shared memory interface underpins the split
> + * device drivers for block and network IO.
> + *
> + * Each domain has its own grant table. This is a data structure that
> + * is shared with Xen; it allows the domain to tell Xen what kind of
> + * permissions other domains have on its pages. Entries in the grant
> + * 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.
> + *
> + * This capability-based system allows shared-memory communications
> + * between unprivileged domains. A grant reference also encapsulates
> + * the details of a shared page, removing the need for a domain to
> + * know the real machine address of a page it is sharing. This makes
> + * it possible to share memory correctly with domains running in
> + * fully virtualised memory.
> + */
> +
> +/***********************************
> + * GRANT TABLE REPRESENTATION
> + */
> +
> +/* Some rough guidelines on accessing and updating grant-table entries
> + * in a concurrency-safe manner. For more information, Linux contains a
> + * reference implementation for guest OSes (drivers/xen/grant_table.c, see
> + * 
> http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob;f=drivers/xen/grant-table.c;hb=HEAD
> + *
> + * NB. WMB is a no-op on current-generation x86 processors. However, a
> + *     compiler barrier will still be required.
> + *
> + * Introducing a valid entry into the grant table:
> + *  1. Write ent->domid.
> + *  2. Write ent->frame:
> + *      GTF_permit_access:   Frame to which access is permitted.
> + *      GTF_accept_transfer: Pseudo-phys frame slot being filled by new
> + *                           frame, or zero if none.
> + *  3. Write memory barrier (WMB).
> + *  4. Write ent->flags, inc. valid type.
> + *
> + * Invalidating an unused GTF_permit_access entry:
> + *  1. flags = ent->flags.
> + *  2. Observe that !(flags & (GTF_reading|GTF_writing)).
> + *  3. Check result of SMP-safe CMPXCHG(&ent->flags, flags, 0).
> + *  NB. No need for WMB as reuse of entry is control-dependent on success of
> + *      step 3, and all architectures guarantee ordering of ctrl-dep writes.
> + *
> + * Invalidating an in-use GTF_permit_access entry:
> + *  This cannot be done directly. Request assistance from the domain 
> controller
> + *  which can set a timeout on the use of a grant entry and take necessary
> + *  action. (NB. This is not yet implemented!).
> + *
> + * Invalidating an unused GTF_accept_transfer entry:
> + *  1. flags = ent->flags.
> + *  2. Observe that !(flags & GTF_transfer_committed). [*]
> + *  3. Check result of SMP-safe CMPXCHG(&ent->flags, flags, 0).
> + *  NB. No need for WMB as reuse of entry is control-dependent on success of
> + *      step 3, and all architectures guarantee ordering of ctrl-dep writes.
> + *  [*] If GTF_transfer_committed is set then the grant entry is 'committed'.
> + *      The guest must /not/ modify the grant entry until the address of the
> + *      transferred frame is written. It is safe for the guest to spin 
> waiting
> + *      for this to occur (detect by observing GTF_transfer_completed in
> + *      ent->flags).
> + *
> + * Invalidating a committed GTF_accept_transfer entry:
> + *  1. Wait for (ent->flags & GTF_transfer_completed).
> + *
> + * Changing a GTF_permit_access from writable to read-only:
> + *  Use SMP-safe CMPXCHG to set GTF_readonly, while checking !GTF_writing.
> + *
> + * Changing a GTF_permit_access from read-only to writable:
> + *  Use SMP-safe bit-setting instruction.
> + */
> +
> +/*
> + * Reference to a grant entry in a specified domain's grant table.
> + */
> +typedef UINT32 grant_ref_t;
> +
> +/*
> + * A grant table comprises a packed array of grant entries in one or more
> + * page frames shared between Xen and a guest.
> + * [XEN]: This field is written by Xen and read by the sharing guest.
> + * [GST]: This field is written by the guest and read by Xen.
> + */
> +
> +/*
> + * Version 1 of the grant table entry structure is maintained purely
> + * for backwards compatibility.  New guests should use version 2.
> + */
> +#if __XEN_INTERFACE_VERSION__ < 0x0003020a
> +#define grant_entry_v1 grant_entry
> +#define grant_entry_v1_t grant_entry_t
> +#endif
> +struct grant_entry_v1 {
> +    /* GTF_xxx: various type and flag information.  [XEN,GST] */
> +    UINT16 flags;
> +    /* 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]
> +     */
> +    UINT32 frame;
> +};
> +typedef struct grant_entry_v1 grant_entry_v1_t;
> +
> +/* The first few grant table entries will be preserved across grant table
> + * version changes and may be pre-populated at domain creation by tools.
> + */
> +#define GNTTAB_NR_RESERVED_ENTRIES     8
> +#define GNTTAB_RESERVED_CONSOLE        0
> +#define GNTTAB_RESERVED_XENSTORE       1
> +
> +/*
> + * Type of grant entry.
> + *  GTF_invalid: This grant entry grants no privileges.
> + *  GTF_permit_access: Allow @domid to map/access @frame.
> + *  GTF_accept_transfer: Allow @domid to transfer ownership of one page frame
> + *                       to this guest. Xen writes the page number to @frame.
> + *  GTF_transitive: Allow @domid to transitively access a subrange of
> + *                  @trans_grant in @trans_domid.  No mappings are allowed.
> + */
> +#define GTF_invalid         (0U<<0)
> +#define GTF_permit_access   (1U<<0)
> +#define GTF_accept_transfer (2U<<0)
> +#define GTF_transitive      (3U<<0)
> +#define GTF_type_mask       (3U<<0)
> +
> +/*
> + * Subflags for GTF_permit_access.
> + *  GTF_readonly: Restrict @domid to read-only mappings and accesses. [GST]
> + *  GTF_reading: Grant entry is currently mapped for reading by @domid. [XEN]
> + *  GTF_writing: Grant entry is currently mapped for writing by @domid. [XEN]
> + *  GTF_PAT, GTF_PWT, GTF_PCD: (x86) cache attribute flags for the grant 
> [GST]
> + *  GTF_sub_page: Grant access to only a subrange of the page.  @domid
> + *                will only be allowed to copy from the grant, and not
> + *                map it. [GST]
> + */
> +#define _GTF_readonly       (2)
> +#define GTF_readonly        (1U<<_GTF_readonly)
> +#define _GTF_reading        (3)
> +#define GTF_reading         (1U<<_GTF_reading)
> +#define _GTF_writing        (4)
> +#define GTF_writing         (1U<<_GTF_writing)
> +#define _GTF_PWT            (5)
> +#define GTF_PWT             (1U<<_GTF_PWT)
> +#define _GTF_PCD            (6)
> +#define GTF_PCD             (1U<<_GTF_PCD)
> +#define _GTF_PAT            (7)
> +#define GTF_PAT             (1U<<_GTF_PAT)
> +#define _GTF_sub_page       (8)
> +#define GTF_sub_page        (1U<<_GTF_sub_page)
> +
> +/*
> + * Subflags for GTF_accept_transfer:
> + *  GTF_transfer_committed: Xen sets this flag to indicate that it is 
> committed
> + *      to transferring ownership of a page frame. When a guest sees this 
> flag
> + *      it must /not/ modify the grant entry until GTF_transfer_completed is
> + *      set by Xen.
> + *  GTF_transfer_completed: It is safe for the guest to spin-wait on this 
> flag
> + *      after reading GTF_transfer_committed. Xen will always write the frame
> + *      address, followed by ORing this flag, in a timely manner.
> + */
> +#define _GTF_transfer_committed (2)
> +#define GTF_transfer_committed  (1U<<_GTF_transfer_committed)
> +#define _GTF_transfer_completed (3)
> +#define GTF_transfer_completed  (1U<<_GTF_transfer_completed)
> +
> +/*
> + * Version 2 grant table entries.  These fulfil the same role as
> + * version 1 entries, but can represent more complicated operations.
> + * Any given domain will have either a version 1 or a version 2 table,
> + * and every entry in the table will be the same version.
> + *
> + * The interface by which domains use grant references does not depend
> + * on the grant table version in use by the other domain.
> + */
> +#if __XEN_INTERFACE_VERSION__ >= 0x0003020a
> +/*
> + * Version 1 and version 2 grant entries share a common prefix.  The
> + * fields of the prefix are documented as part of struct
> + * grant_entry_v1.
> + */
> +struct grant_entry_header {
> +    UINT16 flags;
> +    domid_t  domid;
> +};
> +typedef struct grant_entry_header grant_entry_header_t;
> +
> +/*
> + * Version 2 of the grant entry structure.
> + */
> +union grant_entry_v2 {
> +    grant_entry_header_t hdr;
> +
> +    /*
> +     * This member is used for V1-style full page grants, where either:
> +     *
> +     * -- hdr.type is GTF_accept_transfer, or
> +     * -- hdr.type is GTF_permit_access and GTF_sub_page is not set.
> +     *
> +     * In that case, the frame field has the same semantics as the
> +     * field of the same name in the V1 entry structure.
> +     */
> +    struct {
> +        grant_entry_header_t hdr;
> +        UINT32 pad0;
> +        UINT64 frame;
> +    } full_page;
> +
> +    /*
> +     * If the grant type is GTF_grant_access and GTF_sub_page is set,
> +     * @domid is allowed to access bytes [@page_off,@page_off+@length)
> +     * in frame @frame.
> +     */
> +    struct {
> +        grant_entry_header_t hdr;
> +        UINT16 page_off;
> +        UINT16 length;
> +        UINT64 frame;
> +    } sub_page;
> +
> +    /*
> +     * If the grant is GTF_transitive, @domid is allowed to use the
> +     * grant @gref in domain @trans_domid, as if it was the local
> +     * domain.  Obviously, the transitive access must be compatible
> +     * with the original grant.
> +     *
> +     * The current version of Xen does not allow transitive grants
> +     * to be mapped.
> +     */
> +    struct {
> +        grant_entry_header_t hdr;
> +        domid_t trans_domid;
> +        UINT16 pad0;
> +        grant_ref_t gref;
> +    } transitive;
> +
> +    UINT32 __spacer[4]; /* Pad to a power of two */
> +};
> +typedef union grant_entry_v2 grant_entry_v2_t;
> +
> +typedef UINT16 grant_status_t;
> +
> +#endif /* __XEN_INTERFACE_VERSION__ */
> +
> +/***********************************
> + * GRANT TABLE QUERIES AND USES
> + */
> +
> +/* ` enum neg_errnoval
> + * ` HYPERVISOR_grant_table_op(enum grant_table_op cmd,
> + * `                           VOID *args,
> + * `                           UINT32 count)
> + * `
> + *
> + * @args points to an array of a per-command data structure. The array
> + * has @count members
> + */
> +
> +/* ` enum grant_table_op { // GNTTABOP_* => struct gnttab_* */
> +#define GNTTABOP_map_grant_ref        0
> +#define GNTTABOP_unmap_grant_ref      1
> +/* ` } */
> +
> +/*
> + * Handle to track a mapping created via a grant reference.
> + */
> +typedef UINT32 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>
> + * is a negative status code.
> + * NOTES:
> + *  1. If GNTMAP_device_map is specified then <dev_bus_addr> is the address
> + *     via which I/O devices may access the granted frame.
> + *  2. If GNTMAP_host_map is specified then a mapping will be added at
> + *     either a host virtual address in the current address space, or at
> + *     a PTE at the specified machine address.  The type of mapping to
> + *     perform is selected through the GNTMAP_contains_pte flag, and the
> + *     address is specified in <host_addr>.
> + *  3. Mappings should only be destroyed via GNTTABOP_unmap_grant_ref. If a
> + *     host mapping is destroyed by other means then it is *NOT* guaranteed
> + *     to be accounted to the correct grant reference!
> + */
> +struct gnttab_map_grant_ref {
> +    /* IN parameters. */
> +    UINT64 host_addr;
> +    UINT32 flags;               /* GNTMAP_* */
> +    grant_ref_t ref;
> +    domid_t  dom;
> +    /* OUT parameters. */
> +    INT16  status;              /* => enum grant_status */
> +    grant_handle_t handle;
> +    UINT64 dev_bus_addr;
> +};
> +typedef struct gnttab_map_grant_ref gnttab_map_grant_ref_t;
> +DEFINE_XEN_GUEST_HANDLE(gnttab_map_grant_ref_t);
> +
> +/*
> + * GNTTABOP_unmap_grant_ref: Destroy one or more grant-reference mappings
> + * tracked by <handle>. If <host_addr> or <dev_bus_addr> is zero, that
> + * field is ignored. If non-zero, they must refer to a device/host mapping
> + * that is tracked by <handle>
> + * NOTES:
> + *  1. The call may fail in an undefined manner if either mapping is not
> + *     tracked by <handle>.
> + *  3. After executing a batch of unmaps, it is guaranteed that no stale
> + *     mappings will remain in the device or host TLBs.
> + */
> +struct gnttab_unmap_grant_ref {
> +    /* IN parameters. */
> +    UINT64 host_addr;
> +    UINT64 dev_bus_addr;
> +    grant_handle_t handle;
> +    /* OUT parameters. */
> +    INT16  status;              /* => enum grant_status */
> +};
> +typedef struct gnttab_unmap_grant_ref gnttab_unmap_grant_ref_t;
> +DEFINE_XEN_GUEST_HANDLE(gnttab_unmap_grant_ref_t);
> +
> +/*
> + * Bitfield values for gnttab_map_grant_ref.flags.
> + */
> + /* Map the grant entry for access by I/O devices. */
> +#define _GNTMAP_device_map      (0)
> +#define GNTMAP_device_map       (1<<_GNTMAP_device_map)
> + /* Map the grant entry for access by host CPUs. */
> +#define _GNTMAP_host_map        (1)
> +#define GNTMAP_host_map         (1<<_GNTMAP_host_map)
> + /* Accesses to the granted frame will be restricted to read-only access. */
> +#define _GNTMAP_readonly        (2)
> +#define GNTMAP_readonly         (1<<_GNTMAP_readonly)
> + /*
> +  * GNTMAP_host_map subflag:
> +  *  0 => The host mapping is usable only by the guest OS.
> +  *  1 => The host mapping is usable by guest OS + current application.
> +  */
> +#define _GNTMAP_application_map (3)
> +#define GNTMAP_application_map  (1<<_GNTMAP_application_map)
> +
> + /*
> +  * GNTMAP_contains_pte subflag:
> +  *  0 => This map request contains a host virtual address.
> +  *  1 => This map request contains the machine addess of the PTE to update.
> +  */
> +#define _GNTMAP_contains_pte    (4)
> +#define GNTMAP_contains_pte     (1<<_GNTMAP_contains_pte)
> +
> +#define _GNTMAP_can_fail        (5)
> +#define GNTMAP_can_fail         (1<<_GNTMAP_can_fail)
> +
> +/*
> + * Bits to be placed in guest kernel available PTE bits (architecture
> + * dependent; only supported when XENFEAT_gnttab_map_avail_bits is set).
> + */
> +#define _GNTMAP_guest_avail0    (16)
> +#define GNTMAP_guest_avail_mask ((UINT32)~0 << _GNTMAP_guest_avail0)
> +
> +/*
> + * Values for error status returns. All errors are -ve.
> + */
> +/* ` enum grant_status { */
> +#define GNTST_okay             (0)  /* Normal return.                        
> */
> +#define GNTST_general_error    (-1) /* General undefined error.              
> */
> +#define GNTST_bad_domain       (-2) /* Unrecognsed domain id.                
> */
> +#define GNTST_bad_gntref       (-3) /* Unrecognised or inappropriate gntref. 
> */
> +#define GNTST_bad_handle       (-4) /* Unrecognised or inappropriate handle. 
> */
> +#define GNTST_bad_virt_addr    (-5) /* Inappropriate virtual address to map. 
> */
> +#define GNTST_bad_dev_addr     (-6) /* Inappropriate device address to 
> unmap.*/
> +#define GNTST_no_device_space  (-7) /* Out of space in I/O MMU.              
> */
> +#define GNTST_permission_denied (-8) /* Not enough privilege for operation.  
> */
> +#define GNTST_bad_page         (-9) /* Specified page was invalid for op.    
> */
> +#define GNTST_bad_copy_arg    (-10) /* copy arguments cross page boundary.   
> */
> +#define GNTST_address_too_big (-11) /* transfer page address too large.      
> */
> +#define GNTST_eagain          (-12) /* Operation not done; try again.        
> */
> +/* ` } */
> +
> +#define GNTTABOP_error_msgs {                   \
> +    "okay",                                     \
> +    "undefined error",                          \
> +    "unrecognised domain id",                   \
> +    "invalid grant reference",                  \
> +    "invalid mapping handle",                   \
> +    "invalid virtual address",                  \
> +    "invalid device address",                   \
> +    "no spare translation slot in the I/O MMU", \
> +    "permission denied",                        \
> +    "bad page",                                 \
> +    "copy arguments cross page boundary",       \
> +    "page address size too large",              \
> +    "operation not done; try again"             \
> +}
> +
> +#endif /* __XEN_PUBLIC_GRANT_TABLE_H__ */
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * tab-width: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/hvm/hvm_op.h 
> b/OvmfPkg/Include/IndustryStandard/Xen/hvm/hvm_op.h
> new file mode 100644
> index 0000000..120f62f
> --- /dev/null
> +++ b/OvmfPkg/Include/IndustryStandard/Xen/hvm/hvm_op.h
> @@ -0,0 +1,37 @@
> +/*
> + * 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_HVM_OP_H__
> +#define __XEN_PUBLIC_HVM_HVM_OP_H__
> +
> +#include "../xen.h"
> +
> +/* Get/set subcommands: extra argument == pointer to xen_hvm_param struct. */
> +#define HVMOP_set_param           0
> +#define HVMOP_get_param           1
> +struct xen_hvm_param {
> +    domid_t  domid;    /* IN */
> +    UINT32 index;    /* IN */
> +    UINT64 value;    /* IN/OUT */
> +};
> +typedef struct xen_hvm_param xen_hvm_param_t;
> +DEFINE_XEN_GUEST_HANDLE(xen_hvm_param_t);
> +
> +#endif /* __XEN_PUBLIC_HVM_HVM_OP_H__ */
> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/hvm/params.h 
> b/OvmfPkg/Include/IndustryStandard/Xen/hvm/params.h
> new file mode 100644
> index 0000000..517a184
> --- /dev/null
> +++ b/OvmfPkg/Include/IndustryStandard/Xen/hvm/params.h
> @@ -0,0 +1,150 @@
> +/*
> + * 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_PARAMS_H__
> +#define __XEN_PUBLIC_HVM_PARAMS_H__
> +
> +#include "hvm_op.h"
> +
> +/*
> + * Parameter space for HVMOP_{set,get}_param.
> + */
> +
> +/*
> + * 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.
> + */
> +#define HVM_PARAM_CALLBACK_IRQ 0
> +
> +/*
> + * 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_PAE_ENABLED  4
> +
> +#define HVM_PARAM_IOREQ_PFN    5
> +
> +#define HVM_PARAM_BUFIOREQ_PFN 6
> +#define HVM_PARAM_BUFIOREQ_EVTCHN 26
> +
> +#if defined(__i386__) || defined(__x86_64__)
> +
> +/* Expose Viridian interfaces to this HVM guest? */
> +#define HVM_PARAM_VIRIDIAN     9
> +
> +#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
> +
> +/* Device Model domain, defaults to 0. */
> +#define HVM_PARAM_DM_DOMAIN    13
> +
> +/* 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
> +
> +/* Enable blocking memory events, async or sync (pause vcpu until response) 
> + * onchangeonly indicates messages only on a change of value */
> +#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_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_SHARING_RING_PFN  29
> +
> +/* SHUTDOWN_* action in case of a triple fault */
> +#define HVM_PARAM_TRIPLE_FAULT_REASON 31
> +
> +#define HVM_NR_PARAMS          32
> +
> +#endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */
> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/io/protocols.h 
> b/OvmfPkg/Include/IndustryStandard/Xen/io/protocols.h
> new file mode 100644
> index 0000000..80b196b
> --- /dev/null
> +++ b/OvmfPkg/Include/IndustryStandard/Xen/io/protocols.h
> @@ -0,0 +1,40 @@
> +/******************************************************************************
> + * protocols.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.
> + */
> +
> +#ifndef __XEN_PROTOCOLS_H__
> +#define __XEN_PROTOCOLS_H__
> +
> +#define XEN_IO_PROTO_ABI_X86_32     "x86_32-abi"
> +#define XEN_IO_PROTO_ABI_X86_64     "x86_64-abi"
> +#define XEN_IO_PROTO_ABI_ARM        "arm-abi"
> +
> +#if defined(__i386__)
> +# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_X86_32
> +#elif defined(__x86_64__)
> +# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_X86_64
> +#elif defined(__arm__) || defined(__aarch64__)
> +# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_ARM
> +#else
> +# error arch fixup needed here
> +#endif
> +
> +#endif
> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/io/ring.h 
> b/OvmfPkg/Include/IndustryStandard/Xen/io/ring.h
> new file mode 100644
> index 0000000..a8e9ea0
> --- /dev/null
> +++ b/OvmfPkg/Include/IndustryStandard/Xen/io/ring.h
> @@ -0,0 +1,312 @@
> +/******************************************************************************
> + * ring.h
> + * 
> + * Shared producer-consumer ring macros.
> + *
> + * 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.
> + *
> + * Tim Deegan and Andrew Warfield November 2004.
> + */
> +
> +#ifndef __XEN_PUBLIC_IO_RING_H__
> +#define __XEN_PUBLIC_IO_RING_H__
> +
> +#include "../xen-compat.h"
> +
> +#if __XEN_INTERFACE_VERSION__ < 0x00030208
> +#define xen_mb()  mb()
> +#define xen_rmb() rmb()
> +#define xen_wmb() wmb()
> +#endif
> +
> +typedef UINT32 RING_IDX;
> +
> +/* Round a 32-bit unsigned constant down to the nearest power of two. */
> +#define __RD2(_x)  (((_x) & 0x00000002) ? 0x2                  : ((_x) & 
> 0x1))
> +#define __RD4(_x)  (((_x) & 0x0000000c) ? __RD2((_x)>>2)<<2    : __RD2(_x))
> +#define __RD8(_x)  (((_x) & 0x000000f0) ? __RD4((_x)>>4)<<4    : __RD4(_x))
> +#define __RD16(_x) (((_x) & 0x0000ff00) ? __RD8((_x)>>8)<<8    : __RD8(_x))
> +#define __RD32(_x) (((_x) & 0xffff0000) ? __RD16((_x)>>16)<<16 : __RD16(_x))
> +
> +/*
> + * 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 
> + * 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(((struct _s##_sring *)0)->ring[0])))
> +/*
> + * The same for passing in an actual pointer instead of a name tag.
> + */
> +#define __RING_SIZE(_s, _sz) \
> +    (__RD32(((_sz) - (INTN)(_s)->ring + (INTN)(_s)) / sizeof((_s)->ring[0])))
> +
> +/*
> + * 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.
> + *
> + * In a header where you want the ring datatype declared, you then do:
> + *
> + *     DEFINE_RING_TYPES(mytag, request_t, response_t);
> + *
> + * 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.
> + *
> + * To initialize a ring in your code you need to know the location and size
> + * of the shared memory area (PAGE_SIZE, for instance). To initialise
> + * the front half:
> + *
> + *     mytag_front_ring_t front_ring;
> + *     SHARED_RING_INIT((mytag_sring_t *)shared_page);
> + *     FRONT_RING_INIT(&front_ring, (mytag_sring_t *)shared_page, PAGE_SIZE);
> + *
> + * Initializing the back follows similarly (note that only the front
> + * initializes the shared ring):
> + *
> + *     mytag_back_ring_t back_ring;
> + *     BACK_RING_INIT(&back_ring, (mytag_sring_t *)shared_page, PAGE_SIZE);
> + */
> +
> +#define DEFINE_RING_TYPES(__name, __req_t, __rsp_t)                     \
> +                                                                        \
> +/* Shared ring entry */                                                 \
> +union __name##_sring_entry {                                            \
> +    __req_t req;                                                        \
> +    __rsp_t rsp;                                                        \
> +};                                                                      \
> +                                                                        \
> +/* Shared ring page */                                                  \
> +struct __name##_sring {                                                 \
> +    RING_IDX req_prod, req_event;                                       \
> +    RING_IDX rsp_prod, rsp_event;                                       \
> +    union {                                                             \
> +        struct {                                                        \
> +            UINT8 smartpoll_active;                                   \
> +        } netif;                                                        \
> +        struct {                                                        \
> +            UINT8 msg;                                                \
> +        } tapif_user;                                                   \
> +        UINT8 pvt_pad[4];                                             \
> +    } private;                                                          \
> +    UINT8 __pad[44];                                                  \
> +    union __name##_sring_entry ring[1]; /* variable-length */           \
> +};                                                                      \
> +                                                                        \
> +/* "Front" end's private variables */                                   \
> +struct __name##_front_ring {                                            \
> +    RING_IDX req_prod_pvt;                                              \
> +    RING_IDX rsp_cons;                                                  \
> +    UINT32 nr_ents;                                               \
> +    struct __name##_sring *sring;                                       \
> +};                                                                      \
> +                                                                        \
> +/* "Back" end's private variables */                                    \
> +struct __name##_back_ring {                                             \
> +    RING_IDX rsp_prod_pvt;                                              \
> +    RING_IDX req_cons;                                                  \
> +    UINT32 nr_ents;                                               \
> +    struct __name##_sring *sring;                                       \
> +};                                                                      \
> +                                                                        \
> +/* Syntactic sugar */                                                   \
> +typedef struct __name##_sring __name##_sring_t;                         \
> +typedef struct __name##_front_ring __name##_front_ring_t;               \
> +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 
> + * requests are pushed on to the ring and responses taken off it.
> + * 
> + * 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 
> + * requestor (front end) never has more than RING_SIZE()-1
> + * outstanding requests.
> + */
> +
> +/* Initialising empty rings */
> +#define SHARED_RING_INIT(_s) do {                                       \
> +    (_s)->req_prod  = (_s)->rsp_prod  = 0;                              \
> +    (_s)->req_event = (_s)->rsp_event = 1;                              \
> +    (VOID)ZeroMem((_s)->private.pvt_pad, sizeof((_s)->private.pvt_pad)); \
> +    (VOID)ZeroMem((_s)->__pad, sizeof((_s)->__pad));                  \
> +} while(0)
> +
> +#define FRONT_RING_INIT(_r, _s, __size) do {                            \
> +    (_r)->req_prod_pvt = 0;                                             \
> +    (_r)->rsp_cons = 0;                                                 \
> +    (_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;                                                 \
> +    (_r)->nr_ents = __RING_SIZE(_s, __size);                            \
> +    (_r)->sring = (_s);                                                 \
> +} while (0)
> +
> +/* How big is this ring? */
> +#define RING_SIZE(_r)                                                   \
> +    ((_r)->nr_ents)
> +
> +/* Number of free requests (for use on front side only). */
> +#define RING_FREE_REQUESTS(_r)                                          \
> +    (RING_SIZE(_r) - ((_r)->req_prod_pvt - (_r)->rsp_cons))
> +
> +/* Test if there is an empty slot available on the front ring.
> + * (This is only meaningful from the front. )
> + */
> +#define RING_FULL(_r)                                                   \
> +    (RING_FREE_REQUESTS(_r) == 0)
> +
> +/* Test if there are outstanding messages to be processed on a ring. */
> +#define RING_HAS_UNCONSUMED_RESPONSES(_r)                               \
> +    ((_r)->sring->rsp_prod - (_r)->rsp_cons)
> +
> +#ifdef __GNUC__
> +#define RING_HAS_UNCONSUMED_REQUESTS(_r) ({                             \
> +    UINT32 req = (_r)->sring->req_prod - (_r)->req_cons;          \
> +    UINT32 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))
> +
> +/* Loop termination condition: Would the specified index overflow the ring? 
> */
> +#define RING_REQUEST_CONS_OVERFLOW(_r, _cons)                           \
> +    (((_cons) - (_r)->rsp_prod_pvt) >= RING_SIZE(_r))
> +
> +/* Ill-behaved frontend determination: Can there be this many requests? */
> +#define RING_REQUEST_PROD_OVERFLOW(_r, _prod)                           \
> +    (((_prod) - (_r)->rsp_prod_pvt) > 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;                         \
> +} while (0)
> +
> +#define RING_PUSH_RESPONSES(_r) do {                                    \
> +    xen_wmb(); /* front sees resps /before/ updated producer index */   \
> +    (_r)->sring->rsp_prod = (_r)->rsp_prod_pvt;                         \
> +} while (0)
> +
> +/*
> + * 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
> + *  messages have been enqueued) then you will need to create a customised
> + *  version of the FINAL_CHECK macro in your own code, which sets the event
> + *  field appropriately.
> + */
> +
> +#define RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(_r, _notify) do {           \
> +    RING_IDX __old = (_r)->sring->req_prod;                             \
> +    RING_IDX __new = (_r)->req_prod_pvt;                                \
> +    xen_wmb(); /* back sees requests /before/ updated producer index */ \
> +    (_r)->sring->req_prod = __new;                                      \
> +    xen_mb(); /* back sees new requests /before/ we check req_event */  \
> +    (_notify) = ((RING_IDX)(__new - (_r)->sring->req_event) <           \
> +                 (RING_IDX)(__new - __old));                            \
> +} while (0)
> +
> +#define RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(_r, _notify) do {          \
> +    RING_IDX __old = (_r)->sring->rsp_prod;                             \
> +    RING_IDX __new = (_r)->rsp_prod_pvt;                                \
> +    xen_wmb(); /* front sees resps /before/ updated producer index */   \
> +    (_r)->sring->rsp_prod = __new;                                      \
> +    xen_mb(); /* front sees new resps /before/ we check rsp_event */    \
> +    (_notify) = ((RING_IDX)(__new - (_r)->sring->rsp_event) <           \
> +                 (RING_IDX)(__new - __old));                            \
> +} while (0)
> +
> +#define RING_FINAL_CHECK_FOR_REQUESTS(_r, _work_to_do) do {             \
> +    (_work_to_do) = RING_HAS_UNCONSUMED_REQUESTS(_r);                   \
> +    if (_work_to_do) break;                                             \
> +    (_r)->sring->req_event = (_r)->req_cons + 1;                        \
> +    xen_mb();                                                           \
> +    (_work_to_do) = RING_HAS_UNCONSUMED_REQUESTS(_r);                   \
> +} while (0)
> +
> +#define RING_FINAL_CHECK_FOR_RESPONSES(_r, _work_to_do) do {            \
> +    (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r);                  \
> +    if (_work_to_do) break;                                             \
> +    (_r)->sring->rsp_event = (_r)->rsp_cons + 1;                        \
> +    xen_mb();                                                           \
> +    (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r);                  \
> +} while (0)
> +
> +#endif /* __XEN_PUBLIC_IO_RING_H__ */
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * tab-width: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/io/xenbus.h 
> b/OvmfPkg/Include/IndustryStandard/Xen/io/xenbus.h
> new file mode 100644
> index 0000000..927f9db
> --- /dev/null
> +++ b/OvmfPkg/Include/IndustryStandard/Xen/io/xenbus.h
> @@ -0,0 +1,80 @@
> +/*****************************************************************************
> + * xenbus.h
> + *
> + * Xenbus protocol details.
> + *
> + * 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 XenSource Ltd.
> + */
> +
> +#ifndef _XEN_PUBLIC_IO_XENBUS_H
> +#define _XEN_PUBLIC_IO_XENBUS_H
> +
> +/*
> + * The state of either end of the Xenbus, i.e. the current communication
> + * status of initialisation across the bus.  States here imply nothing about
> + * the state of the connection between the driver and the kernel's device
> + * layers.
> + */
> +enum xenbus_state {
> +    XenbusStateUnknown       = 0,
> +
> +    XenbusStateInitialising  = 1,
> +
> +    /*
> +     * InitWait: Finished early initialisation but waiting for information
> +     * from the peer or hotplug scripts.
> +     */
> +    XenbusStateInitWait      = 2,
> +
> +    /*
> +     * Initialised: Waiting for a connection from the peer.
> +     */
> +    XenbusStateInitialised   = 3,
> +
> +    XenbusStateConnected     = 4,
> +
> +    /*
> +     * Closing: The device is being closed due to an error or an unplug 
> event.
> +     */
> +    XenbusStateClosing       = 5,
> +
> +    XenbusStateClosed        = 6,
> +
> +    /*
> +     * Reconfiguring: The device is being reconfigured.
> +     */
> +    XenbusStateReconfiguring = 7,
> +
> +    XenbusStateReconfigured  = 8
> +};
> +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:
> + */
> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/memory.h 
> b/OvmfPkg/Include/IndustryStandard/Xen/memory.h
> new file mode 100644
> index 0000000..00156a4
> --- /dev/null
> +++ b/OvmfPkg/Include/IndustryStandard/Xen/memory.h
> @@ -0,0 +1,94 @@
> +/******************************************************************************
> + * memory.h
> + * 
> + * Memory reservation and 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, Keir Fraser <keir@xxxxxxxxxxxxx>
> + */
> +
> +#ifndef __XEN_PUBLIC_MEMORY_H__
> +#define __XEN_PUBLIC_MEMORY_H__
> +
> +#include "xen.h"
> +
> +/* Source mapping space. */
> +/* ` enum phys_map_space { */
> +#define XENMAPSPACE_shared_info  0 /* shared info page */
> +#define XENMAPSPACE_grant_table  1 /* grant table page */
> +#define XENMAPSPACE_gmfn         2 /* GMFN */
> +#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. */
> +/* ` } */
> +
> +/*
> + * Sets the GPFN at which a particular page appears in the specified guest's
> + * pseudophysical address space.
> + * arg == addr of xen_add_to_physmap_t.
> + */
> +#define XENMEM_add_to_physmap      7
> +struct xen_add_to_physmap {
> +    /* Which domain to change the mapping for. */
> +    domid_t domid;
> +
> +    /* Number of pages to go through for gmfn_range */
> +    UINT16    size;
> +
> +    UINT32 space; /* => enum phys_map_space */
> +
> +#define XENMAPIDX_grant_table_status 0x80000000
> +
> +    /* Index into space being mapped. */
> +    xen_ulong_t idx;
> +
> +    /* GPFN in domid where the source mapping page should appear. */
> +    xen_pfn_t     gpfn;
> +};
> +typedef struct xen_add_to_physmap xen_add_to_physmap_t;
> +DEFINE_XEN_GUEST_HANDLE(xen_add_to_physmap_t);
> +
> +/*
> + * Unmaps the page appearing at a particular GPFN from the specified guest's
> + * pseudophysical address space.
> + * arg == addr of xen_remove_from_physmap_t.
> + */
> +#define XENMEM_remove_from_physmap      15
> +struct xen_remove_from_physmap {
> +    /* Which domain to change the mapping for. */
> +    domid_t domid;
> +
> +    /* GPFN of the current mapping of the page. */
> +    xen_pfn_t     gpfn;
> +};
> +typedef struct xen_remove_from_physmap xen_remove_from_physmap_t;
> +DEFINE_XEN_GUEST_HANDLE(xen_remove_from_physmap_t);
> +
> +#endif /* __XEN_PUBLIC_MEMORY_H__ */
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * tab-width: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/xen-compat.h 
> b/OvmfPkg/Include/IndustryStandard/Xen/xen-compat.h
> new file mode 100644
> index 0000000..3eb80a0
> --- /dev/null
> +++ b/OvmfPkg/Include/IndustryStandard/Xen/xen-compat.h
> @@ -0,0 +1,44 @@
> +/******************************************************************************
> + * 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__ 0x00040400
> +
> +#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
> +
> +#endif /* __XEN_PUBLIC_XEN_COMPAT_H__ */
> diff --git a/OvmfPkg/Include/IndustryStandard/Xen/xen.h 
> b/OvmfPkg/Include/IndustryStandard/Xen/xen.h
> new file mode 100644
> index 0000000..b93bd47
> --- /dev/null
> +++ b/OvmfPkg/Include/IndustryStandard/Xen/xen.h
> @@ -0,0 +1,341 @@
> +/******************************************************************************
> + * xen.h
> + * 
> + * Guest OS interface to 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
> + * 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) 2004, K A Fraser
> + */
> +
> +#ifndef __XEN_PUBLIC_XEN_H__
> +#define __XEN_PUBLIC_XEN_H__
> +
> +#include "xen-compat.h"
> +
> +#if defined(__i386__) || defined(__x86_64__)
> +#include "arch-x86/xen.h"
> +#elif defined(__arm__) || defined (__aarch64__)
> +#include "arch-arm.h"
> +#else
> +#error "Unsupported architecture"
> +#endif
> +
> +#ifndef __ASSEMBLY__
> +/* Guest handles for primitive C types. */
> +DEFINE_XEN_GUEST_HANDLE(CHAR8);
> +/* __DEFINE_XEN_GUEST_HANDLE(uchar, unsigned char); */
> +DEFINE_XEN_GUEST_HANDLE(INT32);
> +__DEFINE_XEN_GUEST_HANDLE(uint,  UINT32);
> +#if __XEN_INTERFACE_VERSION__ < 0x00040300
> +DEFINE_XEN_GUEST_HANDLE(INTN);
> +__DEFINE_XEN_GUEST_HANDLE(ulong, UINTN);
> +#endif
> +DEFINE_XEN_GUEST_HANDLE(VOID);
> +
> +DEFINE_XEN_GUEST_HANDLE(UINT64);
> +DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
> +DEFINE_XEN_GUEST_HANDLE(xen_ulong_t);
> +#endif
> +
> +/*
> + * HYPERCALLS
> + */
> +
> +/* `incontents 100 hcalls List of hypercalls
> + * ` enum hypercall_num { // __HYPERVISOR_* => HYPERVISOR_*()
> + */
> +
> +#define __HYPERVISOR_set_trap_table        0
> +#define __HYPERVISOR_mmu_update            1
> +#define __HYPERVISOR_set_gdt               2
> +#define __HYPERVISOR_stack_switch          3
> +#define __HYPERVISOR_set_callbacks         4
> +#define __HYPERVISOR_fpu_taskswitch        5
> +#define __HYPERVISOR_sched_op_compat       6 /* compat since 0x00030101 */
> +#define __HYPERVISOR_platform_op           7
> +#define __HYPERVISOR_set_debugreg          8
> +#define __HYPERVISOR_get_debugreg          9
> +#define __HYPERVISOR_update_descriptor    10
> +#define __HYPERVISOR_memory_op            12
> +#define __HYPERVISOR_multicall            13
> +#define __HYPERVISOR_update_va_mapping    14
> +#define __HYPERVISOR_set_timer_op         15
> +#define __HYPERVISOR_event_channel_op_compat 16 /* compat since 0x00030202 */
> +#define __HYPERVISOR_xen_version          17
> +#define __HYPERVISOR_console_io           18
> +#define __HYPERVISOR_physdev_op_compat    19 /* compat since 0x00030202 */
> +#define __HYPERVISOR_grant_table_op       20
> +#define __HYPERVISOR_vm_assist            21
> +#define __HYPERVISOR_update_va_mapping_otherdomain 22
> +#define __HYPERVISOR_iret                 23 /* x86 only */
> +#define __HYPERVISOR_vcpu_op              24
> +#define __HYPERVISOR_set_segment_base     25 /* x86/64 only */
> +#define __HYPERVISOR_mmuext_op            26
> +#define __HYPERVISOR_xsm_op               27
> +#define __HYPERVISOR_nmi_op               28
> +#define __HYPERVISOR_sched_op             29
> +#define __HYPERVISOR_callback_op          30
> +#define __HYPERVISOR_xenoprof_op          31
> +#define __HYPERVISOR_event_channel_op     32
> +#define __HYPERVISOR_physdev_op           33
> +#define __HYPERVISOR_hvm_op               34
> +#define __HYPERVISOR_sysctl               35
> +#define __HYPERVISOR_domctl               36
> +#define __HYPERVISOR_kexec_op             37
> +#define __HYPERVISOR_tmem_op              38
> +#define __HYPERVISOR_xc_reserved_op       39 /* reserved for XenClient */
> +
> +/* Architecture-specific hypercall definitions. */
> +#define __HYPERVISOR_arch_0               48
> +#define __HYPERVISOR_arch_1               49
> +#define __HYPERVISOR_arch_2               50
> +#define __HYPERVISOR_arch_3               51
> +#define __HYPERVISOR_arch_4               52
> +#define __HYPERVISOR_arch_5               53
> +#define __HYPERVISOR_arch_6               54
> +#define __HYPERVISOR_arch_7               55
> +
> +/* ` } */
> +
> +/*
> + * HYPERCALL COMPATIBILITY.
> + */
> +
> +/* New sched_op hypercall introduced in 0x00030101. */
> +#if __XEN_INTERFACE_VERSION__ < 0x00030101
> +#undef __HYPERVISOR_sched_op
> +#define __HYPERVISOR_sched_op __HYPERVISOR_sched_op_compat
> +#endif
> +
> +/* New event-channel and physdev hypercalls introduced in 0x00030202. */
> +#if __XEN_INTERFACE_VERSION__ < 0x00030202
> +#undef __HYPERVISOR_event_channel_op
> +#define __HYPERVISOR_event_channel_op __HYPERVISOR_event_channel_op_compat
> +#undef __HYPERVISOR_physdev_op
> +#define __HYPERVISOR_physdev_op __HYPERVISOR_physdev_op_compat
> +#endif
> +
> +/* New platform_op hypercall introduced in 0x00030204. */
> +#if __XEN_INTERFACE_VERSION__ < 0x00030204
> +#define __HYPERVISOR_dom0_op __HYPERVISOR_platform_op
> +#endif
> +
> +#ifndef __ASSEMBLY__
> +
> +typedef UINT16 domid_t;
> +
> +/* Domain ids >= DOMID_FIRST_RESERVED cannot be used for ordinary domains. */
> +#define DOMID_FIRST_RESERVED (0x7FF0U)
> +
> +/* DOMID_SELF is used in certain contexts to refer to oneself. */
> +#define DOMID_SELF (0x7FF0U)
> +
> +/*
> + * DOMID_IO is used to restrict page-table updates to mapping I/O memory.
> + * Although no Foreign Domain need be specified to map I/O pages, DOMID_IO
> + * 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.
> + */
> +#define DOMID_IO   (0x7FF1U)
> +
> +/*
> + * 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.
> + */
> +#define DOMID_XEN  (0x7FF2U)
> +
> +/*
> + * DOMID_COW is used as the owner of sharable pages */
> +#define DOMID_COW  (0x7FF3U)
> +
> +/* DOMID_INVALID is used to identify pages with unknown owner. */
> +#define DOMID_INVALID (0x7FF4U)
> +
> +/* Idle domain. */
> +#define DOMID_IDLE (0x7FFFU)
> +
> +#if __XEN_INTERFACE_VERSION__ < 0x00040400
> +/*
> + * Event channel endpoints per domain (when using the 2-level ABI):
> + *  1024 if a INTN is 32 bits; 4096 if a INTN is 64 bits.
> + */
> +#define NR_EVENT_CHANNELS EVTCHN_2L_NR_CHANNELS
> +#endif
> +
> +struct vcpu_time_info {
> +    /*
> +     * Updates to the following values are preceded and followed by an
> +     * increment of 'version'. The guest can therefore detect updates by
> +     * looking for changes to 'version'. If the least-significant bit of
> +     * the version number is set then an update is in progress and the guest
> +     * must wait to read a consistent set of values.
> +     * The correct way to interact with the version number is similar to
> +     * Linux's seqlock: see the implementations of 
> read_seqbegin/read_seqretry.
> +     */
> +    UINT32 version;
> +    UINT32 pad0;
> +    UINT64 tsc_timestamp;   /* TSC at last update of time vals.  */
> +    UINT64 system_time;     /* Time, in nanosecs, since boot.    */
> +    /*
> +     * Current system time:
> +     *   system_time +
> +     *   ((((tsc - tsc_timestamp) << tsc_shift) * tsc_to_system_mul) >> 32)
> +     * CPU frequency (Hz):
> +     *   ((10^9 << 32) / tsc_to_system_mul) >> tsc_shift
> +     */
> +    UINT32 tsc_to_system_mul;
> +    INT8   tsc_shift;
> +    INT8   pad1[3];
> +}; /* 32 bytes */
> +typedef struct vcpu_time_info vcpu_time_info_t;
> +
> +struct vcpu_info {
> +    /*
> +     * 'evtchn_upcall_pending' is written non-zero by Xen to indicate
> +     * a pending notification for a particular VCPU. It is then cleared 
> +     * by the guest OS /before/ checking for pending work, thus avoiding
> +     * a set-and-check race. Note that the mask is only accessed by Xen
> +     * on the CPU that is currently hosting the VCPU. This means that the
> +     * pending and mask flags can be updated by the guest without special
> +     * synchronisation (i.e., no need for the x86 LOCK prefix).
> +     * This may seem suboptimal because if the pending flag is set by
> +     * a different CPU then an IPI may be scheduled even when the mask
> +     * is set. However, note:
> +     *  1. The task of 'interrupt holdoff' is covered by the per-event-
> +     *     channel mask bits. A 'noisy' event that is continually being
> +     *     triggered can be masked at source at this very precise
> +     *     granularity.
> +     *  2. The main purpose of the per-VCPU mask is therefore to restrict
> +     *     reentrant execution: whether for concurrency control, or to
> +     *     prevent unbounded stack usage. Whatever the purpose, we expect
> +     *     that the mask will be asserted only for short periods at a time,
> +     *     and so the likelihood of a 'spurious' IPI is suitably small.
> +     * The mask is read before making an event upcall to the guest: a
> +     * non-zero mask therefore guarantees that the VCPU will not receive
> +     * an upcall activation. The mask is cleared when the VCPU requests
> +     * to block: this avoids wakeup-waiting races.
> +     */
> +    UINT8 evtchn_upcall_pending;
> +#ifdef XEN_HAVE_PV_UPCALL_MASK
> +    UINT8 evtchn_upcall_mask;
> +#else /* XEN_HAVE_PV_UPCALL_MASK */
> +    UINT8 pad0;
> +#endif /* XEN_HAVE_PV_UPCALL_MASK */
> +    xen_ulong_t evtchn_pending_sel;
> +    struct arch_vcpu_info arch;
> +    struct vcpu_time_info time;
> +}; /* 64 bytes (x86) */
> +#ifndef __XEN__
> +typedef struct vcpu_info vcpu_info_t;
> +#endif
> +
> +/*
> + * `incontents 200 startofday_shared Start-of-day shared data structure
> + * Xen/kernel shared data -- pointer provided in start_info.
> + *
> + * This structure is defined to be both smaller than a page, and the
> + * only data on the shared page, but may vary in actual size even within
> + * compatible Xen versions; guests should not rely on the size
> + * of this structure remaining constant.
> + */
> +struct shared_info {
> +    struct vcpu_info vcpu_info[XEN_LEGACY_MAX_VCPUS];
> +
> +    /*
> +     * A domain can create "event channels" on which it can send and receive
> +     * asynchronous event notifications. There are three classes of event 
> that
> +     * are delivered by this mechanism:
> +     *  1. Bi-directional inter- and intra-domain connections. Domains must
> +     *     arrange out-of-band to set up a connection (usually by allocating
> +     *     an unbound 'listener' port and avertising that via a storage 
> service
> +     *     such as xenstore).
> +     *  2. Physical interrupts. A domain with suitable hardware-access
> +     *     privileges can bind an event-channel port to a physical interrupt
> +     *     source.
> +     *  3. Virtual interrupts ('events'). A domain can bind an event-channel
> +     *     port to a virtual interrupt source, such as the virtual-timer
> +     *     device or the emergency console.
> +     * 
> +     * Event channels are addressed by a "port index". Each channel is
> +     * associated with two bits of information:
> +     *  1. PENDING -- notifies the domain that there is a pending 
> notification
> +     *     to be processed. This bit is cleared by the guest.
> +     *  2. MASK -- if this bit is clear then a 0->1 transition of PENDING
> +     *     will cause an asynchronous upcall to be scheduled. This bit is 
> only
> +     *     updated by the guest. It is read-only within Xen. If a channel
> +     *     becomes pending while the channel is masked then the 'edge' is 
> lost
> +     *     (i.e., when the channel is unmasked, the guest must manually 
> handle
> +     *     pending notifications as no upcall will be scheduled by Xen).
> +     * 
> +     * To expedite scanning of pending notifications, any 0->1 pending
> +     * transition on an unmasked channel causes a corresponding bit in a
> +     * per-vcpu selector word to be set. Each bit in the selector covers a
> +     * 'C INTN' in the PENDING bitfield array.
> +     */
> +    xen_ulong_t evtchn_pending[sizeof(xen_ulong_t) * 8];
> +    xen_ulong_t evtchn_mask[sizeof(xen_ulong_t) * 8];
> +
> +    /*
> +     * Wallclock time: updated only by control software. Guests should base
> +     * their gettimeofday() syscall on this wallclock-base value.
> +     */
> +    UINT32 wc_version;      /* Version counter: see vcpu_time_info_t. */
> +    UINT32 wc_sec;          /* Secs  00:00:00 UTC, Jan 1, 1970.  */
> +    UINT32 wc_nsec;         /* Nsecs 00:00:00 UTC, Jan 1, 1970.  */
> +
> +    struct arch_shared_info arch;
> +
> +};
> +#ifndef __XEN__
> +typedef struct shared_info shared_info_t;
> +#endif
> +
> +/* Turn a plain number into a C UINTN constant. */
> +#define __mk_unsigned_long(x) x ## UL
> +#define mk_unsigned_long(x) __mk_unsigned_long(x)
> +
> +__DEFINE_XEN_GUEST_HANDLE(uint8,  UINT8);
> +__DEFINE_XEN_GUEST_HANDLE(uint16, UINT16);
> +__DEFINE_XEN_GUEST_HANDLE(uint32, UINT32);
> +__DEFINE_XEN_GUEST_HANDLE(uint64, UINT64);
> +
> +#else /* __ASSEMBLY__ */
> +
> +/* In assembly code we cannot use C numeric constant suffixes. */
> +#define mk_unsigned_long(x) x
> +
> +#endif /* !__ASSEMBLY__ */
> +
> +#endif /* __XEN_PUBLIC_XEN_H__ */
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * tab-width: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> -- 
> Anthony PERARD
> 
> 
> ------------------------------------------------------------------------------
> Comprehensive Server Monitoring with Site24x7.
> Monitor 10 servers for $9/Month.
> Get alerted through email, SMS, voice calls or mobile push notifications.
> Take corrective actions from your mobile device.
> http://p.sf.net/sfu/Zoho
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@xxxxxxxxxxxxxxxxxxxxx
> https://lists.sourceforge.net/lists/listinfo/edk2-devel

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.