aboutsummaryrefslogtreecommitdiffstats
path: root/main/grub
diff options
context:
space:
mode:
authorHenrik Riomar <henrik.riomar@gmail.com>2019-04-03 16:07:12 +0200
committerLeonardo Arena <rnalrd@alpinelinux.org>2019-04-05 06:53:00 +0000
commitc40e9ceff34231100ff228d3015900e945727a7f (patch)
treec1960c097ca33cac4b1718485144cd5603f6b96a /main/grub
parent311f3a86010da63e189043d072f745b478b45309 (diff)
downloadaports-c40e9ceff34231100ff228d3015900e945727a7f.tar.bz2
aports-c40e9ceff34231100ff228d3015900e945727a7f.tar.xz
main/grub: add xen pvh support
* Backport xen_pvh patches from grub master branch * Adds grub-i386-xen_pvh.bin to the grub-xenhost package
Diffstat (limited to 'main/grub')
-rw-r--r--main/grub/0001-xen-Add-some-Xen-headers.patch2322
-rw-r--r--main/grub/0002-loader-linux-Support-passing-RSDP-address-via-boot-p.patch51
-rw-r--r--main/grub/0003-xen-Carve-out-grant-tab-initialization-into-dedicate.patch89
-rw-r--r--main/grub/0004-xen-Prepare-common-code-for-Xen-PVH-support.patch245
-rw-r--r--main/grub/0005-xen-Add-some-dummy-headers-for-PVH-mode.patch70
-rw-r--r--main/grub/0006-xen-Rearrange-xen-init.c-to-prepare-it-for-Xen-PVH-m.patch135
-rw-r--r--main/grub/0007-xen-Modify-grub_xen_ptr2mfn-for-Xen-PVH.patch33
-rw-r--r--main/grub/0008-xen-Add-PVH-specific-defines-to-offset.h.patch63
-rw-r--r--main/grub/0009-xen-Add-basic-hooks-for-PVH-in-current-code.patch267
-rw-r--r--main/grub/0010-xen-Add-PVH-boot-entry-code.patch86
-rw-r--r--main/grub/0011-xen-Setup-hypercall-page-for-PVH.patch145
-rw-r--r--main/grub/0012-xen-Get-memory-map-from-hypervisor-for-PVH.patch144
-rw-r--r--main/grub/0013-xen-Setup-Xen-specific-data-for-PVH.patch194
-rw-r--r--main/grub/0014-xen-Init-memory-regions-for-PVH.patch79
-rw-r--r--main/grub/0015-xen_pvh-Add-build-runes-for-grub-core.patch245
-rw-r--r--main/grub/0016-grub-module-verifier-Ignore-all_video-for-xen_pvh.patch35
-rw-r--r--main/grub/0017-xen-Use-elfnote-defines-instead-of-plain-numbers.patch86
-rw-r--r--main/grub/0018-xen_pvh-Support-building-a-standalone-image.patch199
-rw-r--r--main/grub/0019-xen_pvh-Support-grub-install-for-xen_pvh.patch104
-rw-r--r--main/grub/0020-xen_pvh-Add-support-to-configure.patch46
-rw-r--r--main/grub/APKBUILD79
21 files changed, 4714 insertions, 3 deletions
diff --git a/main/grub/0001-xen-Add-some-Xen-headers.patch b/main/grub/0001-xen-Add-some-Xen-headers.patch
new file mode 100644
index 0000000000..fc3f138537
--- /dev/null
+++ b/main/grub/0001-xen-Add-some-Xen-headers.patch
@@ -0,0 +1,2322 @@
+From d05d23ac337d951d94b94002211b684759619634 Mon Sep 17 00:00:00 2001
+From: Juergen Gross <jgross@suse.com>
+Date: Fri, 7 Dec 2018 13:11:29 +0100
+Subject: [PATCH 01/20] xen: Add some Xen headers
+
+In order to support grub2 in Xen PVH environment some additional Xen
+headers are needed as grub2 will be started in PVH mode requiring to
+use several HVM hypercalls and structures.
+
+Add the needed headers from Xen 4.10 being the first Xen version with
+full (not only experimental) PVH guest support.
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+Tested-by: Hans van Kranenburg <hans@knorrie.org>
+(cherry picked from commit 9118effd1b1fb67d82168b37cf6dd1142feced3b)
+---
+ include/xen/hvm/hvm_op.h | 296 ++++++++++++++++
+ include/xen/hvm/params.h | 284 +++++++++++++++
+ include/xen/hvm/start_info.h | 98 ++++++
+ include/xen/memory.h | 665 +++++++++++++++++++++++++++++++++++
+ include/xen/physdev.h | 387 ++++++++++++++++++++
+ include/xen/trace.h | 339 ++++++++++++++++++
+ include/xen/xen.h | 104 ++++--
+ 7 files changed, 2142 insertions(+), 31 deletions(-)
+ create mode 100644 include/xen/hvm/hvm_op.h
+ create mode 100644 include/xen/hvm/params.h
+ create mode 100644 include/xen/hvm/start_info.h
+ create mode 100644 include/xen/memory.h
+ create mode 100644 include/xen/physdev.h
+ create mode 100644 include/xen/trace.h
+
+diff --git a/include/xen/hvm/hvm_op.h b/include/xen/hvm/hvm_op.h
+new file mode 100644
+index 000000000..0bdafdf59
+--- /dev/null
++++ b/include/xen/hvm/hvm_op.h
+@@ -0,0 +1,296 @@
++/*
++ * 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_HVM_OP_H__
++#define __XEN_PUBLIC_HVM_HVM_OP_H__
++
++#include "../xen.h"
++#include "../trace.h"
++#include "../event_channel.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_t index; /* IN */
++ uint64_t value; /* IN/OUT */
++};
++typedef struct xen_hvm_param xen_hvm_param_t;
++DEFINE_XEN_GUEST_HANDLE(xen_hvm_param_t);
++
++#if __XEN_INTERFACE_VERSION__ < 0x00040900
++
++/* Set the logical level of one of a domain's PCI INTx wires. */
++#define HVMOP_set_pci_intx_level 2
++struct xen_hvm_set_pci_intx_level {
++ /* Domain to be updated. */
++ domid_t domid;
++ /* PCI INTx identification in PCI topology (domain:bus:device:intx). */
++ uint8_t domain, bus, device, intx;
++ /* Assertion level (0 = unasserted, 1 = asserted). */
++ uint8_t level;
++};
++typedef struct xen_hvm_set_pci_intx_level xen_hvm_set_pci_intx_level_t;
++DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_pci_intx_level_t);
++
++/* Set the logical level of one of a domain's ISA IRQ wires. */
++#define HVMOP_set_isa_irq_level 3
++struct xen_hvm_set_isa_irq_level {
++ /* Domain to be updated. */
++ domid_t domid;
++ /* ISA device identification, by ISA IRQ (0-15). */
++ uint8_t isa_irq;
++ /* Assertion level (0 = unasserted, 1 = asserted). */
++ uint8_t level;
++};
++typedef struct xen_hvm_set_isa_irq_level xen_hvm_set_isa_irq_level_t;
++DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_isa_irq_level_t);
++
++#define HVMOP_set_pci_link_route 4
++struct xen_hvm_set_pci_link_route {
++ /* Domain to be updated. */
++ domid_t domid;
++ /* PCI link identifier (0-3). */
++ uint8_t link;
++ /* ISA IRQ (1-15), or 0 (disable link). */
++ uint8_t isa_irq;
++};
++typedef struct xen_hvm_set_pci_link_route xen_hvm_set_pci_link_route_t;
++DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_pci_link_route_t);
++
++#endif /* __XEN_INTERFACE_VERSION__ < 0x00040900 */
++
++/* Flushes all VCPU TLBs: @arg must be NULL. */
++#define HVMOP_flush_tlbs 5
++
++typedef enum {
++ HVMMEM_ram_rw, /* Normal read/write guest RAM */
++ HVMMEM_ram_ro, /* Read-only; writes are discarded */
++ HVMMEM_mmio_dm, /* Reads and write go to the device model */
++#if __XEN_INTERFACE_VERSION__ < 0x00040700
++ HVMMEM_mmio_write_dm, /* Read-only; writes go to the device model */
++#else
++ HVMMEM_unused, /* Placeholder; setting memory to this type
++ will fail for code after 4.7.0 */
++#endif
++ HVMMEM_ioreq_server /* Memory type claimed by an ioreq server; type
++ changes to this value are only allowed after
++ an ioreq server has claimed its ownership.
++ Only pages with HVMMEM_ram_rw are allowed to
++ change to this type; conversely, pages with
++ this type are only allowed to be changed back
++ to HVMMEM_ram_rw. */
++} hvmmem_type_t;
++
++/* Hint from PV drivers for pagetable destruction. */
++#define HVMOP_pagetable_dying 9
++struct xen_hvm_pagetable_dying {
++ /* Domain with a pagetable about to be destroyed. */
++ domid_t domid;
++ uint16_t pad[3]; /* align next field on 8-byte boundary */
++ /* guest physical address of the toplevel pagetable dying */
++ uint64_t gpa;
++};
++typedef struct xen_hvm_pagetable_dying xen_hvm_pagetable_dying_t;
++DEFINE_XEN_GUEST_HANDLE(xen_hvm_pagetable_dying_t);
++
++/* Get the current Xen time, in nanoseconds since system boot. */
++#define HVMOP_get_time 10
++struct xen_hvm_get_time {
++ uint64_t now; /* OUT */
++};
++typedef struct xen_hvm_get_time xen_hvm_get_time_t;
++DEFINE_XEN_GUEST_HANDLE(xen_hvm_get_time_t);
++
++#define HVMOP_xentrace 11
++struct xen_hvm_xentrace {
++ uint16_t event, extra_bytes;
++ uint8_t extra[TRACE_EXTRA_MAX * sizeof(uint32_t)];
++};
++typedef struct xen_hvm_xentrace xen_hvm_xentrace_t;
++DEFINE_XEN_GUEST_HANDLE(xen_hvm_xentrace_t);
++
++/* Following tools-only interfaces may change in future. */
++#if defined(__XEN__) || defined(__XEN_TOOLS__)
++
++/* Deprecated by XENMEM_access_op_set_access */
++#define HVMOP_set_mem_access 12
++
++/* Deprecated by XENMEM_access_op_get_access */
++#define HVMOP_get_mem_access 13
++
++#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */
++
++#define HVMOP_get_mem_type 15
++/* Return hvmmem_type_t for the specified pfn. */
++struct xen_hvm_get_mem_type {
++ /* Domain to be queried. */
++ domid_t domid;
++ /* OUT variable. */
++ uint16_t mem_type;
++ uint16_t pad[2]; /* align next field on 8-byte boundary */
++ /* IN variable. */
++ uint64_t pfn;
++};
++typedef struct xen_hvm_get_mem_type xen_hvm_get_mem_type_t;
++DEFINE_XEN_GUEST_HANDLE(xen_hvm_get_mem_type_t);
++
++/* Following tools-only interfaces may change in future. */
++#if defined(__XEN__) || defined(__XEN_TOOLS__)
++
++/*
++ * Definitions relating to DMOP_create_ioreq_server. (Defined here for
++ * backwards compatibility).
++ */
++
++#define HVM_IOREQSRV_BUFIOREQ_OFF 0
++#define HVM_IOREQSRV_BUFIOREQ_LEGACY 1
++/*
++ * Use this when read_pointer gets updated atomically and
++ * the pointer pair gets read atomically:
++ */
++#define HVM_IOREQSRV_BUFIOREQ_ATOMIC 2
++
++#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */
++
++#if defined(__i386__) || defined(__x86_64__)
++
++/*
++ * HVMOP_set_evtchn_upcall_vector: Set a <vector> that should be used for event
++ * channel upcalls on the specified <vcpu>. If set,
++ * this vector will be used in preference to the
++ * domain global callback via (see
++ * HVM_PARAM_CALLBACK_IRQ).
++ */
++#define HVMOP_set_evtchn_upcall_vector 23
++struct xen_hvm_evtchn_upcall_vector {
++ uint32_t vcpu;
++ uint8_t vector;
++};
++typedef struct xen_hvm_evtchn_upcall_vector xen_hvm_evtchn_upcall_vector_t;
++DEFINE_XEN_GUEST_HANDLE(xen_hvm_evtchn_upcall_vector_t);
++
++#endif /* defined(__i386__) || defined(__x86_64__) */
++
++#define HVMOP_guest_request_vm_event 24
++
++/* HVMOP_altp2m: perform altp2m state operations */
++#define HVMOP_altp2m 25
++
++#define HVMOP_ALTP2M_INTERFACE_VERSION 0x00000001
++
++struct xen_hvm_altp2m_domain_state {
++ /* IN or OUT variable on/off */
++ uint8_t state;
++};
++typedef struct xen_hvm_altp2m_domain_state xen_hvm_altp2m_domain_state_t;
++DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_domain_state_t);
++
++struct xen_hvm_altp2m_vcpu_enable_notify {
++ uint32_t vcpu_id;
++ uint32_t pad;
++ /* #VE info area gfn */
++ uint64_t gfn;
++};
++typedef struct xen_hvm_altp2m_vcpu_enable_notify xen_hvm_altp2m_vcpu_enable_notify_t;
++DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_vcpu_enable_notify_t);
++
++struct xen_hvm_altp2m_view {
++ /* IN/OUT variable */
++ uint16_t view;
++ /* Create view only: default access type
++ * NOTE: currently ignored */
++ uint16_t hvmmem_default_access; /* xenmem_access_t */
++};
++typedef struct xen_hvm_altp2m_view xen_hvm_altp2m_view_t;
++DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_view_t);
++
++struct xen_hvm_altp2m_set_mem_access {
++ /* view */
++ uint16_t view;
++ /* Memory type */
++ uint16_t hvmmem_access; /* xenmem_access_t */
++ uint32_t pad;
++ /* gfn */
++ uint64_t gfn;
++};
++typedef struct xen_hvm_altp2m_set_mem_access xen_hvm_altp2m_set_mem_access_t;
++DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_set_mem_access_t);
++
++struct xen_hvm_altp2m_change_gfn {
++ /* view */
++ uint16_t view;
++ uint16_t pad1;
++ uint32_t pad2;
++ /* old gfn */
++ uint64_t old_gfn;
++ /* new gfn, INVALID_GFN (~0UL) means revert */
++ uint64_t new_gfn;
++};
++typedef struct xen_hvm_altp2m_change_gfn xen_hvm_altp2m_change_gfn_t;
++DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_change_gfn_t);
++
++struct xen_hvm_altp2m_op {
++ uint32_t version; /* HVMOP_ALTP2M_INTERFACE_VERSION */
++ uint32_t cmd;
++/* Get/set the altp2m state for a domain */
++#define HVMOP_altp2m_get_domain_state 1
++#define HVMOP_altp2m_set_domain_state 2
++/* Set the current VCPU to receive altp2m event notifications */
++#define HVMOP_altp2m_vcpu_enable_notify 3
++/* Create a new view */
++#define HVMOP_altp2m_create_p2m 4
++/* Destroy a view */
++#define HVMOP_altp2m_destroy_p2m 5
++/* Switch view for an entire domain */
++#define HVMOP_altp2m_switch_p2m 6
++/* Notify that a page of memory is to have specific access types */
++#define HVMOP_altp2m_set_mem_access 7
++/* Change a p2m entry to have a different gfn->mfn mapping */
++#define HVMOP_altp2m_change_gfn 8
++ domid_t domain;
++ uint16_t pad1;
++ uint32_t pad2;
++ union {
++ struct xen_hvm_altp2m_domain_state domain_state;
++ struct xen_hvm_altp2m_vcpu_enable_notify enable_notify;
++ struct xen_hvm_altp2m_view view;
++ struct xen_hvm_altp2m_set_mem_access set_mem_access;
++ struct xen_hvm_altp2m_change_gfn change_gfn;
++ uint8_t pad[64];
++ } u;
++};
++typedef struct xen_hvm_altp2m_op xen_hvm_altp2m_op_t;
++DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_op_t);
++
++#endif /* __XEN_PUBLIC_HVM_HVM_OP_H__ */
++
++/*
++ * Local variables:
++ * mode: C
++ * c-file-style: "BSD"
++ * c-basic-offset: 4
++ * tab-width: 4
++ * indent-tabs-mode: nil
++ * End:
++ */
+diff --git a/include/xen/hvm/params.h b/include/xen/hvm/params.h
+new file mode 100644
+index 000000000..2ec2e7c80
+--- /dev/null
++++ b/include/xen/hvm/params.h
+@@ -0,0 +1,284 @@
++/*
++ * 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"
++
++/*
++ * 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_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__)
++
++/*
++ * 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)
++
++#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)
++
++#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
++
++/* Deprecated */
++#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
++
++/* 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_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)
++ */
++#define HVM_PARAM_ALTP2M 35
++#define XEN_ALTP2M_disabled 0
++#define XEN_ALTP2M_mixed 1
++#define XEN_ALTP2M_external 2
++#define XEN_ALTP2M_limited 3
++
++/*
++ * Size of the x87 FPU FIP/FDP registers that the hypervisor needs to
++ * save/restore. This is a workaround for a hardware limitation that
++ * does not allow the full FIP/FDP and FCS/FDS to be restored.
++ *
++ * Valid values are:
++ *
++ * 8: save/restore 64-bit FIP/FDP and clear FCS/FDS (default if CPU
++ * has FPCSDS feature).
++ *
++ * 4: save/restore 32-bit FIP/FDP, FCS/FDS, and clear upper 32-bits of
++ * FIP/FDP.
++ *
++ * 0: allow hypervisor to choose based on the value of FIP/FDP
++ * (default if CPU does not have FPCSDS).
++ *
++ * If FPCSDS (bit 13 in CPUID leaf 0x7, subleaf 0x0) is set, the CPU
++ * never saves FCS/FDS and this parameter should be left at the
++ * default of 8.
++ */
++#define HVM_PARAM_X87_FIP_WIDTH 36
++
++/*
++ * TSS (and its size) used on Intel when CR0.PE=0. The address occupies
++ * the low 32 bits, while the size is in the high 32 ones.
++ */
++#define HVM_PARAM_VM86_TSS_SIZED 37
++
++/* Enable MCA capabilities. */
++#define HVM_PARAM_MCA_CAP 38
++#define XEN_HVM_MCA_CAP_LMCE (xen_mk_ullong(1) << 0)
++#define XEN_HVM_MCA_CAP_MASK XEN_HVM_MCA_CAP_LMCE
++
++#define HVM_NR_PARAMS 39
++
++#endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */
+diff --git a/include/xen/hvm/start_info.h b/include/xen/hvm/start_info.h
+new file mode 100644
+index 000000000..648415976
+--- /dev/null
++++ b/include/xen/hvm/start_info.h
+@@ -0,0 +1,98 @@
++/*
++ * Permission is hereby granted, free of charge, to any person obtaining a copy
++ * of this software and associated documentation files (the "Software"), to
++ * deal in the Software without restriction, including without limitation the
++ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
++ * sell copies of the Software, and to permit persons to whom the Software is
++ * furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included in
++ * all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
++ * DEALINGS IN THE SOFTWARE.
++ *
++ * Copyright (c) 2016, Citrix Systems, Inc.
++ */
++
++#ifndef __XEN_PUBLIC_ARCH_X86_HVM_START_INFO_H__
++#define __XEN_PUBLIC_ARCH_X86_HVM_START_INFO_H__
++
++/*
++ * Start of day structure passed to PVH guests and to HVM guests in %ebx.
++ *
++ * NOTE: nothing will be loaded at physical address 0, so a 0 value in any
++ * of the address fields should be treated as not present.
++ *
++ * 0 +----------------+
++ * | magic | Contains the magic value XEN_HVM_START_MAGIC_VALUE
++ * | | ("xEn3" with the 0x80 bit of the "E" set).
++ * 4 +----------------+
++ * | version | Version of this structure. Current version is 0. New
++ * | | versions are guaranteed to be backwards-compatible.
++ * 8 +----------------+
++ * | flags | SIF_xxx flags.
++ * 12 +----------------+
++ * | nr_modules | Number of modules passed to the kernel.
++ * 16 +----------------+
++ * | modlist_paddr | Physical address of an array of modules
++ * | | (layout of the structure below).
++ * 24 +----------------+
++ * | cmdline_paddr | Physical address of the command line,
++ * | | a zero-terminated ASCII string.
++ * 32 +----------------+
++ * | rsdp_paddr | Physical address of the RSDP ACPI data structure.
++ * 40 +----------------+
++ *
++ * The layout of each entry in the module structure is the following:
++ *
++ * 0 +----------------+
++ * | paddr | Physical address of the module.
++ * 8 +----------------+
++ * | size | Size of the module in bytes.
++ * 16 +----------------+
++ * | cmdline_paddr | Physical address of the command line,
++ * | | a zero-terminated ASCII string.
++ * 24 +----------------+
++ * | reserved |
++ * 32 +----------------+
++ *
++ * The address and sizes are always a 64bit little endian unsigned integer.
++ *
++ * NB: Xen on x86 will always try to place all the data below the 4GiB
++ * boundary.
++ */
++#define XEN_HVM_START_MAGIC_VALUE 0x336ec578
++
++/*
++ * C representation of the x86/HVM start info layout.
++ *
++ * The canonical definition of this layout is above, this is just a way to
++ * represent the layout described there using C types.
++ */
++struct hvm_start_info {
++ uint32_t magic; /* Contains the magic value 0x336ec578 */
++ /* ("xEn3" with the 0x80 bit of the "E" set).*/
++ uint32_t version; /* Version of this structure. */
++ uint32_t flags; /* SIF_xxx flags. */
++ uint32_t nr_modules; /* Number of modules passed to the kernel. */
++ uint64_t modlist_paddr; /* Physical address of an array of */
++ /* hvm_modlist_entry. */
++ uint64_t cmdline_paddr; /* Physical address of the command line. */
++ uint64_t rsdp_paddr; /* Physical address of the RSDP ACPI data */
++ /* structure. */
++};
++
++struct hvm_modlist_entry {
++ uint64_t paddr; /* Physical address of the module. */
++ uint64_t size; /* Size of the module in bytes. */
++ uint64_t cmdline_paddr; /* Physical address of the command line. */
++ uint64_t reserved;
++};
++
++#endif /* __XEN_PUBLIC_ARCH_X86_HVM_START_INFO_H__ */
+diff --git a/include/xen/memory.h b/include/xen/memory.h
+new file mode 100644
+index 000000000..20deef5cb
+--- /dev/null
++++ b/include/xen/memory.h
+@@ -0,0 +1,665 @@
++/******************************************************************************
++ * 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@xensource.com>
++ */
++
++#ifndef __XEN_PUBLIC_MEMORY_H__
++#define __XEN_PUBLIC_MEMORY_H__
++
++#include "xen.h"
++#include "physdev.h"
++
++/*
++ * Increase or decrease the specified domain's memory reservation. Returns the
++ * number of extents successfully allocated or freed.
++ * arg == addr of struct xen_memory_reservation.
++ */
++#define XENMEM_increase_reservation 0
++#define XENMEM_decrease_reservation 1
++#define XENMEM_populate_physmap 6
++
++#if __XEN_INTERFACE_VERSION__ >= 0x00030209
++/*
++ * Maximum # bits addressable by the user of the allocated region (e.g., I/O
++ * devices often have a 32-bit limitation even in 64-bit systems). If zero
++ * then the user has no addressing restriction. This field is not used by
++ * XENMEM_decrease_reservation.
++ */
++#define XENMEMF_address_bits(x) (x)
++#define XENMEMF_get_address_bits(x) ((x) & 0xffu)
++/* NUMA node to allocate from. */
++#define XENMEMF_node(x) (((x) + 1) << 8)
++#define XENMEMF_get_node(x) ((((x) >> 8) - 1) & 0xffu)
++/* Flag to populate physmap with populate-on-demand entries */
++#define XENMEMF_populate_on_demand (1<<16)
++/* Flag to request allocation only from the node specified */
++#define XENMEMF_exact_node_request (1<<17)
++#define XENMEMF_exact_node(n) (XENMEMF_node(n) | XENMEMF_exact_node_request)
++/* Flag to indicate the node specified is virtual node */
++#define XENMEMF_vnode (1<<18)
++#endif
++
++struct xen_memory_reservation {
++
++ /*
++ * XENMEM_increase_reservation:
++ * OUT: MFN (*not* GMFN) bases of extents that were allocated
++ * XENMEM_decrease_reservation:
++ * IN: GMFN bases of extents to free
++ * XENMEM_populate_physmap:
++ * IN: GPFN bases of extents to populate with memory
++ * OUT: GMFN bases of extents that were allocated
++ * (NB. This command also updates the mach_to_phys translation table)
++ * XENMEM_claim_pages:
++ * IN: must be zero
++ */
++ XEN_GUEST_HANDLE(xen_pfn_t) extent_start;
++
++ /* Number of extents, and size/alignment of each (2^extent_order pages). */
++ xen_ulong_t nr_extents;
++ unsigned int extent_order;
++
++#if __XEN_INTERFACE_VERSION__ >= 0x00030209
++ /* XENMEMF flags. */
++ unsigned int mem_flags;
++#else
++ unsigned int address_bits;
++#endif
++
++ /*
++ * Domain whose reservation is being changed.
++ * Unprivileged domains can specify only DOMID_SELF.
++ */
++ domid_t domid;
++};
++typedef struct xen_memory_reservation xen_memory_reservation_t;
++DEFINE_XEN_GUEST_HANDLE(xen_memory_reservation_t);
++
++/*
++ * An atomic exchange of memory pages. If return code is zero then
++ * @out.extent_list provides GMFNs of the newly-allocated memory.
++ * Returns zero on complete success, otherwise a negative error code.
++ * On complete success then always @nr_exchanged == @in.nr_extents.
++ * On partial success @nr_exchanged indicates how much work was done.
++ *
++ * Note that only PV guests can use this operation.
++ */
++#define XENMEM_exchange 11
++struct xen_memory_exchange {
++ /*
++ * [IN] Details of memory extents to be exchanged (GMFN bases).
++ * Note that @in.address_bits is ignored and unused.
++ */
++ struct xen_memory_reservation in;
++
++ /*
++ * [IN/OUT] Details of new memory extents.
++ * We require that:
++ * 1. @in.domid == @out.domid
++ * 2. @in.nr_extents << @in.extent_order ==
++ * @out.nr_extents << @out.extent_order
++ * 3. @in.extent_start and @out.extent_start lists must not overlap
++ * 4. @out.extent_start lists GPFN bases to be populated
++ * 5. @out.extent_start is overwritten with allocated GMFN bases
++ */
++ struct xen_memory_reservation out;
++
++ /*
++ * [OUT] Number of input extents that were successfully exchanged:
++ * 1. The first @nr_exchanged input extents were successfully
++ * deallocated.
++ * 2. The corresponding first entries in the output extent list correctly
++ * indicate the GMFNs that were successfully exchanged.
++ * 3. All other input and output extents are untouched.
++ * 4. If not all input exents are exchanged then the return code of this
++ * command will be non-zero.
++ * 5. THIS FIELD MUST BE INITIALISED TO ZERO BY THE CALLER!
++ */
++ xen_ulong_t nr_exchanged;
++};
++typedef struct xen_memory_exchange xen_memory_exchange_t;
++DEFINE_XEN_GUEST_HANDLE(xen_memory_exchange_t);
++
++/*
++ * Returns the maximum machine frame number of mapped RAM in this system.
++ * This command always succeeds (it never returns an error code).
++ * arg == NULL.
++ */
++#define XENMEM_maximum_ram_page 2
++
++/*
++ * Returns the current or maximum memory reservation, in pages, of the
++ * specified domain (may be DOMID_SELF). Returns -ve errcode on failure.
++ * arg == addr of domid_t.
++ */
++#define XENMEM_current_reservation 3
++#define XENMEM_maximum_reservation 4
++
++/*
++ * Returns the maximum GPFN in use by the guest, or -ve errcode on failure.
++ */
++#define XENMEM_maximum_gpfn 14
++
++/*
++ * Returns a list of MFN bases of 2MB extents comprising the machine_to_phys
++ * mapping table. Architectures which do not have a m2p table do not implement
++ * this command.
++ * arg == addr of xen_machphys_mfn_list_t.
++ */
++#define XENMEM_machphys_mfn_list 5
++struct xen_machphys_mfn_list {
++ /*
++ * Size of the 'extent_start' array. Fewer entries will be filled if the
++ * machphys table is smaller than max_extents * 2MB.
++ */
++ unsigned int max_extents;
++
++ /*
++ * Pointer to buffer to fill with list of extent starts. If there are
++ * any large discontiguities in the machine address space, 2MB gaps in
++ * the machphys table will be represented by an MFN base of zero.
++ */
++ XEN_GUEST_HANDLE(xen_pfn_t) extent_start;
++
++ /*
++ * Number of extents written to the above array. This will be smaller
++ * than 'max_extents' if the machphys table is smaller than max_e * 2MB.
++ */
++ unsigned int nr_extents;
++};
++typedef struct xen_machphys_mfn_list xen_machphys_mfn_list_t;
++DEFINE_XEN_GUEST_HANDLE(xen_machphys_mfn_list_t);
++
++/*
++ * For a compat caller, this is identical to XENMEM_machphys_mfn_list.
++ *
++ * For a non compat caller, this functions similarly to
++ * XENMEM_machphys_mfn_list, but returns the mfns making up the compatibility
++ * m2p table.
++ */
++#define XENMEM_machphys_compat_mfn_list 25
++
++/*
++ * Returns the location in virtual address space of the machine_to_phys
++ * mapping table. Architectures which do not have a m2p table, or which do not
++ * map it by default into guest address space, do not implement this command.
++ * arg == addr of xen_machphys_mapping_t.
++ */
++#define XENMEM_machphys_mapping 12
++struct xen_machphys_mapping {
++ xen_ulong_t v_start, v_end; /* Start and end virtual addresses. */
++ xen_ulong_t max_mfn; /* Maximum MFN that can be looked up. */
++};
++typedef struct xen_machphys_mapping xen_machphys_mapping_t;
++DEFINE_XEN_GUEST_HANDLE(xen_machphys_mapping_t);
++
++/* 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. */
++#define XENMAPSPACE_dev_mmio 5 /* device mmio region
++ ARM only; the region is mapped in
++ Stage-2 using the Normal Memory
++ Inner/Outer Write-Back Cacheable
++ memory attribute. */
++/* ` } */
++
++/*
++ * 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_t size;
++
++ unsigned int 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);
++
++/* A batched version of add_to_physmap. */
++#define XENMEM_add_to_physmap_batch 23
++struct xen_add_to_physmap_batch {
++ /* IN */
++ /* Which domain to change the mapping for. */
++ domid_t domid;
++ uint16_t space; /* => enum phys_map_space */
++
++ /* Number of pages to go through */
++ uint16_t size;
++
++#if __XEN_INTERFACE_VERSION__ < 0x00040700
++ domid_t foreign_domid; /* IFF gmfn_foreign. Should be 0 for other spaces. */
++#else
++ union xen_add_to_physmap_batch_extra {
++ domid_t foreign_domid; /* gmfn_foreign */
++ uint16_t res0; /* All the other spaces. Should be 0 */
++ } u;
++#endif
++
++ /* Indexes into space being mapped. */
++ XEN_GUEST_HANDLE(xen_ulong_t) idxs;
++
++ /* GPFN in domid where the source mapping page should appear. */
++ XEN_GUEST_HANDLE(xen_pfn_t) gpfns;
++
++ /* OUT */
++
++ /* Per index error code. */
++ XEN_GUEST_HANDLE(int) errs;
++};
++typedef struct xen_add_to_physmap_batch xen_add_to_physmap_batch_t;
++DEFINE_XEN_GUEST_HANDLE(xen_add_to_physmap_batch_t);
++
++#if __XEN_INTERFACE_VERSION__ < 0x00040400
++#define XENMEM_add_to_physmap_range XENMEM_add_to_physmap_batch
++#define xen_add_to_physmap_range xen_add_to_physmap_batch
++typedef struct xen_add_to_physmap_batch xen_add_to_physmap_range_t;
++DEFINE_XEN_GUEST_HANDLE(xen_add_to_physmap_range_t);
++#endif
++
++/*
++ * 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);
++
++/*** REMOVED ***/
++/*#define XENMEM_translate_gpfn_list 8*/
++
++/*
++ * Returns the pseudo-physical memory map as it was when the domain
++ * was started (specified by XENMEM_set_memory_map).
++ * arg == addr of xen_memory_map_t.
++ */
++#define XENMEM_memory_map 9
++struct xen_memory_map {
++ /*
++ * On call the number of entries which can be stored in buffer. On
++ * return the number of entries which have been stored in
++ * buffer.
++ */
++ unsigned int nr_entries;
++
++ /*
++ * Entries in the buffer are in the same format as returned by the
++ * BIOS INT 0x15 EAX=0xE820 call.
++ */
++ XEN_GUEST_HANDLE(void) buffer;
++};
++typedef struct xen_memory_map xen_memory_map_t;
++DEFINE_XEN_GUEST_HANDLE(xen_memory_map_t);
++
++/*
++ * Returns the real physical memory map. Passes the same structure as
++ * XENMEM_memory_map.
++ * Specifying buffer as NULL will return the number of entries required
++ * to store the complete memory map.
++ * arg == addr of xen_memory_map_t.
++ */
++#define XENMEM_machine_memory_map 10
++
++/*
++ * Set the pseudo-physical memory map of a domain, as returned by
++ * XENMEM_memory_map.
++ * arg == addr of xen_foreign_memory_map_t.
++ */
++#define XENMEM_set_memory_map 13
++struct xen_foreign_memory_map {
++ domid_t domid;
++ struct xen_memory_map map;
++};
++typedef struct xen_foreign_memory_map xen_foreign_memory_map_t;
++DEFINE_XEN_GUEST_HANDLE(xen_foreign_memory_map_t);
++
++#define XENMEM_set_pod_target 16
++#define XENMEM_get_pod_target 17
++struct xen_pod_target {
++ /* IN */
++ uint64_t target_pages;
++ /* OUT */
++ uint64_t tot_pages;
++ uint64_t pod_cache_pages;
++ uint64_t pod_entries;
++ /* IN */
++ domid_t domid;
++};
++typedef struct xen_pod_target xen_pod_target_t;
++
++#if defined(__XEN__) || defined(__XEN_TOOLS__)
++
++#ifndef uint64_aligned_t
++#define uint64_aligned_t uint64_t
++#endif
++
++/*
++ * Get the number of MFNs saved through memory sharing.
++ * The call never fails.
++ */
++#define XENMEM_get_sharing_freed_pages 18
++#define XENMEM_get_sharing_shared_pages 19
++
++#define XENMEM_paging_op 20
++#define XENMEM_paging_op_nominate 0
++#define XENMEM_paging_op_evict 1
++#define XENMEM_paging_op_prep 2
++
++struct xen_mem_paging_op {
++ uint8_t op; /* XENMEM_paging_op_* */
++ domid_t domain;
++
++ /* PAGING_PREP IN: buffer to immediately fill page in */
++ uint64_aligned_t buffer;
++ /* Other OPs */
++ uint64_aligned_t gfn; /* IN: gfn of page being operated on */
++};
++typedef struct xen_mem_paging_op xen_mem_paging_op_t;
++DEFINE_XEN_GUEST_HANDLE(xen_mem_paging_op_t);
++
++#define XENMEM_access_op 21
++#define XENMEM_access_op_set_access 0
++#define XENMEM_access_op_get_access 1
++/*
++ * XENMEM_access_op_enable_emulate and XENMEM_access_op_disable_emulate are
++ * currently unused, but since they have been in use please do not reuse them.
++ *
++ * #define XENMEM_access_op_enable_emulate 2
++ * #define XENMEM_access_op_disable_emulate 3
++ */
++#define XENMEM_access_op_set_access_multi 4
++
++typedef enum {
++ XENMEM_access_n,
++ XENMEM_access_r,
++ XENMEM_access_w,
++ XENMEM_access_rw,
++ XENMEM_access_x,
++ XENMEM_access_rx,
++ XENMEM_access_wx,
++ XENMEM_access_rwx,
++ /*
++ * Page starts off as r-x, but automatically
++ * change to r-w on a write
++ */
++ XENMEM_access_rx2rw,
++ /*
++ * Log access: starts off as n, automatically
++ * goes to rwx, generating an event without
++ * pausing the vcpu
++ */
++ XENMEM_access_n2rwx,
++ /* Take the domain default */
++ XENMEM_access_default
++} xenmem_access_t;
++
++struct xen_mem_access_op {
++ /* XENMEM_access_op_* */
++ uint8_t op;
++ /* xenmem_access_t */
++ uint8_t access;
++ domid_t domid;
++ /*
++ * Number of pages for set op (or size of pfn_list for
++ * XENMEM_access_op_set_access_multi)
++ * Ignored on setting default access and other ops
++ */
++ uint32_t nr;
++ /*
++ * First pfn for set op
++ * pfn for get op
++ * ~0ull is used to set and get the default access for pages
++ */
++ uint64_aligned_t pfn;
++ /*
++ * List of pfns to set access for
++ * Used only with XENMEM_access_op_set_access_multi
++ */
++ XEN_GUEST_HANDLE(const_uint64) pfn_list;
++ /*
++ * Corresponding list of access settings for pfn_list
++ * Used only with XENMEM_access_op_set_access_multi
++ */
++ XEN_GUEST_HANDLE(const_uint8) access_list;
++};
++typedef struct xen_mem_access_op xen_mem_access_op_t;
++DEFINE_XEN_GUEST_HANDLE(xen_mem_access_op_t);
++
++#define XENMEM_sharing_op 22
++#define XENMEM_sharing_op_nominate_gfn 0
++#define XENMEM_sharing_op_nominate_gref 1
++#define XENMEM_sharing_op_share 2
++#define XENMEM_sharing_op_debug_gfn 3
++#define XENMEM_sharing_op_debug_mfn 4
++#define XENMEM_sharing_op_debug_gref 5
++#define XENMEM_sharing_op_add_physmap 6
++#define XENMEM_sharing_op_audit 7
++#define XENMEM_sharing_op_range_share 8
++
++#define XENMEM_SHARING_OP_S_HANDLE_INVALID (-10)
++#define XENMEM_SHARING_OP_C_HANDLE_INVALID (-9)
++
++/* The following allows sharing of grant refs. This is useful
++ * for sharing utilities sitting as "filters" in IO backends
++ * (e.g. memshr + blktap(2)). The IO backend is only exposed
++ * to grant references, and this allows sharing of the grefs */
++#define XENMEM_SHARING_OP_FIELD_IS_GREF_FLAG (xen_mk_ullong(1) << 62)
++
++#define XENMEM_SHARING_OP_FIELD_MAKE_GREF(field, val) \
++ (field) = (XENMEM_SHARING_OP_FIELD_IS_GREF_FLAG | val)
++#define XENMEM_SHARING_OP_FIELD_IS_GREF(field) \
++ ((field) & XENMEM_SHARING_OP_FIELD_IS_GREF_FLAG)
++#define XENMEM_SHARING_OP_FIELD_GET_GREF(field) \
++ ((field) & (~XENMEM_SHARING_OP_FIELD_IS_GREF_FLAG))
++
++struct xen_mem_sharing_op {
++ uint8_t op; /* XENMEM_sharing_op_* */
++ domid_t domain;
++
++ union {
++ struct mem_sharing_op_nominate { /* OP_NOMINATE_xxx */
++ union {
++ uint64_aligned_t gfn; /* IN: gfn to nominate */
++ uint32_t grant_ref; /* IN: grant ref to nominate */
++ } u;
++ uint64_aligned_t handle; /* OUT: the handle */
++ } nominate;
++ struct mem_sharing_op_share { /* OP_SHARE/ADD_PHYSMAP */
++ uint64_aligned_t source_gfn; /* IN: the gfn of the source page */
++ uint64_aligned_t source_handle; /* IN: handle to the source page */
++ uint64_aligned_t client_gfn; /* IN: the client gfn */
++ uint64_aligned_t client_handle; /* IN: handle to the client page */
++ domid_t client_domain; /* IN: the client domain id */
++ } share;
++ struct mem_sharing_op_range { /* OP_RANGE_SHARE */
++ uint64_aligned_t first_gfn; /* IN: the first gfn */
++ uint64_aligned_t last_gfn; /* IN: the last gfn */
++ uint64_aligned_t opaque; /* Must be set to 0 */
++ domid_t client_domain; /* IN: the client domain id */
++ uint16_t _pad[3]; /* Must be set to 0 */
++ } range;
++ struct mem_sharing_op_debug { /* OP_DEBUG_xxx */
++ union {
++ uint64_aligned_t gfn; /* IN: gfn to debug */
++ uint64_aligned_t mfn; /* IN: mfn to debug */
++ uint32_t gref; /* IN: gref to debug */
++ } u;
++ } debug;
++ } u;
++};
++typedef struct xen_mem_sharing_op xen_mem_sharing_op_t;
++DEFINE_XEN_GUEST_HANDLE(xen_mem_sharing_op_t);
++
++/*
++ * Attempt to stake a claim for a domain on a quantity of pages
++ * of system RAM, but _not_ assign specific pageframes. Only
++ * arithmetic is performed so the hypercall is very fast and need
++ * not be preemptible, thus sidestepping time-of-check-time-of-use
++ * races for memory allocation. Returns 0 if the hypervisor page
++ * allocator has atomically and successfully claimed the requested
++ * number of pages, else non-zero.
++ *
++ * Any domain may have only one active claim. When sufficient memory
++ * has been allocated to resolve the claim, the claim silently expires.
++ * Claiming zero pages effectively resets any outstanding claim and
++ * is always successful.
++ *
++ * Note that a valid claim may be staked even after memory has been
++ * allocated for a domain. In this case, the claim is not incremental,
++ * i.e. if the domain's tot_pages is 3, and a claim is staked for 10,
++ * only 7 additional pages are claimed.
++ *
++ * Caller must be privileged or the hypercall fails.
++ */
++#define XENMEM_claim_pages 24
++
++/*
++ * XENMEM_claim_pages flags - the are no flags at this time.
++ * The zero value is appropriate.
++ */
++
++/*
++ * With some legacy devices, certain guest-physical addresses cannot safely
++ * be used for other purposes, e.g. to map guest RAM. This hypercall
++ * enumerates those regions so the toolstack can avoid using them.
++ */
++#define XENMEM_reserved_device_memory_map 27
++struct xen_reserved_device_memory {
++ xen_pfn_t start_pfn;
++ xen_ulong_t nr_pages;
++};
++typedef struct xen_reserved_device_memory xen_reserved_device_memory_t;
++DEFINE_XEN_GUEST_HANDLE(xen_reserved_device_memory_t);
++
++struct xen_reserved_device_memory_map {
++#define XENMEM_RDM_ALL 1 /* Request all regions (ignore dev union). */
++ /* IN */
++ uint32_t flags;
++ /*
++ * IN/OUT
++ *
++ * Gets set to the required number of entries when too low,
++ * signaled by error code -ERANGE.
++ */
++ unsigned int nr_entries;
++ /* OUT */
++ XEN_GUEST_HANDLE(xen_reserved_device_memory_t) buffer;
++ /* IN */
++ union {
++ struct physdev_pci_device pci;
++ } dev;
++};
++typedef struct xen_reserved_device_memory_map xen_reserved_device_memory_map_t;
++DEFINE_XEN_GUEST_HANDLE(xen_reserved_device_memory_map_t);
++
++#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */
++
++/*
++ * XENMEM_get_vnumainfo used by guest to get
++ * vNUMA topology from hypervisor.
++ */
++#define XENMEM_get_vnumainfo 26
++
++/* vNUMA node memory ranges */
++struct xen_vmemrange {
++ uint64_t start, end;
++ unsigned int flags;
++ unsigned int nid;
++};
++typedef struct xen_vmemrange xen_vmemrange_t;
++DEFINE_XEN_GUEST_HANDLE(xen_vmemrange_t);
++
++/*
++ * vNUMA topology specifies vNUMA node number, distance table,
++ * memory ranges and vcpu mapping provided for guests.
++ * XENMEM_get_vnumainfo hypercall expects to see from guest
++ * nr_vnodes, nr_vmemranges and nr_vcpus to indicate available memory.
++ * After filling guests structures, nr_vnodes, nr_vmemranges and nr_vcpus
++ * copied back to guest. Domain returns expected values of nr_vnodes,
++ * nr_vmemranges and nr_vcpus to guest if the values where incorrect.
++ */
++struct xen_vnuma_topology_info {
++ /* IN */
++ domid_t domid;
++ uint16_t pad;
++ /* IN/OUT */
++ unsigned int nr_vnodes;
++ unsigned int nr_vcpus;
++ unsigned int nr_vmemranges;
++ /* OUT */
++ union {
++ XEN_GUEST_HANDLE(uint) h;
++ uint64_t pad;
++ } vdistance;
++ union {
++ XEN_GUEST_HANDLE(uint) h;
++ uint64_t pad;
++ } vcpu_to_vnode;
++ union {
++ XEN_GUEST_HANDLE(xen_vmemrange_t) h;
++ uint64_t pad;
++ } vmemrange;
++};
++typedef struct xen_vnuma_topology_info xen_vnuma_topology_info_t;
++DEFINE_XEN_GUEST_HANDLE(xen_vnuma_topology_info_t);
++
++/* Next available subop number is 28 */
++
++#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/include/xen/physdev.h b/include/xen/physdev.h
+new file mode 100644
+index 000000000..b6faf8350
+--- /dev/null
++++ b/include/xen/physdev.h
+@@ -0,0 +1,387 @@
++/*
++ * 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 {
++ struct physdev_irq_status_query irq_status_query;
++ struct physdev_set_iopl set_iopl;
++ struct physdev_set_iobitmap set_iobitmap;
++ struct physdev_apic apic_op;
++ struct physdev_irq 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)
++ */
++#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
++ uint32_t optarr[];
++#elif defined(__GNUC__)
++ uint32_t optarr[0];
++#endif
++};
++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 {
++ struct physdev_pci_device 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:
++ */
+diff --git a/include/xen/trace.h b/include/xen/trace.h
+new file mode 100644
+index 000000000..a00c01733
+--- /dev/null
++++ b/include/xen/trace.h
+@@ -0,0 +1,339 @@
++/******************************************************************************
++ * 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_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:
++ */
+diff --git a/include/xen/xen.h b/include/xen/xen.h
+index 6c9e42b2b..308109f17 100644
+--- a/include/xen/xen.h
++++ b/include/xen/xen.h
+@@ -53,17 +53,22 @@ DEFINE_XEN_GUEST_HANDLE(uint64_t);
+ DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
+ DEFINE_XEN_GUEST_HANDLE(xen_ulong_t);
+
+-/* Turn a plain number into a C unsigned (long) constant. */
++/* Turn a plain number into a C unsigned (long (long)) constant. */
+ #define __xen_mk_uint(x) x ## U
+ #define __xen_mk_ulong(x) x ## UL
++#ifndef __xen_mk_ullong
++# define __xen_mk_ullong(x) x ## ULL
++#endif
+ #define xen_mk_uint(x) __xen_mk_uint(x)
+ #define xen_mk_ulong(x) __xen_mk_ulong(x)
++#define xen_mk_ullong(x) __xen_mk_ullong(x)
+
+ #else
+
+ /* In assembly code we cannot use C numeric constant suffixes. */
+-#define xen_mk_uint(x) x
+-#define xen_mk_ulong(x) x
++#define xen_mk_uint(x) x
++#define xen_mk_ulong(x) x
++#define xen_mk_ullong(x) x
+
+ #endif
+
+@@ -115,6 +120,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_ulong_t);
+ #define __HYPERVISOR_tmem_op 38
+ #define __HYPERVISOR_xc_reserved_op 39 /* reserved for XenClient */
+ #define __HYPERVISOR_xenpmu_op 40
++#define __HYPERVISOR_dm_op 41
+
+ /* Architecture-specific hypercall definitions. */
+ #define __HYPERVISOR_arch_0 48
+@@ -501,6 +507,21 @@ DEFINE_XEN_GUEST_HANDLE(mmuext_op_t);
+ /* x86/PAE guests: support PDPTs above 4GB. */
+ #define VMASST_TYPE_pae_extended_cr3 3
+
++/*
++ * x86 guests: Sane behaviour for virtual iopl
++ * - virtual iopl updated from do_iret() hypercalls.
++ * - virtual iopl reported in bounce frames.
++ * - guest kernels assumed to be level 0 for the purpose of iopl checks.
++ */
++#define VMASST_TYPE_architectural_iopl 4
++
++/*
++ * All guests: activate update indicator in vcpu_runstate_info
++ * Enable setting the XEN_RUNSTATE_UPDATE flag in guest memory mapped
++ * vcpu_runstate_info during updates of the runstate information.
++ */
++#define VMASST_TYPE_runstate_update_flag 5
++
+ /*
+ * x86/64 guests: strictly hide M2P from user mode.
+ * This allows the guest to control respective hypervisor behavior:
+@@ -529,16 +550,21 @@ DEFINE_XEN_GUEST_HANDLE(mmuext_op_t);
+ * is useful to ensure that no mappings to the OS's own heap are accidentally
+ * installed. (e.g., in Linux this could cause havoc as reference counts
+ * aren't adjusted on the I/O-mapping code path).
+- * This only makes sense in MMUEXT_SET_FOREIGNDOM, but in that context can
+- * be specified by any calling domain.
++ * This only makes sense as HYPERVISOR_mmu_update()'s and
++ * HYPERVISOR_update_va_mapping_otherdomain()'s "foreigndom" argument. For
++ * HYPERVISOR_mmu_update() context it can be specified by any calling domain,
++ * otherwise it's only permitted if the caller is privileged.
+ */
+ #define DOMID_IO xen_mk_uint(0x7FF1)
+
+ /*
+ * DOMID_XEN is used to allow privileged domains to map restricted parts of
+ * Xen's heap space (e.g., the machine_to_phys table).
+- * This only makes sense in MMUEXT_SET_FOREIGNDOM, and is only permitted if
+- * the caller is privileged.
++ * This only makes sense as
++ * - HYPERVISOR_mmu_update()'s, HYPERVISOR_mmuext_op()'s, or
++ * HYPERVISOR_update_va_mapping_otherdomain()'s "foreigndom" argument,
++ * - with XENMAPSPACE_gmfn_foreign,
++ * and is only permitted if the caller is privileged.
+ */
+ #define DOMID_XEN xen_mk_uint(0x7FF2)
+
+@@ -614,10 +640,18 @@ struct vcpu_time_info {
+ */
+ uint32_t tsc_to_system_mul;
+ int8_t tsc_shift;
++#if __XEN_INTERFACE_VERSION__ > 0x040600
++ uint8_t flags;
++ uint8_t pad1[2];
++#else
+ int8_t pad1[3];
++#endif
+ }; /* 32 bytes */
+ typedef struct vcpu_time_info vcpu_time_info_t;
+
++#define XEN_PVCLOCK_TSC_STABLE_BIT (1 << 0)
++#define XEN_PVCLOCK_GUEST_STOPPED (1 << 1)
++
+ struct vcpu_info {
+ /*
+ * 'evtchn_upcall_pending' is written non-zero by Xen to indicate
+@@ -736,7 +770,7 @@ typedef struct shared_info shared_info_t;
+ * (may be omitted)
+ * c. list of allocated page frames [mfn_list, nr_pages]
+ * (unless relocated due to XEN_ELFNOTE_INIT_P2M)
+- * d. start_info_t structure [register ESI (x86)]
++ * d. start_info_t structure [register rSI (x86)]
+ * in case of dom0 this page contains the console info, too
+ * e. unless dom0: xenstore ring page
+ * f. unless dom0: console ring page
+@@ -797,29 +831,6 @@ struct start_info {
+ };
+ typedef struct start_info start_info_t;
+
+-/*
+- * Start of day structure passed to PVH guests in %ebx.
+- *
+- * NOTE: nothing will be loaded at physical address 0, so
+- * a 0 value in any of the address fields should be treated
+- * as not present.
+- */
+-struct hvm_start_info {
+-#define HVM_START_MAGIC_VALUE 0x336ec578
+- uint32_t magic; /* Contains the magic value 0x336ec578 */
+- /* ("xEn3" with the 0x80 bit of the "E" set).*/
+- uint32_t flags; /* SIF_xxx flags. */
+- uint32_t cmdline_paddr; /* Physical address of the command line. */
+- uint32_t nr_modules; /* Number of modules passed to the kernel. */
+- uint32_t modlist_paddr; /* Physical address of an array of */
+- /* hvm_modlist_entry. */
+-};
+-
+-struct hvm_modlist_entry {
+- uint32_t paddr; /* Physical address of the module. */
+- uint32_t size; /* Size of the module in bytes. */
+-};
+-
+ /* New console union for dom0 introduced in 0x00030203. */
+ #if __XEN_INTERFACE_VERSION__ < 0x00030203
+ #define console_mfn console.domU.mfn
+@@ -919,6 +930,37 @@ __DEFINE_XEN_GUEST_HANDLE(uint16, uint16_t);
+ __DEFINE_XEN_GUEST_HANDLE(uint32, uint32_t);
+ __DEFINE_XEN_GUEST_HANDLE(uint64, uint64_t);
+
++typedef struct {
++ uint8_t a[16];
++} xen_uuid_t;
++
++/*
++ * XEN_DEFINE_UUID(0x00112233, 0x4455, 0x6677, 0x8899,
++ * 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff)
++ * will construct UUID 00112233-4455-6677-8899-aabbccddeeff presented as
++ * {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
++ * 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
++ *
++ * NB: This is compatible with Linux kernel and with libuuid, but it is not
++ * compatible with Microsoft, as they use mixed-endian encoding (some
++ * components are little-endian, some are big-endian).
++ */
++#define XEN_DEFINE_UUID_(a, b, c, d, e1, e2, e3, e4, e5, e6) \
++ {{((a) >> 24) & 0xFF, ((a) >> 16) & 0xFF, \
++ ((a) >> 8) & 0xFF, ((a) >> 0) & 0xFF, \
++ ((b) >> 8) & 0xFF, ((b) >> 0) & 0xFF, \
++ ((c) >> 8) & 0xFF, ((c) >> 0) & 0xFF, \
++ ((d) >> 8) & 0xFF, ((d) >> 0) & 0xFF, \
++ e1, e2, e3, e4, e5, e6}}
++
++#if defined(__STDC_VERSION__) ? __STDC_VERSION__ >= 199901L : defined(__GNUC__)
++#define XEN_DEFINE_UUID(a, b, c, d, e1, e2, e3, e4, e5, e6) \
++ ((xen_uuid_t)XEN_DEFINE_UUID_(a, b, c, d, e1, e2, e3, e4, e5, e6))
++#else
++#define XEN_DEFINE_UUID(a, b, c, d, e1, e2, e3, e4, e5, e6) \
++ XEN_DEFINE_UUID_(a, b, c, d, e1, e2, e3, e4, e5, e6)
++#endif /* __STDC_VERSION__ / __GNUC__ */
++
+ #endif /* !__ASSEMBLY__ */
+
+ /* Default definitions for macros used by domctl/sysctl. */
+--
+2.21.0
+
diff --git a/main/grub/0002-loader-linux-Support-passing-RSDP-address-via-boot-p.patch b/main/grub/0002-loader-linux-Support-passing-RSDP-address-via-boot-p.patch
new file mode 100644
index 0000000000..83f55c2681
--- /dev/null
+++ b/main/grub/0002-loader-linux-Support-passing-RSDP-address-via-boot-p.patch
@@ -0,0 +1,51 @@
+From b800b2b23ac56a5d0fb39b1acfcd9e3d4e0a93c0 Mon Sep 17 00:00:00 2001
+From: Juergen Gross <jgross@suse.com>
+Date: Fri, 7 Dec 2018 13:11:30 +0100
+Subject: [PATCH 02/20] loader/linux: Support passing RSDP address via boot
+ params
+
+Xen PVH guests will have the RSDP at an arbitrary address. Support that
+by passing the RSDP address via the boot parameters to Linux.
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+Tested-by: Hans van Kranenburg <hans@knorrie.org>
+(cherry picked from commit d170be42f12b0b2ab91d8d943d7b0bf563c906dd)
+---
+ grub-core/loader/i386/linux.c | 4 ++++
+ include/grub/i386/linux.h | 3 ++-
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
+index 083f9417c..7d6d5d499 100644
+--- a/grub-core/loader/i386/linux.c
++++ b/grub-core/loader/i386/linux.c
+@@ -551,6 +551,10 @@ grub_linux_boot (void)
+ }
+ }
+
++#ifdef GRUB_KERNEL_USE_RSDP_ADDR
++ linux_params.acpi_rsdp_addr = grub_le_to_cpu64 (grub_rsdp_addr);
++#endif
++
+ mmap_size = find_mmap_size ();
+ /* Make sure that each size is aligned to a page boundary. */
+ cl_offset = ALIGN_UP (mmap_size + sizeof (linux_params), 4096);
+diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h
+index da0ca3b83..ada068fa5 100644
+--- a/include/grub/i386/linux.h
++++ b/include/grub/i386/linux.h
+@@ -206,8 +206,9 @@ struct linux_kernel_params
+ grub_uint32_t ist_command; /* 64 */
+ grub_uint32_t ist_event; /* 68 */
+ grub_uint32_t ist_perf_level; /* 6c */
++ grub_uint64_t acpi_rsdp_addr; /* 70 */
+
+- grub_uint8_t padding5[0x80 - 0x70];
++ grub_uint8_t padding5[0x80 - 0x78];
+
+ grub_uint8_t hd0_drive_info[0x10]; /* 80 */
+ grub_uint8_t hd1_drive_info[0x10]; /* 90 */
+--
+2.21.0
+
diff --git a/main/grub/0003-xen-Carve-out-grant-tab-initialization-into-dedicate.patch b/main/grub/0003-xen-Carve-out-grant-tab-initialization-into-dedicate.patch
new file mode 100644
index 0000000000..daaae83c8a
--- /dev/null
+++ b/main/grub/0003-xen-Carve-out-grant-tab-initialization-into-dedicate.patch
@@ -0,0 +1,89 @@
+From 7c45df9ded4ca3201cf468de899bad28e4ac8c55 Mon Sep 17 00:00:00 2001
+From: Juergen Gross <jgross@suse.com>
+Date: Fri, 7 Dec 2018 13:11:31 +0100
+Subject: [PATCH 03/20] xen: Carve out grant tab initialization into dedicated
+ function
+
+Initialize the grant tab in a dedicated function. This will enable
+using it for PVH guests, too.
+
+Call the new function from grub_machine_init() as this will later
+be common between Xen PV and Xen PVH mode.
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+Tested-by: Hans van Kranenburg <hans@knorrie.org>
+(cherry picked from commit c84927272cea59084ad5b0705c55547e8c85b28d)
+---
+ grub-core/kern/xen/init.c | 35 +++++++++++++++++++++--------------
+ 1 file changed, 21 insertions(+), 14 deletions(-)
+
+diff --git a/grub-core/kern/xen/init.c b/grub-core/kern/xen/init.c
+index 0559c033c..29f5bc23d 100644
+--- a/grub-core/kern/xen/init.c
++++ b/grub-core/kern/xen/init.c
+@@ -318,6 +318,25 @@ grub_xenstore_dir (const char *dir,
+
+ unsigned long gntframe = 0;
+
++static void
++grub_xen_setup_gnttab (void)
++{
++ struct gnttab_set_version gnttab_setver;
++ struct gnttab_setup_table gnttab_setup;
++
++ grub_memset (&gnttab_setver, 0, sizeof (gnttab_setver));
++
++ gnttab_setver.version = 1;
++ grub_xen_grant_table_op (GNTTABOP_set_version, &gnttab_setver, 1);
++
++ grub_memset (&gnttab_setup, 0, sizeof (gnttab_setup));
++ gnttab_setup.dom = DOMID_SELF;
++ gnttab_setup.nr_frames = 1;
++ gnttab_setup.frame_list.p = &gntframe;
++
++ grub_xen_grant_table_op (GNTTABOP_setup_table, &gnttab_setup, 1);
++}
++
+ #define MAX_N_UNUSABLE_PAGES 4
+
+ static int
+@@ -357,26 +376,12 @@ map_all_pages (void)
+ (grub_xen_mfn_t *) grub_xen_start_page_addr->mfn_list;
+ grub_uint64_t *pg = (grub_uint64_t *) window;
+ grub_uint64_t oldpgstart, oldpgend;
+- struct gnttab_setup_table gnttab_setup;
+- struct gnttab_set_version gnttab_setver;
+ grub_size_t n_unusable_pages = 0;
+ struct mmu_update m2p_updates[2 * MAX_N_UNUSABLE_PAGES];
+
+ if (total_pages > MAX_TOTAL_PAGES - 4)
+ total_pages = MAX_TOTAL_PAGES - 4;
+
+- grub_memset (&gnttab_setver, 0, sizeof (gnttab_setver));
+-
+- gnttab_setver.version = 1;
+- grub_xen_grant_table_op (GNTTABOP_set_version, &gnttab_setver, 1);
+-
+- grub_memset (&gnttab_setup, 0, sizeof (gnttab_setup));
+- gnttab_setup.dom = DOMID_SELF;
+- gnttab_setup.nr_frames = 1;
+- gnttab_setup.frame_list.p = &gntframe;
+-
+- grub_xen_grant_table_op (GNTTABOP_setup_table, &gnttab_setup, 1);
+-
+ for (j = 0; j < total_pages - n_unusable_pages; j++)
+ while (!grub_xen_is_page_usable (mfn_list[j]))
+ {
+@@ -537,6 +542,8 @@ grub_machine_init (void)
+ + GRUB_KERNEL_MACHINE_MOD_GAP,
+ GRUB_KERNEL_MACHINE_MOD_ALIGN);
+
++ grub_xen_setup_gnttab ();
++
+ map_all_pages ();
+
+ grub_console_init ();
+--
+2.21.0
+
diff --git a/main/grub/0004-xen-Prepare-common-code-for-Xen-PVH-support.patch b/main/grub/0004-xen-Prepare-common-code-for-Xen-PVH-support.patch
new file mode 100644
index 0000000000..f5d42d8829
--- /dev/null
+++ b/main/grub/0004-xen-Prepare-common-code-for-Xen-PVH-support.patch
@@ -0,0 +1,245 @@
+From 49a68b2a338cd55490c776d15b0b399303a08df5 Mon Sep 17 00:00:00 2001
+From: Juergen Gross <jgross@suse.com>
+Date: Fri, 7 Dec 2018 13:11:32 +0100
+Subject: [PATCH 04/20] xen: Prepare common code for Xen PVH support
+
+Some common code needs to be special cased for Xen PVH mode. This hits
+mostly Xen PV mode specific areas.
+
+Split include/grub/i386/pc/int_types.h off from
+include/grub/i386/pc/int.h to support including this file later from
+xen_pvh code without the grub_bios_interrupt definition.
+
+Move definition of struct grub_e820_mmap_entry from
+grub-core/mmap/i386/pc/mmap.c to include/grub/i386/memory.h in order
+to make it usable from xen_pvh code.
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+Tested-by: Hans van Kranenburg <hans@knorrie.org>
+(cherry picked from commit fc9d47ead56365c3335bb42cf651008c9ac1f494)
+---
+ grub-core/kern/i386/tsc.c | 2 +-
+ grub-core/mmap/i386/pc/mmap.c | 8 -----
+ include/grub/i386/memory.h | 7 ++++
+ include/grub/i386/pc/int.h | 36 +------------------
+ include/grub/i386/pc/int_types.h | 59 +++++++++++++++++++++++++++++++
+ include/grub/i386/tsc.h | 2 +-
+ include/grub/i386/xen/hypercall.h | 5 ++-
+ include/grub/kernel.h | 4 ++-
+ 8 files changed, 76 insertions(+), 47 deletions(-)
+ create mode 100644 include/grub/i386/pc/int_types.h
+
+diff --git a/grub-core/kern/i386/tsc.c b/grub-core/kern/i386/tsc.c
+index 2e85289d8..b50831bfc 100644
+--- a/grub-core/kern/i386/tsc.c
++++ b/grub-core/kern/i386/tsc.c
+@@ -65,7 +65,7 @@ grub_tsc_init (void)
+
+ tsc_boot_time = grub_get_tsc ();
+
+-#ifdef GRUB_MACHINE_XEN
++#if defined (GRUB_MACHINE_XEN) || defined (GRUB_MACHINE_XEN_PVH)
+ (void) (grub_tsc_calibrate_from_xen () || calibrate_tsc_hardcode());
+ #elif defined (GRUB_MACHINE_EFI)
+ (void) (grub_tsc_calibrate_from_pit () || grub_tsc_calibrate_from_pmtimer () || grub_tsc_calibrate_from_efi() || calibrate_tsc_hardcode());
+diff --git a/grub-core/mmap/i386/pc/mmap.c b/grub-core/mmap/i386/pc/mmap.c
+index 609994516..6ab4f6730 100644
+--- a/grub-core/mmap/i386/pc/mmap.c
++++ b/grub-core/mmap/i386/pc/mmap.c
+@@ -42,14 +42,6 @@ extern grub_uint16_t grub_machine_mmaphook_kblow;
+ extern grub_uint16_t grub_machine_mmaphook_kbin16mb;
+ extern grub_uint16_t grub_machine_mmaphook_64kbin4gb;
+
+-struct grub_e820_mmap_entry
+-{
+- grub_uint64_t addr;
+- grub_uint64_t len;
+- grub_uint32_t type;
+-} GRUB_PACKED;
+-
+-
+ /* Helper for preboot. */
+ static int fill_hook (grub_uint64_t addr, grub_uint64_t size,
+ grub_memory_type_t type, void *data)
+diff --git a/include/grub/i386/memory.h b/include/grub/i386/memory.h
+index 8bb6e1cbb..5cb607fb4 100644
+--- a/include/grub/i386/memory.h
++++ b/include/grub/i386/memory.h
+@@ -44,6 +44,13 @@
+
+ #include <grub/types.h>
+
++struct grub_e820_mmap_entry
++{
++ grub_uint64_t addr;
++ grub_uint64_t len;
++ grub_uint32_t type;
++} GRUB_PACKED;
++
+ grub_uint64_t grub_mmap_get_upper (void);
+ grub_uint64_t grub_mmap_get_lower (void);
+ grub_uint64_t grub_mmap_get_post64 (void);
+diff --git a/include/grub/i386/pc/int.h b/include/grub/i386/pc/int.h
+index 16a53e4fe..a60104001 100644
+--- a/include/grub/i386/pc/int.h
++++ b/include/grub/i386/pc/int.h
+@@ -20,45 +20,11 @@
+ #define GRUB_INTERRUPT_MACHINE_HEADER 1
+
+ #include <grub/symbol.h>
+-#include <grub/types.h>
+-
+-struct grub_bios_int_registers
+-{
+- grub_uint32_t eax;
+- grub_uint16_t es;
+- grub_uint16_t ds;
+- grub_uint16_t flags;
+- grub_uint16_t dummy;
+- grub_uint32_t ebx;
+- grub_uint32_t ecx;
+- grub_uint32_t edi;
+- grub_uint32_t esi;
+- grub_uint32_t edx;
+-};
+-
+-#define GRUB_CPU_INT_FLAGS_CARRY 0x1
+-#define GRUB_CPU_INT_FLAGS_PARITY 0x4
+-#define GRUB_CPU_INT_FLAGS_ADJUST 0x10
+-#define GRUB_CPU_INT_FLAGS_ZERO 0x40
+-#define GRUB_CPU_INT_FLAGS_SIGN 0x80
+-#define GRUB_CPU_INT_FLAGS_TRAP 0x100
+-#define GRUB_CPU_INT_FLAGS_INTERRUPT 0x200
+-#define GRUB_CPU_INT_FLAGS_DIRECTION 0x400
+-#define GRUB_CPU_INT_FLAGS_OVERFLOW 0x800
+-#ifdef GRUB_MACHINE_PCBIOS
+-#define GRUB_CPU_INT_FLAGS_DEFAULT GRUB_CPU_INT_FLAGS_INTERRUPT
+-#else
+-#define GRUB_CPU_INT_FLAGS_DEFAULT 0
+-#endif
++#include <grub/i386/pc/int_types.h>
+
+ void EXPORT_FUNC (grub_bios_interrupt) (grub_uint8_t intno,
+ struct grub_bios_int_registers *regs)
+ __attribute__ ((regparm(3)));
+-struct grub_i386_idt
+-{
+- grub_uint16_t limit;
+- grub_uint32_t base;
+-} GRUB_PACKED;
+
+ #ifdef GRUB_MACHINE_PCBIOS
+ extern struct grub_i386_idt *EXPORT_VAR(grub_realidt);
+diff --git a/include/grub/i386/pc/int_types.h b/include/grub/i386/pc/int_types.h
+new file mode 100644
+index 000000000..2c5a69b63
+--- /dev/null
++++ b/include/grub/i386/pc/int_types.h
+@@ -0,0 +1,59 @@
++/*
++ * GRUB -- GRand Unified Bootloader
++ * Copyright (C) 2018 Free Software Foundation, Inc.
++ *
++ * GRUB is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation, either version 3 of the License, or
++ * (at your option) any later version.
++ *
++ * GRUB is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
++ */
++
++#ifndef GRUB_INTERRUPT_TYPES_MACHINE_HEADER
++#define GRUB_INTERRUPT_TYPES_MACHINE_HEADER 1
++
++#include <grub/types.h>
++
++#define GRUB_CPU_INT_FLAGS_CARRY 0x1
++#define GRUB_CPU_INT_FLAGS_PARITY 0x4
++#define GRUB_CPU_INT_FLAGS_ADJUST 0x10
++#define GRUB_CPU_INT_FLAGS_ZERO 0x40
++#define GRUB_CPU_INT_FLAGS_SIGN 0x80
++#define GRUB_CPU_INT_FLAGS_TRAP 0x100
++#define GRUB_CPU_INT_FLAGS_INTERRUPT 0x200
++#define GRUB_CPU_INT_FLAGS_DIRECTION 0x400
++#define GRUB_CPU_INT_FLAGS_OVERFLOW 0x800
++#ifdef GRUB_MACHINE_PCBIOS
++#define GRUB_CPU_INT_FLAGS_DEFAULT GRUB_CPU_INT_FLAGS_INTERRUPT
++#else
++#define GRUB_CPU_INT_FLAGS_DEFAULT 0
++#endif
++
++struct grub_bios_int_registers
++{
++ grub_uint32_t eax;
++ grub_uint16_t es;
++ grub_uint16_t ds;
++ grub_uint16_t flags;
++ grub_uint16_t dummy;
++ grub_uint32_t ebx;
++ grub_uint32_t ecx;
++ grub_uint32_t edi;
++ grub_uint32_t esi;
++ grub_uint32_t edx;
++};
++
++struct grub_i386_idt
++{
++ grub_uint16_t limit;
++ grub_uint32_t base;
++} GRUB_PACKED;
++
++#endif
+diff --git a/include/grub/i386/tsc.h b/include/grub/i386/tsc.h
+index a0aa2c573..324174ded 100644
+--- a/include/grub/i386/tsc.h
++++ b/include/grub/i386/tsc.h
+@@ -54,7 +54,7 @@ grub_get_tsc (void)
+ static __inline int
+ grub_cpu_is_tsc_supported (void)
+ {
+-#ifndef GRUB_MACHINE_XEN
++#if !defined(GRUB_MACHINE_XEN) && !defined(GRUB_MACHINE_XEN_PVH)
+ grub_uint32_t a,b,c,d;
+ if (! grub_cpu_is_cpuid_supported ())
+ return 0;
+diff --git a/include/grub/i386/xen/hypercall.h b/include/grub/i386/xen/hypercall.h
+index 198ee94af..4e4c12a49 100644
+--- a/include/grub/i386/xen/hypercall.h
++++ b/include/grub/i386/xen/hypercall.h
+@@ -26,7 +26,10 @@ EXPORT_FUNC (grub_xen_hypercall) (grub_uint32_t callno, grub_uint32_t a0,
+ grub_uint32_t a1, grub_uint32_t a2,
+ grub_uint32_t a3, grub_uint32_t a4,
+ grub_uint32_t a5)
+-__attribute__ ((regparm (3), cdecl));
++#ifdef GRUB_MACHINE_XEN
++ __attribute__ ((regparm (3), cdecl))
++#endif
++ ;
+
+ static inline int
+ grub_xen_sched_op (int cmd, void *arg)
+diff --git a/include/grub/kernel.h b/include/grub/kernel.h
+index 20ddf2da2..c17fc6e60 100644
+--- a/include/grub/kernel.h
++++ b/include/grub/kernel.h
+@@ -78,7 +78,9 @@ struct grub_module_info64
+ #if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) \
+ || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) \
+ || defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_ARC) \
+- || (defined (__sparc__) && defined (GRUB_MACHINE_IEEE1275)) || defined (GRUB_MACHINE_UBOOT) || defined (GRUB_MACHINE_XEN)
++ || (defined (__sparc__) && defined (GRUB_MACHINE_IEEE1275)) \
++ || defined (GRUB_MACHINE_UBOOT) || defined (GRUB_MACHINE_XEN) \
++ || defined(GRUB_MACHINE_XEN_PVH)
+ /* FIXME: stack is between 2 heap regions. Move it. */
+ #define GRUB_KERNEL_PRELOAD_SPACE_REUSABLE 1
+ #endif
+--
+2.21.0
+
diff --git a/main/grub/0005-xen-Add-some-dummy-headers-for-PVH-mode.patch b/main/grub/0005-xen-Add-some-dummy-headers-for-PVH-mode.patch
new file mode 100644
index 0000000000..80704778cd
--- /dev/null
+++ b/main/grub/0005-xen-Add-some-dummy-headers-for-PVH-mode.patch
@@ -0,0 +1,70 @@
+From 02d764a4469d71a5bc78c1358b0bd62987e2dc8e Mon Sep 17 00:00:00 2001
+From: Juergen Gross <jgross@suse.com>
+Date: Fri, 7 Dec 2018 13:11:33 +0100
+Subject: [PATCH 05/20] xen: Add some dummy headers for PVH mode
+
+With Xen PVH mode adding a new machine type the machine related headers
+need to be present for the build to succeed. Most of the headers just
+need to include the related common i386 headers. Add those to the tree.
+
+Note that xen_pvh/int.h needs to include pc/int_types.h instead of
+pc/int.h in order to avoid the definition of grub_bios_interrupt().
+
+xen_pvh/memory.h needs to include coreboot/memory.h (like some other
+<machine>/memory.h do as well) as this contains just the needed stubs.
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+Tested-by: Hans van Kranenburg <hans@knorrie.org>
+(cherry picked from commit 408de833bbd1ccad39ad439eaf3cddd528b039b5)
+---
+ include/grub/i386/xen_pvh/boot.h | 1 +
+ include/grub/i386/xen_pvh/console.h | 1 +
+ include/grub/i386/xen_pvh/int.h | 1 +
+ include/grub/i386/xen_pvh/memory.h | 1 +
+ include/grub/i386/xen_pvh/time.h | 1 +
+ 5 files changed, 5 insertions(+)
+ create mode 100644 include/grub/i386/xen_pvh/boot.h
+ create mode 100644 include/grub/i386/xen_pvh/console.h
+ create mode 100644 include/grub/i386/xen_pvh/int.h
+ create mode 100644 include/grub/i386/xen_pvh/memory.h
+ create mode 100644 include/grub/i386/xen_pvh/time.h
+
+diff --git a/include/grub/i386/xen_pvh/boot.h b/include/grub/i386/xen_pvh/boot.h
+new file mode 100644
+index 000000000..6cd23aa83
+--- /dev/null
++++ b/include/grub/i386/xen_pvh/boot.h
+@@ -0,0 +1 @@
++#include <grub/i386/pc/boot.h>
+diff --git a/include/grub/i386/xen_pvh/console.h b/include/grub/i386/xen_pvh/console.h
+new file mode 100644
+index 000000000..305a46d8e
+--- /dev/null
++++ b/include/grub/i386/xen_pvh/console.h
+@@ -0,0 +1 @@
++#include <grub/i386/pc/console.h>
+diff --git a/include/grub/i386/xen_pvh/int.h b/include/grub/i386/xen_pvh/int.h
+new file mode 100644
+index 000000000..0f1f9ee62
+--- /dev/null
++++ b/include/grub/i386/xen_pvh/int.h
+@@ -0,0 +1 @@
++#include <grub/i386/pc/int_types.h>
+diff --git a/include/grub/i386/xen_pvh/memory.h b/include/grub/i386/xen_pvh/memory.h
+new file mode 100644
+index 000000000..8dd6f7c8c
+--- /dev/null
++++ b/include/grub/i386/xen_pvh/memory.h
+@@ -0,0 +1 @@
++#include <grub/i386/coreboot/memory.h>
+diff --git a/include/grub/i386/xen_pvh/time.h b/include/grub/i386/xen_pvh/time.h
+new file mode 100644
+index 000000000..2298ee8f4
+--- /dev/null
++++ b/include/grub/i386/xen_pvh/time.h
+@@ -0,0 +1 @@
++#include <grub/i386/pc/time.h>
+--
+2.21.0
+
diff --git a/main/grub/0006-xen-Rearrange-xen-init.c-to-prepare-it-for-Xen-PVH-m.patch b/main/grub/0006-xen-Rearrange-xen-init.c-to-prepare-it-for-Xen-PVH-m.patch
new file mode 100644
index 0000000000..35673cc065
--- /dev/null
+++ b/main/grub/0006-xen-Rearrange-xen-init.c-to-prepare-it-for-Xen-PVH-m.patch
@@ -0,0 +1,135 @@
+From 56eb459603e458316d93cf5bdf16e4539dbb6a9d Mon Sep 17 00:00:00 2001
+From: Juergen Gross <jgross@suse.com>
+Date: Fri, 7 Dec 2018 13:11:34 +0100
+Subject: [PATCH 06/20] xen: Rearrange xen/init.c to prepare it for Xen PVH
+ mode
+
+Rearrange grub-core/kern/xen/init.c to prepare adding PVH mode support
+to it. This includes putting some code under #ifdef GRUB_MACHINE_XEN
+as it will not be used when running as PVH.
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+Tested-by: Hans van Kranenburg <hans@knorrie.org>
+(cherry picked from commit bec9edf53f4d0b629a52a7d1145f38f88df8dd1d)
+---
+ grub-core/kern/xen/init.c | 60 ++++++++++++++++++++++-----------------
+ 1 file changed, 34 insertions(+), 26 deletions(-)
+
+diff --git a/grub-core/kern/xen/init.c b/grub-core/kern/xen/init.c
+index 29f5bc23d..10007b411 100644
+--- a/grub-core/kern/xen/init.c
++++ b/grub-core/kern/xen/init.c
+@@ -41,9 +41,11 @@ grub_size_t grub_xen_n_allocated_shared_pages;
+ static grub_xen_mfn_t
+ grub_xen_ptr2mfn (void *ptr)
+ {
++#ifdef GRUB_MACHINE_XEN
+ grub_xen_mfn_t *mfn_list =
+ (grub_xen_mfn_t *) grub_xen_start_page_addr->mfn_list;
+ return mfn_list[(grub_addr_t) ptr >> GRUB_XEN_LOG_PAGE_SIZE];
++#endif
+ }
+
+ void *
+@@ -104,18 +106,6 @@ grub_machine_get_bootlocation (char **device __attribute__ ((unused)),
+ {
+ }
+
+-static grub_uint8_t window[GRUB_XEN_PAGE_SIZE]
+- __attribute__ ((aligned (GRUB_XEN_PAGE_SIZE)));
+-
+-#ifdef __x86_64__
+-#define NUMBER_OF_LEVELS 4
+-#else
+-#define NUMBER_OF_LEVELS 3
+-#endif
+-
+-#define LOG_POINTERS_PER_PAGE 9
+-#define POINTERS_PER_PAGE (1 << LOG_POINTERS_PER_PAGE)
+-
+ void
+ grub_xen_store_send (const void *buf_, grub_size_t len)
+ {
+@@ -337,6 +327,19 @@ grub_xen_setup_gnttab (void)
+ grub_xen_grant_table_op (GNTTABOP_setup_table, &gnttab_setup, 1);
+ }
+
++#ifdef GRUB_MACHINE_XEN
++static grub_uint8_t window[GRUB_XEN_PAGE_SIZE]
++ __attribute__ ((aligned (GRUB_XEN_PAGE_SIZE)));
++
++#ifdef __x86_64__
++#define NUMBER_OF_LEVELS 4
++#else
++#define NUMBER_OF_LEVELS 3
++#endif
++
++#define LOG_POINTERS_PER_PAGE 9
++#define POINTERS_PER_PAGE (1 << LOG_POINTERS_PER_PAGE)
++
+ #define MAX_N_UNUSABLE_PAGES 4
+
+ static int
+@@ -529,13 +532,30 @@ map_all_pages (void)
+ grub_mm_init_region ((void *) heap_start, heap_end - heap_start);
+ }
+
++grub_err_t
++grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
++{
++ grub_uint64_t total_pages = grub_xen_start_page_addr->nr_pages;
++ grub_uint64_t usable_pages = grub_xen_start_page_addr->pt_base >> 12;
++ if (hook (0, page2offset (usable_pages), GRUB_MEMORY_AVAILABLE, hook_data))
++ return GRUB_ERR_NONE;
++
++ hook (page2offset (usable_pages), page2offset (total_pages - usable_pages),
++ GRUB_MEMORY_RESERVED, hook_data);
++
++ return GRUB_ERR_NONE;
++}
++#endif
++
+ extern char _end[];
+
+ void
+ grub_machine_init (void)
+ {
++#ifdef GRUB_MACHINE_XEN
+ #ifdef __i386__
+ grub_xen_vm_assist (VMASST_CMD_enable, VMASST_TYPE_pae_extended_cr3);
++#endif
+ #endif
+
+ grub_modbase = ALIGN_UP ((grub_addr_t) _end
+@@ -544,7 +564,9 @@ grub_machine_init (void)
+
+ grub_xen_setup_gnttab ();
+
++#ifdef GRUB_MACHINE_XEN
+ map_all_pages ();
++#endif
+
+ grub_console_init ();
+
+@@ -571,17 +593,3 @@ grub_machine_fini (int flags __attribute__ ((unused)))
+ grub_xendisk_fini ();
+ grub_boot_fini ();
+ }
+-
+-grub_err_t
+-grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
+-{
+- grub_uint64_t total_pages = grub_xen_start_page_addr->nr_pages;
+- grub_uint64_t usable_pages = grub_xen_start_page_addr->pt_base >> 12;
+- if (hook (0, page2offset (usable_pages), GRUB_MEMORY_AVAILABLE, hook_data))
+- return GRUB_ERR_NONE;
+-
+- hook (page2offset (usable_pages), page2offset (total_pages - usable_pages),
+- GRUB_MEMORY_RESERVED, hook_data);
+-
+- return GRUB_ERR_NONE;
+-}
+--
+2.21.0
+
diff --git a/main/grub/0007-xen-Modify-grub_xen_ptr2mfn-for-Xen-PVH.patch b/main/grub/0007-xen-Modify-grub_xen_ptr2mfn-for-Xen-PVH.patch
new file mode 100644
index 0000000000..aa0de2c411
--- /dev/null
+++ b/main/grub/0007-xen-Modify-grub_xen_ptr2mfn-for-Xen-PVH.patch
@@ -0,0 +1,33 @@
+From 9db97a1c63053bc376419e913a19f9f99a3f7b7d Mon Sep 17 00:00:00 2001
+From: Juergen Gross <jgross@suse.com>
+Date: Fri, 7 Dec 2018 13:11:35 +0100
+Subject: [PATCH 07/20] xen: Modify grub_xen_ptr2mfn() for Xen PVH
+
+grub_xen_ptr2mfn() returns the machine frame number for a given pointer
+value. For Xen-PVH guests this is just the PFN. Add the PVH specific
+variant.
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+Tested-by: Hans van Kranenburg <hans@knorrie.org>
+(cherry picked from commit 3b8d09c7742a1890eadad6987852c82947ea5d4a)
+---
+ grub-core/kern/xen/init.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/grub-core/kern/xen/init.c b/grub-core/kern/xen/init.c
+index 10007b411..a23dad633 100644
+--- a/grub-core/kern/xen/init.c
++++ b/grub-core/kern/xen/init.c
+@@ -45,6 +45,8 @@ grub_xen_ptr2mfn (void *ptr)
+ grub_xen_mfn_t *mfn_list =
+ (grub_xen_mfn_t *) grub_xen_start_page_addr->mfn_list;
+ return mfn_list[(grub_addr_t) ptr >> GRUB_XEN_LOG_PAGE_SIZE];
++#else
++ return (grub_addr_t) ptr >> GRUB_XEN_LOG_PAGE_SIZE;
+ #endif
+ }
+
+--
+2.21.0
+
diff --git a/main/grub/0008-xen-Add-PVH-specific-defines-to-offset.h.patch b/main/grub/0008-xen-Add-PVH-specific-defines-to-offset.h.patch
new file mode 100644
index 0000000000..b98eb163a4
--- /dev/null
+++ b/main/grub/0008-xen-Add-PVH-specific-defines-to-offset.h.patch
@@ -0,0 +1,63 @@
+From d0a9f803262b4702c0509d39820b2262d5bd916d Mon Sep 17 00:00:00 2001
+From: Juergen Gross <jgross@suse.com>
+Date: Fri, 7 Dec 2018 13:11:36 +0100
+Subject: [PATCH 08/20] xen: Add PVH specific defines to offset.h
+
+include/grub/offsets.h needs some defines for Xen PVH mode.
+
+Add them. While at it line up the values in the surrounding lines to
+start at the same column.
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+Tested-by: Hans van Kranenburg <hans@knorrie.org>
+(cherry picked from commit 53a92dea8b675afb3f46aed15c04528695d46d59)
+---
+ include/grub/offsets.h | 21 ++++++++++++---------
+ 1 file changed, 12 insertions(+), 9 deletions(-)
+
+diff --git a/include/grub/offsets.h b/include/grub/offsets.h
+index c88c86d4d..8c784a57d 100644
+--- a/include/grub/offsets.h
++++ b/include/grub/offsets.h
+@@ -36,9 +36,10 @@
+ #define GRUB_DECOMPRESSOR_I386_PC_MAX_DECOMPRESSOR_SIZE (0x9000-0x8200)
+
+ /* The segment where the kernel is loaded. */
+-#define GRUB_BOOT_I386_PC_KERNEL_SEG 0x800
++#define GRUB_BOOT_I386_PC_KERNEL_SEG 0x800
+
+-#define GRUB_KERNEL_I386_PC_LINK_ADDR 0x9000
++#define GRUB_KERNEL_I386_PC_LINK_ADDR 0x9000
++#define GRUB_KERNEL_I386_XEN_PVH_LINK_ADDR 0x100000
+
+ /* The upper memory area (starting at 640 kiB). */
+ #define GRUB_MEMORY_I386_PC_UPPER 0xa0000
+@@ -101,15 +102,17 @@
+ #define GRUB_KERNEL_I386_MULTIBOOT_MOD_ALIGN GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN
+
+ #define GRUB_KERNEL_X86_64_XEN_MOD_ALIGN 0x8
+-#define GRUB_KERNEL_I386_XEN_MOD_ALIGN 0x8
++#define GRUB_KERNEL_I386_XEN_MOD_ALIGN 0x8
++#define GRUB_KERNEL_I386_XEN_PVH_MOD_ALIGN 0x8
+
+ /* Non-zero value is only needed for PowerMacs. */
+-#define GRUB_KERNEL_X86_64_XEN_MOD_GAP 0x0
+-#define GRUB_KERNEL_I386_XEN_MOD_GAP 0x0
+-#define GRUB_KERNEL_I386_IEEE1275_MOD_GAP 0x0
+-#define GRUB_KERNEL_I386_COREBOOT_MOD_GAP 0x0
+-#define GRUB_KERNEL_SPARC64_IEEE1275_MOD_GAP 0x0
+-#define GRUB_KERNEL_ARM_UBOOT_MOD_GAP 0x0
++#define GRUB_KERNEL_X86_64_XEN_MOD_GAP 0x0
++#define GRUB_KERNEL_I386_XEN_MOD_GAP 0x0
++#define GRUB_KERNEL_I386_XEN_PVH_MOD_GAP 0x0
++#define GRUB_KERNEL_I386_IEEE1275_MOD_GAP 0x0
++#define GRUB_KERNEL_I386_COREBOOT_MOD_GAP 0x0
++#define GRUB_KERNEL_SPARC64_IEEE1275_MOD_GAP 0x0
++#define GRUB_KERNEL_ARM_UBOOT_MOD_GAP 0x0
+
+ #define GRUB_KERNEL_POWERPC_IEEE1275_MOD_ALIGN 0x1000
+ #define GRUB_KERNEL_SPARC64_IEEE1275_LOG_MOD_ALIGN 3
+--
+2.21.0
+
diff --git a/main/grub/0009-xen-Add-basic-hooks-for-PVH-in-current-code.patch b/main/grub/0009-xen-Add-basic-hooks-for-PVH-in-current-code.patch
new file mode 100644
index 0000000000..2c663bc551
--- /dev/null
+++ b/main/grub/0009-xen-Add-basic-hooks-for-PVH-in-current-code.patch
@@ -0,0 +1,267 @@
+From 6f19a6f001e182b9716ea850ce39bb2545c558cb Mon Sep 17 00:00:00 2001
+From: Juergen Gross <jgross@suse.com>
+Date: Fri, 7 Dec 2018 13:11:37 +0100
+Subject: [PATCH 09/20] xen: Add basic hooks for PVH in current code
+
+Add the hooks to current code needed for Xen PVH. They will be filled
+with code later when the related functionality is being added.
+
+loader/i386/linux.c needs to include machine/kernel.h now as it needs
+to get GRUB_KERNEL_USE_RSDP_ADDR from there. This in turn requires to
+add an empty kernel.h header for some i386 platforms (efi, coreboot,
+ieee1275, xen) and for x86_64 efi.
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+Tested-by: Hans van Kranenburg <hans@knorrie.org>
+(cherry picked from commit 0b3e4eb2d2e1875e6045e838962f769f2ce161dd)
+---
+ grub-core/Makefile.am | 6 +++++
+ grub-core/kern/i386/xen/pvh.c | 37 +++++++++++++++++++++++++++
+ grub-core/kern/i386/xen/startup_pvh.S | 29 +++++++++++++++++++++
+ grub-core/kern/xen/init.c | 4 +++
+ grub-core/loader/i386/linux.c | 1 +
+ include/grub/i386/coreboot/kernel.h | 0
+ include/grub/i386/efi/kernel.h | 0
+ include/grub/i386/ieee1275/kernel.h | 0
+ include/grub/i386/xen/kernel.h | 0
+ include/grub/i386/xen_pvh/kernel.h | 30 ++++++++++++++++++++++
+ include/grub/x86_64/efi/kernel.h | 0
+ include/grub/xen.h | 5 ++++
+ 12 files changed, 112 insertions(+)
+ create mode 100644 grub-core/kern/i386/xen/pvh.c
+ create mode 100644 grub-core/kern/i386/xen/startup_pvh.S
+ create mode 100644 include/grub/i386/coreboot/kernel.h
+ create mode 100644 include/grub/i386/efi/kernel.h
+ create mode 100644 include/grub/i386/ieee1275/kernel.h
+ create mode 100644 include/grub/i386/xen/kernel.h
+ create mode 100644 include/grub/i386/xen_pvh/kernel.h
+ create mode 100644 include/grub/x86_64/efi/kernel.h
+
+diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am
+index 04e9395fd..e36c109e2 100644
+--- a/grub-core/Makefile.am
++++ b/grub-core/Makefile.am
+@@ -102,6 +102,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
+ endif
+
+ if COND_i386_efi
++KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
+ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
+ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
+ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
+@@ -111,6 +112,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pmtimer.h
+ endif
+
+ if COND_i386_coreboot
++KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
+ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
+ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/coreboot/lbio.h
+ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video.h
+@@ -122,6 +124,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
+ endif
+
+ if COND_i386_multiboot
++KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
+ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
+ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
+ endif
+@@ -132,6 +135,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
+ endif
+
+ if COND_i386_ieee1275
++KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
+ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h
+ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
+ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
+@@ -140,6 +144,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
+ endif
+
+ if COND_i386_xen
++KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
+ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/xen.h
+ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/xen/hypercall.h
+ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
+@@ -158,6 +163,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h
+ endif
+
+ if COND_x86_64_efi
++KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
+ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
+ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
+ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
+diff --git a/grub-core/kern/i386/xen/pvh.c b/grub-core/kern/i386/xen/pvh.c
+new file mode 100644
+index 000000000..4f629b15e
+--- /dev/null
++++ b/grub-core/kern/i386/xen/pvh.c
+@@ -0,0 +1,37 @@
++/*
++ * GRUB -- GRand Unified Bootloader
++ * Copyright (C) 2018 Free Software Foundation, Inc.
++ *
++ * GRUB is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation, either version 3 of the License, or
++ * (at your option) any later version.
++ *
++ * GRUB is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
++ */
++
++#include <grub/kernel.h>
++#include <grub/misc.h>
++#include <grub/memory.h>
++#include <grub/mm.h>
++#include <grub/xen.h>
++#include <xen/hvm/start_info.h>
++#include <grub/machine/kernel.h>
++
++grub_uint64_t grub_rsdp_addr;
++
++void
++grub_xen_setup_pvh (void)
++{
++}
++
++grub_err_t
++grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
++{
++}
+diff --git a/grub-core/kern/i386/xen/startup_pvh.S b/grub-core/kern/i386/xen/startup_pvh.S
+new file mode 100644
+index 000000000..69b8fdcca
+--- /dev/null
++++ b/grub-core/kern/i386/xen/startup_pvh.S
+@@ -0,0 +1,29 @@
++/* startup.S - bootstrap GRUB itself */
++/*
++ * GRUB -- GRand Unified Bootloader
++ * Copyright (C) 2018 Free Software Foundation, Inc.
++ *
++ * GRUB is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation, either version 3 of the License, or
++ * (at your option) any later version.
++ *
++ * GRUB is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
++ */
++
++#include <config.h>
++#include <grub/symbol.h>
++
++ .file "startup_pvh.S"
++ .text
++
++/* Saved pointer to start info structure. */
++ .globl pvh_start_info
++pvh_start_info:
++ .long 0
+diff --git a/grub-core/kern/xen/init.c b/grub-core/kern/xen/init.c
+index a23dad633..782ca7295 100644
+--- a/grub-core/kern/xen/init.c
++++ b/grub-core/kern/xen/init.c
+@@ -564,6 +564,10 @@ grub_machine_init (void)
+ + GRUB_KERNEL_MACHINE_MOD_GAP,
+ GRUB_KERNEL_MACHINE_MOD_ALIGN);
+
++#ifdef GRUB_MACHINE_XEN_PVH
++ grub_xen_setup_pvh ();
++#endif
++
+ grub_xen_setup_gnttab ();
+
+ #ifdef GRUB_MACHINE_XEN
+diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
+index 7d6d5d499..e0825cb21 100644
+--- a/grub-core/loader/i386/linux.c
++++ b/grub-core/loader/i386/linux.c
+@@ -35,6 +35,7 @@
+ #include <grub/i18n.h>
+ #include <grub/lib/cmdline.h>
+ #include <grub/linux.h>
++#include <grub/machine/kernel.h>
+
+ GRUB_MOD_LICENSE ("GPLv3+");
+
+diff --git a/include/grub/i386/coreboot/kernel.h b/include/grub/i386/coreboot/kernel.h
+new file mode 100644
+index 000000000..e69de29bb
+diff --git a/include/grub/i386/efi/kernel.h b/include/grub/i386/efi/kernel.h
+new file mode 100644
+index 000000000..e69de29bb
+diff --git a/include/grub/i386/ieee1275/kernel.h b/include/grub/i386/ieee1275/kernel.h
+new file mode 100644
+index 000000000..e69de29bb
+diff --git a/include/grub/i386/xen/kernel.h b/include/grub/i386/xen/kernel.h
+new file mode 100644
+index 000000000..e69de29bb
+diff --git a/include/grub/i386/xen_pvh/kernel.h b/include/grub/i386/xen_pvh/kernel.h
+new file mode 100644
+index 000000000..2b7b8a129
+--- /dev/null
++++ b/include/grub/i386/xen_pvh/kernel.h
+@@ -0,0 +1,30 @@
++/*
++ * GRUB -- GRand Unified Bootloader
++ * Copyright (C) 2018 Free Software Foundation, Inc.
++ *
++ * GRUB is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation, either version 3 of the License, or
++ * (at your option) any later version.
++ *
++ * GRUB is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
++ */
++
++#ifndef GRUB_KERNEL_MACHINE_HEADER
++#define GRUB_KERNEL_MACHINE_HEADER 1
++
++#ifndef ASM_FILE
++
++#define GRUB_KERNEL_USE_RSDP_ADDR 1
++
++extern grub_uint64_t EXPORT_VAR(grub_rsdp_addr);
++
++#endif /* ! ASM_FILE */
++
++#endif /* GRUB_KERNEL_MACHINE_HEADER */
+diff --git a/include/grub/x86_64/efi/kernel.h b/include/grub/x86_64/efi/kernel.h
+new file mode 100644
+index 000000000..e69de29bb
+diff --git a/include/grub/xen.h b/include/grub/xen.h
+index c31cc10c7..91cb7cf81 100644
+--- a/include/grub/xen.h
++++ b/include/grub/xen.h
+@@ -95,6 +95,11 @@ typedef grub_uint64_t grub_xen_mfn_t;
+ typedef grub_uint32_t grub_xen_mfn_t;
+ #endif
+ typedef unsigned int grub_xen_evtchn_t;
++
++#ifdef GRUB_MACHINE_XEN_PVH
++extern struct hvm_start_info *pvh_start_info;
++void grub_xen_setup_pvh (void);
++#endif
+ #endif
+
+ #endif
+--
+2.21.0
+
diff --git a/main/grub/0010-xen-Add-PVH-boot-entry-code.patch b/main/grub/0010-xen-Add-PVH-boot-entry-code.patch
new file mode 100644
index 0000000000..33c520f2d8
--- /dev/null
+++ b/main/grub/0010-xen-Add-PVH-boot-entry-code.patch
@@ -0,0 +1,86 @@
+From da39673d5d194e66c9ad70ad4de4e90ee69f0886 Mon Sep 17 00:00:00 2001
+From: Juergen Gross <jgross@suse.com>
+Date: Fri, 7 Dec 2018 13:11:38 +0100
+Subject: [PATCH 10/20] xen: Add PVH boot entry code
+
+Add the code for the Xen PVH mode boot entry.
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+Tested-by: Hans van Kranenburg <hans@knorrie.org>
+(cherry picked from commit 1a4d83af2fc1eb0a0951775a2b86860ab074c699)
+---
+ grub-core/kern/i386/xen/startup_pvh.S | 52 +++++++++++++++++++++++++++
+ 1 file changed, 52 insertions(+)
+
+diff --git a/grub-core/kern/i386/xen/startup_pvh.S b/grub-core/kern/i386/xen/startup_pvh.S
+index 69b8fdcca..363c31858 100644
+--- a/grub-core/kern/i386/xen/startup_pvh.S
++++ b/grub-core/kern/i386/xen/startup_pvh.S
+@@ -19,11 +19,63 @@
+
+ #include <config.h>
+ #include <grub/symbol.h>
++#include <grub/machine/memory.h>
+
+ .file "startup_pvh.S"
+ .text
++ .globl start, _start
++ .code32
+
++start:
++_start:
++ cld
++ lgdt gdtdesc
++ ljmp $GRUB_MEMORY_MACHINE_PROT_MODE_CSEG, $1f
++1:
++ movl $GRUB_MEMORY_MACHINE_PROT_MODE_DSEG, %eax
++ mov %eax, %ds
++ mov %eax, %es
++ mov %eax, %fs
++ mov %eax, %gs
++ mov %eax, %ss
++ leal LOCAL(stack_end), %esp
++
++ /* Save address of start info structure. */
++ mov %ebx, pvh_start_info
++ call EXT_C(grub_main)
++ /* Doesn't return. */
++
++ .p2align 3
++gdt:
++ .word 0, 0
++ .byte 0, 0, 0, 0
++
++ /* -- code segment --
++ * base = 0x00000000, limit = 0xFFFFF (4 KiB Granularity), present
++ * type = 32bit code execute/read, DPL = 0
++ */
++ .word 0xFFFF, 0
++ .byte 0, 0x9A, 0xCF, 0
++
++ /* -- data segment --
++ * base = 0x00000000, limit 0xFFFFF (4 KiB Granularity), present
++ * type = 32 bit data read/write, DPL = 0
++ */
++ .word 0xFFFF, 0
++ .byte 0, 0x92, 0xCF, 0
++
++ .p2align 3
++/* this is the GDT descriptor */
++gdtdesc:
++ .word 0x17 /* limit */
++ .long gdt /* addr */
++
++ .p2align 2
+ /* Saved pointer to start info structure. */
+ .globl pvh_start_info
+ pvh_start_info:
+ .long 0
++
++ .bss
++ .space GRUB_MEMORY_MACHINE_PROT_STACK_SIZE
++LOCAL(stack_end):
+--
+2.21.0
+
diff --git a/main/grub/0011-xen-Setup-hypercall-page-for-PVH.patch b/main/grub/0011-xen-Setup-hypercall-page-for-PVH.patch
new file mode 100644
index 0000000000..41051ddd61
--- /dev/null
+++ b/main/grub/0011-xen-Setup-hypercall-page-for-PVH.patch
@@ -0,0 +1,145 @@
+From 5f462874a5ee6471faa55f05d3a09369a5dcff2d Mon Sep 17 00:00:00 2001
+From: Juergen Gross <jgross@suse.com>
+Date: Fri, 7 Dec 2018 13:11:39 +0100
+Subject: [PATCH 11/20] xen: Setup hypercall page for PVH
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add the needed code to setup the hypercall page for calling into the
+Xen hypervisor.
+
+Import the XEN_HVM_DEBUGCONS_IOPORT define from Xen unstable into
+include/xen/arch-x86/xen.h
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+Tested-by: Hans van Kranenburg <hans@knorrie.org>
+(cherry picked from commit da81e42a7ccb545513368ec7488cdf5019c1c2ba)
+---
+ grub-core/kern/i386/xen/pvh.c | 80 +++++++++++++++++++++++++++++++++++
+ include/xen/arch-x86/xen.h | 7 +++
+ 2 files changed, 87 insertions(+)
+
+diff --git a/grub-core/kern/i386/xen/pvh.c b/grub-core/kern/i386/xen/pvh.c
+index 4f629b15e..a2554fb1d 100644
+--- a/grub-core/kern/i386/xen/pvh.c
++++ b/grub-core/kern/i386/xen/pvh.c
+@@ -20,15 +20,95 @@
+ #include <grub/misc.h>
+ #include <grub/memory.h>
+ #include <grub/mm.h>
++#include <grub/i386/cpuid.h>
++#include <grub/i386/io.h>
+ #include <grub/xen.h>
+ #include <xen/hvm/start_info.h>
+ #include <grub/machine/kernel.h>
+
+ grub_uint64_t grub_rsdp_addr;
+
++static char hypercall_page[GRUB_XEN_PAGE_SIZE]
++ __attribute__ ((aligned (GRUB_XEN_PAGE_SIZE)));
++
++static grub_uint32_t xen_cpuid_base;
++
++static void
++grub_xen_cons_msg (const char *msg)
++{
++ const char *c;
++
++ for (c = msg; *c; c++)
++ grub_outb (*c, XEN_HVM_DEBUGCONS_IOPORT);
++}
++
++static void
++grub_xen_panic (const char *msg)
++{
++ grub_xen_cons_msg (msg);
++ grub_xen_cons_msg ("System halted!\n");
++
++ asm volatile ("cli");
++
++ while (1)
++ {
++ asm volatile ("hlt");
++ }
++}
++
++static void
++grub_xen_cpuid_base (void)
++{
++ grub_uint32_t base, eax, signature[3];
++
++ for (base = 0x40000000; base < 0x40010000; base += 0x100)
++ {
++ grub_cpuid (base, eax, signature[0], signature[1], signature[2]);
++ if (!grub_memcmp ("XenVMMXenVMM", signature, 12) && (eax - base) >= 2)
++ {
++ xen_cpuid_base = base;
++ return;
++ }
++ }
++
++ grub_xen_panic ("Found no Xen signature!\n");
++}
++
++static void
++grub_xen_setup_hypercall_page (void)
++{
++ grub_uint32_t msr, addr, eax, ebx, ecx, edx;
++
++ /* Get base address of Xen-specific MSRs. */
++ grub_cpuid (xen_cpuid_base + 2, eax, ebx, ecx, edx);
++ msr = ebx;
++ addr = (grub_uint32_t) (&hypercall_page);
++
++ /* Specify hypercall page address for Xen. */
++ asm volatile ("wrmsr" : : "c" (msr), "a" (addr), "d" (0) : "memory");
++}
++
++int
++grub_xen_hypercall (grub_uint32_t callno, grub_uint32_t a0,
++ grub_uint32_t a1, grub_uint32_t a2,
++ grub_uint32_t a3, grub_uint32_t a4,
++ grub_uint32_t a5 __attribute__ ((unused)))
++{
++ grub_uint32_t res;
++
++ asm volatile ("call *%[callno]"
++ : "=a" (res), "+b" (a0), "+c" (a1), "+d" (a2),
++ "+S" (a3), "+D" (a4)
++ : [callno] "a" (&hypercall_page[callno * 32])
++ : "memory");
++ return res;
++}
++
+ void
+ grub_xen_setup_pvh (void)
+ {
++ grub_xen_cpuid_base ();
++ grub_xen_setup_hypercall_page ();
+ }
+
+ grub_err_t
+diff --git a/include/xen/arch-x86/xen.h b/include/xen/arch-x86/xen.h
+index f35804b88..56be26cb6 100644
+--- a/include/xen/arch-x86/xen.h
++++ b/include/xen/arch-x86/xen.h
+@@ -260,6 +260,13 @@ typedef struct arch_shared_info arch_shared_info_t;
+ #define XEN_CPUID XEN_EMULATE_PREFIX "cpuid"
+ #endif
+
++/*
++ * Debug console IO port, also called "port E9 hack". Each character written
++ * to this IO port will be printed on the hypervisor console, subject to log
++ * level restrictions.
++ */
++#define XEN_HVM_DEBUGCONS_IOPORT 0xe9
++
+ #endif /* __XEN_PUBLIC_ARCH_X86_XEN_H__ */
+
+ /*
+--
+2.21.0
+
diff --git a/main/grub/0012-xen-Get-memory-map-from-hypervisor-for-PVH.patch b/main/grub/0012-xen-Get-memory-map-from-hypervisor-for-PVH.patch
new file mode 100644
index 0000000000..cdab0c08bf
--- /dev/null
+++ b/main/grub/0012-xen-Get-memory-map-from-hypervisor-for-PVH.patch
@@ -0,0 +1,144 @@
+From 4acff24f747e43c3f9bb0551c7d09114355c7d3a Mon Sep 17 00:00:00 2001
+From: Juergen Gross <jgross@suse.com>
+Date: Fri, 7 Dec 2018 13:11:40 +0100
+Subject: [PATCH 12/20] xen: Get memory map from hypervisor for PVH
+
+Retrieve the memory map from the hypervisor and normalize it to contain
+no overlapping entries and to be sorted by address.
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+Tested-by: Hans van Kranenburg <hans@knorrie.org>
+(cherry picked from commit 2b7a21afd319b829941a928f5763e017d1cc2951)
+---
+ grub-core/kern/i386/xen/pvh.c | 94 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 94 insertions(+)
+
+diff --git a/grub-core/kern/i386/xen/pvh.c b/grub-core/kern/i386/xen/pvh.c
+index a2554fb1d..2b68ac333 100644
+--- a/grub-core/kern/i386/xen/pvh.c
++++ b/grub-core/kern/i386/xen/pvh.c
+@@ -24,7 +24,12 @@
+ #include <grub/i386/io.h>
+ #include <grub/xen.h>
+ #include <xen/hvm/start_info.h>
++#include <grub/i386/linux.h>
+ #include <grub/machine/kernel.h>
++#include <grub/machine/memory.h>
++#include <xen/memory.h>
++
++#define XEN_MEMORY_MAP_SIZE 128
+
+ grub_uint64_t grub_rsdp_addr;
+
+@@ -32,6 +37,8 @@ static char hypercall_page[GRUB_XEN_PAGE_SIZE]
+ __attribute__ ((aligned (GRUB_XEN_PAGE_SIZE)));
+
+ static grub_uint32_t xen_cpuid_base;
++static struct grub_e820_mmap_entry map[XEN_MEMORY_MAP_SIZE];
++static unsigned int nr_map_entries;
+
+ static void
+ grub_xen_cons_msg (const char *msg)
+@@ -104,11 +111,98 @@ grub_xen_hypercall (grub_uint32_t callno, grub_uint32_t a0,
+ return res;
+ }
+
++static void
++grub_xen_sort_mmap (void)
++{
++ grub_uint64_t from, to;
++ unsigned int i;
++ struct grub_e820_mmap_entry tmp;
++
++ /* Align map entries to page boundaries. */
++ for (i = 0; i < nr_map_entries; i++)
++ {
++ from = map[i].addr;
++ to = from + map[i].len;
++ if (map[i].type == GRUB_MEMORY_AVAILABLE)
++ {
++ from = ALIGN_UP (from, GRUB_XEN_PAGE_SIZE);
++ to = ALIGN_DOWN (to, GRUB_XEN_PAGE_SIZE);
++ }
++ else
++ {
++ from = ALIGN_DOWN (from, GRUB_XEN_PAGE_SIZE);
++ to = ALIGN_UP (to, GRUB_XEN_PAGE_SIZE);
++ }
++ map[i].addr = from;
++ map[i].len = to - from;
++ }
++
++ again:
++ /* Sort entries by start address. */
++ for (i = 1; i < nr_map_entries; i++)
++ {
++ if (map[i].addr >= map[i - 1].addr)
++ continue;
++ tmp = map[i];
++ map[i] = map[i - 1];
++ map[i - 1] = tmp;
++ i = 0;
++ }
++
++ /* Detect overlapping areas. */
++ for (i = 1; i < nr_map_entries; i++)
++ {
++ if (map[i].addr >= map[i - 1].addr + map[i - 1].len)
++ continue;
++ tmp = map[i - 1];
++ map[i - 1].len = map[i].addr - map[i - 1].addr;
++ if (map[i].addr + map[i].len >= tmp.addr + tmp.len)
++ continue;
++ if (nr_map_entries < ARRAY_SIZE (map))
++ {
++ map[nr_map_entries].addr = map[i].addr + map[i].len;
++ map[nr_map_entries].len = tmp.addr + tmp.len - map[nr_map_entries].addr;
++ map[nr_map_entries].type = tmp.type;
++ nr_map_entries++;
++ goto again;
++ }
++ }
++
++ /* Merge adjacent entries. */
++ for (i = 1; i < nr_map_entries; i++)
++ {
++ if (map[i].type == map[i - 1].type &&
++ map[i].addr == map[i - 1].addr + map[i - 1].len)
++ {
++ map[i - 1].len += map[i].len;
++ map[i] = map[nr_map_entries - 1];
++ nr_map_entries--;
++ goto again;
++ }
++ }
++}
++
++static void
++grub_xen_get_mmap (void)
++{
++ struct xen_memory_map memmap;
++
++ memmap.nr_entries = ARRAY_SIZE (map);
++ set_xen_guest_handle (memmap.buffer, map);
++ if (grub_xen_hypercall (__HYPERVISOR_memory_op, XENMEM_memory_map,
++ (grub_uint32_t) (&memmap), 0, 0, 0, 0))
++ grub_xen_panic ("Could not get memory map from Xen!\n");
++ nr_map_entries = memmap.nr_entries;
++
++ grub_xen_sort_mmap ();
++}
++
+ void
+ grub_xen_setup_pvh (void)
+ {
+ grub_xen_cpuid_base ();
+ grub_xen_setup_hypercall_page ();
++ grub_xen_get_mmap ();
+ }
+
+ grub_err_t
+--
+2.21.0
+
diff --git a/main/grub/0013-xen-Setup-Xen-specific-data-for-PVH.patch b/main/grub/0013-xen-Setup-Xen-specific-data-for-PVH.patch
new file mode 100644
index 0000000000..8559b6d73d
--- /dev/null
+++ b/main/grub/0013-xen-Setup-Xen-specific-data-for-PVH.patch
@@ -0,0 +1,194 @@
+From 49ff2168260da6223ca90342d681d8b40909ae5b Mon Sep 17 00:00:00 2001
+From: Juergen Gross <jgross@suse.com>
+Date: Fri, 7 Dec 2018 13:11:41 +0100
+Subject: [PATCH 13/20] xen: Setup Xen specific data for PVH
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Initialize the needed Xen specific data. This is:
+
+- the Xen start of day page containing the console and Xenstore ring
+ page PFN and event channel
+- the grant table
+- the shared info page
+
+Write back the possibly modified memory map to the hypervisor in case
+the guest is reading it from there again.
+
+Set the RSDP address for the guest from the start_info page passed
+as boot parameter.
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
+Tested-by: Hans van Kranenburg <hans@knorrie.org>
+(cherry picked from commit 4c9b4a7c92c9373315fd8b0f8f889275814bba41)
+---
+ grub-core/kern/i386/xen/pvh.c | 123 ++++++++++++++++++++++++++++++++++
+ 1 file changed, 123 insertions(+)
+
+diff --git a/grub-core/kern/i386/xen/pvh.c b/grub-core/kern/i386/xen/pvh.c
+index 2b68ac333..472085ed1 100644
+--- a/grub-core/kern/i386/xen/pvh.c
++++ b/grub-core/kern/i386/xen/pvh.c
+@@ -27,6 +27,7 @@
+ #include <grub/i386/linux.h>
+ #include <grub/machine/kernel.h>
+ #include <grub/machine/memory.h>
++#include <xen/hvm/params.h>
+ #include <xen/memory.h>
+
+ #define XEN_MEMORY_MAP_SIZE 128
+@@ -37,6 +38,7 @@ static char hypercall_page[GRUB_XEN_PAGE_SIZE]
+ __attribute__ ((aligned (GRUB_XEN_PAGE_SIZE)));
+
+ static grub_uint32_t xen_cpuid_base;
++static struct start_info grub_xen_start_page;
+ static struct grub_e820_mmap_entry map[XEN_MEMORY_MAP_SIZE];
+ static unsigned int nr_map_entries;
+
+@@ -111,6 +113,36 @@ grub_xen_hypercall (grub_uint32_t callno, grub_uint32_t a0,
+ return res;
+ }
+
++static grub_uint32_t
++grub_xen_get_param (int idx)
++{
++ struct xen_hvm_param xhv;
++ int r;
++
++ xhv.domid = DOMID_SELF;
++ xhv.index = idx;
++ r = grub_xen_hypercall (__HYPERVISOR_hvm_op, HVMOP_get_param,
++ (grub_uint32_t) (&xhv), 0, 0, 0, 0);
++ if (r < 0)
++ grub_xen_panic ("Could not get parameter from Xen!\n");
++ return xhv.value;
++}
++
++static void *
++grub_xen_add_physmap (unsigned int space, void *addr)
++{
++ struct xen_add_to_physmap xatp;
++
++ xatp.domid = DOMID_SELF;
++ xatp.idx = 0;
++ xatp.space = space;
++ xatp.gpfn = (grub_addr_t) addr >> GRUB_XEN_LOG_PAGE_SIZE;
++ if (grub_xen_hypercall (__HYPERVISOR_memory_op, XENMEM_add_to_physmap,
++ (grub_uint32_t) (&xatp), 0, 0, 0, 0))
++ grub_xen_panic ("Memory_op hypercall failed!\n");
++ return addr;
++}
++
+ static void
+ grub_xen_sort_mmap (void)
+ {
+@@ -197,12 +229,103 @@ grub_xen_get_mmap (void)
+ grub_xen_sort_mmap ();
+ }
+
++static void
++grub_xen_set_mmap (void)
++{
++ struct xen_foreign_memory_map memmap;
++
++ memmap.domid = DOMID_SELF;
++ memmap.map.nr_entries = nr_map_entries;
++ set_xen_guest_handle (memmap.map.buffer, map);
++ grub_xen_hypercall (__HYPERVISOR_memory_op, XENMEM_set_memory_map,
++ (grub_uint32_t) (&memmap), 0, 0, 0, 0);
++}
++
++static grub_uint64_t
++grub_xen_find_page (grub_uint64_t start)
++{
++ unsigned int i, j;
++ grub_uint64_t last = start;
++
++ /*
++ * Try to find a e820 map hole below 4G.
++ * Relies on page-aligned entries (addr and len) and input (start).
++ */
++
++ for (i = 0; i < nr_map_entries; i++)
++ {
++ if (last > map[i].addr + map[i].len)
++ continue;
++ if (last < map[i].addr)
++ return last;
++ if ((map[i].addr >> 32) || ((map[i].addr + map[i].len) >> 32))
++ break;
++ last = map[i].addr + map[i].len;
++ }
++ if (i == nr_map_entries)
++ return last;
++
++ /* No hole found, use the highest RAM page below 4G and reserve it. */
++ if (nr_map_entries == ARRAY_SIZE (map))
++ grub_xen_panic ("Memory map size limit reached!\n");
++ for (i = 0, j = 0; i < nr_map_entries; i++)
++ {
++ if (map[i].type != GRUB_MEMORY_AVAILABLE)
++ continue;
++ if (map[i].addr >> 32)
++ break;
++ j = i;
++ if ((map[i].addr + map[i].len) >> 32)
++ break;
++ }
++ if (map[j].type != GRUB_MEMORY_AVAILABLE)
++ grub_xen_panic ("No free memory page found!\n");
++ if ((map[j].addr + map[j].len) >> 32)
++ last = (1ULL << 32) - GRUB_XEN_PAGE_SIZE;
++ else
++ last = map[j].addr + map[j].len - GRUB_XEN_PAGE_SIZE;
++ map[nr_map_entries].addr = last;
++ map[nr_map_entries].len = GRUB_XEN_PAGE_SIZE;
++ map[nr_map_entries].type = GRUB_MEMORY_RESERVED;
++ nr_map_entries++;
++ grub_xen_sort_mmap ();
++
++ return last;
++}
++
+ void
+ grub_xen_setup_pvh (void)
+ {
++ grub_addr_t par;
++
+ grub_xen_cpuid_base ();
+ grub_xen_setup_hypercall_page ();
+ grub_xen_get_mmap ();
++
++ /* Setup Xen data. */
++ grub_xen_start_page_addr = &grub_xen_start_page;
++
++ par = grub_xen_get_param (HVM_PARAM_CONSOLE_PFN);
++ grub_xen_start_page_addr->console.domU.mfn = par;
++ grub_xen_xcons = (void *) (grub_addr_t) (par << GRUB_XEN_LOG_PAGE_SIZE);
++ par = grub_xen_get_param (HVM_PARAM_CONSOLE_EVTCHN);
++ grub_xen_start_page_addr->console.domU.evtchn = par;
++
++ par = grub_xen_get_param (HVM_PARAM_STORE_PFN);
++ grub_xen_start_page_addr->store_mfn = par;
++ grub_xen_xenstore = (void *) (grub_addr_t) (par << GRUB_XEN_LOG_PAGE_SIZE);
++ par = grub_xen_get_param (HVM_PARAM_STORE_EVTCHN);
++ grub_xen_start_page_addr->store_evtchn = par;
++
++ par = grub_xen_find_page (0);
++ grub_xen_grant_table = grub_xen_add_physmap (XENMAPSPACE_grant_table,
++ (void *) par);
++ par = grub_xen_find_page (par + GRUB_XEN_PAGE_SIZE);
++ grub_xen_shared_info = grub_xen_add_physmap (XENMAPSPACE_shared_info,
++ (void *) par);
++ grub_xen_set_mmap ();
++
++ grub_rsdp_addr = pvh_start_info->rsdp_paddr;
+ }
+
+ grub_err_t
+--
+2.21.0
+
diff --git a/main/grub/0014-xen-Init-memory-regions-for-PVH.patch b/main/grub/0014-xen-Init-memory-regions-for-PVH.patch
new file mode 100644
index 0000000000..3476868ea2
--- /dev/null
+++ b/main/grub/0014-xen-Init-memory-regions-for-PVH.patch
@@ -0,0 +1,79 @@
+From c411fd781843b50bfb00b83dd039cdf8eb93d2f6 Mon Sep 17 00:00:00 2001
+From: Juergen Gross <jgross@suse.com>
+Date: Fri, 7 Dec 2018 13:11:42 +0100
+Subject: [PATCH 14/20] xen: Init memory regions for PVH
+
+Add all usable memory regions to grub memory management and add the
+needed mmap iterate code, which will be used by grub core (e.g.
+grub-core/lib/relocator.c or grub-core/mmap/mmap.c).
+
+As we are running in 32-bit mode don't add memory above 4GB.
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+Tested-by: Hans van Kranenburg <hans@knorrie.org>
+(cherry picked from commit 1d2473a024a9e1f46a7caa75d5c8186ed2cdb6e1)
+---
+ grub-core/kern/i386/xen/pvh.c | 35 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 35 insertions(+)
+
+diff --git a/grub-core/kern/i386/xen/pvh.c b/grub-core/kern/i386/xen/pvh.c
+index 472085ed1..91fbca859 100644
+--- a/grub-core/kern/i386/xen/pvh.c
++++ b/grub-core/kern/i386/xen/pvh.c
+@@ -241,6 +241,30 @@ grub_xen_set_mmap (void)
+ (grub_uint32_t) (&memmap), 0, 0, 0, 0);
+ }
+
++static void
++grub_xen_mm_init_regions (void)
++{
++ grub_uint64_t modend, from, to;
++ unsigned int i;
++
++ modend = grub_modules_get_end ();
++
++ for (i = 0; i < nr_map_entries; i++)
++ {
++ if (map[i].type != GRUB_MEMORY_AVAILABLE)
++ continue;
++ from = map[i].addr;
++ to = from + map[i].len;
++ if (from < modend)
++ from = modend;
++ if (from >= to || from >= (1ULL << 32))
++ continue;
++ if (to > (1ULL << 32))
++ to = 1ULL << 32;
++ grub_mm_init_region ((void *) (grub_addr_t) from, to - from);
++ }
++}
++
+ static grub_uint64_t
+ grub_xen_find_page (grub_uint64_t start)
+ {
+@@ -325,10 +349,21 @@ grub_xen_setup_pvh (void)
+ (void *) par);
+ grub_xen_set_mmap ();
+
++ grub_xen_mm_init_regions ();
++
+ grub_rsdp_addr = pvh_start_info->rsdp_paddr;
+ }
+
+ grub_err_t
+ grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
+ {
++ unsigned int i;
++
++ for (i = 0; i < nr_map_entries; i++)
++ {
++ if (map[i].len && hook (map[i].addr, map[i].len, map[i].type, hook_data))
++ break;
++ }
++
++ return GRUB_ERR_NONE;
+ }
+--
+2.21.0
+
diff --git a/main/grub/0015-xen_pvh-Add-build-runes-for-grub-core.patch b/main/grub/0015-xen_pvh-Add-build-runes-for-grub-core.patch
new file mode 100644
index 0000000000..9fb4d5253c
--- /dev/null
+++ b/main/grub/0015-xen_pvh-Add-build-runes-for-grub-core.patch
@@ -0,0 +1,245 @@
+From 5b988dcabbab55b6a0c71dab2dad798ff2224d11 Mon Sep 17 00:00:00 2001
+From: Juergen Gross <jgross@suse.com>
+Date: Fri, 7 Dec 2018 13:11:43 +0100
+Subject: [PATCH 15/20] xen_pvh: Add build runes for grub-core
+
+Add the modifications to the build system needed to build a xen_pvh
+grub.
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+Tested-by: Hans van Kranenburg <hans@knorrie.org>
+(cherry picked from commit 9c062ad42c32a42b677da4b066cb33debf1dfe30)
+---
+ gentpl.py | 4 ++--
+ grub-core/Makefile.am | 12 ++++++++++++
+ grub-core/Makefile.core.def | 35 +++++++++++++++++++++++++++++++++++
+ 3 files changed, 49 insertions(+), 2 deletions(-)
+
+diff --git a/gentpl.py b/gentpl.py
+index f08bcc404..24d890895 100644
+--- a/gentpl.py
++++ b/gentpl.py
+@@ -28,7 +28,7 @@ import re
+
+ GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot",
+ "i386_multiboot", "i386_ieee1275", "x86_64_efi",
+- "i386_xen", "x86_64_xen",
++ "i386_xen", "x86_64_xen", "i386_xen_pvh",
+ "mips_loongson", "sparc64_ieee1275",
+ "powerpc_ieee1275", "mips_arc", "ia64_efi",
+ "mips_qemu_mips", "arm_uboot", "arm_efi", "arm64_efi" ]
+@@ -69,7 +69,7 @@ GROUPS["videomodules"] = GRUB_PLATFORMS[:];
+ for i in GROUPS["videoinkernel"]: GROUPS["videomodules"].remove(i)
+
+ # Similar for terminfo
+-GROUPS["terminfoinkernel"] = [ "emu", "mips_loongson", "mips_arc", "mips_qemu_mips" ] + GROUPS["xen"] + GROUPS["ieee1275"] + GROUPS["uboot"];
++GROUPS["terminfoinkernel"] = [ "emu", "mips_loongson", "mips_arc", "mips_qemu_mips", "i386_xen_pvh" ] + GROUPS["xen"] + GROUPS["ieee1275"] + GROUPS["uboot"];
+ GROUPS["terminfomodule"] = GRUB_PLATFORMS[:];
+ for i in GROUPS["terminfoinkernel"]: GROUPS["terminfomodule"].remove(i)
+
+diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am
+index e36c109e2..06f620a87 100644
+--- a/grub-core/Makefile.am
++++ b/grub-core/Makefile.am
+@@ -101,6 +101,18 @@ KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/int.h
+ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
+ endif
+
++if COND_i386_xen_pvh
++KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
++KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/int.h
++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h
++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/xen.h
++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/xen/hypercall.h
++endif
++
+ if COND_i386_efi
+ KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
+ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
+diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
+index 2dfa22a92..391ace18e 100644
+--- a/grub-core/Makefile.core.def
++++ b/grub-core/Makefile.core.def
+@@ -79,6 +79,8 @@ kernel = {
+ i386_xen_ldflags = '$(TARGET_IMG_BASE_LDOPT),0';
+ x86_64_xen_ldflags = '$(TARGET_IMG_LDFLAGS)';
+ x86_64_xen_ldflags = '$(TARGET_IMG_BASE_LDOPT),0';
++ i386_xen_pvh_ldflags = '$(TARGET_IMG_LDFLAGS)';
++ i386_xen_pvh_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x100000';
+
+ mips_loongson_ldflags = '-Wl,-Ttext,0x80200000';
+ powerpc_ieee1275_ldflags = '-Wl,-Ttext,0x200000';
+@@ -98,6 +100,7 @@ kernel = {
+ x86_64_efi_startup = kern/x86_64/efi/startup.S;
+ i386_xen_startup = kern/i386/xen/startup.S;
+ x86_64_xen_startup = kern/x86_64/xen/startup.S;
++ i386_xen_pvh_startup = kern/i386/xen/startup_pvh.S;
+ i386_qemu_startup = kern/i386/qemu/startup.S;
+ i386_ieee1275_startup = kern/i386/ieee1275/startup.S;
+ i386_coreboot_startup = kern/i386/coreboot/startup.S;
+@@ -159,6 +162,7 @@ kernel = {
+
+ i386 = kern/i386/dl.c;
+ i386_xen = kern/i386/dl.c;
++ i386_xen_pvh = kern/i386/dl.c;
+
+ i386_coreboot = kern/i386/coreboot/init.c;
+ i386_multiboot = kern/i386/coreboot/init.c;
+@@ -204,6 +208,14 @@ kernel = {
+ xen = disk/xen/xendisk.c;
+ xen = commands/boot.c;
+
++ i386_xen_pvh = commands/boot.c;
++ i386_xen_pvh = disk/xen/xendisk.c;
++ i386_xen_pvh = kern/i386/tsc.c;
++ i386_xen_pvh = kern/i386/xen/tsc.c;
++ i386_xen_pvh = kern/i386/xen/pvh.c;
++ i386_xen_pvh = kern/xen/init.c;
++ i386_xen_pvh = term/xen/console.c;
++
+ ia64_efi = kern/ia64/efi/startup.S;
+ ia64_efi = kern/ia64/efi/init.c;
+ ia64_efi = kern/ia64/dl.c;
+@@ -775,6 +787,7 @@ module = {
+ name = cpuid;
+ common = commands/i386/cpuid.c;
+ enable = x86;
++ enable = i386_xen_pvh;
+ enable = i386_xen;
+ enable = x86_64_xen;
+ };
+@@ -834,6 +847,7 @@ module = {
+ i386_coreboot = lib/i386/halt.c;
+ i386_qemu = lib/i386/halt.c;
+ xen = lib/xen/halt.c;
++ i386_xen_pvh = lib/xen/halt.c;
+ efi = lib/efi/halt.c;
+ ieee1275 = lib/ieee1275/halt.c;
+ emu = lib/emu/halt.c;
+@@ -854,6 +868,7 @@ module = {
+ mips_loongson = lib/mips/loongson/reboot.c;
+ mips_qemu_mips = lib/mips/qemu_mips/reboot.c;
+ xen = lib/xen/reboot.c;
++ i386_xen_pvh = lib/xen/reboot.c;
+ uboot = lib/uboot/reboot.c;
+ common = commands/reboot.c;
+ };
+@@ -1517,12 +1532,18 @@ module = {
+ x86 = lib/i386/relocator16.S;
+ x86 = lib/i386/relocator32.S;
+ x86 = lib/i386/relocator64.S;
++ i386_xen_pvh = lib/i386/relocator16.S;
++ i386_xen_pvh = lib/i386/relocator32.S;
++ i386_xen_pvh = lib/i386/relocator64.S;
+ i386 = lib/i386/relocator_asm.S;
++ i386_xen_pvh = lib/i386/relocator_asm.S;
+ x86_64 = lib/x86_64/relocator_asm.S;
+ i386_xen = lib/i386/relocator_asm.S;
+ x86_64_xen = lib/x86_64/relocator_asm.S;
+ x86 = lib/i386/relocator.c;
+ x86 = lib/i386/relocator_common_c.c;
++ i386_xen_pvh = lib/i386/relocator.c;
++ i386_xen_pvh = lib/i386/relocator_common_c.c;
+ ieee1275 = lib/ieee1275/relocator.c;
+ efi = lib/efi/relocator.c;
+ mips = lib/mips/relocator_asm.S;
+@@ -1541,6 +1562,7 @@ module = {
+ enable = mips;
+ enable = powerpc;
+ enable = x86;
++ enable = i386_xen_pvh;
+ enable = xen;
+ };
+
+@@ -1554,6 +1576,7 @@ module = {
+ sparc64_ieee1275 = lib/ieee1275/cmos.c;
+ powerpc_ieee1275 = lib/ieee1275/cmos.c;
+ xen = lib/xen/datetime.c;
++ i386_xen_pvh = lib/xen/datetime.c;
+
+ mips_arc = lib/arc/datetime.c;
+ enable = noemu;
+@@ -1640,6 +1663,7 @@ module = {
+ common = lib/cmdline.c;
+ common = loader/multiboot_mbi2.c;
+ enable = x86;
++ enable = i386_xen_pvh;
+ enable = mips;
+ };
+
+@@ -1648,8 +1672,10 @@ module = {
+ common = loader/multiboot.c;
+ common = lib/cmdline.c;
+ x86 = loader/i386/multiboot_mbi.c;
++ i386_xen_pvh = loader/i386/multiboot_mbi.c;
+ extra_dist = loader/multiboot_elfxx.c;
+ enable = x86;
++ enable = i386_xen_pvh;
+ };
+
+ module = {
+@@ -1662,8 +1688,10 @@ module = {
+ module = {
+ name = linux;
+ x86 = loader/i386/linux.c;
++ i386_xen_pvh = loader/i386/linux.c;
+ xen = loader/i386/xen.c;
+ i386_pc = lib/i386/pc/vesa_modes_table.c;
++ i386_xen_pvh = lib/i386/pc/vesa_modes_table.c;
+ mips = loader/mips/linux.c;
+ powerpc_ieee1275 = loader/powerpc/ieee1275/linux.c;
+ sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c;
+@@ -1749,6 +1777,8 @@ module = {
+ common = mmap/mmap.c;
+ x86 = mmap/i386/uppermem.c;
+ x86 = mmap/i386/mmap.c;
++ i386_xen_pvh = mmap/i386/uppermem.c;
++ i386_xen_pvh = mmap/i386/mmap.c;
+
+ i386_pc = mmap/i386/pc/mmap.c;
+ i386_pc = mmap/i386/pc/mmap_helper.S;
+@@ -1758,6 +1788,7 @@ module = {
+ mips = mmap/mips/uppermem.c;
+
+ enable = x86;
++ enable = i386_xen_pvh;
+ enable = ia64_efi;
+ enable = arm_efi;
+ enable = arm64_efi;
+@@ -1991,6 +2022,7 @@ module = {
+ name = legacy_password_test;
+ common = tests/legacy_password_test.c;
+ enable = i386_pc;
++ enable = i386_xen_pvh;
+ enable = i386_efi;
+ enable = x86_64_efi;
+ enable = emu;
+@@ -2189,6 +2221,7 @@ module = {
+ xen = lib/i386/pc/vesa_modes_table.c;
+
+ enable = i386_pc;
++ enable = i386_xen_pvh;
+ enable = i386_efi;
+ enable = x86_64_efi;
+ enable = emu;
+@@ -2232,10 +2265,12 @@ module = {
+ module = {
+ name = backtrace;
+ x86 = lib/i386/backtrace.c;
++ i386_xen_pvh = lib/i386/backtrace.c;
+ i386_xen = lib/i386/backtrace.c;
+ x86_64_xen = lib/i386/backtrace.c;
+ common = lib/backtrace.c;
+ enable = x86;
++ enable = i386_xen_pvh;
+ enable = i386_xen;
+ enable = x86_64_xen;
+ };
+--
+2.21.0
+
diff --git a/main/grub/0016-grub-module-verifier-Ignore-all_video-for-xen_pvh.patch b/main/grub/0016-grub-module-verifier-Ignore-all_video-for-xen_pvh.patch
new file mode 100644
index 0000000000..9a0e52dfb0
--- /dev/null
+++ b/main/grub/0016-grub-module-verifier-Ignore-all_video-for-xen_pvh.patch
@@ -0,0 +1,35 @@
+From 98b8fb8b1e8baf5573adf31aca9d64aab0a86e67 Mon Sep 17 00:00:00 2001
+From: Hans van Kranenburg <hans@knorrie.org>
+Date: Fri, 7 Dec 2018 13:11:44 +0100
+Subject: [PATCH 16/20] grub-module-verifier: Ignore all_video for xen_pvh
+
+This solves the build failing with "Error: no symbol table and no
+.moddeps section"
+
+Also see:
+- 6371e9c10433578bb236a8284ddb9ce9e201eb59
+- https://savannah.gnu.org/bugs/?49012
+
+Signed-off-by: Hans van Kranenburg <hans@knorrie.org>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+Tested-by: Hans van Kranenburg <hans@knorrie.org>
+(cherry picked from commit a40b219e269ac407c10a569ce6b0c5d7f419d127)
+---
+ util/grub-module-verifier.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/util/grub-module-verifier.c b/util/grub-module-verifier.c
+index 9179285a5..968eb135d 100644
+--- a/util/grub-module-verifier.c
++++ b/util/grub-module-verifier.c
+@@ -128,6 +128,7 @@ struct platform_whitelist {
+
+ static struct platform_whitelist whitelists[] = {
+ {"i386", "xen", (const char *[]) {"all_video", 0}},
++ {"i386", "xen_pvh", (const char *[]) {"all_video", 0}},
+ {"x86_64", "xen", (const char *[]) {"all_video", 0}},
+ {"sparc64", "ieee1275", (const char *[]) {"all_video", 0}},
+
+--
+2.21.0
+
diff --git a/main/grub/0017-xen-Use-elfnote-defines-instead-of-plain-numbers.patch b/main/grub/0017-xen-Use-elfnote-defines-instead-of-plain-numbers.patch
new file mode 100644
index 0000000000..eff71cf901
--- /dev/null
+++ b/main/grub/0017-xen-Use-elfnote-defines-instead-of-plain-numbers.patch
@@ -0,0 +1,86 @@
+From 688cab35a913ba61f39439f6071381bc3201fcda Mon Sep 17 00:00:00 2001
+From: Juergen Gross <jgross@suse.com>
+Date: Fri, 7 Dec 2018 13:11:45 +0100
+Subject: [PATCH 17/20] xen: Use elfnote defines instead of plain numbers
+
+In order to avoid using plain integers for the ELF notes use the
+available Xen include instead.
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+Tested-by: Hans van Kranenburg <hans@knorrie.org>
+(cherry picked from commit 9bce25213a44553c71527776f65fabc3b729c2f3)
+---
+ util/grub-mkimagexx.c | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c
+index e63f148e4..e7b8cf161 100644
+--- a/util/grub-mkimagexx.c
++++ b/util/grub-mkimagexx.c
+@@ -48,6 +48,8 @@
+ #include <grub/util/install.h>
+ #include <grub/util/mkimage.h>
+
++#include <xen/elfnote.h>
++
+ #pragma GCC diagnostic ignored "-Wcast-align"
+
+ /* These structures are defined according to the CHRP binding to IEEE1275,
+@@ -312,7 +314,7 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
+ note_ptr = (Elf_Nhdr *) ptr;
+ note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME));
+ note_ptr->n_descsz = grub_host_to_target32 (sizeof (PACKAGE_NAME));
+- note_ptr->n_type = grub_host_to_target32 (6);
++ note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_GUEST_OS);
+ ptr += sizeof (Elf_Nhdr);
+ memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME));
+ ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4);
+@@ -323,7 +325,7 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
+ note_ptr = (Elf_Nhdr *) ptr;
+ note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME));
+ note_ptr->n_descsz = grub_host_to_target32 (sizeof ("generic"));
+- note_ptr->n_type = grub_host_to_target32 (8);
++ note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_LOADER);
+ ptr += sizeof (Elf_Nhdr);
+ memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME));
+ ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4);
+@@ -334,7 +336,7 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
+ note_ptr = (Elf_Nhdr *) ptr;
+ note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME));
+ note_ptr->n_descsz = grub_host_to_target32 (sizeof ("xen-3.0"));
+- note_ptr->n_type = grub_host_to_target32 (5);
++ note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_XEN_VERSION);
+ ptr += sizeof (Elf_Nhdr);
+ memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME));
+ ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4);
+@@ -345,7 +347,7 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
+ note_ptr = (Elf_Nhdr *) ptr;
+ note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME));
+ note_ptr->n_descsz = grub_host_to_target32 (image_target->voidp_sizeof);
+- note_ptr->n_type = grub_host_to_target32 (1);
++ note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_ENTRY);
+ ptr += sizeof (Elf_Nhdr);
+ memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME));
+ ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4);
+@@ -356,7 +358,7 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
+ note_ptr = (Elf_Nhdr *) ptr;
+ note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME));
+ note_ptr->n_descsz = grub_host_to_target32 (image_target->voidp_sizeof);
+- note_ptr->n_type = grub_host_to_target32 (3);
++ note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_VIRT_BASE);
+ ptr += sizeof (Elf_Nhdr);
+ memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME));
+ ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4);
+@@ -369,7 +371,7 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
+ note_ptr = (Elf_Nhdr *) ptr;
+ note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME));
+ note_ptr->n_descsz = grub_host_to_target32 (sizeof ("yes,bimodal"));
+- note_ptr->n_type = grub_host_to_target32 (9);
++ note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_PAE_MODE);
+ ptr += sizeof (Elf_Nhdr);
+ memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME));
+ ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4);
+--
+2.21.0
+
diff --git a/main/grub/0018-xen_pvh-Support-building-a-standalone-image.patch b/main/grub/0018-xen_pvh-Support-building-a-standalone-image.patch
new file mode 100644
index 0000000000..1d1b43f33d
--- /dev/null
+++ b/main/grub/0018-xen_pvh-Support-building-a-standalone-image.patch
@@ -0,0 +1,199 @@
+From f8edde763ef26a2eb9cab40998d97e8bc50bf7ef Mon Sep 17 00:00:00 2001
+From: Juergen Gross <jgross@suse.com>
+Date: Fri, 7 Dec 2018 13:11:46 +0100
+Subject: [PATCH 18/20] xen_pvh: Support building a standalone image
+
+Support mkimage for xen_pvh.
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+Tested-by: Hans van Kranenburg <hans@knorrie.org>
+(cherry picked from commit 78899c42d74d638a48c9b3f0f25f39445b3c1d4c)
+---
+ include/grub/util/mkimage.h | 3 ++-
+ util/grub-mkimage32.c | 4 +++-
+ util/grub-mkimage64.c | 4 +++-
+ util/grub-mkimagexx.c | 44 +++++++++++++++++++++++++++++++++----
+ util/mkimage.c | 23 ++++++++++++++++++-
+ 5 files changed, 70 insertions(+), 8 deletions(-)
+
+diff --git a/include/grub/util/mkimage.h b/include/grub/util/mkimage.h
+index 1a18708a8..776c58581 100644
+--- a/include/grub/util/mkimage.h
++++ b/include/grub/util/mkimage.h
+@@ -71,7 +71,8 @@ struct grub_install_image_target_desc
+ IMAGE_I386_IEEE1275,
+ IMAGE_LOONGSON_ELF, IMAGE_QEMU, IMAGE_PPC, IMAGE_YEELOONG_FLASH,
+ IMAGE_FULOONG2F_FLASH, IMAGE_I386_PC_PXE, IMAGE_MIPS_ARC,
+- IMAGE_QEMU_MIPS_FLASH, IMAGE_UBOOT, IMAGE_XEN, IMAGE_I386_PC_ELTORITO
++ IMAGE_QEMU_MIPS_FLASH, IMAGE_UBOOT, IMAGE_XEN, IMAGE_I386_PC_ELTORITO,
++ IMAGE_XEN_PVH
+ } id;
+ enum
+ {
+diff --git a/util/grub-mkimage32.c b/util/grub-mkimage32.c
+index 9b31397bc..b2a4be7e6 100644
+--- a/util/grub-mkimage32.c
++++ b/util/grub-mkimage32.c
+@@ -17,6 +17,8 @@
+ # define ELF_R_SYM(val) ELF32_R_SYM(val)
+ # define ELF_R_TYPE(val) ELF32_R_TYPE(val)
+ # define ELF_ST_TYPE(val) ELF32_ST_TYPE(val)
+-#define XEN_NOTE_SIZE 132
++
++#define XEN_NOTE_SIZE 132
++#define XEN_PVH_NOTE_SIZE 20
+
+ #include "grub-mkimagexx.c"
+diff --git a/util/grub-mkimage64.c b/util/grub-mkimage64.c
+index d83345924..aef033743 100644
+--- a/util/grub-mkimage64.c
++++ b/util/grub-mkimage64.c
+@@ -17,6 +17,8 @@
+ # define ELF_R_SYM(val) ELF64_R_SYM(val)
+ # define ELF_R_TYPE(val) ELF64_R_TYPE(val)
+ # define ELF_ST_TYPE(val) ELF64_ST_TYPE(val)
+-#define XEN_NOTE_SIZE 120
++
++#define XEN_NOTE_SIZE 120
++#define XEN_PVH_NOTE_SIZE 24
+
+ #include "grub-mkimagexx.c"
+diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c
+index e7b8cf161..bf8f9bf9c 100644
+--- a/util/grub-mkimagexx.c
++++ b/util/grub-mkimagexx.c
+@@ -208,12 +208,12 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
+ phnum++;
+ footer_size += sizeof (struct grub_ieee1275_note);
+ }
+- if (image_target->id == IMAGE_XEN)
++ if (image_target->id == IMAGE_XEN || image_target->id == IMAGE_XEN_PVH)
+ {
+ phnum++;
+ shnum++;
+ string_size += sizeof (".xen");
+- footer_size += XEN_NOTE_SIZE;
++ footer_size += (image_target->id == IMAGE_XEN) ? XEN_NOTE_SIZE : XEN_PVH_NOTE_SIZE;
+ }
+ header_size = ALIGN_UP (sizeof (*ehdr) + phnum * sizeof (*phdr)
+ + shnum * sizeof (*shdr) + string_size, align);
+@@ -392,6 +392,39 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
+ phdr->p_offset = grub_host_to_target32 (header_size + program_size);
+ }
+
++ if (image_target->id == IMAGE_XEN_PVH)
++ {
++ char *note_start = (elf_img + program_size + header_size);
++ Elf_Nhdr *note_ptr;
++ char *ptr = (char *) note_start;
++
++ grub_util_info ("adding XEN NOTE segment");
++
++ /* Phys32 Entry. */
++ note_ptr = (Elf_Nhdr *) ptr;
++ note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME));
++ note_ptr->n_descsz = grub_host_to_target32 (image_target->voidp_sizeof);
++ note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_PHYS32_ENTRY);
++ ptr += sizeof (Elf_Nhdr);
++ memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME));
++ ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4);
++ memset (ptr, 0, image_target->voidp_sizeof);
++ *(grub_uint32_t *) ptr = GRUB_KERNEL_I386_XEN_PVH_LINK_ADDR;
++ ptr += image_target->voidp_sizeof;
++
++ assert (XEN_PVH_NOTE_SIZE == (ptr - note_start));
++
++ phdr++;
++ phdr->p_type = grub_host_to_target32 (PT_NOTE);
++ phdr->p_flags = grub_host_to_target32 (PF_R);
++ phdr->p_align = grub_host_to_target32 (image_target->voidp_sizeof);
++ phdr->p_vaddr = 0;
++ phdr->p_paddr = 0;
++ phdr->p_filesz = grub_host_to_target32 (XEN_PVH_NOTE_SIZE);
++ phdr->p_memsz = 0;
++ phdr->p_offset = grub_host_to_target32 (header_size + program_size);
++ }
++
+ if (note)
+ {
+ int note_size = sizeof (struct grub_ieee1275_note);
+@@ -467,7 +500,7 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
+ shdr->sh_entsize = grub_host_to_target32 (0);
+ shdr++;
+
+- if (image_target->id == IMAGE_XEN)
++ if (image_target->id == IMAGE_XEN || image_target->id == IMAGE_XEN_PVH)
+ {
+ memcpy (ptr, ".xen", sizeof (".xen"));
+ shdr->sh_name = grub_host_to_target32 (ptr - str_start);
+@@ -475,7 +508,10 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
+ shdr->sh_type = grub_host_to_target32 (SHT_PROGBITS);
+ shdr->sh_addr = grub_host_to_target_addr (target_addr + kernel_size);
+ shdr->sh_offset = grub_host_to_target_addr (program_size + header_size);
+- shdr->sh_size = grub_host_to_target32 (XEN_NOTE_SIZE);
++ if (image_target->id == IMAGE_XEN)
++ shdr->sh_size = grub_host_to_target32 (XEN_NOTE_SIZE);
++ else
++ shdr->sh_size = grub_host_to_target32 (XEN_PVH_NOTE_SIZE);
+ shdr->sh_link = grub_host_to_target32 (0);
+ shdr->sh_info = grub_host_to_target32 (0);
+ shdr->sh_addralign = grub_host_to_target32 (image_target->voidp_sizeof);
+diff --git a/util/mkimage.c b/util/mkimage.c
+index 9ad4cfe42..c3bd23479 100644
+--- a/util/mkimage.c
++++ b/util/mkimage.c
+@@ -132,6 +132,24 @@ static const struct grub_install_image_target_desc image_targets[] =
+ .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR,
+ .default_compression = GRUB_COMPRESSION_LZMA
+ },
++ {
++ .dirname = "i386-xen_pvh",
++ .names = { "i386-xen_pvh", NULL },
++ .voidp_sizeof = 4,
++ .bigendian = 0,
++ .id = IMAGE_XEN_PVH,
++ .flags = PLATFORM_FLAGS_NONE,
++ .total_module_size = TARGET_NO_FIELD,
++ .decompressor_compressed_size = TARGET_NO_FIELD,
++ .decompressor_uncompressed_size = TARGET_NO_FIELD,
++ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
++ .elf_target = EM_386,
++ .section_align = 1,
++ .vaddr_offset = 0,
++ .link_addr = GRUB_KERNEL_I386_XEN_PVH_LINK_ADDR,
++ .mod_align = GRUB_KERNEL_I386_XEN_PVH_MOD_ALIGN,
++ .link_align = 4
++ },
+ {
+ .dirname = "i386-pc",
+ .names = { "i386-pc-pxe", NULL },
+@@ -816,7 +834,8 @@ grub_install_generate_image (const char *dir, const char *prefix,
+ else
+ kernel_img = grub_mkimage_load_image64 (kernel_path, total_module_size,
+ &layout, image_target);
+- if (image_target->id == IMAGE_XEN && layout.align < 4096)
++ if ((image_target->id == IMAGE_XEN || image_target->id == IMAGE_XEN_PVH) &&
++ layout.align < 4096)
+ layout.align = 4096;
+
+ if ((image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS)
+@@ -1046,6 +1065,7 @@ grub_install_generate_image (const char *dir, const char *prefix,
+ case IMAGE_MIPS_ARC:
+ case IMAGE_QEMU_MIPS_FLASH:
+ case IMAGE_XEN:
++ case IMAGE_XEN_PVH:
+ break;
+ case IMAGE_SPARC64_AOUT:
+ case IMAGE_SPARC64_RAW:
+@@ -1622,6 +1642,7 @@ grub_install_generate_image (const char *dir, const char *prefix,
+ case IMAGE_LOONGSON_ELF:
+ case IMAGE_PPC:
+ case IMAGE_XEN:
++ case IMAGE_XEN_PVH:
+ case IMAGE_COREBOOT:
+ case IMAGE_I386_IEEE1275:
+ {
+--
+2.21.0
+
diff --git a/main/grub/0019-xen_pvh-Support-grub-install-for-xen_pvh.patch b/main/grub/0019-xen_pvh-Support-grub-install-for-xen_pvh.patch
new file mode 100644
index 0000000000..0eb9fc4caa
--- /dev/null
+++ b/main/grub/0019-xen_pvh-Support-grub-install-for-xen_pvh.patch
@@ -0,0 +1,104 @@
+From 733c4c99b6cf66fe0413e1baa84400bd00663e8b Mon Sep 17 00:00:00 2001
+From: Juergen Gross <jgross@suse.com>
+Date: Fri, 7 Dec 2018 13:11:47 +0100
+Subject: [PATCH 19/20] xen_pvh: Support grub-install for xen_pvh
+
+Add xen_pvh support to grub-install.
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+Tested-by: Hans van Kranenburg <hans@knorrie.org>
+(cherry picked from commit 90b7b14fa5293c83c0645bfdcf4ef0cdac230d09)
+---
+ include/grub/util/install.h | 1 +
+ util/grub-install-common.c | 1 +
+ util/grub-install.c | 7 +++++++
+ 3 files changed, 9 insertions(+)
+
+diff --git a/include/grub/util/install.h b/include/grub/util/install.h
+index 5ca4811cd..eafb3c360 100644
+--- a/include/grub/util/install.h
++++ b/include/grub/util/install.h
+@@ -98,6 +98,7 @@ enum grub_install_plat
+ GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS,
+ GRUB_INSTALL_PLATFORM_I386_XEN,
+ GRUB_INSTALL_PLATFORM_X86_64_XEN,
++ GRUB_INSTALL_PLATFORM_I386_XEN_PVH,
+ GRUB_INSTALL_PLATFORM_ARM64_EFI,
+ GRUB_INSTALL_PLATFORM_MAX
+ };
+diff --git a/util/grub-install-common.c b/util/grub-install-common.c
+index 452b230da..e4a3bb5cb 100644
+--- a/util/grub-install-common.c
++++ b/util/grub-install-common.c
+@@ -655,6 +655,7 @@ static struct
+ [GRUB_INSTALL_PLATFORM_X86_64_EFI] = { "x86_64", "efi" },
+ [GRUB_INSTALL_PLATFORM_I386_XEN] = { "i386", "xen" },
+ [GRUB_INSTALL_PLATFORM_X86_64_XEN] = { "x86_64", "xen" },
++ [GRUB_INSTALL_PLATFORM_I386_XEN_PVH] = { "i386", "xen_pvh" },
+ [GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON] = { "mipsel", "loongson" },
+ [GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS] = { "mipsel", "qemu_mips" },
+ [GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS] = { "mips", "qemu_mips" },
+diff --git a/util/grub-install.c b/util/grub-install.c
+index 9074d3e9e..454d97835 100644
+--- a/util/grub-install.c
++++ b/util/grub-install.c
+@@ -495,6 +495,7 @@ have_bootdev (enum grub_install_plat pl)
+
+ case GRUB_INSTALL_PLATFORM_I386_XEN:
+ case GRUB_INSTALL_PLATFORM_X86_64_XEN:
++ case GRUB_INSTALL_PLATFORM_I386_XEN_PVH:
+ return 0;
+
+ /* pacify warning. */
+@@ -907,6 +908,7 @@ main (int argc, char *argv[])
+ case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
+ case GRUB_INSTALL_PLATFORM_I386_XEN:
+ case GRUB_INSTALL_PLATFORM_X86_64_XEN:
++ case GRUB_INSTALL_PLATFORM_I386_XEN_PVH:
+ break;
+
+ case GRUB_INSTALL_PLATFORM_I386_QEMU:
+@@ -952,6 +954,7 @@ main (int argc, char *argv[])
+ case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS:
+ case GRUB_INSTALL_PLATFORM_I386_XEN:
+ case GRUB_INSTALL_PLATFORM_X86_64_XEN:
++ case GRUB_INSTALL_PLATFORM_I386_XEN_PVH:
+ free (install_device);
+ install_device = NULL;
+ break;
+@@ -1458,6 +1461,7 @@ main (int argc, char *argv[])
+ case GRUB_INSTALL_PLATFORM_ARM_UBOOT:
+ case GRUB_INSTALL_PLATFORM_I386_XEN:
+ case GRUB_INSTALL_PLATFORM_X86_64_XEN:
++ case GRUB_INSTALL_PLATFORM_I386_XEN_PVH:
+ grub_util_warn ("%s", _("no hints available for your platform. Expect reduced performance"));
+ break;
+ /* pacify warning. */
+@@ -1547,6 +1551,7 @@ main (int argc, char *argv[])
+ case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
+ case GRUB_INSTALL_PLATFORM_I386_XEN:
+ case GRUB_INSTALL_PLATFORM_X86_64_XEN:
++ case GRUB_INSTALL_PLATFORM_I386_XEN_PVH:
+ core_name = "core.elf";
+ snprintf (mkimage_target, sizeof (mkimage_target),
+ "%s-%s",
+@@ -1638,6 +1643,7 @@ main (int argc, char *argv[])
+ case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275:
+ case GRUB_INSTALL_PLATFORM_I386_XEN:
+ case GRUB_INSTALL_PLATFORM_X86_64_XEN:
++ case GRUB_INSTALL_PLATFORM_I386_XEN_PVH:
+ break;
+ /* pacify warning. */
+ case GRUB_INSTALL_PLATFORM_MAX:
+@@ -1895,6 +1901,7 @@ main (int argc, char *argv[])
+ case GRUB_INSTALL_PLATFORM_I386_QEMU:
+ case GRUB_INSTALL_PLATFORM_I386_XEN:
+ case GRUB_INSTALL_PLATFORM_X86_64_XEN:
++ case GRUB_INSTALL_PLATFORM_I386_XEN_PVH:
+ grub_util_warn ("%s",
+ _("WARNING: no platform-specific install was performed"));
+ break;
+--
+2.21.0
+
diff --git a/main/grub/0020-xen_pvh-Add-support-to-configure.patch b/main/grub/0020-xen_pvh-Add-support-to-configure.patch
new file mode 100644
index 0000000000..29059700b0
--- /dev/null
+++ b/main/grub/0020-xen_pvh-Add-support-to-configure.patch
@@ -0,0 +1,46 @@
+From 7dbb1b71c029f192273c46589d5b28f390929618 Mon Sep 17 00:00:00 2001
+From: Juergen Gross <jgross@suse.com>
+Date: Fri, 7 Dec 2018 13:11:48 +0100
+Subject: [PATCH 20/20] xen_pvh: Add support to configure
+
+Support platform i386/xen_pvh in configure.
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+Tested-by: Hans van Kranenburg <hans@knorrie.org>
+(cherry picked from commit d789e70e26340bd35b36d595a948dbc399b9ffba)
+---
+ configure.ac | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/configure.ac b/configure.ac
+index edd184154..ad1903e66 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -147,6 +147,7 @@ case "$target_cpu"-"$platform" in
+ i386-efi) ;;
+ x86_64-efi) ;;
+ i386-xen) ;;
++ i386-xen_pvh) ;;
+ x86_64-xen) ;;
+ i386-pc) ;;
+ i386-multiboot) ;;
+@@ -213,6 +214,7 @@ case "$platform" in
+ multiboot) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MULTIBOOT=1" ;;
+ efi) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_EFI=1" ;;
+ xen) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_XEN=1" ;;
++ xen_pvh) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_XEN_PVH=1" ;;
+ ieee1275) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_IEEE1275=1" ;;
+ uboot) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_UBOOT=1" ;;
+ qemu) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_QEMU=1" ;;
+@@ -1893,6 +1895,7 @@ AM_CONDITIONAL([COND_i386_coreboot], [test x$target_cpu = xi386 -a x$platform =
+ AM_CONDITIONAL([COND_i386_multiboot], [test x$target_cpu = xi386 -a x$platform = xmultiboot])
+ AM_CONDITIONAL([COND_x86_64_efi], [test x$target_cpu = xx86_64 -a x$platform = xefi])
+ AM_CONDITIONAL([COND_i386_xen], [test x$target_cpu = xi386 -a x$platform = xxen])
++AM_CONDITIONAL([COND_i386_xen_pvh], [test x$target_cpu = xi386 -a x$platform = xxen_pvh])
+ AM_CONDITIONAL([COND_x86_64_xen], [test x$target_cpu = xx86_64 -a x$platform = xxen])
+ AM_CONDITIONAL([COND_mips_loongson], [test x$target_cpu = xmipsel -a x$platform = xloongson])
+ AM_CONDITIONAL([COND_mips_qemu_mips], [test "(" x$target_cpu = xmips -o x$target_cpu = xmipsel ")" -a x$platform = xqemu_mips])
+--
+2.21.0
+
diff --git a/main/grub/APKBUILD b/main/grub/APKBUILD
index 22aa7ec84a..ab7c3e6ad4 100644
--- a/main/grub/APKBUILD
+++ b/main/grub/APKBUILD
@@ -2,7 +2,7 @@
# Maintainer: Timo Teräs <timo.teras@iki.fi>
pkgname=grub
pkgver=2.02
-pkgrel=14
+pkgrel=15
pkgdesc="Bootloader with support for Linux, Multiboot and more"
url="https://www.gnu.org/software/grub/"
arch="all !s390x"
@@ -21,13 +21,14 @@ subpackages="$pkgname-dev $pkgname-doc"
flavors=""
case "$CARCH" in
x86) flavors="efi bios";;
-x86_64) flavors="efi bios xenhost";;
+x86_64) flavors="efi bios xenhost xenhost_pvh";;
aarch64|arm*) flavors="efi";;
mips*) flavors="qemu_mips";;
ppc*) flavors="ieee1275"; makedepends="$makedepends powerpc-utils" ;;
s390x) flavors="emu" ;;
esac
for f in $flavors; do
+ [ x"$f" = x"xenhost_pvh" ] && continue # xenhost_pvh shipped in the xenhost subpackage
subpackages="$subpackages $pkgname-$f"
done
@@ -41,6 +42,27 @@ source="https://ftp.gnu.org/gnu/grub/grub-$pkgver.tar.xz
x86-64-Treat-R_X86_64_PLT32-as-R_X86_64_PC32.patch
alpine-use-uuid.patch
f2fs-support.patch
+
+ 0001-xen-Add-some-Xen-headers.patch
+ 0002-loader-linux-Support-passing-RSDP-address-via-boot-p.patch
+ 0003-xen-Carve-out-grant-tab-initialization-into-dedicate.patch
+ 0004-xen-Prepare-common-code-for-Xen-PVH-support.patch
+ 0005-xen-Add-some-dummy-headers-for-PVH-mode.patch
+ 0006-xen-Rearrange-xen-init.c-to-prepare-it-for-Xen-PVH-m.patch
+ 0007-xen-Modify-grub_xen_ptr2mfn-for-Xen-PVH.patch
+ 0008-xen-Add-PVH-specific-defines-to-offset.h.patch
+ 0009-xen-Add-basic-hooks-for-PVH-in-current-code.patch
+ 0010-xen-Add-PVH-boot-entry-code.patch
+ 0011-xen-Setup-hypercall-page-for-PVH.patch
+ 0012-xen-Get-memory-map-from-hypervisor-for-PVH.patch
+ 0013-xen-Setup-Xen-specific-data-for-PVH.patch
+ 0014-xen-Init-memory-regions-for-PVH.patch
+ 0015-xen_pvh-Add-build-runes-for-grub-core.patch
+ 0016-grub-module-verifier-Ignore-all_video-for-xen_pvh.patch
+ 0017-xen-Use-elfnote-defines-instead-of-plain-numbers.patch
+ 0018-xen_pvh-Support-building-a-standalone-image.patch
+ 0019-xen_pvh-Support-grub-install-for-xen_pvh.patch
+ 0020-xen_pvh-Add-support-to-configure.patch
"
builddir="$srcdir/grub-$pkgver"
@@ -78,7 +100,9 @@ build() {
bios) _build_flavor $f --with-platform=pc;;
efi) _build_flavor $f --with-platform=efi --disable-efiemu;;
xenhost) _build_flavor $f --with-platform=xen;;
+ xenhost_pvh) _build_flavor $f --with-platform=xen_pvh --target=i386;;
*) _build_flavor $f --with-platform=$f;;
+
esac
done
}
@@ -106,11 +130,37 @@ _install_xen() {
rm "$cfg" "$grub_memdisk"
}
+_install_xenpvh() {
+ grub_dir=`mktemp -d`
+ cfg=`mktemp`
+ grub_memdisk=`mktemp`
+
+ mkdir -p $grub_dir/boot/grub
+ echo 'normal (memdisk)/grub.cfg' > $cfg
+ sed -e "s/@@PVBOOT_ARCH@@/$CARCH/g" \
+ $srcdir/grub-xen-host_grub.cfg \
+ > $grub_dir/grub.cfg
+ tar -cf - -C $grub_dir grub.cfg > $grub_memdisk
+
+ echo "About to run grub-mkimage in: $PWD"
+ # Note: only i386-xen_pvh supported
+ ./grub-mkimage \
+ -O i386-xen_pvh \
+ -c $cfg \
+ -d ./grub-core ./grub-core/*.mod \
+ -m $grub_memdisk \
+ -o $pkgdir/grub-i386-xen_pvh.bin
+
+ rm -r "$grub_dir"
+ rm "$cfg" "$grub_memdisk"
+}
+
_install_flavor() {
local flavor="$1"
cd "$srcdir"/build-$flavor
case $flavor in
xenhost) _install_xen;;
+ xenhost_pvh) _install_xenpvh;;
*) make DESTDIR="$pkgdir" install-strip;;
esac
}
@@ -153,6 +203,9 @@ xenhost() {
pkgdesc="$pkgdesc (XEN host version)"
mkdir -p $subpkgdir/usr/lib/grub-xen
mv $pkgdir/*-xen.bin $subpkgdir/usr/lib/grub-xen/
+
+ # pick up result from xenhost_pvh build as well
+ mv $pkgdir/*-xen_pvh.bin $subpkgdir/usr/lib/grub-xen/
}
qemu_mips() {
@@ -185,4 +238,24 @@ f2a7d9ab6c445f4e402e790db56378cecd6631b5c367451aa6ce5c01cd95b95c83c3dd24d6d4b857
4723c5dd9fd6e9b6c8677e32e4906c7995d695c7e85e834b1b29eb1d9a024678f8fa75846c7b929d1db9b5911b604c69c1b0379cb3b9adc98d5bb6d6719eb2c4 0009-xfs-Accept-filesystem-with-sparse-inodes.patch
e11f62b5012ecc8abf9d4912db12a263470887671b05ccb4de54981fb3b32a52d4557439a160e69e0654e35a57fdb0afd5fe801709b8037a6ea4a50d8b8455ec x86-64-Treat-R_X86_64_PLT32-as-R_X86_64_PC32.patch
ce788fa909bb89a3ccabbc144bb46226373cf846ffe1f315b0bf8b02403220d95c8fe67baf3c37c4e12cb36f22d70f62bbd2d0c5ff6b7230f05e5964b5c548ac alpine-use-uuid.patch
-e4e7716cef9f183810eade57751617595c5d5fac740223a5ac3ed13e2215bbb38781328a3f8da3d4c71dd39ffec55d27d3e55b55c189dce55748e9a8512d4b41 f2fs-support.patch"
+e4e7716cef9f183810eade57751617595c5d5fac740223a5ac3ed13e2215bbb38781328a3f8da3d4c71dd39ffec55d27d3e55b55c189dce55748e9a8512d4b41 f2fs-support.patch
+9daf00b36108852a7443ce4b5b1114d2e87cbfc72148b7847508965ff0dfab14b3f56980a0110c82170f5c2b75ef7a337a15398f59a4cb7e6404227499bffd9a 0001-xen-Add-some-Xen-headers.patch
+33505273a8525aa4b44acba69f1b7f0dbee144809fb86626879895d44ce7eed889abf442644fc96536b4ebf86ab7c84a982749fc1181976e89e59a5cf7f7944e 0002-loader-linux-Support-passing-RSDP-address-via-boot-p.patch
+1e446051930a96078e2b22831f53e939affdcee371e35e45d87efb8bdf02e2eea03247b7636525daf7d9306ec47cd4351e4d74abe357d19658b0b3fc884f9343 0003-xen-Carve-out-grant-tab-initialization-into-dedicate.patch
+ceba427cdfc7e4566a0b9ba7ab1f7d52136510938a3789f0bddbabd45f7b3ccdd39e143d2b19a39ceae2348f08a0af92fd8297788828565571ec1a2491c11768 0004-xen-Prepare-common-code-for-Xen-PVH-support.patch
+d185926d2e70cfa4d78a929d05932e2603cf9fa728c1afae7119bd26a9d60d9a769a560bab79b65b0733c7861e2907424542352019b3c6edf0a58be367573ba9 0005-xen-Add-some-dummy-headers-for-PVH-mode.patch
+501cea14809a88ff11c81a325063b04c4f75efb490b7acaf6ca1435d98d24b3bcd8fd3b0df76a3e7200561c5020d299bb4ffb178f85f3e88bd18ba4ec656260f 0006-xen-Rearrange-xen-init.c-to-prepare-it-for-Xen-PVH-m.patch
+8afefbecce41fb67a47c04fc3a068f3fae36f424746bd09298cbf774620dcf8493f366e66cd554c9112bbc18d31a09be5b5f6ed78d422d861873cf03755b7ddd 0007-xen-Modify-grub_xen_ptr2mfn-for-Xen-PVH.patch
+e18e0e58ff325f2e50bf1625d4befe42e9e66d271563bbeabe7f0abacd3499b858ff2a827256cf0726f629d8a944a60dcd1d620a5f0823f44613d88f86cd41ed 0008-xen-Add-PVH-specific-defines-to-offset.h.patch
+5337a029b5ae11d04a8c821baf15c360f35bf49892ff3c97e1c4b36775e4918feea6188850ecb99275ebf2cd4630ea887007e568a0743661f31663d5b9a4e3dd 0009-xen-Add-basic-hooks-for-PVH-in-current-code.patch
+cc84a610e07180d732691163c08fc8de3252a6f23af4ec739ef18192c9bd8cdee60252bebcf2c224ef296f3accc86f9d57dde0f2069536ce1d4c203ab56166e2 0010-xen-Add-PVH-boot-entry-code.patch
+0bc6becfd10c2948980e305268906d009729fb0795b9f7ef3a80ae169728461faa2582444cfad40f2c6063dd3a82ee5a030be092cba65833a7ab30feba147e43 0011-xen-Setup-hypercall-page-for-PVH.patch
+49e146a955fb41e8dbb8cef9c1d321737d2646d0f4ac686a054a0e70db05879367e0110ee74690cff3357791397f1c86262311335a41fd81de15db722fe0f58d 0012-xen-Get-memory-map-from-hypervisor-for-PVH.patch
+47b8572a1778ccf5221a5a0b7880e4f4bd86a03b5716b13444b5e8f7a4059c9b5cd6a01ddd29ca78fe89c0599d7ee018728979bce4771e7ca4420c14f8855dd7 0013-xen-Setup-Xen-specific-data-for-PVH.patch
+e7f1311ed679dfd969225af91293a046fced7c046afcaa716f54b8cb18dbbe364d471e6b493d686cf8b63651e7e3a89b8c31ddc7457581117ebacafce3ceaea9 0014-xen-Init-memory-regions-for-PVH.patch
+45d14b87a949ce5f1d63ba5cd0048205d94359d23d3f230017b7f6de6e5d25388b2d1af06b8f32fe187adfde2d3ef30e7100e6624f6201cb9d8365bd0a742ddb 0015-xen_pvh-Add-build-runes-for-grub-core.patch
+fe7ea6eeab330c0fdfd0b2a858acdff88c68f69d80b9abb21b4c3cd1d18f8717ab7c47729e28857c564c4c1427d9b1ce6b9b93643507717a8f5ec2d99c843c70 0016-grub-module-verifier-Ignore-all_video-for-xen_pvh.patch
+3e78cd3cd1c70236d8e9e3a536eb2f887283b5d257f60533d22d093df76c1c3c60e490acae4b738301c87edbac2e27398fce6ddbbeb9b2f193191c76afb9bd8b 0017-xen-Use-elfnote-defines-instead-of-plain-numbers.patch
+c8a16db1224c9fb4a26ef39fbd8c36bf26ff68d45d88fb4e2530369c5bccadf0208551c34c0d16e9ee4a3102d67edad26a46e7b8388222f530310762246df8ef 0018-xen_pvh-Support-building-a-standalone-image.patch
+b00cb9146cadc1f48586dcab31ac4605d9591d860283000accf709a489f136bf5c8fe3351dbefe51f9e27407ca3f1ce5dd7bc2ac64ac826f593183ef5d3a9759 0019-xen_pvh-Support-grub-install-for-xen_pvh.patch
+78bc31b69cde95a29b365b43898caf69238c036683a26e5448d66cd48c7a4906d2a9eff065f082c5300b72616d6e63033891fd75d59ce724759dc998d9942a37 0020-xen_pvh-Add-support-to-configure.patch"