summaryrefslogtreecommitdiffstats
path: root/meta-xilinx-virtualization
diff options
context:
space:
mode:
Diffstat (limited to 'meta-xilinx-virtualization')
-rw-r--r--meta-xilinx-virtualization/COPYING.MIT17
-rw-r--r--meta-xilinx-virtualization/README.md143
-rw-r--r--meta-xilinx-virtualization/conf/layer.conf27
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-native_%.bbappend1
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-system-native_%.bbappend1
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-tpm.inc4
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xen_7.1.inc33
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xen_8.1.inc20
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0001-xen-pt-fix-syntax-error-that-causes-FTBFS-in-some-co.patch40
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0001-xen-when-unplugging-emulated-devices-skip-virtio-dev.patch51
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0001-xen_common-return-error-from-xen_create_ioreq_server.patch55
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0002-xen-add-pseudo-RAM-region-for-grant-mappings.patch252
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0002-xen-mapcache-move-xen-mapcache.c-to-hw-xen.patch88
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0003-hw-i386-xen-rearrange-xen_hvm_init_pc.patch106
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0003-softmmu-let-qemu_map_ram_ptr-use-qemu_ram_ptr_length.patch113
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0004-xen-hvm-move-x86-specific-fields-out-of-XenIOState.patch180
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0004-xen-let-xen_ram_addr_from_mapcache-return-1-in-case-.patch49
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0005-memory-add-MemoryRegion-map-and-unmap-callbacks.patch150
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0005-xen-hvm-create-arch_handle_ioreq-and-arch_xen_set_me.patch192
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0006-xen-add-map-and-unmap-callbacks-for-grant-region.patch255
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0006-xen-hvm-move-common-functions-to-hw-xen-xen-hvm-comm.patch2094
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0007-xen-mapcache-Fix-build-on-Arm.patch37
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0007-xen-skip-ioreq-creation-on-ioreq-registration-failur.patch42
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0008-accel-xen-xen-all-export-xenstore_record_dm_state.patch48
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0008-hw-arm-Add-grant-mapping.patch39
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0009-xen-hvm-enable-xen-hvm-common-build-for-ARM.patch43
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0010-hw-arm-introduce-xenpv-machine.patch230
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0011-meson.build-do-not-set-have_xen_pci_passthrough-for-.patch33
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0012-xen-arm-call-qemu_find_tpm_be-if-CONFIG_TPM.patch72
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0013-arm-xenpv-fix-TPM-address-print-warning.patch27
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0014-xen_arm-Create-virtio-mmio-devices-during-initializa.patch83
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0015-xen_arm-Initialize-RAM-and-add-hi-low-memory-regions.patch105
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0016-xen_arm-Add-accel-xen-and-drop-extra-interface-openi.patch79
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0001-arm-xenpvh-Introduce-virtio-pci-support.patch353
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0001-xen_arm-Create-virtio-mmio-devices-during-initializa.patch116
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0002-xen_arm-Initialize-RAM-and-add-hi-low-memory-regions.patch124
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0003-Xen-Fix-xen_set_irq-and-xendevicemodel_set_irq_level.patch55
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0004-xen-when-unplugging-emulated-devices-skip-virtio-dev.patch70
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0005-softmmu-physmem-Split-ram_block_add.patch117
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0006-xen-add-pseudo-RAM-region-for-grant-mappings.patch153
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0007-softmmu-let-qemu_map_ram_ptr-use-qemu_ram_ptr_length.patch117
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0008-xen-let-xen_ram_addr_from_mapcache-return-1-in-case-.patch49
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0009-memory-add-MemoryRegion-map-and-unmap-callbacks.patch155
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0010-xen-add-map-and-unmap-callbacks-for-grant-region.patch262
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0011-hw-arm-Add-grant-mapping.patch30
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-native_%.bbappend1
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-system-native_%.bbappend1
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx_2023%.bbappend5
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx_2024%.bbappend5
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu_7.1%.bbappend5
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu_8.1%.bbappend5
-rw-r--r--meta-xilinx-virtualization/recipes-extended/xen/files/0001-menuconfig-mconf-cfg-Allow-specification-of-ncurses-location.patch57
-rw-r--r--meta-xilinx-virtualization/recipes-extended/xen/files/0001-python-pygrub-pass-DISTUTILS-xen-4.15.patch73
-rw-r--r--meta-xilinx-virtualization/recipes-extended/xen/files/0001-python-pygrub-pass-DISTUTILS-xen-4.18.patch43
-rw-r--r--meta-xilinx-virtualization/recipes-extended/xen/files/xen-flask-race-fix.patch54
-rw-r--r--meta-xilinx-virtualization/recipes-extended/xen/xen-arch.inc18
-rw-r--r--meta-xilinx-virtualization/recipes-extended/xen/xen-blktap.inc76
-rw-r--r--meta-xilinx-virtualization/recipes-extended/xen/xen-hypervisor.inc117
-rw-r--r--meta-xilinx-virtualization/recipes-extended/xen/xen-tools-xilinx.inc25
-rw-r--r--meta-xilinx-virtualization/recipes-extended/xen/xen-tools.inc861
-rw-r--r--meta-xilinx-virtualization/recipes-extended/xen/xen-tools_4.17.bb18
-rw-r--r--meta-xilinx-virtualization/recipes-extended/xen/xen-tools_4.17.bbappend2
-rw-r--r--meta-xilinx-virtualization/recipes-extended/xen/xen-tools_4.18.bb18
-rw-r--r--meta-xilinx-virtualization/recipes-extended/xen/xen-tools_4.18.bbappend2
-rw-r--r--meta-xilinx-virtualization/recipes-extended/xen/xen-xilinx_4.17.inc7
-rw-r--r--meta-xilinx-virtualization/recipes-extended/xen/xen-xilinx_4.18.inc7
-rw-r--r--meta-xilinx-virtualization/recipes-extended/xen/xen.inc233
-rw-r--r--meta-xilinx-virtualization/recipes-extended/xen/xen_4.17.bb19
-rw-r--r--meta-xilinx-virtualization/recipes-extended/xen/xen_4.17.bbappend20
-rw-r--r--meta-xilinx-virtualization/recipes-extended/xen/xen_4.18.bb18
-rw-r--r--meta-xilinx-virtualization/recipes-extended/xen/xen_4.18.bbappend20
-rw-r--r--meta-xilinx-virtualization/recipes-graphics/xorg-xserver/xserver-xorg_%.bbappend8
72 files changed, 8028 insertions, 0 deletions
diff --git a/meta-xilinx-virtualization/COPYING.MIT b/meta-xilinx-virtualization/COPYING.MIT
new file mode 100644
index 00000000..fb950dc6
--- /dev/null
+++ b/meta-xilinx-virtualization/COPYING.MIT
@@ -0,0 +1,17 @@
1Permission is hereby granted, free of charge, to any person obtaining a copy
2of this software and associated documentation files (the "Software"), to deal
3in the Software without restriction, including without limitation the rights
4to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
5copies of the Software, and to permit persons to whom the Software is
6furnished to do so, subject to the following conditions:
7
8The above copyright notice and this permission notice shall be included in
9all copies or substantial portions of the Software.
10
11THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
17THE SOFTWARE.
diff --git a/meta-xilinx-virtualization/README.md b/meta-xilinx-virtualization/README.md
new file mode 100644
index 00000000..ad6d4ada
--- /dev/null
+++ b/meta-xilinx-virtualization/README.md
@@ -0,0 +1,143 @@
1# meta-xilinx-vendor
2
3This layer enables AMD Xilinx Xen configurations and features for ZynqMP and
4Versal devices and also provides related metadata.
5
6## Xen Build Instructions
7
8The Yocto Project setup for AMD Xilinx Xen configurations workflow is as follows.
9Be sure to read everything below.
10
111. Follow [Building Instructions](../README.building.md) upto step 2.
12
132. Clone the meta-security repository.
14
15```
16$ git clone -b <release-branch> https://git.yoctoproject.org/meta-security
17```
18
193. Continue [Building Instructions](../README.building.md) from step 4.
20
21> **Note:**
22> * For System Device Tree(SDT) workflow see [SDT Building Instructions](../meta-xilinx-standalone-experimental/README.md)
23
244. Add meta-xilinx-virtualization layer to bblayers.conf as shown below.
25
26```
27$ bitbake-layers add-layer ./<path-to-layer>/meta-xilinx/meta-xilinx-virtualization
28```
29
305. The following variables needs to be added to the end of the conf/local.conf file.
31
32```
33# Xen variables
34BOOTMODE = "xen"
35ENABLE_XEN_UBOOT_SCR = "1"
36ENABLE_XEN_DTSI = "1"
37ENABLE_XEN_QEMU_DTSI = "1"
38
39DISTRO_FEATURES:append = " multiarch security tpm virtualization vmsep xen"
40
41IMAGE_FEATURES += "ssh-server-openssh"
42
43DISTRO_FEATURES:append = " systemd"
44VIRTUAL-RUNTIME_init_manager = "systemd"
45DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"
46
47IMAGE_INSTALL:append = " \
48 kernel-module-xen-blkback \
49 kernel-module-xen-gntalloc \
50 kernel-module-xen-gntdev \
51 kernel-module-xen-netback \
52 kernel-module-xen-wdt \
53 xen \
54 xen-tools \
55 xen-tools-xenstat \
56 ${@bb.utils.contains('DISTRO_FEATURES', 'vmsep', 'qemu-aarch64 qemu-keymaps', 'qemu', d)} \
57 "
58```
59
606. Continue [Building Instructions](../README.building.md) from step 5.
61
62## Xen Boot Instructions
63
64> **Note:**
65> * This README provides instructions for Xen Dom0 only.
66
671. Follow [Booting Instructions](../README.booting.md) upto step 2.
68
692. Verify Xen Dom0 is up and running on QEMU or target as shown below.
70
71```
72Poky (Yocto Project Reference Distro) 4.1.4 zynqmp-generic hvc0
73
74zynqmp-generic login: root
75root@zynqmp-generic:~# xl list
76Name ID Mem VCPUs State Time(s)
77Domain-0 0 1500 1 r----- 123.5
78root@zynqmp-generic:~# xl info
79host : zynqmp-generic
80release : 6.1.0-xilinx-v2024.1
81version : #1 SMP Thu Dec 21 07:00:11 UTC 2023
82machine : aarch64
83nr_cpus : 4
84max_cpu_id : 3
85nr_nodes : 1
86cores_per_socket : 1
87threads_per_core : 1
88cpu_mhz : 99.990
89hw_caps : 00000000:00000000:00000000:00000000:00000000:00000000:00000000:00000000
90virt_caps : hvm hvm_directio hap iommu_hap_pt_share vpmu gnttab-v1
91total_memory : 4095
92free_memory : 2529
93sharing_freed_memory : 0
94sharing_used_memory : 0
95outstanding_claims : 0
96free_cpus : 0
97xen_major : 4
98xen_minor : 17
99xen_extra : .0
100xen_version : 4.17.0
101xen_caps : xen-3.0-aarch64 xen-3.0-armv7l
102xen_scheduler : credit2
103xen_pagesize : 4096
104platform_params : virt_start=0x200000
105xen_changeset : Tue Dec 12 10:08:40 2023 +0100 git:38eebc6e5c-dirty
106xen_commandline : console=dtuart dtuart=serial0 dom0_mem=1500M dom0_max_vcpus=1 bootscrub=0 vwfi=native
107cc_compiler : aarch64-poky-linux-gcc (GCC) 12.2.0
108cc_compile_by : santraju
109cc_compile_domain :
110cc_compile_date : 2023-12-12
111build_id : 5e2952e1dd06c52a2a09ada7476333c48d88a285
112xend_config_format : 4
113root@zynqmp-generic:~#
114```
115
116## Dependencies
117
118This layer depends on:
119
120 URI: https://git.yoctoproject.org/poky
121 layers: meta, meta-poky
122 branch: langdale
123
124 URI: https://git.openembedded.org/meta-openembedded
125 layers: meta-oe, meta-python, meta-filesystems, meta-networking.
126 branch: langdale
127
128 URI:
129 https://git.yoctoproject.org/meta-xilinx (official version)
130 https://github.com/Xilinx/meta-xilinx (development and amd xilinx release)
131 layers: meta-xilinx-core, meta-xilinx-standalone
132 branch: langdale or amd xilinx release version (e.g. rel-v2024.1)
133
134 URI: https://git.yoctoproject.org/meta-virtualization
135 branch: langdale
136
137 URI: https://git.yoctoproject.org/meta-security
138 layers: meta-tpm
139 branch: langdale
140
141## References
142
143* https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842530/Xen+Hypervisor
diff --git a/meta-xilinx-virtualization/conf/layer.conf b/meta-xilinx-virtualization/conf/layer.conf
new file mode 100644
index 00000000..5e03cde4
--- /dev/null
+++ b/meta-xilinx-virtualization/conf/layer.conf
@@ -0,0 +1,27 @@
1# We have a conf and classes directory, add to BBPATH
2BBPATH .= ":${LAYERDIR}"
3
4# We have packages directories, add to BBFILES
5BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
6 ${LAYERDIR}/recipes-*/*/*.bbappend"
7
8BBFILE_COLLECTIONS += "xilinx-virtualization"
9BBFILE_PATTERN_xilinx-virtualization = "^${LAYERDIR}/"
10BBFILE_PRIORITY_xilinx-virtualization = "5"
11
12LAYERDEPENDS_xilinx-virtualization = "\
13 xilinx \
14 virtualization-layer \
15 security \
16 tpm-layer \
17 "
18
19LAYERSERIES_COMPAT_xilinx-virtualization = "scarthgap"
20
21XILINX_XEN_VERSION[v2022.1] = "4.17-xilinx+git%"
22XILINX_XEN_VERSION[v2022.2] = "4.17-xilinx+git%"
23XILINX_XEN_VERSION[v2023.1] = "4.17-xilinx+git%"
24XILINX_XEN_VERSION[v2023.2] = "4.17-xilinx+git%"
25XILINX_XEN_VERSION[v2024.1] = "4.18-xilinx+git%"
26PREFERRED_VERSION_xen ?= "${@d.getVarFlag('XILINX_XEN_VERSION', d.getVar('XILINX_RELEASE_VERSION')) or 'undefined'}"
27PREFERRED_VERSION_xen-tools ?= "${@d.getVarFlag('XILINX_XEN_VERSION', d.getVar('XILINX_RELEASE_VERSION')) or 'undefined'}"
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-native_%.bbappend b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-native_%.bbappend
new file mode 100644
index 00000000..e84844cf
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-native_%.bbappend
@@ -0,0 +1 @@
require qemu-tpm.inc
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-system-native_%.bbappend b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-system-native_%.bbappend
new file mode 100644
index 00000000..e84844cf
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-system-native_%.bbappend
@@ -0,0 +1 @@
require qemu-tpm.inc
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-tpm.inc b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-tpm.inc
new file mode 100644
index 00000000..a582b035
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-tpm.inc
@@ -0,0 +1,4 @@
1PACKAGECONFIG:append = "${@bb.utils.contains('DISTRO_FEATURES', 'tpm', ' tpm', '', d)}"
2
3PACKAGECONFIG[tpm] = "--enable-tpm,--disable-tpm,,swtpm libtpm"
4
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xen_7.1.inc b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xen_7.1.inc
new file mode 100644
index 00000000..1210a3de
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xen_7.1.inc
@@ -0,0 +1,33 @@
1# Xen-4.17 specific changes are only applicable on the target
2SRC_URI_XEN = ""
3SRC_URI_XEN:class-target = " \
4 file://0001-xen-pt-fix-syntax-error-that-causes-FTBFS-in-some-co.patch \
5 file://0001-xen_common-return-error-from-xen_create_ioreq_server.patch \
6 file://0002-xen-mapcache-move-xen-mapcache.c-to-hw-xen.patch \
7 file://0003-hw-i386-xen-rearrange-xen_hvm_init_pc.patch \
8 file://0004-xen-hvm-move-x86-specific-fields-out-of-XenIOState.patch \
9 file://0005-xen-hvm-create-arch_handle_ioreq-and-arch_xen_set_me.patch \
10 file://0006-xen-hvm-move-common-functions-to-hw-xen-xen-hvm-comm.patch \
11 file://0007-xen-skip-ioreq-creation-on-ioreq-registration-failur.patch \
12 file://0008-accel-xen-xen-all-export-xenstore_record_dm_state.patch \
13 file://0009-xen-hvm-enable-xen-hvm-common-build-for-ARM.patch \
14 file://0010-hw-arm-introduce-xenpv-machine.patch \
15 file://0011-meson.build-do-not-set-have_xen_pci_passthrough-for-.patch \
16 file://0012-xen-arm-call-qemu_find_tpm_be-if-CONFIG_TPM.patch \
17 file://0013-arm-xenpv-fix-TPM-address-print-warning.patch \
18 file://0014-xen_arm-Create-virtio-mmio-devices-during-initializa.patch \
19 file://0015-xen_arm-Initialize-RAM-and-add-hi-low-memory-regions.patch \
20 file://0016-xen_arm-Add-accel-xen-and-drop-extra-interface-openi.patch \
21 file://0001-xen-when-unplugging-emulated-devices-skip-virtio-dev.patch \
22 file://0002-xen-add-pseudo-RAM-region-for-grant-mappings.patch \
23 file://0003-softmmu-let-qemu_map_ram_ptr-use-qemu_ram_ptr_length.patch \
24 file://0004-xen-let-xen_ram_addr_from_mapcache-return-1-in-case-.patch \
25 file://0005-memory-add-MemoryRegion-map-and-unmap-callbacks.patch \
26 file://0006-xen-add-map-and-unmap-callbacks-for-grant-region.patch \
27 file://0007-xen-mapcache-Fix-build-on-Arm.patch \
28 file://0008-hw-arm-Add-grant-mapping.patch \
29 "
30
31FILESEXTRAPATHS:prepend:class-target := "${THISDIR}/qemu-xilinx-7.1:"
32
33SRC_URI .= "${@bb.utils.contains('DISTRO_FEATURES', 'xen', '${SRC_URI_XEN}', '', d)}"
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xen_8.1.inc b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xen_8.1.inc
new file mode 100644
index 00000000..c674dc1a
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xen_8.1.inc
@@ -0,0 +1,20 @@
1# Xen-4.18 specific changes are only applicable on the target
2SRC_URI_XEN = ""
3SRC_URI_XEN:class-target = " \
4 file://0001-xen_arm-Create-virtio-mmio-devices-during-initializa.patch \
5 file://0002-xen_arm-Initialize-RAM-and-add-hi-low-memory-regions.patch \
6 file://0003-Xen-Fix-xen_set_irq-and-xendevicemodel_set_irq_level.patch \
7 file://0004-xen-when-unplugging-emulated-devices-skip-virtio-dev.patch \
8 file://0005-softmmu-physmem-Split-ram_block_add.patch \
9 file://0006-xen-add-pseudo-RAM-region-for-grant-mappings.patch \
10 file://0007-softmmu-let-qemu_map_ram_ptr-use-qemu_ram_ptr_length.patch \
11 file://0008-xen-let-xen_ram_addr_from_mapcache-return-1-in-case-.patch \
12 file://0009-memory-add-MemoryRegion-map-and-unmap-callbacks.patch \
13 file://0010-xen-add-map-and-unmap-callbacks-for-grant-region.patch \
14 file://0011-hw-arm-Add-grant-mapping.patch \
15 file://0001-arm-xenpvh-Introduce-virtio-pci-support.patch \
16 "
17
18FILESEXTRAPATHS:prepend:class-target := "${THISDIR}/qemu-xilinx-8.1:"
19
20SRC_URI .= "${@bb.utils.contains('DISTRO_FEATURES', 'xen', '${SRC_URI_XEN}', '', d)}"
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0001-xen-pt-fix-syntax-error-that-causes-FTBFS-in-some-co.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0001-xen-pt-fix-syntax-error-that-causes-FTBFS-in-some-co.patch
new file mode 100644
index 00000000..99eaeeaf
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0001-xen-pt-fix-syntax-error-that-causes-FTBFS-in-some-co.patch
@@ -0,0 +1,40 @@
1From ba24456b93a205b728475d5f0880f3ec495e383a Mon Sep 17 00:00:00 2001
2From: Chuck Zmudzinski <brchuckz@aol.com>
3Date: Mon, 31 Oct 2022 17:35:52 -0400
4Subject: [PATCH] xen/pt: fix syntax error that causes FTBFS in some
5 configurations
6MIME-Version: 1.0
7Content-Type: text/plain; charset=UTF-8
8Content-Transfer-Encoding: 8bit
9
10When Qemu is built with --enable-xen and --disable-xen-pci-passthrough
11and the target os is linux, the build fails with:
12
13meson.build:3477:2: ERROR: File xen_pt_stub.c does not exist.
14
15Fixes: 582ea95f5f93 ("meson: convert hw/xen")
16
17Signed-off-by: Chuck Zmudzinski <brchuckz@aol.com>
18Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
19Message-Id: <5f1342a13c09af77b1a7b0aeaba5955bcea89731.1667242033.git.brchuckz@aol.com>
20Signed-off-by: Laurent Vivier <laurent@vivier.eu>
21---
22 hw/xen/meson.build | 2 +-
23 1 file changed, 1 insertion(+), 1 deletion(-)
24
25diff --git a/hw/xen/meson.build b/hw/xen/meson.build
26index 08dc1f6857..ae0ace3046 100644
27--- a/hw/xen/meson.build
28+++ b/hw/xen/meson.build
29@@ -18,7 +18,7 @@ if have_xen_pci_passthrough
30 'xen_pt_msi.c',
31 ))
32 else
33- xen_specific_ss.add('xen_pt_stub.c')
34+ xen_specific_ss.add(files('xen_pt_stub.c'))
35 endif
36
37 specific_ss.add_all(when: ['CONFIG_XEN', xen], if_true: xen_specific_ss)
38--
392.17.0
40
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0001-xen-when-unplugging-emulated-devices-skip-virtio-dev.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0001-xen-when-unplugging-emulated-devices-skip-virtio-dev.patch
new file mode 100644
index 00000000..71dfb3be
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0001-xen-when-unplugging-emulated-devices-skip-virtio-dev.patch
@@ -0,0 +1,51 @@
1From e2b85efc82bc26a838f666c8282528ee38cf6377 Mon Sep 17 00:00:00 2001
2From: Juergen Gross <jgross@suse.com>
3Date: Tue, 16 Mar 2021 14:00:33 +0100
4Subject: [PATCH 1/8] xen: when unplugging emulated devices skip virtio devices
5
6Virtio devices should never be unplugged at boot time, as they are
7similar to pci passthrough devices.
8
9Signed-off-by: Juergen Gross <jgross@suse.com>
10Acked-by: Stefano Stabellini <stefano.stabellini@amd.com>
11---
12 hw/i386/xen/xen_platform.c | 9 ++++++++-
13 1 file changed, 8 insertions(+), 1 deletion(-)
14
15diff --git a/hw/i386/xen/xen_platform.c b/hw/i386/xen/xen_platform.c
16index a64265cca0..39bbb12675 100644
17--- a/hw/i386/xen/xen_platform.c
18+++ b/hw/i386/xen/xen_platform.c
19@@ -30,6 +30,7 @@
20 #include "hw/pci/pci.h"
21 #include "hw/xen/xen_common.h"
22 #include "migration/vmstate.h"
23+#include "hw/virtio/virtio-bus.h"
24 #include "hw/xen/xen-legacy-backend.h"
25 #include "trace.h"
26 #include "sysemu/xen.h"
27@@ -114,7 +115,8 @@ static void unplug_nic(PCIBus *b, PCIDevice *d, void *o)
28 /* We have to ignore passthrough devices */
29 if (pci_get_word(d->config + PCI_CLASS_DEVICE) ==
30 PCI_CLASS_NETWORK_ETHERNET
31- && strcmp(d->name, "xen-pci-passthrough") != 0) {
32+ && strcmp(d->name, "xen-pci-passthrough") != 0
33+ && !qdev_get_child_bus(&d->qdev, TYPE_VIRTIO_BUS)) {
34 object_unparent(OBJECT(d));
35 }
36 }
37@@ -191,6 +193,11 @@ static void unplug_disks(PCIBus *b, PCIDevice *d, void *opaque)
38 return;
39 }
40
41+ /* Ignore virtio devices */
42+ if (qdev_get_child_bus(&d->qdev, TYPE_VIRTIO_BUS)) {
43+ return;
44+ }
45+
46 switch (pci_get_word(d->config + PCI_CLASS_DEVICE)) {
47 case PCI_CLASS_STORAGE_IDE:
48 pci_xen_ide_unplug(DEVICE(d), aux);
49--
502.25.1
51
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0001-xen_common-return-error-from-xen_create_ioreq_server.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0001-xen_common-return-error-from-xen_create_ioreq_server.patch
new file mode 100644
index 00000000..d4349b1d
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0001-xen_common-return-error-from-xen_create_ioreq_server.patch
@@ -0,0 +1,55 @@
1From ef4d512aff004c62d550cdd64329c6c1acd0f217 Mon Sep 17 00:00:00 2001
2From: Stefano Stabellini <stefano.stabellini@amd.com>
3Date: Fri, 1 Jul 2022 18:48:03 -0700
4Subject: [PATCH 01/16] xen_common: return error from xen_create_ioreq_server
5
6Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
7---
8 include/hw/xen/xen_common.h | 12 +++++++-----
9 1 file changed, 7 insertions(+), 5 deletions(-)
10
11diff --git a/include/hw/xen/xen_common.h b/include/hw/xen/xen_common.h
12index 77ce17d8a4..c2d2f36bde 100644
13--- a/include/hw/xen/xen_common.h
14+++ b/include/hw/xen/xen_common.h
15@@ -467,8 +467,8 @@ static inline void xen_unmap_pcidev(domid_t dom,
16 {
17 }
18
19-static inline void xen_create_ioreq_server(domid_t dom,
20- ioservid_t *ioservid)
21+static inline int xen_create_ioreq_server(domid_t dom,
22+ ioservid_t *ioservid)
23 {
24 }
25
26@@ -600,8 +600,8 @@ static inline void xen_unmap_pcidev(domid_t dom,
27 PCI_FUNC(pci_dev->devfn));
28 }
29
30-static inline void xen_create_ioreq_server(domid_t dom,
31- ioservid_t *ioservid)
32+static inline int xen_create_ioreq_server(domid_t dom,
33+ ioservid_t *ioservid)
34 {
35 int rc = xendevicemodel_create_ioreq_server(xen_dmod, dom,
36 HVM_IOREQSRV_BUFIOREQ_ATOMIC,
37@@ -609,12 +609,14 @@ static inline void xen_create_ioreq_server(domid_t dom,
38
39 if (rc == 0) {
40 trace_xen_ioreq_server_create(*ioservid);
41- return;
42+ return rc;
43 }
44
45 *ioservid = 0;
46 use_default_ioreq_server = true;
47 trace_xen_default_ioreq_server();
48+
49+ return rc;
50 }
51
52 static inline void xen_destroy_ioreq_server(domid_t dom,
53--
542.17.1
55
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0002-xen-add-pseudo-RAM-region-for-grant-mappings.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0002-xen-add-pseudo-RAM-region-for-grant-mappings.patch
new file mode 100644
index 00000000..8facb189
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0002-xen-add-pseudo-RAM-region-for-grant-mappings.patch
@@ -0,0 +1,252 @@
1From e18daac2f6d3f60c8217f44189a91cf8240a591f Mon Sep 17 00:00:00 2001
2From: Juergen Gross <jgross@suse.com>
3Date: Thu, 20 May 2021 11:19:58 +0200
4Subject: [PATCH 2/8] xen: add pseudo RAM region for grant mappings
5
6Add a memory region which can be used to automatically map granted
7memory. It is starting at 0x8000000000000000ULL in order to be able to
8distinguish it from normal RAM.
9
10For this reason the xen.ram memory region is expanded, which has no
11further impact as it is used just as a container of the real RAM
12regions and now the grant region.
13
14Signed-off-by: Juergen Gross <jgross@suse.com>
15Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com>
16Acked-by: Stefano Stabellini <stefano.stabellini@amd.com>
17---
18 hw/i386/xen/xen-hvm.c | 3 ++
19 hw/xen/xen-hvm-common.c | 4 +--
20 hw/xen/xen-mapcache.c | 28 +++++++++++++++
21 include/exec/ram_addr.h | 1 +
22 include/hw/xen/xen-hvm-common.h | 2 ++
23 include/hw/xen/xen_pvdev.h | 3 ++
24 include/sysemu/xen-mapcache.h | 3 ++
25 softmmu/physmem.c | 61 ++++++++++++++++++++-------------
26 8 files changed, 80 insertions(+), 25 deletions(-)
27
28diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
29index 36d87555a9..2dcc2e1179 100644
30--- a/hw/i386/xen/xen-hvm.c
31+++ b/hw/i386/xen/xen-hvm.c
32@@ -171,6 +171,9 @@ static void xen_ram_init(PCMachineState *pcms,
33 x86ms->above_4g_mem_size);
34 memory_region_add_subregion(sysmem, 0x100000000ULL, &ram_hi);
35 }
36+
37+ /* Add grant mappings as a pseudo RAM region. */
38+ ram_grants = *xen_init_grant_ram();
39 }
40
41 static XenPhysmap *get_physmapping(hwaddr start_addr, ram_addr_t size)
42diff --git a/hw/xen/xen-hvm-common.c b/hw/xen/xen-hvm-common.c
43index 7e7d23397f..abd6e379d3 100644
44--- a/hw/xen/xen-hvm-common.c
45+++ b/hw/xen/xen-hvm-common.c
46@@ -10,7 +10,7 @@
47 #include "hw/boards.h"
48 #include "hw/xen/arch_hvm.h"
49
50-MemoryRegion ram_memory;
51+MemoryRegion ram_memory, ram_grants;
52
53 MemoryListener xen_io_listener = {
54 .name = "xen-io",
55@@ -742,7 +742,7 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr,
56 return;
57 }
58
59- if (mr == &ram_memory) {
60+ if (mr == &ram_memory || mr == &ram_grants) {
61 return;
62 }
63
64diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
65index a2f93096e7..0b75f1633a 100644
66--- a/hw/xen/xen-mapcache.c
67+++ b/hw/xen/xen-mapcache.c
68@@ -14,7 +14,10 @@
69
70 #include <sys/resource.h>
71
72+#include "hw/xen/xen-hvm-common.h"
73 #include "hw/xen/xen-legacy-backend.h"
74+#include "hw/xen/xen_pvdev.h"
75+
76 #include "qemu/bitmap.h"
77
78 #include "sysemu/runstate.h"
79@@ -597,3 +600,28 @@ uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
80 mapcache_unlock();
81 return p;
82 }
83+
84+MemoryRegion *xen_init_grant_ram(void)
85+{
86+ RAMBlock *block;
87+
88+ memory_region_init(&ram_grants, NULL, "xen.grants",
89+ XEN_MAX_VIRTIO_GRANTS * XC_PAGE_SIZE);
90+ block = g_malloc0(sizeof(*block));
91+ block->mr = &ram_grants;
92+ block->used_length = XEN_MAX_VIRTIO_GRANTS * XC_PAGE_SIZE;
93+ block->max_length = XEN_MAX_VIRTIO_GRANTS * XC_PAGE_SIZE;
94+ block->fd = -1;
95+ block->page_size = XC_PAGE_SIZE;
96+ block->host = (void *)XEN_GRANT_ADDR_OFF;
97+ block->offset = XEN_GRANT_ADDR_OFF;
98+ block->flags = RAM_PREALLOC;
99+ ram_grants.ram_block = block;
100+ ram_grants.ram = true;
101+ ram_grants.terminates = true;
102+ ram_block_add_list(block);
103+ memory_region_add_subregion(get_system_memory(), XEN_GRANT_ADDR_OFF,
104+ &ram_grants);
105+
106+ return &ram_grants;
107+}
108diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
109index f3e0c78161..e60b055867 100644
110--- a/include/exec/ram_addr.h
111+++ b/include/exec/ram_addr.h
112@@ -137,6 +137,7 @@ void qemu_ram_free(RAMBlock *block);
113 int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp);
114
115 void qemu_ram_msync(RAMBlock *block, ram_addr_t start, ram_addr_t length);
116+void ram_block_add_list(RAMBlock *new_block);
117
118 /* Clear whole block of mem */
119 static inline void qemu_ram_block_writeback(RAMBlock *block)
120diff --git a/include/hw/xen/xen-hvm-common.h b/include/hw/xen/xen-hvm-common.h
121index 2979f84ee2..6f7cc05d38 100644
122--- a/include/hw/xen/xen-hvm-common.h
123+++ b/include/hw/xen/xen-hvm-common.h
124@@ -16,6 +16,8 @@
125 #include <xen/hvm/ioreq.h>
126
127 extern MemoryRegion ram_memory;
128+
129+extern MemoryRegion ram_grants;
130 extern MemoryListener xen_io_listener;
131 extern DeviceListener xen_device_listener;
132
133diff --git a/include/hw/xen/xen_pvdev.h b/include/hw/xen/xen_pvdev.h
134index 7cd4bc2b82..36cd3ec1d4 100644
135--- a/include/hw/xen/xen_pvdev.h
136+++ b/include/hw/xen/xen_pvdev.h
137@@ -78,4 +78,7 @@ int xen_pv_send_notify(struct XenLegacyDevice *xendev);
138 void xen_pv_printf(struct XenLegacyDevice *xendev, int msg_level,
139 const char *fmt, ...) G_GNUC_PRINTF(3, 4);
140
141+#define XEN_GRANT_ADDR_OFF 0x8000000000000000ULL
142+#define XEN_MAX_VIRTIO_GRANTS 65536
143+
144 #endif /* QEMU_HW_XEN_PVDEV_H */
145diff --git a/include/sysemu/xen-mapcache.h b/include/sysemu/xen-mapcache.h
146index c8e7c2f6cf..f4bedb1c11 100644
147--- a/include/sysemu/xen-mapcache.h
148+++ b/include/sysemu/xen-mapcache.h
149@@ -10,6 +10,7 @@
150 #define XEN_MAPCACHE_H
151
152 #include "exec/cpu-common.h"
153+#include "exec/ram_addr.h"
154
155 typedef hwaddr (*phys_offset_to_gaddr_t)(hwaddr phys_offset,
156 ram_addr_t size);
157@@ -25,6 +26,8 @@ void xen_invalidate_map_cache(void);
158 uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
159 hwaddr new_phys_addr,
160 hwaddr size);
161+MemoryRegion *xen_init_grant_ram(void);
162+
163 #else
164
165 static inline void xen_map_cache_init(phys_offset_to_gaddr_t f,
166diff --git a/softmmu/physmem.c b/softmmu/physmem.c
167index dc3c3e5f2e..63ba5f7495 100644
168--- a/softmmu/physmem.c
169+++ b/softmmu/physmem.c
170@@ -1971,12 +1971,46 @@ static void dirty_memory_extend(ram_addr_t old_ram_size,
171 }
172 }
173
174+static void ram_block_add_list_locked(RAMBlock *new_block)
175+ {
176+ RAMBlock *block;
177+ RAMBlock *last_block = NULL;
178+
179+ /* Keep the list sorted from biggest to smallest block. Unlike QTAILQ,
180+ * QLIST (which has an RCU-friendly variant) does not have insertion at
181+ * tail, so save the last element in last_block.
182+ */
183+ RAMBLOCK_FOREACH(block) {
184+ last_block = block;
185+ if (block->max_length < new_block->max_length) {
186+ break;
187+ }
188+ }
189+ if (block) {
190+ QLIST_INSERT_BEFORE_RCU(block, new_block, next);
191+ } else if (last_block) {
192+ QLIST_INSERT_AFTER_RCU(last_block, new_block, next);
193+ } else { /* list is empty */
194+ QLIST_INSERT_HEAD_RCU(&ram_list.blocks, new_block, next);
195+ }
196+ ram_list.mru_block = NULL;
197+
198+ /* Write list before version */
199+ smp_wmb();
200+ ram_list.version++;
201+}
202+
203+void ram_block_add_list(RAMBlock *new_block)
204+{
205+ qemu_mutex_lock_ramlist();
206+ ram_block_add_list_locked(new_block);
207+ qemu_mutex_unlock_ramlist();
208+}
209+
210 static void ram_block_add(RAMBlock *new_block, Error **errp)
211 {
212 const bool noreserve = qemu_ram_is_noreserve(new_block);
213 const bool shared = qemu_ram_is_shared(new_block);
214- RAMBlock *block;
215- RAMBlock *last_block = NULL;
216 ram_addr_t old_ram_size, new_ram_size;
217 Error *err = NULL;
218
219@@ -2014,28 +2048,9 @@ static void ram_block_add(RAMBlock *new_block, Error **errp)
220 if (new_ram_size > old_ram_size) {
221 dirty_memory_extend(old_ram_size, new_ram_size);
222 }
223- /* Keep the list sorted from biggest to smallest block. Unlike QTAILQ,
224- * QLIST (which has an RCU-friendly variant) does not have insertion at
225- * tail, so save the last element in last_block.
226- */
227- RAMBLOCK_FOREACH(block) {
228- last_block = block;
229- if (block->max_length < new_block->max_length) {
230- break;
231- }
232- }
233- if (block) {
234- QLIST_INSERT_BEFORE_RCU(block, new_block, next);
235- } else if (last_block) {
236- QLIST_INSERT_AFTER_RCU(last_block, new_block, next);
237- } else { /* list is empty */
238- QLIST_INSERT_HEAD_RCU(&ram_list.blocks, new_block, next);
239- }
240- ram_list.mru_block = NULL;
241
242- /* Write list before version */
243- smp_wmb();
244- ram_list.version++;
245+ ram_block_add_list_locked(new_block);
246+
247 qemu_mutex_unlock_ramlist();
248
249 cpu_physical_memory_set_dirty_range(new_block->offset,
250--
2512.25.1
252
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0002-xen-mapcache-move-xen-mapcache.c-to-hw-xen.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0002-xen-mapcache-move-xen-mapcache.c-to-hw-xen.patch
new file mode 100644
index 00000000..35ca6df4
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0002-xen-mapcache-move-xen-mapcache.c-to-hw-xen.patch
@@ -0,0 +1,88 @@
1From 423468bdb3728154e95af18ef755bc75c5d59a3a Mon Sep 17 00:00:00 2001
2From: Vikram Garhwal <vikram.garhwal@amd.com>
3Date: Thu, 30 Jun 2022 18:19:50 -0700
4Subject: [PATCH 02/16] xen-mapcache: move xen-mapcache.c to hw/xen
5
6xen-mapcache.c contains common functions which are useful for Xen on ARM
7IOREQ handling. Moving it out of i386 to hw/xen for commong access.
8
9Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com>
10Reviewed-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
11Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
12---
13 hw/i386/meson.build | 1 +
14 hw/i386/xen/meson.build | 1 -
15 hw/i386/xen/trace-events | 5 -----
16 hw/xen/meson.build | 4 ++++
17 hw/xen/trace-events | 5 +++++
18 hw/{i386 => }/xen/xen-mapcache.c | 0
19 6 files changed, 10 insertions(+), 6 deletions(-)
20 rename hw/{i386 => }/xen/xen-mapcache.c (100%)
21
22diff --git a/hw/i386/meson.build b/hw/i386/meson.build
23index 213e2e82b3..cfdbfdcbcb 100644
24--- a/hw/i386/meson.build
25+++ b/hw/i386/meson.build
26@@ -33,5 +33,6 @@ subdir('kvm')
27 subdir('xen')
28
29 i386_ss.add_all(xenpv_ss)
30+i386_ss.add_all(xen_ss)
31
32 hw_arch += {'i386': i386_ss}
33diff --git a/hw/i386/xen/meson.build b/hw/i386/xen/meson.build
34index be84130300..2fcc46e6ca 100644
35--- a/hw/i386/xen/meson.build
36+++ b/hw/i386/xen/meson.build
37@@ -1,6 +1,5 @@
38 i386_ss.add(when: 'CONFIG_XEN', if_true: files(
39 'xen-hvm.c',
40- 'xen-mapcache.c',
41 'xen_apic.c',
42 'xen_platform.c',
43 'xen_pvdevice.c',
44diff --git a/hw/i386/xen/trace-events b/hw/i386/xen/trace-events
45index 5d6be61090..a0c89d91c4 100644
46--- a/hw/i386/xen/trace-events
47+++ b/hw/i386/xen/trace-events
48@@ -21,8 +21,3 @@ xen_map_resource_ioreq(uint32_t id, void *addr) "id: %u addr: %p"
49 cpu_ioreq_config_read(void *req, uint32_t sbdf, uint32_t reg, uint32_t size, uint32_t data) "I/O=%p sbdf=0x%x reg=%u size=%u data=0x%x"
50 cpu_ioreq_config_write(void *req, uint32_t sbdf, uint32_t reg, uint32_t size, uint32_t data) "I/O=%p sbdf=0x%x reg=%u size=%u data=0x%x"
51
52-# xen-mapcache.c
53-xen_map_cache(uint64_t phys_addr) "want 0x%"PRIx64
54-xen_remap_bucket(uint64_t index) "index 0x%"PRIx64
55-xen_map_cache_return(void* ptr) "%p"
56-
57diff --git a/hw/xen/meson.build b/hw/xen/meson.build
58index ae0ace3046..19d0637c46 100644
59--- a/hw/xen/meson.build
60+++ b/hw/xen/meson.build
61@@ -22,3 +22,7 @@ else
62 endif
63
64 specific_ss.add_all(when: ['CONFIG_XEN', xen], if_true: xen_specific_ss)
65+
66+xen_ss = ss.source_set()
67+
68+xen_ss.add(when: 'CONFIG_XEN', if_true: files('xen-mapcache.c'))
69diff --git a/hw/xen/trace-events b/hw/xen/trace-events
70index 3da3fd8348..2c8f238f42 100644
71--- a/hw/xen/trace-events
72+++ b/hw/xen/trace-events
73@@ -41,3 +41,8 @@ xs_node_vprintf(char *path, char *value) "%s %s"
74 xs_node_vscanf(char *path, char *value) "%s %s"
75 xs_node_watch(char *path) "%s"
76 xs_node_unwatch(char *path) "%s"
77+
78+# xen-mapcache.c
79+xen_map_cache(uint64_t phys_addr) "want 0x%"PRIx64
80+xen_remap_bucket(uint64_t index) "index 0x%"PRIx64
81+xen_map_cache_return(void* ptr) "%p"
82diff --git a/hw/i386/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
83similarity index 100%
84rename from hw/i386/xen/xen-mapcache.c
85rename to hw/xen/xen-mapcache.c
86--
872.17.1
88
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0003-hw-i386-xen-rearrange-xen_hvm_init_pc.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0003-hw-i386-xen-rearrange-xen_hvm_init_pc.patch
new file mode 100644
index 00000000..1113cf39
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0003-hw-i386-xen-rearrange-xen_hvm_init_pc.patch
@@ -0,0 +1,106 @@
1From 4472924c800e9dbf46e4c2432565d3e406b35d27 Mon Sep 17 00:00:00 2001
2From: Vikram Garhwal <vikram.garhwal@amd.com>
3Date: Fri, 1 Jul 2022 16:32:33 -0700
4Subject: [PATCH 03/16] hw/i386/xen: rearrange xen_hvm_init_pc
5
6Move references to:
7- xen_get_vmport_regs_pfn
8- xen_suspend_notifier
9- xen_wakeup_notifier
10- xen_ram_init
11
12towards the end of the function. This is done to keep the the common
13ioreq functions in one place which will be moved to new function in next
14patch in order to make it useful to ARM machines also.
15
16Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com>
17Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
18Reviewed-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
19---
20 hw/i386/xen/xen-hvm.c | 49 ++++++++++++++++++++++---------------------
21 1 file changed, 25 insertions(+), 24 deletions(-)
22
23diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
24index e4293d6d66..b27484ad22 100644
25--- a/hw/i386/xen/xen-hvm.c
26+++ b/hw/i386/xen/xen-hvm.c
27@@ -1416,12 +1416,6 @@ void xen_hvm_init_pc(PCMachineState *pcms, MemoryRegion **ram_memory)
28 state->exit.notify = xen_exit_notifier;
29 qemu_add_exit_notifier(&state->exit);
30
31- state->suspend.notify = xen_suspend_notifier;
32- qemu_register_suspend_notifier(&state->suspend);
33-
34- state->wakeup.notify = xen_wakeup_notifier;
35- qemu_register_wakeup_notifier(&state->wakeup);
36-
37 /*
38 * Register wake-up support in QMP query-current-machine API
39 */
40@@ -1432,23 +1426,6 @@ void xen_hvm_init_pc(PCMachineState *pcms, MemoryRegion **ram_memory)
41 goto err;
42 }
43
44- rc = xen_get_vmport_regs_pfn(xen_xc, xen_domid, &ioreq_pfn);
45- if (!rc) {
46- DPRINTF("shared vmport page at pfn %lx\n", ioreq_pfn);
47- state->shared_vmport_page =
48- xenforeignmemory_map(xen_fmem, xen_domid, PROT_READ|PROT_WRITE,
49- 1, &ioreq_pfn, NULL);
50- if (state->shared_vmport_page == NULL) {
51- error_report("map shared vmport IO page returned error %d handle=%p",
52- errno, xen_xc);
53- goto err;
54- }
55- } else if (rc != -ENOSYS) {
56- error_report("get vmport regs pfn returned error %d, rc=%d",
57- errno, rc);
58- goto err;
59- }
60-
61 /* Note: cpus is empty at this point in init */
62 state->cpu_by_vcpu_id = g_new0(CPUState *, max_cpus);
63
64@@ -1486,7 +1463,6 @@ void xen_hvm_init_pc(PCMachineState *pcms, MemoryRegion **ram_memory)
65 #else
66 xen_map_cache_init(NULL, state);
67 #endif
68- xen_ram_init(pcms, ms->ram_size, ram_memory);
69
70 qemu_add_vm_change_state_handler(xen_hvm_change_state_handler, state);
71
72@@ -1513,6 +1489,31 @@ void xen_hvm_init_pc(PCMachineState *pcms, MemoryRegion **ram_memory)
73 QLIST_INIT(&xen_physmap);
74 xen_read_physmap(state);
75
76+ state->suspend.notify = xen_suspend_notifier;
77+ qemu_register_suspend_notifier(&state->suspend);
78+
79+ state->wakeup.notify = xen_wakeup_notifier;
80+ qemu_register_wakeup_notifier(&state->wakeup);
81+
82+ rc = xen_get_vmport_regs_pfn(xen_xc, xen_domid, &ioreq_pfn);
83+ if (!rc) {
84+ DPRINTF("shared vmport page at pfn %lx\n", ioreq_pfn);
85+ state->shared_vmport_page =
86+ xenforeignmemory_map(xen_fmem, xen_domid, PROT_READ|PROT_WRITE,
87+ 1, &ioreq_pfn, NULL);
88+ if (state->shared_vmport_page == NULL) {
89+ error_report("map shared vmport IO page returned error %d handle=%p",
90+ errno, xen_xc);
91+ goto err;
92+ }
93+ } else if (rc != -ENOSYS) {
94+ error_report("get vmport regs pfn returned error %d, rc=%d",
95+ errno, rc);
96+ goto err;
97+ }
98+
99+ xen_ram_init(pcms, ms->ram_size, ram_memory);
100+
101 /* Disable ACPI build because Xen handles it */
102 pcms->acpi_build_enabled = false;
103
104--
1052.17.1
106
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0003-softmmu-let-qemu_map_ram_ptr-use-qemu_ram_ptr_length.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0003-softmmu-let-qemu_map_ram_ptr-use-qemu_ram_ptr_length.patch
new file mode 100644
index 00000000..bff815bc
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0003-softmmu-let-qemu_map_ram_ptr-use-qemu_ram_ptr_length.patch
@@ -0,0 +1,113 @@
1From cb4be1f7185c5974523c764f3f6efe3af6633d71 Mon Sep 17 00:00:00 2001
2From: Juergen Gross <jgross@suse.com>
3Date: Thu, 20 May 2021 11:54:48 +0200
4Subject: [PATCH 3/8] softmmu: let qemu_map_ram_ptr() use qemu_ram_ptr_length()
5
6qemu_map_ram_ptr() and qemu_ram_ptr_length() share quite some code, so
7modify qemu_ram_ptr_length() a little bit and use it for
8qemu_map_ram_ptr(), too.
9
10Signed-off-by: Juergen Gross <jgross@suse.com>
11Acked-by: Stefano Stabellini <stefano.stabellini@amd.com>
12---
13 softmmu/physmem.c | 56 ++++++++++++++++++-----------------------------
14 1 file changed, 21 insertions(+), 35 deletions(-)
15
16diff --git a/softmmu/physmem.c b/softmmu/physmem.c
17index 63ba5f7495..439a53a1be 100644
18--- a/softmmu/physmem.c
19+++ b/softmmu/physmem.c
20@@ -2306,38 +2306,7 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
21 }
22 #endif /* !_WIN32 */
23
24-/* Return a host pointer to ram allocated with qemu_ram_alloc.
25- * This should not be used for general purpose DMA. Use address_space_map
26- * or address_space_rw instead. For local memory (e.g. video ram) that the
27- * device owns, use memory_region_get_ram_ptr.
28- *
29- * Called within RCU critical section.
30- */
31-void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr)
32-{
33- RAMBlock *block = ram_block;
34-
35- if (block == NULL) {
36- block = qemu_get_ram_block(addr);
37- addr -= block->offset;
38- }
39-
40- if (xen_enabled() && block->host == NULL) {
41- /* We need to check if the requested address is in the RAM
42- * because we don't want to map the entire memory in QEMU.
43- * In that case just map until the end of the page.
44- */
45- if (block->offset == 0) {
46- return xen_map_cache(addr, 0, 0, false);
47- }
48-
49- block->host = xen_map_cache(block->offset, block->max_length, 1, false);
50- }
51- return ramblock_ptr(block, addr);
52-}
53-
54-/* Return a host pointer to guest's ram. Similar to qemu_map_ram_ptr
55- * but takes a size argument.
56+/* Return a host pointer to guest's ram.
57 *
58 * Called within RCU critical section.
59 */
60@@ -2345,7 +2314,9 @@ static void *qemu_ram_ptr_length(RAMBlock *ram_block, ram_addr_t addr,
61 hwaddr *size, bool lock)
62 {
63 RAMBlock *block = ram_block;
64- if (*size == 0) {
65+ hwaddr len = 0;
66+
67+ if (size && *size == 0) {
68 return NULL;
69 }
70
71@@ -2353,7 +2324,10 @@ static void *qemu_ram_ptr_length(RAMBlock *ram_block, ram_addr_t addr,
72 block = qemu_get_ram_block(addr);
73 addr -= block->offset;
74 }
75- *size = MIN(*size, block->max_length - addr);
76+ if (size) {
77+ *size = MIN(*size, block->max_length - addr);
78+ len = *size;
79+ }
80
81 if (xen_enabled() && block->host == NULL) {
82 /* We need to check if the requested address is in the RAM
83@@ -2361,7 +2335,7 @@ static void *qemu_ram_ptr_length(RAMBlock *ram_block, ram_addr_t addr,
84 * In that case just map the requested area.
85 */
86 if (block->offset == 0) {
87- return xen_map_cache(addr, *size, lock, lock);
88+ return xen_map_cache(addr, len, lock, lock);
89 }
90
91 block->host = xen_map_cache(block->offset, block->max_length, 1, lock);
92@@ -2370,6 +2344,18 @@ static void *qemu_ram_ptr_length(RAMBlock *ram_block, ram_addr_t addr,
93 return ramblock_ptr(block, addr);
94 }
95
96+/* Return a host pointer to ram allocated with qemu_ram_alloc.
97+ * This should not be used for general purpose DMA. Use address_space_map
98+ * or address_space_rw instead. For local memory (e.g. video ram) that the
99+ * device owns, use memory_region_get_ram_ptr.
100+ *
101+ * Called within RCU critical section.
102+ */
103+void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr)
104+{
105+ return qemu_ram_ptr_length(ram_block, addr, NULL, false);
106+}
107+
108 /* Return the offset of a hostpointer within a ramblock */
109 ram_addr_t qemu_ram_block_host_offset(RAMBlock *rb, void *host)
110 {
111--
1122.25.1
113
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0004-xen-hvm-move-x86-specific-fields-out-of-XenIOState.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0004-xen-hvm-move-x86-specific-fields-out-of-XenIOState.patch
new file mode 100644
index 00000000..4337e0c8
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0004-xen-hvm-move-x86-specific-fields-out-of-XenIOState.patch
@@ -0,0 +1,180 @@
1From 2a01fa06d267f68148d3a6df50675edfe090601a Mon Sep 17 00:00:00 2001
2From: Stefano Stabellini <stefano.stabellini@amd.com>
3Date: Fri, 1 Jul 2022 18:16:52 -0700
4Subject: [PATCH 04/16] xen-hvm: move x86-specific fields out of XenIOState
5
6Move:
7- shared_vmport_page
8- log_for_dirtybit
9- dirty_bitmap
10- suspend
11- wakeup
12
13out of XenIOState as they are only used on x86, especially the ones
14related to dirty logging.
15
16Remove free_phys_offset that was unused.
17
18Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
19---
20 hw/i386/xen/xen-hvm.c | 58 ++++++++++++++++++++-----------------------
21 1 file changed, 27 insertions(+), 31 deletions(-)
22
23diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
24index b27484ad22..225cfdf8b7 100644
25--- a/hw/i386/xen/xen-hvm.c
26+++ b/hw/i386/xen/xen-hvm.c
27@@ -73,6 +73,7 @@ struct shared_vmport_iopage {
28 };
29 typedef struct shared_vmport_iopage shared_vmport_iopage_t;
30 #endif
31+static shared_vmport_iopage_t *shared_vmport_page;
32
33 static inline uint32_t xen_vcpu_eport(shared_iopage_t *shared_page, int i)
34 {
35@@ -95,6 +96,11 @@ typedef struct XenPhysmap {
36 } XenPhysmap;
37
38 static QLIST_HEAD(, XenPhysmap) xen_physmap;
39+static const XenPhysmap *log_for_dirtybit = NULL;
40+/* Buffer used by xen_sync_dirty_bitmap */
41+static unsigned long *dirty_bitmap = NULL;
42+static Notifier suspend;
43+static Notifier wakeup;
44
45 typedef struct XenPciDevice {
46 PCIDevice *pci_dev;
47@@ -105,7 +111,6 @@ typedef struct XenPciDevice {
48 typedef struct XenIOState {
49 ioservid_t ioservid;
50 shared_iopage_t *shared_page;
51- shared_vmport_iopage_t *shared_vmport_page;
52 buffered_iopage_t *buffered_io_page;
53 xenforeignmemory_resource_handle *fres;
54 QEMUTimer *buffered_io_timer;
55@@ -125,14 +130,8 @@ typedef struct XenIOState {
56 MemoryListener io_listener;
57 QLIST_HEAD(, XenPciDevice) dev_list;
58 DeviceListener device_listener;
59- hwaddr free_phys_offset;
60- const XenPhysmap *log_for_dirtybit;
61- /* Buffer used by xen_sync_dirty_bitmap */
62- unsigned long *dirty_bitmap;
63
64 Notifier exit;
65- Notifier suspend;
66- Notifier wakeup;
67 } XenIOState;
68
69 /* Xen specific function for piix pci */
70@@ -462,10 +461,10 @@ static int xen_remove_from_physmap(XenIOState *state,
71 }
72
73 QLIST_REMOVE(physmap, list);
74- if (state->log_for_dirtybit == physmap) {
75- state->log_for_dirtybit = NULL;
76- g_free(state->dirty_bitmap);
77- state->dirty_bitmap = NULL;
78+ if (log_for_dirtybit == physmap) {
79+ log_for_dirtybit = NULL;
80+ g_free(dirty_bitmap);
81+ dirty_bitmap = NULL;
82 }
83 g_free(physmap);
84
85@@ -626,16 +625,16 @@ static void xen_sync_dirty_bitmap(XenIOState *state,
86 return;
87 }
88
89- if (state->log_for_dirtybit == NULL) {
90- state->log_for_dirtybit = physmap;
91- state->dirty_bitmap = g_new(unsigned long, bitmap_size);
92- } else if (state->log_for_dirtybit != physmap) {
93+ if (log_for_dirtybit == NULL) {
94+ log_for_dirtybit = physmap;
95+ dirty_bitmap = g_new(unsigned long, bitmap_size);
96+ } else if (log_for_dirtybit != physmap) {
97 /* Only one range for dirty bitmap can be tracked. */
98 return;
99 }
100
101 rc = xen_track_dirty_vram(xen_domid, start_addr >> TARGET_PAGE_BITS,
102- npages, state->dirty_bitmap);
103+ npages, dirty_bitmap);
104 if (rc < 0) {
105 #ifndef ENODATA
106 #define ENODATA ENOENT
107@@ -650,7 +649,7 @@ static void xen_sync_dirty_bitmap(XenIOState *state,
108 }
109
110 for (i = 0; i < bitmap_size; i++) {
111- unsigned long map = state->dirty_bitmap[i];
112+ unsigned long map = dirty_bitmap[i];
113 while (map != 0) {
114 j = ctzl(map);
115 map &= ~(1ul << j);
116@@ -676,12 +675,10 @@ static void xen_log_start(MemoryListener *listener,
117 static void xen_log_stop(MemoryListener *listener, MemoryRegionSection *section,
118 int old, int new)
119 {
120- XenIOState *state = container_of(listener, XenIOState, memory_listener);
121-
122 if (old & ~new & (1 << DIRTY_MEMORY_VGA)) {
123- state->log_for_dirtybit = NULL;
124- g_free(state->dirty_bitmap);
125- state->dirty_bitmap = NULL;
126+ log_for_dirtybit = NULL;
127+ g_free(dirty_bitmap);
128+ dirty_bitmap = NULL;
129 /* Disable dirty bit tracking */
130 xen_track_dirty_vram(xen_domid, 0, 0, NULL);
131 }
132@@ -1021,9 +1018,9 @@ static void handle_vmport_ioreq(XenIOState *state, ioreq_t *req)
133 {
134 vmware_regs_t *vmport_regs;
135
136- assert(state->shared_vmport_page);
137+ assert(shared_vmport_page);
138 vmport_regs =
139- &state->shared_vmport_page->vcpu_vmport_regs[state->send_vcpu];
140+ &shared_vmport_page->vcpu_vmport_regs[state->send_vcpu];
141 QEMU_BUILD_BUG_ON(sizeof(*req) < sizeof(*vmport_regs));
142
143 current_cpu = state->cpu_by_vcpu_id[state->send_vcpu];
144@@ -1468,7 +1465,6 @@ void xen_hvm_init_pc(PCMachineState *pcms, MemoryRegion **ram_memory)
145
146 state->memory_listener = xen_memory_listener;
147 memory_listener_register(&state->memory_listener, &address_space_memory);
148- state->log_for_dirtybit = NULL;
149
150 state->io_listener = xen_io_listener;
151 memory_listener_register(&state->io_listener, &address_space_io);
152@@ -1489,19 +1485,19 @@ void xen_hvm_init_pc(PCMachineState *pcms, MemoryRegion **ram_memory)
153 QLIST_INIT(&xen_physmap);
154 xen_read_physmap(state);
155
156- state->suspend.notify = xen_suspend_notifier;
157- qemu_register_suspend_notifier(&state->suspend);
158+ suspend.notify = xen_suspend_notifier;
159+ qemu_register_suspend_notifier(&suspend);
160
161- state->wakeup.notify = xen_wakeup_notifier;
162- qemu_register_wakeup_notifier(&state->wakeup);
163+ wakeup.notify = xen_wakeup_notifier;
164+ qemu_register_wakeup_notifier(&wakeup);
165
166 rc = xen_get_vmport_regs_pfn(xen_xc, xen_domid, &ioreq_pfn);
167 if (!rc) {
168 DPRINTF("shared vmport page at pfn %lx\n", ioreq_pfn);
169- state->shared_vmport_page =
170+ shared_vmport_page =
171 xenforeignmemory_map(xen_fmem, xen_domid, PROT_READ|PROT_WRITE,
172 1, &ioreq_pfn, NULL);
173- if (state->shared_vmport_page == NULL) {
174+ if (shared_vmport_page == NULL) {
175 error_report("map shared vmport IO page returned error %d handle=%p",
176 errno, xen_xc);
177 goto err;
178--
1792.17.1
180
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0004-xen-let-xen_ram_addr_from_mapcache-return-1-in-case-.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0004-xen-let-xen_ram_addr_from_mapcache-return-1-in-case-.patch
new file mode 100644
index 00000000..25dc0ae0
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0004-xen-let-xen_ram_addr_from_mapcache-return-1-in-case-.patch
@@ -0,0 +1,49 @@
1From 7dfa8828bd2e61fc5bf2bf6294aad16b2bf4ff8a Mon Sep 17 00:00:00 2001
2From: Juergen Gross <jgross@suse.com>
3Date: Thu, 20 May 2021 13:31:32 +0200
4Subject: [PATCH 4/8] xen: let xen_ram_addr_from_mapcache() return -1 in case
5 of not found entry
6
7Today xen_ram_addr_from_mapcache() will either abort() or return 0 in
8case it can't find a matching entry for a pointer value. Both cases
9are bad, so change that to return an invalid address instead.
10
11Signed-off-by: Juergen Gross <jgross@suse.com>
12Acked-by: Stefano Stabellini <stefano.stabellini@amd.com>
13---
14 hw/xen/xen-mapcache.c | 12 +++---------
15 1 file changed, 3 insertions(+), 9 deletions(-)
16
17diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
18index 0b75f1633a..e53e7221f1 100644
19--- a/hw/xen/xen-mapcache.c
20+++ b/hw/xen/xen-mapcache.c
21@@ -405,13 +405,8 @@ ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
22 }
23 }
24 if (!found) {
25- fprintf(stderr, "%s, could not find %p\n", __func__, ptr);
26- QTAILQ_FOREACH(reventry, &mapcache->locked_entries, next) {
27- DPRINTF(" "TARGET_FMT_plx" -> %p is present\n", reventry->paddr_index,
28- reventry->vaddr_req);
29- }
30- abort();
31- return 0;
32+ mapcache_unlock();
33+ return RAM_ADDR_INVALID;
34 }
35
36 entry = &mapcache->entry[paddr_index % mapcache->nr_buckets];
37@@ -419,8 +414,7 @@ ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
38 entry = entry->next;
39 }
40 if (!entry) {
41- DPRINTF("Trying to find address %p that is not in the mapcache!\n", ptr);
42- raddr = 0;
43+ raddr = RAM_ADDR_INVALID;
44 } else {
45 raddr = (reventry->paddr_index << MCACHE_BUCKET_SHIFT) +
46 ((unsigned long) ptr - (unsigned long) entry->vaddr_base);
47--
482.25.1
49
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0005-memory-add-MemoryRegion-map-and-unmap-callbacks.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0005-memory-add-MemoryRegion-map-and-unmap-callbacks.patch
new file mode 100644
index 00000000..db6d8fe5
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0005-memory-add-MemoryRegion-map-and-unmap-callbacks.patch
@@ -0,0 +1,150 @@
1From bd32a130ca633eae7cf0f4ff0fa856004d413df0 Mon Sep 17 00:00:00 2001
2From: Juergen Gross <jgross@suse.com>
3Date: Thu, 27 May 2021 15:27:55 +0200
4Subject: [PATCH 5/8] memory: add MemoryRegion map and unmap callbacks
5
6In order to support mapping and unmapping guest memory dynamically to
7and from qemu during address_space_[un]map() operations add the map()
8and unmap() callbacks to MemoryRegionOps.
9
10Those will be used e.g. for Xen grant mappings when performing guest
11I/Os.
12
13Signed-off-by: Juergen Gross <jgross@suse.com>
14Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com>
15Acked-by: Stefano Stabellini <stefano.stabellini@amd.com>
16---
17 include/exec/memory.h | 19 +++++++++++++++++
18 softmmu/physmem.c | 47 +++++++++++++++++++++++++++++++++----------
19 2 files changed, 55 insertions(+), 11 deletions(-)
20
21diff --git a/include/exec/memory.h b/include/exec/memory.h
22index bfb1de8eea..19e2aac694 100644
23--- a/include/exec/memory.h
24+++ b/include/exec/memory.h
25@@ -245,6 +245,25 @@ struct MemoryRegionOps {
26 unsigned size,
27 MemTxAttrs attrs);
28
29+ /* Dynamically create mapping. @addr is the guest address to map; @plen
30+ * is the pointer to the usable length of the buffer.
31+ * @mr contents can be changed in case a new memory region is created for
32+ * the mapping.
33+ * Returns the buffer address for accessing the data. */
34+ void *(*map)(MemoryRegion **mr,
35+ hwaddr addr,
36+ hwaddr *plen,
37+ bool is_write,
38+ MemTxAttrs attrs);
39+
40+ /* Unmap an area obtained via map() before. */
41+ void (*unmap)(MemoryRegion *mr,
42+ void *buffer,
43+ ram_addr_t addr,
44+ hwaddr len,
45+ bool is_write,
46+ hwaddr access_len);
47+
48 enum device_endian endianness;
49 /* Guest-visible constraints: */
50 struct {
51diff --git a/softmmu/physmem.c b/softmmu/physmem.c
52index 439a53a1be..2038240311 100644
53--- a/softmmu/physmem.c
54+++ b/softmmu/physmem.c
55@@ -3237,7 +3237,7 @@ void *address_space_map(AddressSpace *as,
56 hwaddr len = *plen;
57 hwaddr l, xlat;
58 MemoryRegion *mr;
59- void *ptr;
60+ void *ptr = NULL;
61 FlatView *fv;
62
63 if (len == 0) {
64@@ -3273,10 +3273,17 @@ void *address_space_map(AddressSpace *as,
65
66
67 memory_region_ref(mr);
68+
69+ if (mr->ops && mr->ops->map) {
70+ ptr = mr->ops->map(&mr, addr, plen, is_write, attrs);
71+ }
72+
73 *plen = flatview_extend_translation(fv, addr, len, mr, xlat,
74 l, is_write, attrs);
75 fuzz_dma_read_cb(addr, *plen, mr);
76- ptr = qemu_ram_ptr_length(mr->ram_block, xlat, plen, true);
77+ if (ptr == NULL) {
78+ ptr = qemu_ram_ptr_length(mr->ram_block, xlat, plen, true);
79+ }
80
81 return ptr;
82 }
83@@ -3294,11 +3301,16 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
84
85 mr = memory_region_from_host(buffer, &addr1);
86 assert(mr != NULL);
87- if (is_write) {
88- invalidate_and_set_dirty(mr, addr1, access_len);
89- }
90- if (xen_enabled()) {
91- xen_invalidate_map_cache_entry(buffer);
92+
93+ if (mr->ops && mr->ops->unmap) {
94+ mr->ops->unmap(mr, buffer, addr1, len, is_write, access_len);
95+ } else {
96+ if (is_write) {
97+ invalidate_and_set_dirty(mr, addr1, access_len);
98+ }
99+ if (xen_enabled()) {
100+ xen_invalidate_map_cache_entry(buffer);
101+ }
102 }
103 memory_region_unref(mr);
104 return;
105@@ -3370,10 +3382,17 @@ int64_t address_space_cache_init(MemoryRegionCache *cache,
106 * doing this if we found actual RAM, which behaves the same
107 * regardless of attributes; so UNSPECIFIED is fine.
108 */
109+ if (mr->ops && mr->ops->map) {
110+ cache->ptr = mr->ops->map(&mr, addr, &l, is_write,
111+ MEMTXATTRS_UNSPECIFIED);
112+ }
113+
114 l = flatview_extend_translation(cache->fv, addr, len, mr,
115 cache->xlat, l, is_write,
116 MEMTXATTRS_UNSPECIFIED);
117- cache->ptr = qemu_ram_ptr_length(mr->ram_block, cache->xlat, &l, true);
118+ if (!cache->ptr) {
119+ cache->ptr = qemu_ram_ptr_length(mr->ram_block, cache->xlat, &l, true);
120+ }
121 } else {
122 cache->ptr = NULL;
123 }
124@@ -3395,14 +3414,20 @@ void address_space_cache_invalidate(MemoryRegionCache *cache,
125
126 void address_space_cache_destroy(MemoryRegionCache *cache)
127 {
128- if (!cache->mrs.mr) {
129+ MemoryRegion *mr = cache->mrs.mr;
130+
131+ if (!mr) {
132 return;
133 }
134
135- if (xen_enabled()) {
136+ if (mr->ops && mr->ops->unmap) {
137+ mr->ops->unmap(mr, cache->ptr, cache->xlat, cache->len,
138+ cache->is_write, cache->len);
139+ } else if (xen_enabled()) {
140 xen_invalidate_map_cache_entry(cache->ptr);
141 }
142- memory_region_unref(cache->mrs.mr);
143+
144+ memory_region_unref(mr);
145 flatview_unref(cache->fv);
146 cache->mrs.mr = NULL;
147 cache->fv = NULL;
148--
1492.25.1
150
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0005-xen-hvm-create-arch_handle_ioreq-and-arch_xen_set_me.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0005-xen-hvm-create-arch_handle_ioreq-and-arch_xen_set_me.patch
new file mode 100644
index 00000000..6b56a39e
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0005-xen-hvm-create-arch_handle_ioreq-and-arch_xen_set_me.patch
@@ -0,0 +1,192 @@
1From c38436434fc888ba8844d99eab451f9b734e5e5b Mon Sep 17 00:00:00 2001
2From: Stefano Stabellini <stefano.stabellini@amd.com>
3Date: Fri, 1 Jul 2022 19:34:39 -0700
4Subject: [PATCH 05/16] xen-hvm: create arch_handle_ioreq and
5 arch_xen_set_memory
6
7In preparation to moving most of xen-hvm code to an arch-neutral
8location, move the x86-specific portion of xen_set_memory to
9arch_xen_set_memory.
10
11Also move handle_vmport_ioreq to arch_handle_ioreq.
12
13Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
14Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com>
15Reviewed-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
16---
17 hw/i386/xen/xen-hvm.c | 98 ++++++++++++++++++++--------------
18 include/hw/i386/xen_arch_hvm.h | 10 ++++
19 include/hw/xen/arch_hvm.h | 3 ++
20 3 files changed, 71 insertions(+), 40 deletions(-)
21 create mode 100644 include/hw/i386/xen_arch_hvm.h
22 create mode 100644 include/hw/xen/arch_hvm.h
23
24diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
25index 225cfdf8b7..178f0c68fc 100644
26--- a/hw/i386/xen/xen-hvm.c
27+++ b/hw/i386/xen/xen-hvm.c
28@@ -134,6 +134,8 @@ typedef struct XenIOState {
29 Notifier exit;
30 } XenIOState;
31
32+#include "hw/xen/arch_hvm.h"
33+
34 /* Xen specific function for piix pci */
35
36 int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
37@@ -476,10 +478,6 @@ static void xen_set_memory(struct MemoryListener *listener,
38 bool add)
39 {
40 XenIOState *state = container_of(listener, XenIOState, memory_listener);
41- hwaddr start_addr = section->offset_within_address_space;
42- ram_addr_t size = int128_get64(section->size);
43- bool log_dirty = memory_region_is_logging(section->mr, DIRTY_MEMORY_VGA);
44- hvmmem_type_t mem_type;
45
46 if (section->mr == &ram_memory) {
47 return;
48@@ -492,38 +490,7 @@ static void xen_set_memory(struct MemoryListener *listener,
49 section);
50 }
51 }
52-
53- if (!memory_region_is_ram(section->mr)) {
54- return;
55- }
56-
57- if (log_dirty != add) {
58- return;
59- }
60-
61- trace_xen_client_set_memory(start_addr, size, log_dirty);
62-
63- start_addr &= TARGET_PAGE_MASK;
64- size = TARGET_PAGE_ALIGN(size);
65-
66- if (add) {
67- if (!memory_region_is_rom(section->mr)) {
68- xen_add_to_physmap(state, start_addr, size,
69- section->mr, section->offset_within_region);
70- } else {
71- mem_type = HVMMEM_ram_ro;
72- if (xen_set_mem_type(xen_domid, mem_type,
73- start_addr >> TARGET_PAGE_BITS,
74- size >> TARGET_PAGE_BITS)) {
75- DPRINTF("xen_set_mem_type error, addr: "TARGET_FMT_plx"\n",
76- start_addr);
77- }
78- }
79- } else {
80- if (xen_remove_from_physmap(state, start_addr, size) < 0) {
81- DPRINTF("physmapping does not exist at "TARGET_FMT_plx"\n", start_addr);
82- }
83- }
84+ arch_xen_set_memory(state, section, add);
85 }
86
87 static void xen_region_add(MemoryListener *listener,
88@@ -1051,9 +1018,6 @@ static void handle_ioreq(XenIOState *state, ioreq_t *req)
89 case IOREQ_TYPE_COPY:
90 cpu_ioreq_move(req);
91 break;
92- case IOREQ_TYPE_VMWARE_PORT:
93- handle_vmport_ioreq(state, req);
94- break;
95 case IOREQ_TYPE_TIMEOFFSET:
96 break;
97 case IOREQ_TYPE_INVALIDATE:
98@@ -1063,7 +1027,7 @@ static void handle_ioreq(XenIOState *state, ioreq_t *req)
99 cpu_ioreq_config(state, req);
100 break;
101 default:
102- hw_error("Invalid ioreq type 0x%x\n", req->type);
103+ arch_handle_ioreq(state, req);
104 }
105 if (req->dir == IOREQ_READ) {
106 trace_handle_ioreq_read(req, req->type, req->df, req->data_is_ptr,
107@@ -1604,3 +1568,57 @@ void qmp_xen_set_global_dirty_log(bool enable, Error **errp)
108 memory_global_dirty_log_stop(GLOBAL_DIRTY_MIGRATION);
109 }
110 }
111+
112+void arch_xen_set_memory(XenIOState *state,MemoryRegionSection *section,
113+ bool add)
114+{
115+ hwaddr start_addr = section->offset_within_address_space;
116+ ram_addr_t size = int128_get64(section->size);
117+ bool log_dirty = memory_region_is_logging(section->mr, DIRTY_MEMORY_VGA);
118+ hvmmem_type_t mem_type;
119+
120+ if (!memory_region_is_ram(section->mr)) {
121+ return;
122+ }
123+
124+ if (log_dirty != add) {
125+ return;
126+ }
127+
128+ trace_xen_client_set_memory(start_addr, size, log_dirty);
129+
130+ start_addr &= TARGET_PAGE_MASK;
131+ size = TARGET_PAGE_ALIGN(size);
132+
133+ if (add) {
134+ if (!memory_region_is_rom(section->mr)) {
135+ xen_add_to_physmap(state, start_addr, size,
136+ section->mr, section->offset_within_region);
137+ } else {
138+ mem_type = HVMMEM_ram_ro;
139+ if (xen_set_mem_type(xen_domid, mem_type,
140+ start_addr >> TARGET_PAGE_BITS,
141+ size >> TARGET_PAGE_BITS)) {
142+ DPRINTF("xen_set_mem_type error, addr: "TARGET_FMT_plx"\n",
143+ start_addr);
144+ }
145+ }
146+ } else {
147+ if (xen_remove_from_physmap(state, start_addr, size) < 0) {
148+ DPRINTF("physmapping does not exist at "TARGET_FMT_plx"\n", start_addr);
149+ }
150+ }
151+}
152+
153+void arch_handle_ioreq(XenIOState *state, ioreq_t *req)
154+{
155+ switch (req->type) {
156+ case IOREQ_TYPE_VMWARE_PORT:
157+ handle_vmport_ioreq(state, req);
158+ break;
159+ default:
160+ hw_error("Invalid ioreq type 0x%x\n", req->type);
161+ }
162+
163+ return;
164+}
165diff --git a/include/hw/i386/xen_arch_hvm.h b/include/hw/i386/xen_arch_hvm.h
166new file mode 100644
167index 0000000000..1b2c71ba4f
168--- /dev/null
169+++ b/include/hw/i386/xen_arch_hvm.h
170@@ -0,0 +1,10 @@
171+#ifndef HW_XEN_ARCH_I386_HVM_H
172+#define HW_XEN_ARCH_I386_HVM_H
173+
174+#include <xen/hvm/ioreq.h>
175+
176+void arch_handle_ioreq(XenIOState *state, ioreq_t *req);
177+void arch_xen_set_memory(XenIOState *state,
178+ MemoryRegionSection *section,
179+ bool add);
180+#endif
181diff --git a/include/hw/xen/arch_hvm.h b/include/hw/xen/arch_hvm.h
182new file mode 100644
183index 0000000000..26674648d8
184--- /dev/null
185+++ b/include/hw/xen/arch_hvm.h
186@@ -0,0 +1,3 @@
187+#if defined(TARGET_I386) || defined(TARGET_X86_64)
188+#include "hw/i386/xen_arch_hvm.h"
189+#endif
190--
1912.17.1
192
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0006-xen-add-map-and-unmap-callbacks-for-grant-region.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0006-xen-add-map-and-unmap-callbacks-for-grant-region.patch
new file mode 100644
index 00000000..87bbc3c6
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0006-xen-add-map-and-unmap-callbacks-for-grant-region.patch
@@ -0,0 +1,255 @@
1From ef94d70d4a22c5282d6955a7ed066ef502e99829 Mon Sep 17 00:00:00 2001
2From: Juergen Gross <jgross@suse.com>
3Date: Fri, 26 Aug 2022 13:57:06 +0200
4Subject: [PATCH 6/8] xen: add map and unmap callbacks for grant region
5
6Add the callbacks for mapping/unmapping guest memory via grants to the
7special grant memory region.
8
9Signed-off-by: Juergen Gross <jgross@suse.com>
10Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com>
11Signed-off-by: Stefano Stabellini <stefano.stabellini@amd.com>
12Acked-by: Stefano Stabellini <stefano.stabellini@amd.com>
13---
14 hw/xen/xen-mapcache.c | 167 +++++++++++++++++++++++++++++++++++++++++-
15 softmmu/physmem.c | 11 ++-
16 2 files changed, 173 insertions(+), 5 deletions(-)
17
18diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
19index e53e7221f1..f81b75d216 100644
20--- a/hw/xen/xen-mapcache.c
21+++ b/hw/xen/xen-mapcache.c
22@@ -9,6 +9,8 @@
23 */
24
25 #include "qemu/osdep.h"
26+#include "qemu/queue.h"
27+#include "qemu/thread.h"
28 #include "qemu/units.h"
29 #include "qemu/error-report.h"
30
31@@ -24,6 +26,8 @@
32 #include "sysemu/xen-mapcache.h"
33 #include "trace.h"
34
35+#include <xenevtchn.h>
36+#include <xengnttab.h>
37
38 //#define MAPCACHE_DEBUG
39
40@@ -386,7 +390,7 @@ uint8_t *xen_map_cache(hwaddr phys_addr, hwaddr size,
41 return p;
42 }
43
44-ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
45+static ram_addr_t xen_ram_addr_from_mapcache_try(void *ptr)
46 {
47 MapCacheEntry *entry = NULL;
48 MapCacheRev *reventry;
49@@ -595,10 +599,170 @@ uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
50 return p;
51 }
52
53+struct XENMappedGrantRegion {
54+ void *addr;
55+ unsigned int pages;
56+ unsigned int refs;
57+ unsigned int prot;
58+ uint32_t idx;
59+ QLIST_ENTRY(XENMappedGrantRegion) list;
60+};
61+
62+static xengnttab_handle *xen_region_gnttabdev;
63+static QLIST_HEAD(GrantRegionList, XENMappedGrantRegion) xen_grant_mappings =
64+ QLIST_HEAD_INITIALIZER(xen_grant_mappings);
65+static QemuMutex xen_map_mutex;
66+
67+static void *xen_map_grant_dyn(MemoryRegion **mr, hwaddr addr, hwaddr *plen,
68+ bool is_write, MemTxAttrs attrs)
69+{
70+ unsigned int page_off = addr & (XC_PAGE_SIZE - 1);
71+ unsigned int i;
72+ unsigned int nrefs = (page_off + *plen + XC_PAGE_SIZE - 1) >> XC_PAGE_SHIFT;
73+ uint32_t ref = (addr - XEN_GRANT_ADDR_OFF) >> XC_PAGE_SHIFT;
74+ uint32_t *refs;
75+ unsigned int prot = PROT_READ;
76+ struct XENMappedGrantRegion *mgr = NULL;
77+
78+ if (is_write) {
79+ prot |= PROT_WRITE;
80+ }
81+
82+ qemu_mutex_lock(&xen_map_mutex);
83+
84+ QLIST_FOREACH(mgr, &xen_grant_mappings, list) {
85+ if (mgr->idx == ref &&
86+ mgr->pages == nrefs &&
87+ (mgr->prot & prot) == prot) {
88+ break;
89+ }
90+ }
91+ if (!mgr) {
92+ mgr = g_new(struct XENMappedGrantRegion, 1);
93+
94+ if (nrefs == 1) {
95+ refs = &ref;
96+ } else {
97+ refs = g_new(uint32_t, nrefs);
98+ for (i = 0; i < nrefs; i++) {
99+ refs[i] = ref + i;
100+ }
101+ }
102+ mgr->addr = xengnttab_map_domain_grant_refs(xen_region_gnttabdev, nrefs,
103+ xen_domid, refs, prot);
104+ if (mgr->addr) {
105+ mgr->pages = nrefs;
106+ mgr->refs = 1;
107+ mgr->prot = prot;
108+ mgr->idx = ref;
109+
110+ QLIST_INSERT_HEAD(&xen_grant_mappings, mgr, list);
111+ } else {
112+ g_free(mgr);
113+ mgr = NULL;
114+ }
115+ } else {
116+ mgr->refs++;
117+ }
118+
119+ qemu_mutex_unlock(&xen_map_mutex);
120+
121+ if (nrefs > 1) {
122+ g_free(refs);
123+ }
124+
125+ return mgr ? mgr->addr + page_off : NULL;
126+}
127+
128+static void xen_unmap_grant_dyn(MemoryRegion *mr, void *buffer, ram_addr_t addr,
129+ hwaddr len, bool is_write, hwaddr access_len)
130+{
131+ unsigned int page_off = (unsigned long)buffer & (XC_PAGE_SIZE - 1);
132+ unsigned int nrefs = (page_off + len + XC_PAGE_SIZE - 1) >> XC_PAGE_SHIFT;
133+ unsigned int prot = PROT_READ;
134+ struct XENMappedGrantRegion *mgr = NULL;
135+
136+ if (is_write) {
137+ prot |= PROT_WRITE;
138+ }
139+
140+ qemu_mutex_lock(&xen_map_mutex);
141+
142+ QLIST_FOREACH(mgr, &xen_grant_mappings, list) {
143+ if (mgr->addr == buffer - page_off &&
144+ mgr->pages == nrefs &&
145+ (mgr->prot & prot) == prot) {
146+ break;
147+ }
148+ }
149+ if (mgr) {
150+ mgr->refs--;
151+ if (!mgr->refs) {
152+ xengnttab_unmap(xen_region_gnttabdev, mgr->addr, nrefs);
153+
154+ QLIST_REMOVE(mgr, list);
155+ g_free(mgr);
156+ }
157+ } else {
158+ error_report("xen_unmap_grant_dyn() trying to unmap unknown buffer");
159+ }
160+
161+ qemu_mutex_unlock(&xen_map_mutex);
162+}
163+
164+static ram_addr_t xen_ram_addr_from_grant_cache(void *ptr)
165+{
166+ unsigned int page_off = (unsigned long)ptr & (XC_PAGE_SIZE - 1);
167+ struct XENMappedGrantRegion *mgr = NULL;
168+ ram_addr_t raddr = RAM_ADDR_INVALID;
169+
170+ qemu_mutex_lock(&xen_map_mutex);
171+
172+ QLIST_FOREACH(mgr, &xen_grant_mappings, list) {
173+ if (mgr->addr == ptr - page_off) {
174+ break;
175+ }
176+ }
177+
178+ if (mgr) {
179+ raddr = (mgr->idx << XC_PAGE_SHIFT) + page_off + XEN_GRANT_ADDR_OFF;
180+ }
181+
182+ qemu_mutex_unlock(&xen_map_mutex);
183+
184+ return raddr;
185+}
186+
187+ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
188+{
189+ ram_addr_t raddr;
190+
191+ raddr = xen_ram_addr_from_mapcache_try(ptr);
192+ if (raddr == RAM_ADDR_INVALID) {
193+ raddr = xen_ram_addr_from_grant_cache(ptr);
194+ }
195+
196+ return raddr;
197+}
198+
199+static const struct MemoryRegionOps xen_grant_mr_ops = {
200+ .map = xen_map_grant_dyn,
201+ .unmap = xen_unmap_grant_dyn,
202+ .endianness = DEVICE_LITTLE_ENDIAN,
203+};
204+
205 MemoryRegion *xen_init_grant_ram(void)
206 {
207 RAMBlock *block;
208
209+ qemu_mutex_init(&xen_map_mutex);
210+
211+ xen_region_gnttabdev = xengnttab_open(NULL, 0);
212+ if (xen_region_gnttabdev == NULL) {
213+ fprintf(stderr, "can't open gnttab device\n");
214+ return NULL;
215+ }
216+
217 memory_region_init(&ram_grants, NULL, "xen.grants",
218 XEN_MAX_VIRTIO_GRANTS * XC_PAGE_SIZE);
219 block = g_malloc0(sizeof(*block));
220@@ -613,6 +777,7 @@ MemoryRegion *xen_init_grant_ram(void)
221 ram_grants.ram_block = block;
222 ram_grants.ram = true;
223 ram_grants.terminates = true;
224+ ram_grants.ops = &xen_grant_mr_ops;
225 ram_block_add_list(block);
226 memory_region_add_subregion(get_system_memory(), XEN_GRANT_ADDR_OFF,
227 &ram_grants);
228diff --git a/softmmu/physmem.c b/softmmu/physmem.c
229index 2038240311..6b2a02fc87 100644
230--- a/softmmu/physmem.c
231+++ b/softmmu/physmem.c
232@@ -2391,13 +2391,16 @@ RAMBlock *qemu_ram_block_from_host(void *ptr, bool round_offset,
233
234 if (xen_enabled()) {
235 ram_addr_t ram_addr;
236+
237 RCU_READ_LOCK_GUARD();
238 ram_addr = xen_ram_addr_from_mapcache(ptr);
239- block = qemu_get_ram_block(ram_addr);
240- if (block) {
241- *offset = ram_addr - block->offset;
242+ if (ram_addr != RAM_ADDR_INVALID) {
243+ block = qemu_get_ram_block(ram_addr);
244+ if (block) {
245+ *offset = ram_addr - block->offset;
246+ }
247+ return block;
248 }
249- return block;
250 }
251
252 RCU_READ_LOCK_GUARD();
253--
2542.25.1
255
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0006-xen-hvm-move-common-functions-to-hw-xen-xen-hvm-comm.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0006-xen-hvm-move-common-functions-to-hw-xen-xen-hvm-comm.patch
new file mode 100644
index 00000000..7df302a2
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0006-xen-hvm-move-common-functions-to-hw-xen-xen-hvm-comm.patch
@@ -0,0 +1,2094 @@
1From 87d362e72e65b604da7554657204344a6540d88c Mon Sep 17 00:00:00 2001
2From: Vikram Garhwal <vikram.garhwal@amd.com>
3Date: Fri, 1 Jul 2022 15:59:47 -0700
4Subject: [PATCH 06/16] xen-hvm: move common functions to
5 hw/xen/xen-hvm-common.c
6
7Extract common functionalities from xen-hvm.c and move them to
8hw/xen/xen-hvm-common.c. These common functions are useful for creating
9an IOREQ server.
10
11Moved the common usable IOREQ creation part to a new function
12xen_register_ioreq() which can be used by both x86 and ARM machines.
13
14NOTE: This patch will break the build as the patch only involves moving
15of functions. Build fixes will be in the next patch.
16
17Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com>
18Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
19Reviewed-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
20---
21 hw/i386/xen/trace-events | 14 -
22 hw/i386/xen/xen-hvm.c | 927 +-------------------------------
23 hw/xen/meson.build | 5 +-
24 hw/xen/trace-events | 14 +
25 hw/xen/xen-hvm-common.c | 861 +++++++++++++++++++++++++++++
26 include/hw/i386/xen_arch_hvm.h | 1 +
27 include/hw/xen/xen-hvm-common.h | 98 ++++
28 7 files changed, 986 insertions(+), 934 deletions(-)
29 create mode 100644 hw/xen/xen-hvm-common.c
30 create mode 100644 include/hw/xen/xen-hvm-common.h
31
32diff --git a/hw/i386/xen/trace-events b/hw/i386/xen/trace-events
33index a0c89d91c4..5d0a8d6dcf 100644
34--- a/hw/i386/xen/trace-events
35+++ b/hw/i386/xen/trace-events
36@@ -7,17 +7,3 @@ xen_platform_log(char *s) "xen platform: %s"
37 xen_pv_mmio_read(uint64_t addr) "WARNING: read from Xen PV Device MMIO space (address 0x%"PRIx64")"
38 xen_pv_mmio_write(uint64_t addr) "WARNING: write to Xen PV Device MMIO space (address 0x%"PRIx64")"
39
40-# xen-hvm.c
41-xen_ram_alloc(unsigned long ram_addr, unsigned long size) "requested: 0x%lx, size 0x%lx"
42-xen_client_set_memory(uint64_t start_addr, unsigned long size, bool log_dirty) "0x%"PRIx64" size 0x%lx, log_dirty %i"
43-handle_ioreq(void *req, uint32_t type, uint32_t dir, uint32_t df, uint32_t data_is_ptr, uint64_t addr, uint64_t data, uint32_t count, uint32_t size) "I/O=%p type=%d dir=%d df=%d ptr=%d port=0x%"PRIx64" data=0x%"PRIx64" count=%d size=%d"
44-handle_ioreq_read(void *req, uint32_t type, uint32_t df, uint32_t data_is_ptr, uint64_t addr, uint64_t data, uint32_t count, uint32_t size) "I/O=%p read type=%d df=%d ptr=%d port=0x%"PRIx64" data=0x%"PRIx64" count=%d size=%d"
45-handle_ioreq_write(void *req, uint32_t type, uint32_t df, uint32_t data_is_ptr, uint64_t addr, uint64_t data, uint32_t count, uint32_t size) "I/O=%p write type=%d df=%d ptr=%d port=0x%"PRIx64" data=0x%"PRIx64" count=%d size=%d"
46-cpu_ioreq_pio(void *req, uint32_t dir, uint32_t df, uint32_t data_is_ptr, uint64_t addr, uint64_t data, uint32_t count, uint32_t size) "I/O=%p pio dir=%d df=%d ptr=%d port=0x%"PRIx64" data=0x%"PRIx64" count=%d size=%d"
47-cpu_ioreq_pio_read_reg(void *req, uint64_t data, uint64_t addr, uint32_t size) "I/O=%p pio read reg data=0x%"PRIx64" port=0x%"PRIx64" size=%d"
48-cpu_ioreq_pio_write_reg(void *req, uint64_t data, uint64_t addr, uint32_t size) "I/O=%p pio write reg data=0x%"PRIx64" port=0x%"PRIx64" size=%d"
49-cpu_ioreq_move(void *req, uint32_t dir, uint32_t df, uint32_t data_is_ptr, uint64_t addr, uint64_t data, uint32_t count, uint32_t size) "I/O=%p copy dir=%d df=%d ptr=%d port=0x%"PRIx64" data=0x%"PRIx64" count=%d size=%d"
50-xen_map_resource_ioreq(uint32_t id, void *addr) "id: %u addr: %p"
51-cpu_ioreq_config_read(void *req, uint32_t sbdf, uint32_t reg, uint32_t size, uint32_t data) "I/O=%p sbdf=0x%x reg=%u size=%u data=0x%x"
52-cpu_ioreq_config_write(void *req, uint32_t sbdf, uint32_t reg, uint32_t size, uint32_t data) "I/O=%p sbdf=0x%x reg=%u size=%u data=0x%x"
53-
54diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
55index 178f0c68fc..36d87555a9 100644
56--- a/hw/i386/xen/xen-hvm.c
57+++ b/hw/i386/xen/xen-hvm.c
58@@ -10,43 +10,21 @@
59
60 #include "qemu/osdep.h"
61 #include "qemu/units.h"
62+#include "qapi/error.h"
63+#include "qapi/qapi-commands-migration.h"
64+#include "trace.h"
65
66-#include "cpu.h"
67-#include "hw/pci/pci.h"
68-#include "hw/pci/pci_host.h"
69 #include "hw/i386/pc.h"
70 #include "hw/irq.h"
71-#include "hw/hw.h"
72 #include "hw/i386/apic-msidef.h"
73-#include "hw/xen/xen_common.h"
74-#include "hw/xen/xen-legacy-backend.h"
75-#include "hw/xen/xen-bus.h"
76 #include "hw/xen/xen-x86.h"
77-#include "qapi/error.h"
78-#include "qapi/qapi-commands-migration.h"
79-#include "qemu/error-report.h"
80-#include "qemu/main-loop.h"
81 #include "qemu/range.h"
82-#include "sysemu/runstate.h"
83-#include "sysemu/sysemu.h"
84-#include "sysemu/xen.h"
85-#include "sysemu/xen-mapcache.h"
86-#include "trace.h"
87
88-#include <xen/hvm/ioreq.h>
89+#include "hw/xen/xen-hvm-common.h"
90+#include "hw/xen/arch_hvm.h"
91 #include <xen/hvm/e820.h>
92
93-//#define DEBUG_XEN_HVM
94-
95-#ifdef DEBUG_XEN_HVM
96-#define DPRINTF(fmt, ...) \
97- do { fprintf(stderr, "xen: " fmt, ## __VA_ARGS__); } while (0)
98-#else
99-#define DPRINTF(fmt, ...) \
100- do { } while (0)
101-#endif
102-
103-static MemoryRegion ram_memory, ram_640k, ram_lo, ram_hi;
104+static MemoryRegion ram_640k, ram_lo, ram_hi;
105 static MemoryRegion *framebuffer;
106 static bool xen_in_migration;
107
108@@ -75,25 +53,6 @@ typedef struct shared_vmport_iopage shared_vmport_iopage_t;
109 #endif
110 static shared_vmport_iopage_t *shared_vmport_page;
111
112-static inline uint32_t xen_vcpu_eport(shared_iopage_t *shared_page, int i)
113-{
114- return shared_page->vcpu_ioreq[i].vp_eport;
115-}
116-static inline ioreq_t *xen_vcpu_ioreq(shared_iopage_t *shared_page, int vcpu)
117-{
118- return &shared_page->vcpu_ioreq[vcpu];
119-}
120-
121-#define BUFFER_IO_MAX_DELAY 100
122-
123-typedef struct XenPhysmap {
124- hwaddr start_addr;
125- ram_addr_t size;
126- const char *name;
127- hwaddr phys_offset;
128-
129- QLIST_ENTRY(XenPhysmap) list;
130-} XenPhysmap;
131
132 static QLIST_HEAD(, XenPhysmap) xen_physmap;
133 static const XenPhysmap *log_for_dirtybit = NULL;
134@@ -102,40 +61,6 @@ static unsigned long *dirty_bitmap = NULL;
135 static Notifier suspend;
136 static Notifier wakeup;
137
138-typedef struct XenPciDevice {
139- PCIDevice *pci_dev;
140- uint32_t sbdf;
141- QLIST_ENTRY(XenPciDevice) entry;
142-} XenPciDevice;
143-
144-typedef struct XenIOState {
145- ioservid_t ioservid;
146- shared_iopage_t *shared_page;
147- buffered_iopage_t *buffered_io_page;
148- xenforeignmemory_resource_handle *fres;
149- QEMUTimer *buffered_io_timer;
150- CPUState **cpu_by_vcpu_id;
151- /* the evtchn port for polling the notification, */
152- evtchn_port_t *ioreq_local_port;
153- /* evtchn remote and local ports for buffered io */
154- evtchn_port_t bufioreq_remote_port;
155- evtchn_port_t bufioreq_local_port;
156- /* the evtchn fd for polling */
157- xenevtchn_handle *xce_handle;
158- /* which vcpu we are serving */
159- int send_vcpu;
160-
161- struct xs_handle *xenstore;
162- MemoryListener memory_listener;
163- MemoryListener io_listener;
164- QLIST_HEAD(, XenPciDevice) dev_list;
165- DeviceListener device_listener;
166-
167- Notifier exit;
168-} XenIOState;
169-
170-#include "hw/xen/arch_hvm.h"
171-
172 /* Xen specific function for piix pci */
173
174 int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
175@@ -248,42 +173,6 @@ static void xen_ram_init(PCMachineState *pcms,
176 }
177 }
178
179-void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr,
180- Error **errp)
181-{
182- unsigned long nr_pfn;
183- xen_pfn_t *pfn_list;
184- int i;
185-
186- if (runstate_check(RUN_STATE_INMIGRATE)) {
187- /* RAM already populated in Xen */
188- fprintf(stderr, "%s: do not alloc "RAM_ADDR_FMT
189- " bytes of ram at "RAM_ADDR_FMT" when runstate is INMIGRATE\n",
190- __func__, size, ram_addr);
191- return;
192- }
193-
194- if (mr == &ram_memory) {
195- return;
196- }
197-
198- trace_xen_ram_alloc(ram_addr, size);
199-
200- nr_pfn = size >> TARGET_PAGE_BITS;
201- pfn_list = g_malloc(sizeof (*pfn_list) * nr_pfn);
202-
203- for (i = 0; i < nr_pfn; i++) {
204- pfn_list[i] = (ram_addr >> TARGET_PAGE_BITS) + i;
205- }
206-
207- if (xc_domain_populate_physmap_exact(xen_xc, xen_domid, nr_pfn, 0, 0, pfn_list)) {
208- error_setg(errp, "xen: failed to populate ram at " RAM_ADDR_FMT,
209- ram_addr);
210- }
211-
212- g_free(pfn_list);
213-}
214-
215 static XenPhysmap *get_physmapping(hwaddr start_addr, ram_addr_t size)
216 {
217 XenPhysmap *physmap = NULL;
218@@ -473,109 +362,6 @@ static int xen_remove_from_physmap(XenIOState *state,
219 return 0;
220 }
221
222-static void xen_set_memory(struct MemoryListener *listener,
223- MemoryRegionSection *section,
224- bool add)
225-{
226- XenIOState *state = container_of(listener, XenIOState, memory_listener);
227-
228- if (section->mr == &ram_memory) {
229- return;
230- } else {
231- if (add) {
232- xen_map_memory_section(xen_domid, state->ioservid,
233- section);
234- } else {
235- xen_unmap_memory_section(xen_domid, state->ioservid,
236- section);
237- }
238- }
239- arch_xen_set_memory(state, section, add);
240-}
241-
242-static void xen_region_add(MemoryListener *listener,
243- MemoryRegionSection *section)
244-{
245- memory_region_ref(section->mr);
246- xen_set_memory(listener, section, true);
247-}
248-
249-static void xen_region_del(MemoryListener *listener,
250- MemoryRegionSection *section)
251-{
252- xen_set_memory(listener, section, false);
253- memory_region_unref(section->mr);
254-}
255-
256-static void xen_io_add(MemoryListener *listener,
257- MemoryRegionSection *section)
258-{
259- XenIOState *state = container_of(listener, XenIOState, io_listener);
260- MemoryRegion *mr = section->mr;
261-
262- if (mr->ops == &unassigned_io_ops) {
263- return;
264- }
265-
266- memory_region_ref(mr);
267-
268- xen_map_io_section(xen_domid, state->ioservid, section);
269-}
270-
271-static void xen_io_del(MemoryListener *listener,
272- MemoryRegionSection *section)
273-{
274- XenIOState *state = container_of(listener, XenIOState, io_listener);
275- MemoryRegion *mr = section->mr;
276-
277- if (mr->ops == &unassigned_io_ops) {
278- return;
279- }
280-
281- xen_unmap_io_section(xen_domid, state->ioservid, section);
282-
283- memory_region_unref(mr);
284-}
285-
286-static void xen_device_realize(DeviceListener *listener,
287- DeviceState *dev)
288-{
289- XenIOState *state = container_of(listener, XenIOState, device_listener);
290-
291- if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
292- PCIDevice *pci_dev = PCI_DEVICE(dev);
293- XenPciDevice *xendev = g_new(XenPciDevice, 1);
294-
295- xendev->pci_dev = pci_dev;
296- xendev->sbdf = PCI_BUILD_BDF(pci_dev_bus_num(pci_dev),
297- pci_dev->devfn);
298- QLIST_INSERT_HEAD(&state->dev_list, xendev, entry);
299-
300- xen_map_pcidev(xen_domid, state->ioservid, pci_dev);
301- }
302-}
303-
304-static void xen_device_unrealize(DeviceListener *listener,
305- DeviceState *dev)
306-{
307- XenIOState *state = container_of(listener, XenIOState, device_listener);
308-
309- if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
310- PCIDevice *pci_dev = PCI_DEVICE(dev);
311- XenPciDevice *xendev, *next;
312-
313- xen_unmap_pcidev(xen_domid, state->ioservid, pci_dev);
314-
315- QLIST_FOREACH_SAFE(xendev, &state->dev_list, entry, next) {
316- if (xendev->pci_dev == pci_dev) {
317- QLIST_REMOVE(xendev, entry);
318- g_free(xendev);
319- break;
320- }
321- }
322- }
323-}
324-
325 static void xen_sync_dirty_bitmap(XenIOState *state,
326 hwaddr start_addr,
327 ram_addr_t size)
328@@ -683,277 +469,6 @@ static MemoryListener xen_memory_listener = {
329 .priority = 10,
330 };
331
332-static MemoryListener xen_io_listener = {
333- .name = "xen-io",
334- .region_add = xen_io_add,
335- .region_del = xen_io_del,
336- .priority = 10,
337-};
338-
339-static DeviceListener xen_device_listener = {
340- .realize = xen_device_realize,
341- .unrealize = xen_device_unrealize,
342-};
343-
344-/* get the ioreq packets from share mem */
345-static ioreq_t *cpu_get_ioreq_from_shared_memory(XenIOState *state, int vcpu)
346-{
347- ioreq_t *req = xen_vcpu_ioreq(state->shared_page, vcpu);
348-
349- if (req->state != STATE_IOREQ_READY) {
350- DPRINTF("I/O request not ready: "
351- "%x, ptr: %x, port: %"PRIx64", "
352- "data: %"PRIx64", count: %u, size: %u\n",
353- req->state, req->data_is_ptr, req->addr,
354- req->data, req->count, req->size);
355- return NULL;
356- }
357-
358- xen_rmb(); /* see IOREQ_READY /then/ read contents of ioreq */
359-
360- req->state = STATE_IOREQ_INPROCESS;
361- return req;
362-}
363-
364-/* use poll to get the port notification */
365-/* ioreq_vec--out,the */
366-/* retval--the number of ioreq packet */
367-static ioreq_t *cpu_get_ioreq(XenIOState *state)
368-{
369- MachineState *ms = MACHINE(qdev_get_machine());
370- unsigned int max_cpus = ms->smp.max_cpus;
371- int i;
372- evtchn_port_t port;
373-
374- port = xenevtchn_pending(state->xce_handle);
375- if (port == state->bufioreq_local_port) {
376- timer_mod(state->buffered_io_timer,
377- BUFFER_IO_MAX_DELAY + qemu_clock_get_ms(QEMU_CLOCK_REALTIME));
378- return NULL;
379- }
380-
381- if (port != -1) {
382- for (i = 0; i < max_cpus; i++) {
383- if (state->ioreq_local_port[i] == port) {
384- break;
385- }
386- }
387-
388- if (i == max_cpus) {
389- hw_error("Fatal error while trying to get io event!\n");
390- }
391-
392- /* unmask the wanted port again */
393- xenevtchn_unmask(state->xce_handle, port);
394-
395- /* get the io packet from shared memory */
396- state->send_vcpu = i;
397- return cpu_get_ioreq_from_shared_memory(state, i);
398- }
399-
400- /* read error or read nothing */
401- return NULL;
402-}
403-
404-static uint32_t do_inp(uint32_t addr, unsigned long size)
405-{
406- switch (size) {
407- case 1:
408- return cpu_inb(addr);
409- case 2:
410- return cpu_inw(addr);
411- case 4:
412- return cpu_inl(addr);
413- default:
414- hw_error("inp: bad size: %04x %lx", addr, size);
415- }
416-}
417-
418-static void do_outp(uint32_t addr,
419- unsigned long size, uint32_t val)
420-{
421- switch (size) {
422- case 1:
423- return cpu_outb(addr, val);
424- case 2:
425- return cpu_outw(addr, val);
426- case 4:
427- return cpu_outl(addr, val);
428- default:
429- hw_error("outp: bad size: %04x %lx", addr, size);
430- }
431-}
432-
433-/*
434- * Helper functions which read/write an object from/to physical guest
435- * memory, as part of the implementation of an ioreq.
436- *
437- * Equivalent to
438- * cpu_physical_memory_rw(addr + (req->df ? -1 : +1) * req->size * i,
439- * val, req->size, 0/1)
440- * except without the integer overflow problems.
441- */
442-static void rw_phys_req_item(hwaddr addr,
443- ioreq_t *req, uint32_t i, void *val, int rw)
444-{
445- /* Do everything unsigned so overflow just results in a truncated result
446- * and accesses to undesired parts of guest memory, which is up
447- * to the guest */
448- hwaddr offset = (hwaddr)req->size * i;
449- if (req->df) {
450- addr -= offset;
451- } else {
452- addr += offset;
453- }
454- cpu_physical_memory_rw(addr, val, req->size, rw);
455-}
456-
457-static inline void read_phys_req_item(hwaddr addr,
458- ioreq_t *req, uint32_t i, void *val)
459-{
460- rw_phys_req_item(addr, req, i, val, 0);
461-}
462-static inline void write_phys_req_item(hwaddr addr,
463- ioreq_t *req, uint32_t i, void *val)
464-{
465- rw_phys_req_item(addr, req, i, val, 1);
466-}
467-
468-
469-static void cpu_ioreq_pio(ioreq_t *req)
470-{
471- uint32_t i;
472-
473- trace_cpu_ioreq_pio(req, req->dir, req->df, req->data_is_ptr, req->addr,
474- req->data, req->count, req->size);
475-
476- if (req->size > sizeof(uint32_t)) {
477- hw_error("PIO: bad size (%u)", req->size);
478- }
479-
480- if (req->dir == IOREQ_READ) {
481- if (!req->data_is_ptr) {
482- req->data = do_inp(req->addr, req->size);
483- trace_cpu_ioreq_pio_read_reg(req, req->data, req->addr,
484- req->size);
485- } else {
486- uint32_t tmp;
487-
488- for (i = 0; i < req->count; i++) {
489- tmp = do_inp(req->addr, req->size);
490- write_phys_req_item(req->data, req, i, &tmp);
491- }
492- }
493- } else if (req->dir == IOREQ_WRITE) {
494- if (!req->data_is_ptr) {
495- trace_cpu_ioreq_pio_write_reg(req, req->data, req->addr,
496- req->size);
497- do_outp(req->addr, req->size, req->data);
498- } else {
499- for (i = 0; i < req->count; i++) {
500- uint32_t tmp = 0;
501-
502- read_phys_req_item(req->data, req, i, &tmp);
503- do_outp(req->addr, req->size, tmp);
504- }
505- }
506- }
507-}
508-
509-static void cpu_ioreq_move(ioreq_t *req)
510-{
511- uint32_t i;
512-
513- trace_cpu_ioreq_move(req, req->dir, req->df, req->data_is_ptr, req->addr,
514- req->data, req->count, req->size);
515-
516- if (req->size > sizeof(req->data)) {
517- hw_error("MMIO: bad size (%u)", req->size);
518- }
519-
520- if (!req->data_is_ptr) {
521- if (req->dir == IOREQ_READ) {
522- for (i = 0; i < req->count; i++) {
523- read_phys_req_item(req->addr, req, i, &req->data);
524- }
525- } else if (req->dir == IOREQ_WRITE) {
526- for (i = 0; i < req->count; i++) {
527- write_phys_req_item(req->addr, req, i, &req->data);
528- }
529- }
530- } else {
531- uint64_t tmp;
532-
533- if (req->dir == IOREQ_READ) {
534- for (i = 0; i < req->count; i++) {
535- read_phys_req_item(req->addr, req, i, &tmp);
536- write_phys_req_item(req->data, req, i, &tmp);
537- }
538- } else if (req->dir == IOREQ_WRITE) {
539- for (i = 0; i < req->count; i++) {
540- read_phys_req_item(req->data, req, i, &tmp);
541- write_phys_req_item(req->addr, req, i, &tmp);
542- }
543- }
544- }
545-}
546-
547-static void cpu_ioreq_config(XenIOState *state, ioreq_t *req)
548-{
549- uint32_t sbdf = req->addr >> 32;
550- uint32_t reg = req->addr;
551- XenPciDevice *xendev;
552-
553- if (req->size != sizeof(uint8_t) && req->size != sizeof(uint16_t) &&
554- req->size != sizeof(uint32_t)) {
555- hw_error("PCI config access: bad size (%u)", req->size);
556- }
557-
558- if (req->count != 1) {
559- hw_error("PCI config access: bad count (%u)", req->count);
560- }
561-
562- QLIST_FOREACH(xendev, &state->dev_list, entry) {
563- if (xendev->sbdf != sbdf) {
564- continue;
565- }
566-
567- if (!req->data_is_ptr) {
568- if (req->dir == IOREQ_READ) {
569- req->data = pci_host_config_read_common(
570- xendev->pci_dev, reg, PCI_CONFIG_SPACE_SIZE,
571- req->size);
572- trace_cpu_ioreq_config_read(req, xendev->sbdf, reg,
573- req->size, req->data);
574- } else if (req->dir == IOREQ_WRITE) {
575- trace_cpu_ioreq_config_write(req, xendev->sbdf, reg,
576- req->size, req->data);
577- pci_host_config_write_common(
578- xendev->pci_dev, reg, PCI_CONFIG_SPACE_SIZE,
579- req->data, req->size);
580- }
581- } else {
582- uint32_t tmp;
583-
584- if (req->dir == IOREQ_READ) {
585- tmp = pci_host_config_read_common(
586- xendev->pci_dev, reg, PCI_CONFIG_SPACE_SIZE,
587- req->size);
588- trace_cpu_ioreq_config_read(req, xendev->sbdf, reg,
589- req->size, tmp);
590- write_phys_req_item(req->data, req, 0, &tmp);
591- } else if (req->dir == IOREQ_WRITE) {
592- read_phys_req_item(req->data, req, 0, &tmp);
593- trace_cpu_ioreq_config_write(req, xendev->sbdf, reg,
594- req->size, tmp);
595- pci_host_config_write_common(
596- xendev->pci_dev, reg, PCI_CONFIG_SPACE_SIZE,
597- tmp, req->size);
598- }
599- }
600- }
601-}
602-
603 static void regs_to_cpu(vmware_regs_t *vmport_regs, ioreq_t *req)
604 {
605 X86CPU *cpu;
606@@ -997,223 +512,6 @@ static void handle_vmport_ioreq(XenIOState *state, ioreq_t *req)
607 current_cpu = NULL;
608 }
609
610-static void handle_ioreq(XenIOState *state, ioreq_t *req)
611-{
612- trace_handle_ioreq(req, req->type, req->dir, req->df, req->data_is_ptr,
613- req->addr, req->data, req->count, req->size);
614-
615- if (!req->data_is_ptr && (req->dir == IOREQ_WRITE) &&
616- (req->size < sizeof (target_ulong))) {
617- req->data &= ((target_ulong) 1 << (8 * req->size)) - 1;
618- }
619-
620- if (req->dir == IOREQ_WRITE)
621- trace_handle_ioreq_write(req, req->type, req->df, req->data_is_ptr,
622- req->addr, req->data, req->count, req->size);
623-
624- switch (req->type) {
625- case IOREQ_TYPE_PIO:
626- cpu_ioreq_pio(req);
627- break;
628- case IOREQ_TYPE_COPY:
629- cpu_ioreq_move(req);
630- break;
631- case IOREQ_TYPE_TIMEOFFSET:
632- break;
633- case IOREQ_TYPE_INVALIDATE:
634- xen_invalidate_map_cache();
635- break;
636- case IOREQ_TYPE_PCI_CONFIG:
637- cpu_ioreq_config(state, req);
638- break;
639- default:
640- arch_handle_ioreq(state, req);
641- }
642- if (req->dir == IOREQ_READ) {
643- trace_handle_ioreq_read(req, req->type, req->df, req->data_is_ptr,
644- req->addr, req->data, req->count, req->size);
645- }
646-}
647-
648-static bool handle_buffered_iopage(XenIOState *state)
649-{
650- buffered_iopage_t *buf_page = state->buffered_io_page;
651- buf_ioreq_t *buf_req = NULL;
652- bool handled_ioreq = false;
653- ioreq_t req;
654- int qw;
655-
656- if (!buf_page) {
657- return 0;
658- }
659-
660- memset(&req, 0x00, sizeof(req));
661- req.state = STATE_IOREQ_READY;
662- req.count = 1;
663- req.dir = IOREQ_WRITE;
664-
665- for (;;) {
666- uint32_t rdptr = buf_page->read_pointer, wrptr;
667-
668- xen_rmb();
669- wrptr = buf_page->write_pointer;
670- xen_rmb();
671- if (rdptr != buf_page->read_pointer) {
672- continue;
673- }
674- if (rdptr == wrptr) {
675- break;
676- }
677- buf_req = &buf_page->buf_ioreq[rdptr % IOREQ_BUFFER_SLOT_NUM];
678- req.size = 1U << buf_req->size;
679- req.addr = buf_req->addr;
680- req.data = buf_req->data;
681- req.type = buf_req->type;
682- xen_rmb();
683- qw = (req.size == 8);
684- if (qw) {
685- if (rdptr + 1 == wrptr) {
686- hw_error("Incomplete quad word buffered ioreq");
687- }
688- buf_req = &buf_page->buf_ioreq[(rdptr + 1) %
689- IOREQ_BUFFER_SLOT_NUM];
690- req.data |= ((uint64_t)buf_req->data) << 32;
691- xen_rmb();
692- }
693-
694- handle_ioreq(state, &req);
695-
696- /* Only req.data may get updated by handle_ioreq(), albeit even that
697- * should not happen as such data would never make it to the guest (we
698- * can only usefully see writes here after all).
699- */
700- assert(req.state == STATE_IOREQ_READY);
701- assert(req.count == 1);
702- assert(req.dir == IOREQ_WRITE);
703- assert(!req.data_is_ptr);
704-
705- qatomic_add(&buf_page->read_pointer, qw + 1);
706- handled_ioreq = true;
707- }
708-
709- return handled_ioreq;
710-}
711-
712-static void handle_buffered_io(void *opaque)
713-{
714- XenIOState *state = opaque;
715-
716- if (handle_buffered_iopage(state)) {
717- timer_mod(state->buffered_io_timer,
718- BUFFER_IO_MAX_DELAY + qemu_clock_get_ms(QEMU_CLOCK_REALTIME));
719- } else {
720- timer_del(state->buffered_io_timer);
721- xenevtchn_unmask(state->xce_handle, state->bufioreq_local_port);
722- }
723-}
724-
725-static void cpu_handle_ioreq(void *opaque)
726-{
727- XenIOState *state = opaque;
728- ioreq_t *req = cpu_get_ioreq(state);
729-
730- handle_buffered_iopage(state);
731- if (req) {
732- ioreq_t copy = *req;
733-
734- xen_rmb();
735- handle_ioreq(state, &copy);
736- req->data = copy.data;
737-
738- if (req->state != STATE_IOREQ_INPROCESS) {
739- fprintf(stderr, "Badness in I/O request ... not in service?!: "
740- "%x, ptr: %x, port: %"PRIx64", "
741- "data: %"PRIx64", count: %u, size: %u, type: %u\n",
742- req->state, req->data_is_ptr, req->addr,
743- req->data, req->count, req->size, req->type);
744- destroy_hvm_domain(false);
745- return;
746- }
747-
748- xen_wmb(); /* Update ioreq contents /then/ update state. */
749-
750- /*
751- * We do this before we send the response so that the tools
752- * have the opportunity to pick up on the reset before the
753- * guest resumes and does a hlt with interrupts disabled which
754- * causes Xen to powerdown the domain.
755- */
756- if (runstate_is_running()) {
757- ShutdownCause request;
758-
759- if (qemu_shutdown_requested_get()) {
760- destroy_hvm_domain(false);
761- }
762- request = qemu_reset_requested_get();
763- if (request) {
764- qemu_system_reset(request);
765- destroy_hvm_domain(true);
766- }
767- }
768-
769- req->state = STATE_IORESP_READY;
770- xenevtchn_notify(state->xce_handle,
771- state->ioreq_local_port[state->send_vcpu]);
772- }
773-}
774-
775-static void xen_main_loop_prepare(XenIOState *state)
776-{
777- int evtchn_fd = -1;
778-
779- if (state->xce_handle != NULL) {
780- evtchn_fd = xenevtchn_fd(state->xce_handle);
781- }
782-
783- state->buffered_io_timer = timer_new_ms(QEMU_CLOCK_REALTIME, handle_buffered_io,
784- state);
785-
786- if (evtchn_fd != -1) {
787- CPUState *cpu_state;
788-
789- DPRINTF("%s: Init cpu_by_vcpu_id\n", __func__);
790- CPU_FOREACH(cpu_state) {
791- DPRINTF("%s: cpu_by_vcpu_id[%d]=%p\n",
792- __func__, cpu_state->cpu_index, cpu_state);
793- state->cpu_by_vcpu_id[cpu_state->cpu_index] = cpu_state;
794- }
795- qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, state);
796- }
797-}
798-
799-
800-static void xen_hvm_change_state_handler(void *opaque, bool running,
801- RunState rstate)
802-{
803- XenIOState *state = opaque;
804-
805- if (running) {
806- xen_main_loop_prepare(state);
807- }
808-
809- xen_set_ioreq_server_state(xen_domid,
810- state->ioservid,
811- (rstate == RUN_STATE_RUNNING));
812-}
813-
814-static void xen_exit_notifier(Notifier *n, void *data)
815-{
816- XenIOState *state = container_of(n, XenIOState, exit);
817-
818- xen_destroy_ioreq_server(xen_domid, state->ioservid);
819- if (state->fres != NULL) {
820- xenforeignmemory_unmap_resource(xen_fmem, state->fres);
821- }
822-
823- xenevtchn_close(state->xce_handle);
824- xs_daemon_close(state->xenstore);
825-}
826-
827 #ifdef XEN_COMPAT_PHYSMAP
828 static void xen_read_physmap(XenIOState *state)
829 {
830@@ -1273,178 +571,17 @@ static void xen_wakeup_notifier(Notifier *notifier, void *data)
831 xc_set_hvm_param(xen_xc, xen_domid, HVM_PARAM_ACPI_S_STATE, 0);
832 }
833
834-static int xen_map_ioreq_server(XenIOState *state)
835-{
836- void *addr = NULL;
837- xen_pfn_t ioreq_pfn;
838- xen_pfn_t bufioreq_pfn;
839- evtchn_port_t bufioreq_evtchn;
840- int rc;
841-
842- /*
843- * Attempt to map using the resource API and fall back to normal
844- * foreign mapping if this is not supported.
845- */
846- QEMU_BUILD_BUG_ON(XENMEM_resource_ioreq_server_frame_bufioreq != 0);
847- QEMU_BUILD_BUG_ON(XENMEM_resource_ioreq_server_frame_ioreq(0) != 1);
848- state->fres = xenforeignmemory_map_resource(xen_fmem, xen_domid,
849- XENMEM_resource_ioreq_server,
850- state->ioservid, 0, 2,
851- &addr,
852- PROT_READ | PROT_WRITE, 0);
853- if (state->fres != NULL) {
854- trace_xen_map_resource_ioreq(state->ioservid, addr);
855- state->buffered_io_page = addr;
856- state->shared_page = addr + TARGET_PAGE_SIZE;
857- } else if (errno != EOPNOTSUPP) {
858- error_report("failed to map ioreq server resources: error %d handle=%p",
859- errno, xen_xc);
860- return -1;
861- }
862-
863- rc = xen_get_ioreq_server_info(xen_domid, state->ioservid,
864- (state->shared_page == NULL) ?
865- &ioreq_pfn : NULL,
866- (state->buffered_io_page == NULL) ?
867- &bufioreq_pfn : NULL,
868- &bufioreq_evtchn);
869- if (rc < 0) {
870- error_report("failed to get ioreq server info: error %d handle=%p",
871- errno, xen_xc);
872- return rc;
873- }
874-
875- if (state->shared_page == NULL) {
876- DPRINTF("shared page at pfn %lx\n", ioreq_pfn);
877-
878- state->shared_page = xenforeignmemory_map(xen_fmem, xen_domid,
879- PROT_READ | PROT_WRITE,
880- 1, &ioreq_pfn, NULL);
881- if (state->shared_page == NULL) {
882- error_report("map shared IO page returned error %d handle=%p",
883- errno, xen_xc);
884- }
885- }
886-
887- if (state->buffered_io_page == NULL) {
888- DPRINTF("buffered io page at pfn %lx\n", bufioreq_pfn);
889-
890- state->buffered_io_page = xenforeignmemory_map(xen_fmem, xen_domid,
891- PROT_READ | PROT_WRITE,
892- 1, &bufioreq_pfn,
893- NULL);
894- if (state->buffered_io_page == NULL) {
895- error_report("map buffered IO page returned error %d", errno);
896- return -1;
897- }
898- }
899-
900- if (state->shared_page == NULL || state->buffered_io_page == NULL) {
901- return -1;
902- }
903-
904- DPRINTF("buffered io evtchn is %x\n", bufioreq_evtchn);
905-
906- state->bufioreq_remote_port = bufioreq_evtchn;
907-
908- return 0;
909-}
910-
911 void xen_hvm_init_pc(PCMachineState *pcms, MemoryRegion **ram_memory)
912 {
913 MachineState *ms = MACHINE(pcms);
914 unsigned int max_cpus = ms->smp.max_cpus;
915- int i, rc;
916+ int rc;
917 xen_pfn_t ioreq_pfn;
918 XenIOState *state;
919
920 state = g_new0(XenIOState, 1);
921
922- state->xce_handle = xenevtchn_open(NULL, 0);
923- if (state->xce_handle == NULL) {
924- perror("xen: event channel open");
925- goto err;
926- }
927-
928- state->xenstore = xs_daemon_open();
929- if (state->xenstore == NULL) {
930- perror("xen: xenstore open");
931- goto err;
932- }
933-
934- xen_create_ioreq_server(xen_domid, &state->ioservid);
935-
936- state->exit.notify = xen_exit_notifier;
937- qemu_add_exit_notifier(&state->exit);
938-
939- /*
940- * Register wake-up support in QMP query-current-machine API
941- */
942- qemu_register_wakeup_support();
943-
944- rc = xen_map_ioreq_server(state);
945- if (rc < 0) {
946- goto err;
947- }
948-
949- /* Note: cpus is empty at this point in init */
950- state->cpu_by_vcpu_id = g_new0(CPUState *, max_cpus);
951-
952- rc = xen_set_ioreq_server_state(xen_domid, state->ioservid, true);
953- if (rc < 0) {
954- error_report("failed to enable ioreq server info: error %d handle=%p",
955- errno, xen_xc);
956- goto err;
957- }
958-
959- state->ioreq_local_port = g_new0(evtchn_port_t, max_cpus);
960-
961- /* FIXME: how about if we overflow the page here? */
962- for (i = 0; i < max_cpus; i++) {
963- rc = xenevtchn_bind_interdomain(state->xce_handle, xen_domid,
964- xen_vcpu_eport(state->shared_page, i));
965- if (rc == -1) {
966- error_report("shared evtchn %d bind error %d", i, errno);
967- goto err;
968- }
969- state->ioreq_local_port[i] = rc;
970- }
971-
972- rc = xenevtchn_bind_interdomain(state->xce_handle, xen_domid,
973- state->bufioreq_remote_port);
974- if (rc == -1) {
975- error_report("buffered evtchn bind error %d", errno);
976- goto err;
977- }
978- state->bufioreq_local_port = rc;
979-
980- /* Init RAM management */
981-#ifdef XEN_COMPAT_PHYSMAP
982- xen_map_cache_init(xen_phys_offset_to_gaddr, state);
983-#else
984- xen_map_cache_init(NULL, state);
985-#endif
986-
987- qemu_add_vm_change_state_handler(xen_hvm_change_state_handler, state);
988-
989- state->memory_listener = xen_memory_listener;
990- memory_listener_register(&state->memory_listener, &address_space_memory);
991-
992- state->io_listener = xen_io_listener;
993- memory_listener_register(&state->io_listener, &address_space_io);
994-
995- state->device_listener = xen_device_listener;
996- QLIST_INIT(&state->dev_list);
997- device_listener_register(&state->device_listener);
998-
999- xen_bus_init();
1000-
1001- /* Initialize backend core & drivers */
1002- if (xen_be_init() != 0) {
1003- error_report("xen backend core setup failed");
1004- goto err;
1005- }
1006- xen_be_register_common();
1007+ xen_register_ioreq(state, max_cpus, xen_memory_listener);
1008
1009 QLIST_INIT(&xen_physmap);
1010 xen_read_physmap(state);
1011@@ -1484,59 +621,11 @@ err:
1012 exit(1);
1013 }
1014
1015-void destroy_hvm_domain(bool reboot)
1016-{
1017- xc_interface *xc_handle;
1018- int sts;
1019- int rc;
1020-
1021- unsigned int reason = reboot ? SHUTDOWN_reboot : SHUTDOWN_poweroff;
1022-
1023- if (xen_dmod) {
1024- rc = xendevicemodel_shutdown(xen_dmod, xen_domid, reason);
1025- if (!rc) {
1026- return;
1027- }
1028- if (errno != ENOTTY /* old Xen */) {
1029- perror("xendevicemodel_shutdown failed");
1030- }
1031- /* well, try the old thing then */
1032- }
1033-
1034- xc_handle = xc_interface_open(0, 0, 0);
1035- if (xc_handle == NULL) {
1036- fprintf(stderr, "Cannot acquire xenctrl handle\n");
1037- } else {
1038- sts = xc_domain_shutdown(xc_handle, xen_domid, reason);
1039- if (sts != 0) {
1040- fprintf(stderr, "xc_domain_shutdown failed to issue %s, "
1041- "sts %d, %s\n", reboot ? "reboot" : "poweroff",
1042- sts, strerror(errno));
1043- } else {
1044- fprintf(stderr, "Issued domain %d %s\n", xen_domid,
1045- reboot ? "reboot" : "poweroff");
1046- }
1047- xc_interface_close(xc_handle);
1048- }
1049-}
1050-
1051 void xen_register_framebuffer(MemoryRegion *mr)
1052 {
1053 framebuffer = mr;
1054 }
1055
1056-void xen_shutdown_fatal_error(const char *fmt, ...)
1057-{
1058- va_list ap;
1059-
1060- va_start(ap, fmt);
1061- vfprintf(stderr, fmt, ap);
1062- va_end(ap);
1063- fprintf(stderr, "Will destroy the domain.\n");
1064- /* destroy the domain */
1065- qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_ERROR);
1066-}
1067-
1068 void xen_hvm_modified_memory(ram_addr_t start, ram_addr_t length)
1069 {
1070 if (unlikely(xen_in_migration)) {
1071diff --git a/hw/xen/meson.build b/hw/xen/meson.build
1072index 19d0637c46..008e036d63 100644
1073--- a/hw/xen/meson.build
1074+++ b/hw/xen/meson.build
1075@@ -25,4 +25,7 @@ specific_ss.add_all(when: ['CONFIG_XEN', xen], if_true: xen_specific_ss)
1076
1077 xen_ss = ss.source_set()
1078
1079-xen_ss.add(when: 'CONFIG_XEN', if_true: files('xen-mapcache.c'))
1080+xen_ss.add(when: 'CONFIG_XEN', if_true: files(
1081+ 'xen-mapcache.c',
1082+ 'xen-hvm-common.c',
1083+))
1084diff --git a/hw/xen/trace-events b/hw/xen/trace-events
1085index 2c8f238f42..02ca1183da 100644
1086--- a/hw/xen/trace-events
1087+++ b/hw/xen/trace-events
1088@@ -42,6 +42,20 @@ xs_node_vscanf(char *path, char *value) "%s %s"
1089 xs_node_watch(char *path) "%s"
1090 xs_node_unwatch(char *path) "%s"
1091
1092+# xen-hvm.c
1093+xen_ram_alloc(unsigned long ram_addr, unsigned long size) "requested: 0x%lx, size 0x%lx"
1094+xen_client_set_memory(uint64_t start_addr, unsigned long size, bool log_dirty) "0x%"PRIx64" size 0x%lx, log_dirty %i"
1095+handle_ioreq(void *req, uint32_t type, uint32_t dir, uint32_t df, uint32_t data_is_ptr, uint64_t addr, uint64_t data, uint32_t count, uint32_t size) "I/O=%p type=%d dir=%d df=%d ptr=%d port=0x%"PRIx64" data=0x%"PRIx64" count=%d size=%d"
1096+handle_ioreq_read(void *req, uint32_t type, uint32_t df, uint32_t data_is_ptr, uint64_t addr, uint64_t data, uint32_t count, uint32_t size) "I/O=%p read type=%d df=%d ptr=%d port=0x%"PRIx64" data=0x%"PRIx64" count=%d size=%d"
1097+handle_ioreq_write(void *req, uint32_t type, uint32_t df, uint32_t data_is_ptr, uint64_t addr, uint64_t data, uint32_t count, uint32_t size) "I/O=%p write type=%d df=%d ptr=%d port=0x%"PRIx64" data=0x%"PRIx64" count=%d size=%d"
1098+cpu_ioreq_pio(void *req, uint32_t dir, uint32_t df, uint32_t data_is_ptr, uint64_t addr, uint64_t data, uint32_t count, uint32_t size) "I/O=%p pio dir=%d df=%d ptr=%d port=0x%"PRIx64" data=0x%"PRIx64" count=%d size=%d"
1099+cpu_ioreq_pio_read_reg(void *req, uint64_t data, uint64_t addr, uint32_t size) "I/O=%p pio read reg data=0x%"PRIx64" port=0x%"PRIx64" size=%d"
1100+cpu_ioreq_pio_write_reg(void *req, uint64_t data, uint64_t addr, uint32_t size) "I/O=%p pio write reg data=0x%"PRIx64" port=0x%"PRIx64" size=%d"
1101+cpu_ioreq_move(void *req, uint32_t dir, uint32_t df, uint32_t data_is_ptr, uint64_t addr, uint64_t data, uint32_t count, uint32_t size) "I/O=%p copy dir=%d df=%d ptr=%d port=0x%"PRIx64" data=0x%"PRIx64" count=%d size=%d"
1102+xen_map_resource_ioreq(uint32_t id, void *addr) "id: %u addr: %p"
1103+cpu_ioreq_config_read(void *req, uint32_t sbdf, uint32_t reg, uint32_t size, uint32_t data) "I/O=%p sbdf=0x%x reg=%u size=%u data=0x%x"
1104+cpu_ioreq_config_write(void *req, uint32_t sbdf, uint32_t reg, uint32_t size, uint32_t data) "I/O=%p sbdf=0x%x reg=%u size=%u data=0x%x"
1105+
1106 # xen-mapcache.c
1107 xen_map_cache(uint64_t phys_addr) "want 0x%"PRIx64
1108 xen_remap_bucket(uint64_t index) "index 0x%"PRIx64
1109diff --git a/hw/xen/xen-hvm-common.c b/hw/xen/xen-hvm-common.c
1110new file mode 100644
1111index 0000000000..67f76f6010
1112--- /dev/null
1113+++ b/hw/xen/xen-hvm-common.c
1114@@ -0,0 +1,861 @@
1115+#include "qemu/osdep.h"
1116+#include "qemu/units.h"
1117+#include "qapi/error.h"
1118+#include "trace.h"
1119+
1120+#include "hw/pci/pci_host.h"
1121+#include "hw/xen/xen-hvm-common.h"
1122+#include "hw/xen/xen-legacy-backend.h"
1123+#include "hw/xen/xen-bus.h"
1124+#include "hw/boards.h"
1125+#include "hw/xen/arch_hvm.h"
1126+
1127+MemoryRegion ram_memory;
1128+
1129+MemoryListener xen_io_listener = {
1130+ .name = "xen-io",
1131+ .region_add = xen_io_add,
1132+ .region_del = xen_io_del,
1133+ .priority = 10,
1134+};
1135+
1136+DeviceListener xen_device_listener = {
1137+ .realize = xen_device_realize,
1138+ .unrealize = xen_device_unrealize,
1139+};
1140+
1141+static void xen_set_memory(struct MemoryListener *listener,
1142+ MemoryRegionSection *section,
1143+ bool add)
1144+{
1145+ XenIOState *state = container_of(listener, XenIOState, memory_listener);
1146+
1147+ if (section->mr == &ram_memory) {
1148+ return;
1149+ } else {
1150+ if (add) {
1151+ xen_map_memory_section(xen_domid, state->ioservid,
1152+ section);
1153+ } else {
1154+ xen_unmap_memory_section(xen_domid, state->ioservid,
1155+ section);
1156+ }
1157+ }
1158+ arch_xen_set_memory(state, section, add);
1159+}
1160+
1161+void xen_region_add(MemoryListener *listener,
1162+ MemoryRegionSection *section)
1163+{
1164+ memory_region_ref(section->mr);
1165+ xen_set_memory(listener, section, true);
1166+}
1167+
1168+void xen_region_del(MemoryListener *listener,
1169+ MemoryRegionSection *section)
1170+{
1171+ xen_set_memory(listener, section, false);
1172+ memory_region_unref(section->mr);
1173+}
1174+
1175+void xen_io_add(MemoryListener *listener,
1176+ MemoryRegionSection *section)
1177+{
1178+ XenIOState *state = container_of(listener, XenIOState, io_listener);
1179+ MemoryRegion *mr = section->mr;
1180+
1181+ if (mr->ops == &unassigned_io_ops) {
1182+ return;
1183+ }
1184+
1185+ memory_region_ref(mr);
1186+
1187+ xen_map_io_section(xen_domid, state->ioservid, section);
1188+}
1189+
1190+void xen_io_del(MemoryListener *listener,
1191+ MemoryRegionSection *section)
1192+{
1193+ XenIOState *state = container_of(listener, XenIOState, io_listener);
1194+ MemoryRegion *mr = section->mr;
1195+
1196+ if (mr->ops == &unassigned_io_ops) {
1197+ return;
1198+ }
1199+
1200+ xen_unmap_io_section(xen_domid, state->ioservid, section);
1201+
1202+ memory_region_unref(mr);
1203+}
1204+
1205+void xen_device_realize(DeviceListener *listener,
1206+ DeviceState *dev)
1207+{
1208+ XenIOState *state = container_of(listener, XenIOState, device_listener);
1209+
1210+ if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
1211+ PCIDevice *pci_dev = PCI_DEVICE(dev);
1212+ XenPciDevice *xendev = g_new(XenPciDevice, 1);
1213+
1214+ xendev->pci_dev = pci_dev;
1215+ xendev->sbdf = PCI_BUILD_BDF(pci_dev_bus_num(pci_dev),
1216+ pci_dev->devfn);
1217+ QLIST_INSERT_HEAD(&state->dev_list, xendev, entry);
1218+
1219+ xen_map_pcidev(xen_domid, state->ioservid, pci_dev);
1220+ }
1221+}
1222+
1223+void xen_device_unrealize(DeviceListener *listener,
1224+ DeviceState *dev)
1225+{
1226+ XenIOState *state = container_of(listener, XenIOState, device_listener);
1227+
1228+ if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
1229+ PCIDevice *pci_dev = PCI_DEVICE(dev);
1230+ XenPciDevice *xendev, *next;
1231+
1232+ xen_unmap_pcidev(xen_domid, state->ioservid, pci_dev);
1233+
1234+ QLIST_FOREACH_SAFE(xendev, &state->dev_list, entry, next) {
1235+ if (xendev->pci_dev == pci_dev) {
1236+ QLIST_REMOVE(xendev, entry);
1237+ g_free(xendev);
1238+ break;
1239+ }
1240+ }
1241+ }
1242+}
1243+
1244+/* get the ioreq packets from share mem */
1245+static ioreq_t *cpu_get_ioreq_from_shared_memory(XenIOState *state, int vcpu)
1246+{
1247+ ioreq_t *req = xen_vcpu_ioreq(state->shared_page, vcpu);
1248+
1249+ if (req->state != STATE_IOREQ_READY) {
1250+ DPRINTF("I/O request not ready: "
1251+ "%x, ptr: %x, port: %"PRIx64", "
1252+ "data: %"PRIx64", count: %u, size: %u\n",
1253+ req->state, req->data_is_ptr, req->addr,
1254+ req->data, req->count, req->size);
1255+ return NULL;
1256+ }
1257+
1258+ xen_rmb(); /* see IOREQ_READY /then/ read contents of ioreq */
1259+
1260+ req->state = STATE_IOREQ_INPROCESS;
1261+ return req;
1262+}
1263+
1264+/* use poll to get the port notification */
1265+/* ioreq_vec--out,the */
1266+/* retval--the number of ioreq packet */
1267+static ioreq_t *cpu_get_ioreq(XenIOState *state)
1268+{
1269+ MachineState *ms = MACHINE(qdev_get_machine());
1270+ unsigned int max_cpus = ms->smp.max_cpus;
1271+ int i;
1272+ evtchn_port_t port;
1273+
1274+ port = xenevtchn_pending(state->xce_handle);
1275+ if (port == state->bufioreq_local_port) {
1276+ timer_mod(state->buffered_io_timer,
1277+ BUFFER_IO_MAX_DELAY + qemu_clock_get_ms(QEMU_CLOCK_REALTIME));
1278+ return NULL;
1279+ }
1280+
1281+ if (port != -1) {
1282+ for (i = 0; i < max_cpus; i++) {
1283+ if (state->ioreq_local_port[i] == port) {
1284+ break;
1285+ }
1286+ }
1287+
1288+ if (i == max_cpus) {
1289+ hw_error("Fatal error while trying to get io event!\n");
1290+ }
1291+
1292+ /* unmask the wanted port again */
1293+ xenevtchn_unmask(state->xce_handle, port);
1294+
1295+ /* get the io packet from shared memory */
1296+ state->send_vcpu = i;
1297+ return cpu_get_ioreq_from_shared_memory(state, i);
1298+ }
1299+
1300+ /* read error or read nothing */
1301+ return NULL;
1302+}
1303+
1304+static uint32_t do_inp(uint32_t addr, unsigned long size)
1305+{
1306+ switch (size) {
1307+ case 1:
1308+ return cpu_inb(addr);
1309+ case 2:
1310+ return cpu_inw(addr);
1311+ case 4:
1312+ return cpu_inl(addr);
1313+ default:
1314+ hw_error("inp: bad size: %04x %lx", addr, size);
1315+ }
1316+}
1317+
1318+static void do_outp(uint32_t addr,
1319+ unsigned long size, uint32_t val)
1320+{
1321+ switch (size) {
1322+ case 1:
1323+ return cpu_outb(addr, val);
1324+ case 2:
1325+ return cpu_outw(addr, val);
1326+ case 4:
1327+ return cpu_outl(addr, val);
1328+ default:
1329+ hw_error("outp: bad size: %04x %lx", addr, size);
1330+ }
1331+}
1332+
1333+/*
1334+ * Helper functions which read/write an object from/to physical guest
1335+ * memory, as part of the implementation of an ioreq.
1336+ *
1337+ * Equivalent to
1338+ * cpu_physical_memory_rw(addr + (req->df ? -1 : +1) * req->size * i,
1339+ * val, req->size, 0/1)
1340+ * except without the integer overflow problems.
1341+ */
1342+static void rw_phys_req_item(hwaddr addr,
1343+ ioreq_t *req, uint32_t i, void *val, int rw)
1344+{
1345+ /* Do everything unsigned so overflow just results in a truncated result
1346+ * and accesses to undesired parts of guest memory, which is up
1347+ * to the guest */
1348+ hwaddr offset = (hwaddr)req->size * i;
1349+ if (req->df) {
1350+ addr -= offset;
1351+ } else {
1352+ addr += offset;
1353+ }
1354+ cpu_physical_memory_rw(addr, val, req->size, rw);
1355+}
1356+
1357+static inline void read_phys_req_item(hwaddr addr,
1358+ ioreq_t *req, uint32_t i, void *val)
1359+{
1360+ rw_phys_req_item(addr, req, i, val, 0);
1361+}
1362+static inline void write_phys_req_item(hwaddr addr,
1363+ ioreq_t *req, uint32_t i, void *val)
1364+{
1365+ rw_phys_req_item(addr, req, i, val, 1);
1366+}
1367+
1368+
1369+void cpu_ioreq_pio(ioreq_t *req)
1370+{
1371+ uint32_t i;
1372+
1373+ trace_cpu_ioreq_pio(req, req->dir, req->df, req->data_is_ptr, req->addr,
1374+ req->data, req->count, req->size);
1375+
1376+ if (req->size > sizeof(uint32_t)) {
1377+ hw_error("PIO: bad size (%u)", req->size);
1378+ }
1379+
1380+ if (req->dir == IOREQ_READ) {
1381+ if (!req->data_is_ptr) {
1382+ req->data = do_inp(req->addr, req->size);
1383+ trace_cpu_ioreq_pio_read_reg(req, req->data, req->addr,
1384+ req->size);
1385+ } else {
1386+ uint32_t tmp;
1387+
1388+ for (i = 0; i < req->count; i++) {
1389+ tmp = do_inp(req->addr, req->size);
1390+ write_phys_req_item(req->data, req, i, &tmp);
1391+ }
1392+ }
1393+ } else if (req->dir == IOREQ_WRITE) {
1394+ if (!req->data_is_ptr) {
1395+ trace_cpu_ioreq_pio_write_reg(req, req->data, req->addr,
1396+ req->size);
1397+ do_outp(req->addr, req->size, req->data);
1398+ } else {
1399+ for (i = 0; i < req->count; i++) {
1400+ uint32_t tmp = 0;
1401+
1402+ read_phys_req_item(req->data, req, i, &tmp);
1403+ do_outp(req->addr, req->size, tmp);
1404+ }
1405+ }
1406+ }
1407+}
1408+
1409+static void cpu_ioreq_move(ioreq_t *req)
1410+{
1411+ uint32_t i;
1412+
1413+ trace_cpu_ioreq_move(req, req->dir, req->df, req->data_is_ptr, req->addr,
1414+ req->data, req->count, req->size);
1415+
1416+ if (req->size > sizeof(req->data)) {
1417+ hw_error("MMIO: bad size (%u)", req->size);
1418+ }
1419+
1420+ if (!req->data_is_ptr) {
1421+ if (req->dir == IOREQ_READ) {
1422+ for (i = 0; i < req->count; i++) {
1423+ read_phys_req_item(req->addr, req, i, &req->data);
1424+ }
1425+ } else if (req->dir == IOREQ_WRITE) {
1426+ for (i = 0; i < req->count; i++) {
1427+ write_phys_req_item(req->addr, req, i, &req->data);
1428+ }
1429+ }
1430+ } else {
1431+ uint64_t tmp;
1432+
1433+ if (req->dir == IOREQ_READ) {
1434+ for (i = 0; i < req->count; i++) {
1435+ read_phys_req_item(req->addr, req, i, &tmp);
1436+ write_phys_req_item(req->data, req, i, &tmp);
1437+ }
1438+ } else if (req->dir == IOREQ_WRITE) {
1439+ for (i = 0; i < req->count; i++) {
1440+ read_phys_req_item(req->data, req, i, &tmp);
1441+ write_phys_req_item(req->addr, req, i, &tmp);
1442+ }
1443+ }
1444+ }
1445+}
1446+
1447+static void cpu_ioreq_config(XenIOState *state, ioreq_t *req)
1448+{
1449+ uint32_t sbdf = req->addr >> 32;
1450+ uint32_t reg = req->addr;
1451+ XenPciDevice *xendev;
1452+
1453+ if (req->size != sizeof(uint8_t) && req->size != sizeof(uint16_t) &&
1454+ req->size != sizeof(uint32_t)) {
1455+ hw_error("PCI config access: bad size (%u)", req->size);
1456+ }
1457+
1458+ if (req->count != 1) {
1459+ hw_error("PCI config access: bad count (%u)", req->count);
1460+ }
1461+
1462+ QLIST_FOREACH(xendev, &state->dev_list, entry) {
1463+ if (xendev->sbdf != sbdf) {
1464+ continue;
1465+ }
1466+
1467+ if (!req->data_is_ptr) {
1468+ if (req->dir == IOREQ_READ) {
1469+ req->data = pci_host_config_read_common(
1470+ xendev->pci_dev, reg, PCI_CONFIG_SPACE_SIZE,
1471+ req->size);
1472+ trace_cpu_ioreq_config_read(req, xendev->sbdf, reg,
1473+ req->size, req->data);
1474+ } else if (req->dir == IOREQ_WRITE) {
1475+ trace_cpu_ioreq_config_write(req, xendev->sbdf, reg,
1476+ req->size, req->data);
1477+ pci_host_config_write_common(
1478+ xendev->pci_dev, reg, PCI_CONFIG_SPACE_SIZE,
1479+ req->data, req->size);
1480+ }
1481+ } else {
1482+ uint32_t tmp;
1483+
1484+ if (req->dir == IOREQ_READ) {
1485+ tmp = pci_host_config_read_common(
1486+ xendev->pci_dev, reg, PCI_CONFIG_SPACE_SIZE,
1487+ req->size);
1488+ trace_cpu_ioreq_config_read(req, xendev->sbdf, reg,
1489+ req->size, tmp);
1490+ write_phys_req_item(req->data, req, 0, &tmp);
1491+ } else if (req->dir == IOREQ_WRITE) {
1492+ read_phys_req_item(req->data, req, 0, &tmp);
1493+ trace_cpu_ioreq_config_write(req, xendev->sbdf, reg,
1494+ req->size, tmp);
1495+ pci_host_config_write_common(
1496+ xendev->pci_dev, reg, PCI_CONFIG_SPACE_SIZE,
1497+ tmp, req->size);
1498+ }
1499+ }
1500+ }
1501+}
1502+
1503+static void handle_ioreq(XenIOState *state, ioreq_t *req)
1504+{
1505+ trace_handle_ioreq(req, req->type, req->dir, req->df, req->data_is_ptr,
1506+ req->addr, req->data, req->count, req->size);
1507+
1508+ if (!req->data_is_ptr && (req->dir == IOREQ_WRITE) &&
1509+ (req->size < sizeof (target_ulong))) {
1510+ req->data &= ((target_ulong) 1 << (8 * req->size)) - 1;
1511+ }
1512+
1513+ if (req->dir == IOREQ_WRITE)
1514+ trace_handle_ioreq_write(req, req->type, req->df, req->data_is_ptr,
1515+ req->addr, req->data, req->count, req->size);
1516+
1517+ switch (req->type) {
1518+ case IOREQ_TYPE_PIO:
1519+ cpu_ioreq_pio(req);
1520+ break;
1521+ case IOREQ_TYPE_COPY:
1522+ cpu_ioreq_move(req);
1523+ break;
1524+ case IOREQ_TYPE_TIMEOFFSET:
1525+ break;
1526+ case IOREQ_TYPE_INVALIDATE:
1527+ xen_invalidate_map_cache();
1528+ break;
1529+ case IOREQ_TYPE_PCI_CONFIG:
1530+ cpu_ioreq_config(state, req);
1531+ break;
1532+ default:
1533+ arch_handle_ioreq(state, req);
1534+ }
1535+ if (req->dir == IOREQ_READ) {
1536+ trace_handle_ioreq_read(req, req->type, req->df, req->data_is_ptr,
1537+ req->addr, req->data, req->count, req->size);
1538+ }
1539+}
1540+
1541+static bool handle_buffered_iopage(XenIOState *state)
1542+{
1543+ buffered_iopage_t *buf_page = state->buffered_io_page;
1544+ buf_ioreq_t *buf_req = NULL;
1545+ bool handled_ioreq = false;
1546+ ioreq_t req;
1547+ int qw;
1548+
1549+ if (!buf_page) {
1550+ return 0;
1551+ }
1552+
1553+ memset(&req, 0x00, sizeof(req));
1554+ req.state = STATE_IOREQ_READY;
1555+ req.count = 1;
1556+ req.dir = IOREQ_WRITE;
1557+
1558+ for (;;) {
1559+ uint32_t rdptr = buf_page->read_pointer, wrptr;
1560+
1561+ xen_rmb();
1562+ wrptr = buf_page->write_pointer;
1563+ xen_rmb();
1564+ if (rdptr != buf_page->read_pointer) {
1565+ continue;
1566+ }
1567+ if (rdptr == wrptr) {
1568+ break;
1569+ }
1570+ buf_req = &buf_page->buf_ioreq[rdptr % IOREQ_BUFFER_SLOT_NUM];
1571+ req.size = 1U << buf_req->size;
1572+ req.addr = buf_req->addr;
1573+ req.data = buf_req->data;
1574+ req.type = buf_req->type;
1575+ xen_rmb();
1576+ qw = (req.size == 8);
1577+ if (qw) {
1578+ if (rdptr + 1 == wrptr) {
1579+ hw_error("Incomplete quad word buffered ioreq");
1580+ }
1581+ buf_req = &buf_page->buf_ioreq[(rdptr + 1) %
1582+ IOREQ_BUFFER_SLOT_NUM];
1583+ req.data |= ((uint64_t)buf_req->data) << 32;
1584+ xen_rmb();
1585+ }
1586+
1587+ handle_ioreq(state, &req);
1588+
1589+ /* Only req.data may get updated by handle_ioreq(), albeit even that
1590+ * should not happen as such data would never make it to the guest (we
1591+ * can only usefully see writes here after all).
1592+ */
1593+ assert(req.state == STATE_IOREQ_READY);
1594+ assert(req.count == 1);
1595+ assert(req.dir == IOREQ_WRITE);
1596+ assert(!req.data_is_ptr);
1597+
1598+ qatomic_add(&buf_page->read_pointer, qw + 1);
1599+ }
1600+
1601+ return handled_ioreq;
1602+}
1603+
1604+static void handle_buffered_io(void *opaque)
1605+{
1606+ XenIOState *state = opaque;
1607+
1608+ if (handle_buffered_iopage(state)) {
1609+ timer_mod(state->buffered_io_timer,
1610+ BUFFER_IO_MAX_DELAY + qemu_clock_get_ms(QEMU_CLOCK_REALTIME));
1611+ } else {
1612+ timer_del(state->buffered_io_timer);
1613+ xenevtchn_unmask(state->xce_handle, state->bufioreq_local_port);
1614+ }
1615+}
1616+
1617+static void cpu_handle_ioreq(void *opaque)
1618+{
1619+ XenIOState *state = opaque;
1620+ ioreq_t *req = cpu_get_ioreq(state);
1621+
1622+ handle_buffered_iopage(state);
1623+ if (req) {
1624+ ioreq_t copy = *req;
1625+
1626+ xen_rmb();
1627+ handle_ioreq(state, &copy);
1628+ req->data = copy.data;
1629+
1630+ if (req->state != STATE_IOREQ_INPROCESS) {
1631+ fprintf(stderr, "Badness in I/O request ... not in service?!: "
1632+ "%x, ptr: %x, port: %"PRIx64", "
1633+ "data: %"PRIx64", count: %u, size: %u, type: %u\n",
1634+ req->state, req->data_is_ptr, req->addr,
1635+ req->data, req->count, req->size, req->type);
1636+ destroy_hvm_domain(false);
1637+ return;
1638+ }
1639+
1640+ xen_wmb(); /* Update ioreq contents /then/ update state. */
1641+
1642+ /*
1643+ * We do this before we send the response so that the tools
1644+ * have the opportunity to pick up on the reset before the
1645+ * guest resumes and does a hlt with interrupts disabled which
1646+ * causes Xen to powerdown the domain.
1647+ */
1648+ if (runstate_is_running()) {
1649+ ShutdownCause request;
1650+
1651+ if (qemu_shutdown_requested_get()) {
1652+ destroy_hvm_domain(false);
1653+ }
1654+ request = qemu_reset_requested_get();
1655+ if (request) {
1656+ qemu_system_reset(request);
1657+ destroy_hvm_domain(true);
1658+ }
1659+ }
1660+
1661+ req->state = STATE_IORESP_READY;
1662+ xenevtchn_notify(state->xce_handle,
1663+ state->ioreq_local_port[state->send_vcpu]);
1664+ }
1665+}
1666+
1667+static void xen_main_loop_prepare(XenIOState *state)
1668+{
1669+ int evtchn_fd = -1;
1670+
1671+ if (state->xce_handle != NULL) {
1672+ evtchn_fd = xenevtchn_fd(state->xce_handle);
1673+ }
1674+
1675+ state->buffered_io_timer = timer_new_ms(QEMU_CLOCK_REALTIME, handle_buffered_io,
1676+ state);
1677+
1678+ if (evtchn_fd != -1) {
1679+ CPUState *cpu_state;
1680+
1681+ DPRINTF("%s: Init cpu_by_vcpu_id\n", __func__);
1682+ CPU_FOREACH(cpu_state) {
1683+ DPRINTF("%s: cpu_by_vcpu_id[%d]=%p\n",
1684+ __func__, cpu_state->cpu_index, cpu_state);
1685+ state->cpu_by_vcpu_id[cpu_state->cpu_index] = cpu_state;
1686+ }
1687+ qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, state);
1688+ }
1689+}
1690+
1691+
1692+void xen_hvm_change_state_handler(void *opaque, bool running,
1693+ RunState rstate)
1694+{
1695+ XenIOState *state = opaque;
1696+
1697+ if (running) {
1698+ xen_main_loop_prepare(state);
1699+ }
1700+
1701+ xen_set_ioreq_server_state(xen_domid,
1702+ state->ioservid,
1703+ (rstate == RUN_STATE_RUNNING));
1704+}
1705+
1706+void xen_exit_notifier(Notifier *n, void *data)
1707+{
1708+ XenIOState *state = container_of(n, XenIOState, exit);
1709+
1710+ xen_destroy_ioreq_server(xen_domid, state->ioservid);
1711+ if (state->fres != NULL) {
1712+ xenforeignmemory_unmap_resource(xen_fmem, state->fres);
1713+ }
1714+
1715+ xenevtchn_close(state->xce_handle);
1716+ xs_daemon_close(state->xenstore);
1717+}
1718+
1719+static int xen_map_ioreq_server(XenIOState *state)
1720+{
1721+ void *addr = NULL;
1722+ xen_pfn_t ioreq_pfn;
1723+ xen_pfn_t bufioreq_pfn;
1724+ evtchn_port_t bufioreq_evtchn;
1725+ int rc;
1726+
1727+ /*
1728+ * Attempt to map using the resource API and fall back to normal
1729+ * foreign mapping if this is not supported.
1730+ */
1731+ QEMU_BUILD_BUG_ON(XENMEM_resource_ioreq_server_frame_bufioreq != 0);
1732+ QEMU_BUILD_BUG_ON(XENMEM_resource_ioreq_server_frame_ioreq(0) != 1);
1733+ state->fres = xenforeignmemory_map_resource(xen_fmem, xen_domid,
1734+ XENMEM_resource_ioreq_server,
1735+ state->ioservid, 0, 2,
1736+ &addr,
1737+ PROT_READ | PROT_WRITE, 0);
1738+ if (state->fres != NULL) {
1739+ trace_xen_map_resource_ioreq(state->ioservid, addr);
1740+ state->buffered_io_page = addr;
1741+ state->shared_page = addr + TARGET_PAGE_SIZE;
1742+ } else if (errno != EOPNOTSUPP) {
1743+ error_report("failed to map ioreq server resources: error %d handle=%p",
1744+ errno, xen_xc);
1745+ return -1;
1746+ }
1747+
1748+ rc = xen_get_ioreq_server_info(xen_domid, state->ioservid,
1749+ (state->shared_page == NULL) ?
1750+ &ioreq_pfn : NULL,
1751+ (state->buffered_io_page == NULL) ?
1752+ &bufioreq_pfn : NULL,
1753+ &bufioreq_evtchn);
1754+ if (rc < 0) {
1755+ error_report("failed to get ioreq server info: error %d handle=%p",
1756+ errno, xen_xc);
1757+ return rc;
1758+ }
1759+
1760+ if (state->shared_page == NULL) {
1761+ DPRINTF("shared page at pfn %lx\n", ioreq_pfn);
1762+
1763+ state->shared_page = xenforeignmemory_map(xen_fmem, xen_domid,
1764+ PROT_READ | PROT_WRITE,
1765+ 1, &ioreq_pfn, NULL);
1766+ if (state->shared_page == NULL) {
1767+ error_report("map shared IO page returned error %d handle=%p",
1768+ errno, xen_xc);
1769+ }
1770+ }
1771+
1772+ if (state->buffered_io_page == NULL) {
1773+ DPRINTF("buffered io page at pfn %lx\n", bufioreq_pfn);
1774+
1775+ state->buffered_io_page = xenforeignmemory_map(xen_fmem, xen_domid,
1776+ PROT_READ | PROT_WRITE,
1777+ 1, &bufioreq_pfn,
1778+ NULL);
1779+ if (state->buffered_io_page == NULL) {
1780+ error_report("map buffered IO page returned error %d", errno);
1781+ return -1;
1782+ }
1783+ }
1784+
1785+ if (state->shared_page == NULL || state->buffered_io_page == NULL) {
1786+ return -1;
1787+ }
1788+
1789+ DPRINTF("buffered io evtchn is %x\n", bufioreq_evtchn);
1790+
1791+ state->bufioreq_remote_port = bufioreq_evtchn;
1792+
1793+ return 0;
1794+}
1795+
1796+void xen_shutdown_fatal_error(const char *fmt, ...)
1797+{
1798+ va_list ap;
1799+
1800+ va_start(ap, fmt);
1801+ vfprintf(stderr, fmt, ap);
1802+ va_end(ap);
1803+ fprintf(stderr, "Will destroy the domain.\n");
1804+ /* destroy the domain */
1805+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_ERROR);
1806+}
1807+
1808+void destroy_hvm_domain(bool reboot)
1809+{
1810+ xc_interface *xc_handle;
1811+ int sts;
1812+ int rc;
1813+
1814+ unsigned int reason = reboot ? SHUTDOWN_reboot : SHUTDOWN_poweroff;
1815+
1816+ if (xen_dmod) {
1817+ rc = xendevicemodel_shutdown(xen_dmod, xen_domid, reason);
1818+ if (!rc) {
1819+ return;
1820+ }
1821+ if (errno != ENOTTY /* old Xen */) {
1822+ perror("xendevicemodel_shutdown failed");
1823+ }
1824+ /* well, try the old thing then */
1825+ }
1826+
1827+ xc_handle = xc_interface_open(0, 0, 0);
1828+ if (xc_handle == NULL) {
1829+ fprintf(stderr, "Cannot acquire xenctrl handle\n");
1830+ } else {
1831+ sts = xc_domain_shutdown(xc_handle, xen_domid, reason);
1832+ if (sts != 0) {
1833+ fprintf(stderr, "xc_domain_shutdown failed to issue %s, "
1834+ "sts %d, %s\n", reboot ? "reboot" : "poweroff",
1835+ sts, strerror(errno));
1836+ } else {
1837+ fprintf(stderr, "Issued domain %d %s\n", xen_domid,
1838+ reboot ? "reboot" : "poweroff");
1839+ }
1840+ xc_interface_close(xc_handle);
1841+ }
1842+}
1843+
1844+void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr,
1845+ Error **errp)
1846+{
1847+ unsigned long nr_pfn;
1848+ xen_pfn_t *pfn_list;
1849+ int i;
1850+
1851+ if (runstate_check(RUN_STATE_INMIGRATE)) {
1852+ /* RAM already populated in Xen */
1853+ fprintf(stderr, "%s: do not alloc "RAM_ADDR_FMT
1854+ " bytes of ram at "RAM_ADDR_FMT" when runstate is INMIGRATE\n",
1855+ __func__, size, ram_addr);
1856+ return;
1857+ }
1858+
1859+ if (mr == &ram_memory) {
1860+ return;
1861+ }
1862+
1863+ trace_xen_ram_alloc(ram_addr, size);
1864+
1865+ nr_pfn = size >> TARGET_PAGE_BITS;
1866+ pfn_list = g_malloc(sizeof (*pfn_list) * nr_pfn);
1867+
1868+ for (i = 0; i < nr_pfn; i++) {
1869+ pfn_list[i] = (ram_addr >> TARGET_PAGE_BITS) + i;
1870+ }
1871+
1872+ if (xc_domain_populate_physmap_exact(xen_xc, xen_domid, nr_pfn, 0, 0, pfn_list)) {
1873+ error_setg(errp, "xen: failed to populate ram at " RAM_ADDR_FMT,
1874+ ram_addr);
1875+ }
1876+
1877+ g_free(pfn_list);
1878+}
1879+
1880+void xen_register_ioreq(XenIOState *state, unsigned int max_cpus,
1881+ MemoryListener xen_memory_listener)
1882+{
1883+ int i, rc;
1884+
1885+ state->xce_handle = xenevtchn_open(NULL, 0);
1886+ if (state->xce_handle == NULL) {
1887+ perror("xen: event channel open");
1888+ goto err;
1889+ }
1890+
1891+ state->xenstore = xs_daemon_open();
1892+ if (state->xenstore == NULL) {
1893+ perror("xen: xenstore open");
1894+ goto err;
1895+ }
1896+
1897+ xen_create_ioreq_server(xen_domid, &state->ioservid);
1898+
1899+ state->exit.notify = xen_exit_notifier;
1900+ qemu_add_exit_notifier(&state->exit);
1901+
1902+ /*
1903+ * Register wake-up support in QMP query-current-machine API
1904+ */
1905+ qemu_register_wakeup_support();
1906+
1907+ rc = xen_map_ioreq_server(state);
1908+ if (rc < 0) {
1909+ goto err;
1910+ }
1911+
1912+ /* Note: cpus is empty at this point in init */
1913+ state->cpu_by_vcpu_id = g_new0(CPUState *, max_cpus);
1914+
1915+ rc = xen_set_ioreq_server_state(xen_domid, state->ioservid, true);
1916+ if (rc < 0) {
1917+ error_report("failed to enable ioreq server info: error %d handle=%p",
1918+ errno, xen_xc);
1919+ goto err;
1920+ }
1921+
1922+ state->ioreq_local_port = g_new0(evtchn_port_t, max_cpus);
1923+
1924+ /* FIXME: how about if we overflow the page here? */
1925+ for (i = 0; i < max_cpus; i++) {
1926+ rc = xenevtchn_bind_interdomain(state->xce_handle, xen_domid,
1927+ xen_vcpu_eport(state->shared_page, i));
1928+ if (rc == -1) {
1929+ error_report("shared evtchn %d bind error %d", i, errno);
1930+ goto err;
1931+ }
1932+ state->ioreq_local_port[i] = rc;
1933+ }
1934+
1935+ rc = xenevtchn_bind_interdomain(state->xce_handle, xen_domid,
1936+ state->bufioreq_remote_port);
1937+ if (rc == -1) {
1938+ error_report("buffered evtchn bind error %d", errno);
1939+ goto err;
1940+ }
1941+ state->bufioreq_local_port = rc;
1942+
1943+ /* Init RAM management */
1944+#ifdef XEN_COMPAT_PHYSMAP
1945+ xen_map_cache_init(xen_phys_offset_to_gaddr, state);
1946+#else
1947+ xen_map_cache_init(NULL, state);
1948+#endif
1949+
1950+ qemu_add_vm_change_state_handler(xen_hvm_change_state_handler, state);
1951+
1952+ state->memory_listener = xen_memory_listener;
1953+ memory_listener_register(&state->memory_listener, &address_space_memory);
1954+
1955+ state->io_listener = xen_io_listener;
1956+ memory_listener_register(&state->io_listener, &address_space_io);
1957+
1958+ state->device_listener = xen_device_listener;
1959+ QLIST_INIT(&state->dev_list);
1960+ device_listener_register(&state->device_listener);
1961+
1962+ xen_bus_init();
1963+
1964+ /* Initialize backend core & drivers */
1965+ if (xen_be_init() != 0) {
1966+ error_report("xen backend core setup failed");
1967+ goto err;
1968+ }
1969+ xen_be_register_common();
1970+
1971+ return;
1972+err:
1973+ error_report("xen hardware virtual machine initialisation failed");
1974+ exit(1);
1975+}
1976diff --git a/include/hw/i386/xen_arch_hvm.h b/include/hw/i386/xen_arch_hvm.h
1977index 1b2c71ba4f..1000f8f543 100644
1978--- a/include/hw/i386/xen_arch_hvm.h
1979+++ b/include/hw/i386/xen_arch_hvm.h
1980@@ -2,6 +2,7 @@
1981 #define HW_XEN_ARCH_I386_HVM_H
1982
1983 #include <xen/hvm/ioreq.h>
1984+#include "hw/xen/xen-hvm-common.h"
1985
1986 void arch_handle_ioreq(XenIOState *state, ioreq_t *req);
1987 void arch_xen_set_memory(XenIOState *state,
1988diff --git a/include/hw/xen/xen-hvm-common.h b/include/hw/xen/xen-hvm-common.h
1989new file mode 100644
1990index 0000000000..2979f84ee2
1991--- /dev/null
1992+++ b/include/hw/xen/xen-hvm-common.h
1993@@ -0,0 +1,98 @@
1994+#ifndef HW_XEN_HVM_COMMON_H
1995+#define HW_XEN_HVM_COMMON_H
1996+
1997+#include "qemu/osdep.h"
1998+#include "qemu/units.h"
1999+
2000+#include "cpu.h"
2001+#include "hw/pci/pci.h"
2002+#include "hw/hw.h"
2003+#include "hw/xen/xen_common.h"
2004+#include "sysemu/runstate.h"
2005+#include "sysemu/sysemu.h"
2006+#include "sysemu/xen.h"
2007+#include "sysemu/xen-mapcache.h"
2008+
2009+#include <xen/hvm/ioreq.h>
2010+
2011+extern MemoryRegion ram_memory;
2012+extern MemoryListener xen_io_listener;
2013+extern DeviceListener xen_device_listener;
2014+
2015+//#define DEBUG_XEN_HVM
2016+
2017+#ifdef DEBUG_XEN_HVM
2018+#define DPRINTF(fmt, ...) \
2019+ do { fprintf(stderr, "xen: " fmt, ## __VA_ARGS__); } while (0)
2020+#else
2021+#define DPRINTF(fmt, ...) \
2022+ do { } while (0)
2023+#endif
2024+
2025+static inline uint32_t xen_vcpu_eport(shared_iopage_t *shared_page, int i)
2026+{
2027+ return shared_page->vcpu_ioreq[i].vp_eport;
2028+}
2029+static inline ioreq_t *xen_vcpu_ioreq(shared_iopage_t *shared_page, int vcpu)
2030+{
2031+ return &shared_page->vcpu_ioreq[vcpu];
2032+}
2033+
2034+#define BUFFER_IO_MAX_DELAY 100
2035+
2036+typedef struct XenPhysmap {
2037+ hwaddr start_addr;
2038+ ram_addr_t size;
2039+ const char *name;
2040+ hwaddr phys_offset;
2041+
2042+ QLIST_ENTRY(XenPhysmap) list;
2043+} XenPhysmap;
2044+
2045+typedef struct XenPciDevice {
2046+ PCIDevice *pci_dev;
2047+ uint32_t sbdf;
2048+ QLIST_ENTRY(XenPciDevice) entry;
2049+} XenPciDevice;
2050+
2051+typedef struct XenIOState {
2052+ ioservid_t ioservid;
2053+ shared_iopage_t *shared_page;
2054+ buffered_iopage_t *buffered_io_page;
2055+ xenforeignmemory_resource_handle *fres;
2056+ QEMUTimer *buffered_io_timer;
2057+ CPUState **cpu_by_vcpu_id;
2058+ /* the evtchn port for polling the notification, */
2059+ evtchn_port_t *ioreq_local_port;
2060+ /* evtchn remote and local ports for buffered io */
2061+ evtchn_port_t bufioreq_remote_port;
2062+ evtchn_port_t bufioreq_local_port;
2063+ /* the evtchn fd for polling */
2064+ xenevtchn_handle *xce_handle;
2065+ /* which vcpu we are serving */
2066+ int send_vcpu;
2067+
2068+ struct xs_handle *xenstore;
2069+ MemoryListener memory_listener;
2070+ MemoryListener io_listener;
2071+ QLIST_HEAD(, XenPciDevice) dev_list;
2072+ DeviceListener device_listener;
2073+
2074+ Notifier exit;
2075+} XenIOState;
2076+
2077+void xen_exit_notifier(Notifier *n, void *data);
2078+
2079+void xen_region_add(MemoryListener *listener, MemoryRegionSection *section);
2080+void xen_region_del(MemoryListener *listener, MemoryRegionSection *section);
2081+void xen_io_add(MemoryListener *listener, MemoryRegionSection *section);
2082+void xen_io_del(MemoryListener *listener, MemoryRegionSection *section);
2083+void xen_device_realize(DeviceListener *listener, DeviceState *dev);
2084+void xen_device_unrealize(DeviceListener *listener, DeviceState *dev);
2085+
2086+void xen_hvm_change_state_handler(void *opaque, bool running, RunState rstate);
2087+void xen_register_ioreq(XenIOState *state, unsigned int max_cpus,
2088+ MemoryListener xen_memory_listener);
2089+
2090+void cpu_ioreq_pio(ioreq_t *req);
2091+#endif /* HW_XEN_HVM_COMMON_H */
2092--
20932.17.1
2094
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0007-xen-mapcache-Fix-build-on-Arm.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0007-xen-mapcache-Fix-build-on-Arm.patch
new file mode 100644
index 00000000..7ff202ff
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0007-xen-mapcache-Fix-build-on-Arm.patch
@@ -0,0 +1,37 @@
1From 2aca3ff63a5d5897cd32e0030569623f0c454f2c Mon Sep 17 00:00:00 2001
2From: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
3Date: Mon, 19 Sep 2022 21:59:55 +0300
4Subject: [PATCH 7/8] xen-mapcache: Fix build on Arm
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9../hw/xen/xen-mapcache.c: In function ‘xen_map_grant_dyn’:
10../hw/xen/xen-mapcache.c:668:9: error: ‘refs’ may be used uninitialized
11 in this function [-Werror=maybe-uninitialized]
12 668 | g_free(refs);
13 | ^~~~~~~~~~~~
14cc1: all warnings being treated as errors
15
16Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
17Acked-by: Stefano Stabellini <stefano.stabellini@amd.com>
18---
19 hw/xen/xen-mapcache.c | 2 +-
20 1 file changed, 1 insertion(+), 1 deletion(-)
21
22diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
23index f81b75d216..6544e331e0 100644
24--- a/hw/xen/xen-mapcache.c
25+++ b/hw/xen/xen-mapcache.c
26@@ -620,7 +620,7 @@ static void *xen_map_grant_dyn(MemoryRegion **mr, hwaddr addr, hwaddr *plen,
27 unsigned int i;
28 unsigned int nrefs = (page_off + *plen + XC_PAGE_SIZE - 1) >> XC_PAGE_SHIFT;
29 uint32_t ref = (addr - XEN_GRANT_ADDR_OFF) >> XC_PAGE_SHIFT;
30- uint32_t *refs;
31+ uint32_t *refs = NULL;
32 unsigned int prot = PROT_READ;
33 struct XENMappedGrantRegion *mgr = NULL;
34
35--
362.25.1
37
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0007-xen-skip-ioreq-creation-on-ioreq-registration-failur.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0007-xen-skip-ioreq-creation-on-ioreq-registration-failur.patch
new file mode 100644
index 00000000..83a18c08
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0007-xen-skip-ioreq-creation-on-ioreq-registration-failur.patch
@@ -0,0 +1,42 @@
1From fa475ec44fc78ff246e6536c8b9d408abadbb4a4 Mon Sep 17 00:00:00 2001
2From: Stefano Stabellini <stefano.stabellini@amd.com>
3Date: Fri, 1 Jul 2022 18:50:59 -0700
4Subject: [PATCH 07/16] xen: skip ioreq creation on ioreq registration failure
5
6On ARM it is possible to have a functioning xenpv machine with only the
7PV backends and no IOREQ server. If the IOREQ server creation fails
8continue to the PV backends initialization.
9
10Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
11---
12 hw/xen/xen-hvm-common.c | 7 ++++++-
13 1 file changed, 6 insertions(+), 1 deletion(-)
14
15diff --git a/hw/xen/xen-hvm-common.c b/hw/xen/xen-hvm-common.c
16index 67f76f6010..7e7d23397f 100644
17--- a/hw/xen/xen-hvm-common.c
18+++ b/hw/xen/xen-hvm-common.c
19@@ -780,7 +780,11 @@ void xen_register_ioreq(XenIOState *state, unsigned int max_cpus,
20 goto err;
21 }
22
23- xen_create_ioreq_server(xen_domid, &state->ioservid);
24+ rc = xen_create_ioreq_server(xen_domid, &state->ioservid);
25+ if (rc) {
26+ DPRINTF("xen: failed to create ioreq server\n");
27+ goto no_ioreq;
28+ }
29
30 state->exit.notify = xen_exit_notifier;
31 qemu_add_exit_notifier(&state->exit);
32@@ -845,6 +849,7 @@ void xen_register_ioreq(XenIOState *state, unsigned int max_cpus,
33 QLIST_INIT(&state->dev_list);
34 device_listener_register(&state->device_listener);
35
36+no_ioreq:
37 xen_bus_init();
38
39 /* Initialize backend core & drivers */
40--
412.17.1
42
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0008-accel-xen-xen-all-export-xenstore_record_dm_state.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0008-accel-xen-xen-all-export-xenstore_record_dm_state.patch
new file mode 100644
index 00000000..881076fb
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0008-accel-xen-xen-all-export-xenstore_record_dm_state.patch
@@ -0,0 +1,48 @@
1From 13443fe86bb100849c55b41873f48e0b121c7bc0 Mon Sep 17 00:00:00 2001
2From: Vikram Garhwal <vikram.garhwal@amd.com>
3Date: Fri, 1 Jul 2022 17:28:14 -0700
4Subject: [PATCH 08/16] accel/xen/xen-all: export xenstore_record_dm_state
5
6Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com>
7Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
8Reviewed-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
9---
10 accel/xen/xen-all.c | 2 +-
11 include/hw/xen/xen.h | 2 ++
12 2 files changed, 3 insertions(+), 1 deletion(-)
13
14diff --git a/accel/xen/xen-all.c b/accel/xen/xen-all.c
15index 69aa7d018b..276625b78b 100644
16--- a/accel/xen/xen-all.c
17+++ b/accel/xen/xen-all.c
18@@ -100,7 +100,7 @@ void xenstore_store_pv_console_info(int i, Chardev *chr)
19 }
20
21
22-static void xenstore_record_dm_state(struct xs_handle *xs, const char *state)
23+void xenstore_record_dm_state(struct xs_handle *xs, const char *state)
24 {
25 char path[50];
26
27diff --git a/include/hw/xen/xen.h b/include/hw/xen/xen.h
28index afdf9c436a..31e9538a5c 100644
29--- a/include/hw/xen/xen.h
30+++ b/include/hw/xen/xen.h
31@@ -9,6 +9,7 @@
32 */
33
34 #include "exec/cpu-common.h"
35+#include <xenstore.h>
36
37 /* xen-machine.c */
38 enum xen_mode {
39@@ -31,5 +32,6 @@ qemu_irq *xen_interrupt_controller_init(void);
40 void xenstore_store_pv_console_info(int i, Chardev *chr);
41
42 void xen_register_framebuffer(struct MemoryRegion *mr);
43+void xenstore_record_dm_state(struct xs_handle *xs, const char *state);
44
45 #endif /* QEMU_HW_XEN_H */
46--
472.17.1
48
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0008-hw-arm-Add-grant-mapping.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0008-hw-arm-Add-grant-mapping.patch
new file mode 100644
index 00000000..3b83d229
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0008-hw-arm-Add-grant-mapping.patch
@@ -0,0 +1,39 @@
1From b5e5f60de37bb6f71bc34ecb989c31ef5c834272 Mon Sep 17 00:00:00 2001
2From: Vikram Garhwal <vikram.garhwal@amd.com>
3Date: Tue, 31 Jan 2023 21:46:43 +0000
4Subject: [PATCH 8/8] hw: arm: Add grant mapping.
5
6Add support for grant mapping and change qemu machine name to xenpvh.
7
8Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com>
9Acked-by: Stefano Stabellini <stefano.stabellini@amd.com>
10---
11 hw/arm/xen_arm.c | 5 ++++-
12 1 file changed, 4 insertions(+), 1 deletion(-)
13
14diff --git a/hw/arm/xen_arm.c b/hw/arm/xen_arm.c
15index 4ac425a3c5..392bed7367 100644
16--- a/hw/arm/xen_arm.c
17+++ b/hw/arm/xen_arm.c
18@@ -35,7 +35,7 @@
19 #include "sysemu/tpm.h"
20 #include "hw/xen/arch_hvm.h"
21
22-#define TYPE_XEN_ARM MACHINE_TYPE_NAME("xenpv")
23+#define TYPE_XEN_ARM MACHINE_TYPE_NAME("xenpvh")
24 OBJECT_DECLARE_SIMPLE_TYPE(XenArmState, XEN_ARM)
25
26 static MemoryListener xen_memory_listener = {
27@@ -115,6 +115,9 @@ static void xen_init_ram(MachineState *machine)
28 DPRINTF("Initialized region xen.ram.hi: base 0x%llx size 0x%lx\n",
29 GUEST_RAM1_BASE, ram_size[1]);
30 }
31+
32+ DPRINTF("init grant ram mapping for XEN\n");
33+ ram_grants = *xen_init_grant_ram();
34 }
35
36 void arch_handle_ioreq(XenIOState *state, ioreq_t *req)
37--
382.25.1
39
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0009-xen-hvm-enable-xen-hvm-common-build-for-ARM.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0009-xen-hvm-enable-xen-hvm-common-build-for-ARM.patch
new file mode 100644
index 00000000..1b1aea76
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0009-xen-hvm-enable-xen-hvm-common-build-for-ARM.patch
@@ -0,0 +1,43 @@
1From 2e6a9f464fd1f247c41ce3666ff3e3f66920d0b7 Mon Sep 17 00:00:00 2001
2From: Vikram Garhwal <vikram.garhwal@amd.com>
3Date: Fri, 1 Jul 2022 17:28:15 -0700
4Subject: [PATCH 09/16] xen-hvm: enable xen-hvm-common build for ARM
5
6Add CONFIG_XEN for aarch64 device and change xen-hvm-common.c to
7support build for ARM targets.
8
9Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com>
10Acked-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
11Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
12---
13 hw/arm/meson.build | 1 +
14 meson.build | 2 +-
15 2 files changed, 2 insertions(+), 1 deletion(-)
16
17diff --git a/hw/arm/meson.build b/hw/arm/meson.build
18index 92f9f6e000..3aac913bfd 100644
19--- a/hw/arm/meson.build
20+++ b/hw/arm/meson.build
21@@ -62,5 +62,6 @@ arm_ss.add(when: 'CONFIG_FSL_IMX7', if_true: files('fsl-imx7.c', 'mcimx7d-sabre.
22 arm_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmu-common.c', 'smmuv3.c'))
23 arm_ss.add(when: 'CONFIG_FSL_IMX6UL', if_true: files('fsl-imx6ul.c', 'mcimx6ul-evk.c'))
24 arm_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_soc.c'))
25+arm_ss.add_all(xen_ss)
26
27 hw_arch += {'arm': arm_ss}
28diff --git a/meson.build b/meson.build
29index 5c6b5a1c75..b94f0cd76e 100644
30--- a/meson.build
31+++ b/meson.build
32@@ -125,7 +125,7 @@ endif
33 if cpu in ['x86', 'x86_64', 'arm', 'aarch64']
34 # i386 emulator provides xenpv machine type for multiple architectures
35 accelerator_targets += {
36- 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
37+ 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu', 'aarch64-softmmu'],
38 }
39 endif
40 if cpu in ['x86', 'x86_64']
41--
422.17.1
43
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0010-hw-arm-introduce-xenpv-machine.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0010-hw-arm-introduce-xenpv-machine.patch
new file mode 100644
index 00000000..fc979b52
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0010-hw-arm-introduce-xenpv-machine.patch
@@ -0,0 +1,230 @@
1From 5618a18b1f12d567a8ef85240d55b841e18ef472 Mon Sep 17 00:00:00 2001
2From: Vikram Garhwal <vikram.garhwal@amd.com>
3Date: Fri, 1 Jul 2022 17:28:16 -0700
4Subject: [PATCH 10/16] hw/arm: introduce xenpv machine
5
6Create a new machine xenpv which creates a IOREQ server to connect
7with Xen. It also creates a tpm-tis-device which connects to swtpm to
8support TPM functionalities.
9
10Xen IOREQ connection expect the TARGET_PAGE_SIZE to 4096, and the xenpv
11machine on ARM will have no CPU definitions. We need to define
12TARGET_PAGE_SIZE appropriately ourselves.
13
14Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com>
15Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
16Reviewed-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
17---
18 hw/arm/meson.build | 1 +
19 hw/arm/xen_arm.c | 156 ++++++++++++++++++++++++++++++++++
20 include/hw/arm/xen_arch_hvm.h | 12 +++
21 include/hw/xen/arch_hvm.h | 2 +
22 4 files changed, 171 insertions(+)
23 create mode 100644 hw/arm/xen_arm.c
24 create mode 100644 include/hw/arm/xen_arch_hvm.h
25
26diff --git a/hw/arm/meson.build b/hw/arm/meson.build
27index 3aac913bfd..0cae024374 100644
28--- a/hw/arm/meson.build
29+++ b/hw/arm/meson.build
30@@ -62,6 +62,7 @@ arm_ss.add(when: 'CONFIG_FSL_IMX7', if_true: files('fsl-imx7.c', 'mcimx7d-sabre.
31 arm_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmu-common.c', 'smmuv3.c'))
32 arm_ss.add(when: 'CONFIG_FSL_IMX6UL', if_true: files('fsl-imx6ul.c', 'mcimx6ul-evk.c'))
33 arm_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_soc.c'))
34+arm_ss.add(when: 'CONFIG_XEN', if_true: files('xen_arm.c'))
35 arm_ss.add_all(xen_ss)
36
37 hw_arch += {'arm': arm_ss}
38diff --git a/hw/arm/xen_arm.c b/hw/arm/xen_arm.c
39new file mode 100644
40index 0000000000..0922e3db84
41--- /dev/null
42+++ b/hw/arm/xen_arm.c
43@@ -0,0 +1,156 @@
44+/*
45+ * QEMU ARM Xen PV Machine
46+ *
47+ *
48+ * Permission is hereby granted, free of charge, to any person obtaining a copy
49+ * of this software and associated documentation files (the "Software"), to deal
50+ * in the Software without restriction, including without limitation the rights
51+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
52+ * copies of the Software, and to permit persons to whom the Software is
53+ * furnished to do so, subject to the following conditions:
54+ *
55+ * The above copyright notice and this permission notice shall be included in
56+ * all copies or substantial portions of the Software.
57+ *
58+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
59+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
60+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
61+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
62+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
63+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
64+ * THE SOFTWARE.
65+ */
66+
67+#include "qemu/osdep.h"
68+#include "qemu/error-report.h"
69+#include "qapi/qapi-commands-migration.h"
70+#include "hw/boards.h"
71+#include "hw/sysbus.h"
72+#include "sysemu/block-backend.h"
73+#include "sysemu/tpm_backend.h"
74+#include "sysemu/sysemu.h"
75+#include "hw/xen/xen-legacy-backend.h"
76+#include "hw/xen/xen-hvm-common.h"
77+#include "sysemu/tpm.h"
78+#include "hw/xen/arch_hvm.h"
79+
80+#define TYPE_XEN_ARM MACHINE_TYPE_NAME("xenpv")
81+OBJECT_DECLARE_SIMPLE_TYPE(XenArmState, XEN_ARM)
82+
83+static MemoryListener xen_memory_listener = {
84+ .region_add = xen_region_add,
85+ .region_del = xen_region_del,
86+ .log_start = NULL,
87+ .log_stop = NULL,
88+ .log_sync = NULL,
89+ .log_global_start = NULL,
90+ .log_global_stop = NULL,
91+ .priority = 10,
92+};
93+
94+struct XenArmState {
95+ /*< private >*/
96+ MachineState parent;
97+
98+ XenIOState *state;
99+};
100+
101+void arch_handle_ioreq(XenIOState *state, ioreq_t *req)
102+{
103+ hw_error("Invalid ioreq type 0x%x\n", req->type);
104+
105+ return;
106+}
107+
108+void arch_xen_set_memory(XenIOState *state,MemoryRegionSection *section,
109+ bool add)
110+{
111+}
112+
113+void xen_hvm_modified_memory(ram_addr_t start, ram_addr_t length)
114+{
115+}
116+
117+void qmp_xen_set_global_dirty_log(bool enable, Error **errp)
118+{
119+}
120+
121+static int xen_init_ioreq(XenIOState *state, unsigned int max_cpus)
122+{
123+ xen_dmod = xendevicemodel_open(0, 0);
124+ xen_xc = xc_interface_open(0, 0, 0);
125+
126+ if (xen_xc == NULL) {
127+ perror("xen: can't open xen interface\n");
128+ return -1;
129+ }
130+
131+ xen_fmem = xenforeignmemory_open(0, 0);
132+ if (xen_fmem == NULL) {
133+ perror("xen: can't open xen fmem interface\n");
134+ xc_interface_close(xen_xc);
135+ return -1;
136+ }
137+
138+ xen_register_ioreq(state, max_cpus, xen_memory_listener);
139+
140+ xenstore_record_dm_state(xenstore, "running");
141+
142+ return 0;
143+}
144+
145+
146+static void xen_arm_init(MachineState *machine)
147+{
148+ DeviceState *dev;
149+ SysBusDevice *busdev;
150+ Error *errp = NULL;
151+ XenArmState *xam = XEN_ARM(machine);
152+
153+ xam->state = g_new0(XenIOState, 1);
154+
155+ if (xen_init_ioreq(xam->state, machine->smp.cpus)) {
156+ return;
157+ }
158+
159+ TPMBackend *be = qemu_find_tpm_be("tpm0");
160+ if (be == NULL) {
161+ DPRINTF("Couldn't fine the backend for tpm0\n");
162+ return;
163+ }
164+
165+ dev = qdev_new(TYPE_TPM_TIS_SYSBUS);
166+ object_property_set_link(OBJECT(dev), "tpmdev", OBJECT(be), &errp);
167+ object_property_set_str(OBJECT(dev), "tpmdev", be->id, &errp);
168+ busdev = SYS_BUS_DEVICE(dev);
169+ sysbus_realize_and_unref(busdev, &error_fatal);
170+ sysbus_mmio_map(busdev, 0, GUEST_TPM_BASE);
171+
172+ DPRINTF("Connected tpmdev at address 0x%lx\n", GUEST_TPM_BASE);
173+
174+ return;
175+}
176+
177+static void xen_arm_machine_class_init(ObjectClass *oc, void *data)
178+{
179+
180+ MachineClass *mc = MACHINE_CLASS(oc);
181+ mc->desc = "Xen Para-virtualized PC";
182+ mc->init = xen_arm_init;
183+ mc->max_cpus = 1;
184+ machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS);
185+}
186+
187+static const TypeInfo xen_arm_machine_type = {
188+ .name = TYPE_XEN_ARM,
189+ .parent = TYPE_MACHINE,
190+ .class_init = xen_arm_machine_class_init,
191+ .instance_size = sizeof(XenArmState),
192+};
193+
194+static void xen_arm_machine_register_types(void)
195+{
196+ type_register_static(&xen_arm_machine_type);
197+}
198+
199+type_init(xen_arm_machine_register_types)
200diff --git a/include/hw/arm/xen_arch_hvm.h b/include/hw/arm/xen_arch_hvm.h
201new file mode 100644
202index 0000000000..f645dfec28
203--- /dev/null
204+++ b/include/hw/arm/xen_arch_hvm.h
205@@ -0,0 +1,12 @@
206+#ifndef HW_XEN_ARCH_ARM_HVM_H
207+#define HW_XEN_ARCH_ARM_HVM_H
208+
209+#include <xen/hvm/ioreq.h>
210+void arch_handle_ioreq(XenIOState *state, ioreq_t *req);
211+void arch_xen_set_memory(XenIOState *state,
212+ MemoryRegionSection *section,
213+ bool add);
214+
215+#undef TARGET_PAGE_SIZE
216+#define TARGET_PAGE_SIZE 4096
217+#endif
218diff --git a/include/hw/xen/arch_hvm.h b/include/hw/xen/arch_hvm.h
219index 26674648d8..c7c515220d 100644
220--- a/include/hw/xen/arch_hvm.h
221+++ b/include/hw/xen/arch_hvm.h
222@@ -1,3 +1,5 @@
223 #if defined(TARGET_I386) || defined(TARGET_X86_64)
224 #include "hw/i386/xen_arch_hvm.h"
225+#elif defined(TARGET_ARM) || defined(TARGET_ARM_64)
226+#include "hw/arm/xen_arch_hvm.h"
227 #endif
228--
2292.17.1
230
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0011-meson.build-do-not-set-have_xen_pci_passthrough-for-.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0011-meson.build-do-not-set-have_xen_pci_passthrough-for-.patch
new file mode 100644
index 00000000..dad3029f
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0011-meson.build-do-not-set-have_xen_pci_passthrough-for-.patch
@@ -0,0 +1,33 @@
1From f4ff3490639dea08fb70ec69d60fe73ef479073b Mon Sep 17 00:00:00 2001
2From: Stefano Stabellini <stefano.stabellini@amd.com>
3Date: Thu, 7 Jul 2022 14:03:41 -0700
4Subject: [PATCH 11/16] meson.build: do not set have_xen_pci_passthrough for
5 aarch64 targets
6MIME-Version: 1.0
7Content-Type: text/plain; charset=UTF-8
8Content-Transfer-Encoding: 8bit
9
10have_xen_pci_passthrough is only used for Xen x86 VMs.
11
12Signed-off-by: Stefano Stabellini <stefano.stabellini@amd.com>
13Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
14---
15 meson.build | 2 ++
16 1 file changed, 2 insertions(+)
17
18diff --git a/meson.build b/meson.build
19index b94f0cd76e..a4965251ab 100644
20--- a/meson.build
21+++ b/meson.build
22@@ -1469,6 +1469,8 @@ have_xen_pci_passthrough = get_option('xen_pci_passthrough') \
23 error_message: 'Xen PCI passthrough requested but Xen not enabled') \
24 .require(targetos == 'linux',
25 error_message: 'Xen PCI passthrough not available on this platform') \
26+ .require(cpu == 'x86' or cpu == 'x86_64',
27+ error_message: 'Xen PCI passthrough not available on this platform') \
28 .allowed()
29
30
31--
322.17.1
33
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0012-xen-arm-call-qemu_find_tpm_be-if-CONFIG_TPM.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0012-xen-arm-call-qemu_find_tpm_be-if-CONFIG_TPM.patch
new file mode 100644
index 00000000..f80a0873
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0012-xen-arm-call-qemu_find_tpm_be-if-CONFIG_TPM.patch
@@ -0,0 +1,72 @@
1From a26982a55fa5f47116b344ca5d411f00c3a2b422 Mon Sep 17 00:00:00 2001
2From: Stefano Stabellini <stefano.stabellini@amd.com>
3Date: Thu, 7 Jul 2022 14:35:33 -0700
4Subject: [PATCH 12/16] xen-arm: call qemu_find_tpm_be if CONFIG_TPM
5
6qemu_find_tpm_be is only availablen when CONFIG_TPM is enabled.
7So #ifdef the call to make sure the code builds correctly even when
8CONFIG_TPM is not enabled.
9
10Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
11---
12 hw/arm/xen_arm.c | 28 +++++++++++++++++-----------
13 1 file changed, 17 insertions(+), 11 deletions(-)
14
15diff --git a/hw/arm/xen_arm.c b/hw/arm/xen_arm.c
16index 0922e3db84..f248b5744a 100644
17--- a/hw/arm/xen_arm.c
18+++ b/hw/arm/xen_arm.c
19@@ -99,26 +99,18 @@ static int xen_init_ioreq(XenIOState *state, unsigned int max_cpus)
20 return 0;
21 }
22
23-
24-static void xen_arm_init(MachineState *machine)
25+static void xen_enable_tpm(void)
26 {
27+#ifdef CONFIG_TPM
28+ Error *errp = NULL;
29 DeviceState *dev;
30 SysBusDevice *busdev;
31- Error *errp = NULL;
32- XenArmState *xam = XEN_ARM(machine);
33-
34- xam->state = g_new0(XenIOState, 1);
35-
36- if (xen_init_ioreq(xam->state, machine->smp.cpus)) {
37- return;
38- }
39
40 TPMBackend *be = qemu_find_tpm_be("tpm0");
41 if (be == NULL) {
42 DPRINTF("Couldn't fine the backend for tpm0\n");
43 return;
44 }
45-
46 dev = qdev_new(TYPE_TPM_TIS_SYSBUS);
47 object_property_set_link(OBJECT(dev), "tpmdev", OBJECT(be), &errp);
48 object_property_set_str(OBJECT(dev), "tpmdev", be->id, &errp);
49@@ -127,6 +119,20 @@ static void xen_arm_init(MachineState *machine)
50 sysbus_mmio_map(busdev, 0, GUEST_TPM_BASE);
51
52 DPRINTF("Connected tpmdev at address 0x%lx\n", GUEST_TPM_BASE);
53+#endif
54+}
55+
56+static void xen_arm_init(MachineState *machine)
57+{
58+ XenArmState *xam = XEN_ARM(machine);
59+
60+ xam->state = g_new0(XenIOState, 1);
61+
62+ if (xen_init_ioreq(xam->state, machine->smp.cpus)) {
63+ return;
64+ }
65+
66+ xen_enable_tpm();
67
68 return;
69 }
70--
712.17.1
72
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0013-arm-xenpv-fix-TPM-address-print-warning.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0013-arm-xenpv-fix-TPM-address-print-warning.patch
new file mode 100644
index 00000000..1aa09efb
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0013-arm-xenpv-fix-TPM-address-print-warning.patch
@@ -0,0 +1,27 @@
1From c5b128668d9cd1e1cb4da80d5bc8aaebc6ff2e19 Mon Sep 17 00:00:00 2001
2From: Vikram Garhwal <vikram.garhwal@amd.com>
3Date: Fri, 23 Dec 2022 00:06:29 +0000
4Subject: [PATCH 13/16] arm: xenpv: fix TPM address print warning
5
6Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com>
7Acked-by: Stefano Stabellini <stefano.stabellini@amd.com>
8---
9 hw/arm/xen_arm.c | 2 +-
10 1 file changed, 1 insertion(+), 1 deletion(-)
11
12diff --git a/hw/arm/xen_arm.c b/hw/arm/xen_arm.c
13index f248b5744a..153cedfeb4 100644
14--- a/hw/arm/xen_arm.c
15+++ b/hw/arm/xen_arm.c
16@@ -118,7 +118,7 @@ static void xen_enable_tpm(void)
17 sysbus_realize_and_unref(busdev, &error_fatal);
18 sysbus_mmio_map(busdev, 0, GUEST_TPM_BASE);
19
20- DPRINTF("Connected tpmdev at address 0x%lx\n", GUEST_TPM_BASE);
21+ DPRINTF("Connected tpmdev at address 0x%llx\n", GUEST_TPM_BASE);
22 #endif
23 }
24
25--
262.17.1
27
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0014-xen_arm-Create-virtio-mmio-devices-during-initializa.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0014-xen_arm-Create-virtio-mmio-devices-during-initializa.patch
new file mode 100644
index 00000000..a6925acf
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0014-xen_arm-Create-virtio-mmio-devices-during-initializa.patch
@@ -0,0 +1,83 @@
1From 3dc39d71c3652bea37dc955d5dbf8cd391d2aed0 Mon Sep 17 00:00:00 2001
2From: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
3Date: Sat, 30 Jul 2022 17:51:19 +0300
4Subject: [PATCH 14/16] xen_arm: Create virtio-mmio devices during
5 initialization
6
7In order to use virtio backends we need to allocate virtio-mmio
8parameters (irq and base) and register corresponding buses.
9
10Use the constants defined in public header arch-arm.h to be
11aligned with the toolstack. So the number of current supported
12virtio-mmio devices is 10.
13
14For the interrupts triggering use already existing on Arm
15device-model hypercall.
16
17The toolstack should then insert the same amount of device nodes
18into guest device-tree.
19
20Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
21Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com>
22Reviewed-by: Stefano Stabellini <stefano.stabellini@amd.com>
23---
24 hw/arm/xen_arm.c | 29 +++++++++++++++++++++++++++++
25 1 file changed, 29 insertions(+)
26
27diff --git a/hw/arm/xen_arm.c b/hw/arm/xen_arm.c
28index 153cedfeb4..2012ee7aff 100644
29--- a/hw/arm/xen_arm.c
30+++ b/hw/arm/xen_arm.c
31@@ -25,6 +25,7 @@
32 #include "qemu/error-report.h"
33 #include "qapi/qapi-commands-migration.h"
34 #include "hw/boards.h"
35+#include "hw/irq.h"
36 #include "hw/sysbus.h"
37 #include "sysemu/block-backend.h"
38 #include "sysemu/tpm_backend.h"
39@@ -55,6 +56,32 @@ struct XenArmState {
40 XenIOState *state;
41 };
42
43+#define VIRTIO_MMIO_DEV_SIZE 0x200
44+
45+#define NR_VIRTIO_MMIO_DEVICES \
46+ (GUEST_VIRTIO_MMIO_SPI_LAST - GUEST_VIRTIO_MMIO_SPI_FIRST)
47+
48+static void xen_set_irq(void *opaque, int irq, int level)
49+{
50+ xendevicemodel_set_irq_level(xen_dmod, xen_domid, irq, level);
51+}
52+
53+static void xen_create_virtio_mmio_devices(XenArmState *xam)
54+{
55+ int i;
56+
57+ for (i = 0; i < NR_VIRTIO_MMIO_DEVICES; i++) {
58+ hwaddr base = GUEST_VIRTIO_MMIO_BASE + i * VIRTIO_MMIO_DEV_SIZE;
59+ qemu_irq irq = qemu_allocate_irq(xen_set_irq, NULL,
60+ GUEST_VIRTIO_MMIO_SPI_FIRST + i);
61+
62+ sysbus_create_simple("virtio-mmio", base, irq);
63+
64+ DPRINTF("Created virtio-mmio device %d: irq %d base 0x%lx\n",
65+ i, GUEST_VIRTIO_MMIO_SPI_FIRST + i, base);
66+ }
67+}
68+
69 void arch_handle_ioreq(XenIOState *state, ioreq_t *req)
70 {
71 hw_error("Invalid ioreq type 0x%x\n", req->type);
72@@ -132,6 +159,8 @@ static void xen_arm_init(MachineState *machine)
73 return;
74 }
75
76+ xen_create_virtio_mmio_devices(xam);
77+
78 xen_enable_tpm();
79
80 return;
81--
822.17.1
83
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0015-xen_arm-Initialize-RAM-and-add-hi-low-memory-regions.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0015-xen_arm-Initialize-RAM-and-add-hi-low-memory-regions.patch
new file mode 100644
index 00000000..7c2b272d
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0015-xen_arm-Initialize-RAM-and-add-hi-low-memory-regions.patch
@@ -0,0 +1,105 @@
1From a284a53c5374e19ac37b884f2dd50293e7c8070e Mon Sep 17 00:00:00 2001
2From: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
3Date: Sat, 30 Jul 2022 17:18:06 +0300
4Subject: [PATCH 15/16] xen_arm: Initialize RAM and add hi/low memory regions
5
6In order to use virtio backends we need to initialize RAM for the
7xen-mapcache (which is responsible for mapping guest memory using foreign
8mapping) to work. Calculate and add hi/low memory regions based on
9machine->ram_size.
10
11Use the constants defined in public header arch-arm.h to be aligned with the
12toolstack.
13
14The toolstack should then pass real ram_size using "-m" arg.
15If "-m" is not given, create a QEMU machine without IOREQ, TPM and VIRTIO to
16keep it usable for /etc/init.d/xencommons.
17
18Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
19Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com>
20Reviewed-by: Stefano Stabellini <stefano.stabellini@amd.com>
21---
22 hw/arm/xen_arm.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
23 1 file changed, 46 insertions(+)
24
25diff --git a/hw/arm/xen_arm.c b/hw/arm/xen_arm.c
26index 2012ee7aff..fde919df29 100644
27--- a/hw/arm/xen_arm.c
28+++ b/hw/arm/xen_arm.c
29@@ -56,6 +56,8 @@ struct XenArmState {
30 XenIOState *state;
31 };
32
33+static MemoryRegion ram_lo, ram_hi;
34+
35 #define VIRTIO_MMIO_DEV_SIZE 0x200
36
37 #define NR_VIRTIO_MMIO_DEVICES \
38@@ -82,6 +84,39 @@ static void xen_create_virtio_mmio_devices(XenArmState *xam)
39 }
40 }
41
42+static void xen_init_ram(MachineState *machine)
43+{
44+ MemoryRegion *sysmem = get_system_memory();
45+ ram_addr_t block_len, ram_size[GUEST_RAM_BANKS];
46+
47+ if (machine->ram_size <= GUEST_RAM0_SIZE) {
48+ ram_size[0] = machine->ram_size;
49+ ram_size[1] = 0;
50+ block_len = GUEST_RAM0_BASE + ram_size[0];
51+ } else {
52+ ram_size[0] = GUEST_RAM0_SIZE;
53+ ram_size[1] = machine->ram_size - GUEST_RAM0_SIZE;
54+ block_len = GUEST_RAM1_BASE + ram_size[1];
55+ }
56+
57+ memory_region_init_ram(&ram_memory, NULL, "xen.ram", block_len,
58+ &error_fatal);
59+
60+ memory_region_init_alias(&ram_lo, NULL, "xen.ram.lo", &ram_memory,
61+ GUEST_RAM0_BASE, ram_size[0]);
62+ memory_region_add_subregion(sysmem, GUEST_RAM0_BASE, &ram_lo);
63+ DPRINTF("Initialized region xen.ram.lo: base 0x%llx size 0x%lx\n",
64+ GUEST_RAM0_BASE, ram_size[0]);
65+
66+ if (ram_size[1] > 0) {
67+ memory_region_init_alias(&ram_hi, NULL, "xen.ram.hi", &ram_memory,
68+ GUEST_RAM1_BASE, ram_size[1]);
69+ memory_region_add_subregion(sysmem, GUEST_RAM1_BASE, &ram_hi);
70+ DPRINTF("Initialized region xen.ram.hi: base 0x%llx size 0x%lx\n",
71+ GUEST_RAM1_BASE, ram_size[1]);
72+ }
73+}
74+
75 void arch_handle_ioreq(XenIOState *state, ioreq_t *req)
76 {
77 hw_error("Invalid ioreq type 0x%x\n", req->type);
78@@ -155,6 +190,14 @@ static void xen_arm_init(MachineState *machine)
79
80 xam->state = g_new0(XenIOState, 1);
81
82+ if (machine->ram_size == 0) {
83+ DPRINTF("ram_size not specified. QEMU machine will be started without"
84+ " TPM, IOREQ and Virtio-MMIO backends\n");
85+ return;
86+ }
87+
88+ xen_init_ram(machine);
89+
90 if (xen_init_ioreq(xam->state, machine->smp.cpus)) {
91 return;
92 }
93@@ -173,6 +216,9 @@ static void xen_arm_machine_class_init(ObjectClass *oc, void *data)
94 mc->desc = "Xen Para-virtualized PC";
95 mc->init = xen_arm_init;
96 mc->max_cpus = 1;
97+ /* Set explicitly here to make sure that real ram_size is passed */
98+ mc->default_ram_size = 0;
99+
100 machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS);
101 }
102
103--
1042.17.1
105
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0016-xen_arm-Add-accel-xen-and-drop-extra-interface-openi.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0016-xen_arm-Add-accel-xen-and-drop-extra-interface-openi.patch
new file mode 100644
index 00000000..14f2e240
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-7.1/0016-xen_arm-Add-accel-xen-and-drop-extra-interface-openi.patch
@@ -0,0 +1,79 @@
1From a730d5ea4a0445a8c694b56583dd06bd000fae74 Mon Sep 17 00:00:00 2001
2From: Vikram Garhwal <vikram.garhwal@amd.com>
3Date: Wed, 4 Jan 2023 23:05:25 +0000
4Subject: [PATCH 16/16] xen_arm: Add "accel = xen" and drop extra interface
5 openings
6
7In order to use virtio backends we need to make sure that Xen accelerator
8is enabled (xen_enabled() returns true) as the memory/cache systems
9check for xen_enabled() to perform specific actions. Without that
10the xen-mapcache (which is needed for mapping guest memory) is not in use.
11
12Also drop extra interface opening as this is already done in xen-all.c
13(so drop xen_init_ioreq() completely) and skip virtio/tpm initialization
14if device emulation is not available.
15
16Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
17Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com>
18Reviewed-by: Stefano Stabellini <stefano.stabellini@amd.com>
19---
20 hw/arm/xen_arm.c | 29 ++---------------------------
21 1 file changed, 2 insertions(+), 27 deletions(-)
22
23diff --git a/hw/arm/xen_arm.c b/hw/arm/xen_arm.c
24index fde919df29..4ac425a3c5 100644
25--- a/hw/arm/xen_arm.c
26+++ b/hw/arm/xen_arm.c
27@@ -137,30 +137,6 @@ void qmp_xen_set_global_dirty_log(bool enable, Error **errp)
28 {
29 }
30
31-static int xen_init_ioreq(XenIOState *state, unsigned int max_cpus)
32-{
33- xen_dmod = xendevicemodel_open(0, 0);
34- xen_xc = xc_interface_open(0, 0, 0);
35-
36- if (xen_xc == NULL) {
37- perror("xen: can't open xen interface\n");
38- return -1;
39- }
40-
41- xen_fmem = xenforeignmemory_open(0, 0);
42- if (xen_fmem == NULL) {
43- perror("xen: can't open xen fmem interface\n");
44- xc_interface_close(xen_xc);
45- return -1;
46- }
47-
48- xen_register_ioreq(state, max_cpus, xen_memory_listener);
49-
50- xenstore_record_dm_state(xenstore, "running");
51-
52- return 0;
53-}
54-
55 static void xen_enable_tpm(void)
56 {
57 #ifdef CONFIG_TPM
58@@ -198,9 +174,7 @@ static void xen_arm_init(MachineState *machine)
59
60 xen_init_ram(machine);
61
62- if (xen_init_ioreq(xam->state, machine->smp.cpus)) {
63- return;
64- }
65+ xen_register_ioreq(xam->state, machine->smp.cpus, xen_memory_listener);
66
67 xen_create_virtio_mmio_devices(xam);
68
69@@ -218,6 +192,7 @@ static void xen_arm_machine_class_init(ObjectClass *oc, void *data)
70 mc->max_cpus = 1;
71 /* Set explicitly here to make sure that real ram_size is passed */
72 mc->default_ram_size = 0;
73+ mc->default_machine_opts = "accel=xen";
74
75 machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS);
76 }
77--
782.17.1
79
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0001-arm-xenpvh-Introduce-virtio-pci-support.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0001-arm-xenpvh-Introduce-virtio-pci-support.patch
new file mode 100644
index 00000000..6e3b40f7
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0001-arm-xenpvh-Introduce-virtio-pci-support.patch
@@ -0,0 +1,353 @@
1From 3104d411ee36487ea409ba5a1b474989326f70f2 Mon Sep 17 00:00:00 2001
2From: Vikram Garhwal <vikram.garhwal@amd.com>
3Date: Wed, 15 Nov 2023 14:19:31 -0800
4Subject: [PATCH] arm: xenpvh: Introduce virtio-pci support
5
6The bridge is needed for virtio-pci support, as QEMU can emulate the
7whole bridge with any virtio-pci devices connected to it.
8
9NOTE: A few xen-hvm-common.c and xen_native.h changes are cherry-picked from
10EPAM QEMU patches for xen-arm. This was done to keep least diff with upstream.
11
12Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com>
13Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
14Signed-off-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
15---
16 hw/arm/xen_arm.c | 271 ++++++++++++++++++++++++++++++++++++
17 include/hw/xen/xen_native.h | 3 +
18 2 files changed, 274 insertions(+)
19
20diff --git a/hw/arm/xen_arm.c b/hw/arm/xen_arm.c
21index 1587e2a43b..a7c5b20777 100644
22--- a/hw/arm/xen_arm.c
23+++ b/hw/arm/xen_arm.c
24@@ -34,6 +34,7 @@
25 #include "hw/xen/xen-hvm-common.h"
26 #include "sysemu/tpm.h"
27 #include "hw/xen/arch_hvm.h"
28+#include "hw/pci-host/gpex.h"
29
30 #define TYPE_XEN_ARM MACHINE_TYPE_NAME("xenpvh")
31 OBJECT_DECLARE_SIMPLE_TYPE(XenArmState, XEN_ARM)
32@@ -57,6 +58,9 @@ struct XenArmState {
33
34 struct {
35 uint64_t tpm_base_addr;
36+ MemMapEntry pcie_mmio;
37+ MemMapEntry pcie_ecam;
38+ MemMapEntry pcie_mmio_high;
39 } cfg;
40 };
41
42@@ -132,6 +136,80 @@ static void xen_init_ram(MachineState *machine)
43 ram_grants = *xen_init_grant_ram();
44 }
45
46+static bool xen_validate_pcie_config(XenArmState *xam)
47+{
48+ if (xam->cfg.pcie_ecam.base == 0 &&
49+ xam->cfg.pcie_ecam.size == 0 &&
50+ xam->cfg.pcie_mmio.base == 0 &&
51+ xam->cfg.pcie_mmio.size == 0 &&
52+ xam->cfg.pcie_mmio_high.base == 0 &&
53+ xam->cfg.pcie_mmio_high.size == 0) {
54+ /* It's okay, user just don't want PCIe brige */
55+ return false;
56+ }
57+
58+ if (xam->cfg.pcie_ecam.base == 0 ||
59+ xam->cfg.pcie_ecam.size == 0 ||
60+ xam->cfg.pcie_mmio.base == 0 ||
61+ xam->cfg.pcie_mmio.size == 0 ||
62+ xam->cfg.pcie_mmio_high.base == 0 ||
63+ xam->cfg.pcie_mmio_high.size == 0) {
64+ /* User provided some PCIe options, but not all of them */
65+ error_printf("Incomplete PCIe bridge configuration\n");
66+ exit(1);
67+ }
68+
69+ return true;
70+}
71+
72+static void xen_create_pcie(XenArmState *xam)
73+{
74+ MemoryRegion *mmio_alias, *mmio_alias_high, *mmio_reg;
75+ MemoryRegion *ecam_alias, *ecam_reg;
76+ DeviceState *dev;
77+ int i;
78+
79+ dev = qdev_new(TYPE_GPEX_HOST);
80+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
81+
82+ /* Map ECAM space */
83+ ecam_alias = g_new0(MemoryRegion, 1);
84+ ecam_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
85+ memory_region_init_alias(ecam_alias, OBJECT(dev), "pcie-ecam",
86+ ecam_reg, 0, xam->cfg.pcie_ecam.size);
87+ memory_region_add_subregion(get_system_memory(), xam->cfg.pcie_ecam.base,
88+ ecam_alias);
89+
90+ /* Map the MMIO space */
91+ mmio_alias = g_new0(MemoryRegion, 1);
92+ mmio_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1);
93+ memory_region_init_alias(mmio_alias, OBJECT(dev), "pcie-mmio",
94+ mmio_reg,
95+ xam->cfg.pcie_mmio.base,
96+ xam->cfg.pcie_mmio.size);
97+ memory_region_add_subregion(get_system_memory(), xam->cfg.pcie_mmio.base,
98+ mmio_alias);
99+
100+ /* Map the MMIO_HIGH space */
101+ mmio_alias_high = g_new0(MemoryRegion, 1);
102+ memory_region_init_alias(mmio_alias_high, OBJECT(dev), "pcie-mmio-high",
103+ mmio_reg,
104+ xam->cfg.pcie_mmio_high.base,
105+ xam->cfg.pcie_mmio_high.size);
106+ memory_region_add_subregion(get_system_memory(),
107+ xam->cfg.pcie_mmio_high.base,
108+ mmio_alias_high);
109+
110+ /* Legacy PCI interrupts (#INTA - #INTD) */
111+ for (i = 0; i < GPEX_NUM_IRQS; i++) {
112+ qemu_irq irq = qemu_allocate_irq(xen_set_irq, NULL,
113+ GUEST_VIRTIO_PCI_SPI_FIRST + i);
114+
115+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, irq);
116+ gpex_set_irq_num(GPEX_HOST(dev), i, GUEST_VIRTIO_PCI_SPI_FIRST + i);
117+ }
118+}
119+
120 void arch_handle_ioreq(XenIOState *state, ioreq_t *req)
121 {
122 hw_error("Invalid ioreq type 0x%x\n", req->type);
123@@ -193,6 +271,13 @@ static void xen_arm_init(MachineState *machine)
124
125 xen_create_virtio_mmio_devices(xam);
126
127+ if (xen_validate_pcie_config(xam)) {
128+ xen_create_pcie(xam);
129+ } else {
130+ DPRINTF("PCIe host bridge is not configured,"
131+ " only virtio-mmio can be used\n");
132+ }
133+
134 #ifdef CONFIG_TPM
135 if (xam->cfg.tpm_base_addr) {
136 xen_enable_tpm(xam);
137@@ -228,6 +313,150 @@ static void xen_arm_set_tpm_base_addr(Object *obj, Visitor *v,
138 }
139 #endif
140
141+static void xen_arm_get_pcie_ecam_base_addr(Object *obj, Visitor *v,
142+ const char *name, void *opaque,
143+ Error **errp)
144+{
145+ XenArmState *xam = XEN_ARM(obj);
146+ uint64_t value = xam->cfg.pcie_ecam.base;
147+
148+ visit_type_uint64(v, name, &value, errp);
149+}
150+
151+static void xen_arm_set_pcie_ecam_base_addr(Object *obj, Visitor *v,
152+ const char *name, void *opaque,
153+ Error **errp)
154+{
155+ XenArmState *xam = XEN_ARM(obj);
156+ uint64_t value;
157+
158+ if (!visit_type_uint64(v, name, &value, errp)) {
159+ return;
160+ }
161+
162+ xam->cfg.pcie_ecam.base = value;
163+}
164+
165+static void xen_arm_get_pcie_ecam_size(Object *obj, Visitor *v,
166+ const char *name, void *opaque,
167+ Error **errp)
168+{
169+ XenArmState *xam = XEN_ARM(obj);
170+ uint64_t value = xam->cfg.pcie_ecam.size;
171+
172+ visit_type_uint64(v, name, &value, errp);
173+}
174+
175+static void xen_arm_set_pcie_ecam_size(Object *obj, Visitor *v,
176+ const char *name, void *opaque,
177+ Error **errp)
178+{
179+ XenArmState *xam = XEN_ARM(obj);
180+ uint64_t value;
181+
182+ if (!visit_type_uint64(v, name, &value, errp)) {
183+ return;
184+ }
185+
186+ xam->cfg.pcie_ecam.size = value;
187+}
188+
189+static void xen_arm_get_pcie_mmio_base_addr(Object *obj, Visitor *v,
190+ const char *name, void *opaque,
191+ Error **errp)
192+{
193+ XenArmState *xam = XEN_ARM(obj);
194+ uint64_t value = xam->cfg.pcie_mmio.base;
195+
196+ visit_type_uint64(v, name, &value, errp);
197+}
198+
199+static void xen_arm_set_pcie_mmio_base_addr(Object *obj, Visitor *v,
200+ const char *name, void *opaque,
201+ Error **errp)
202+{
203+ XenArmState *xam = XEN_ARM(obj);
204+ uint64_t value;
205+
206+ if (!visit_type_uint64(v, name, &value, errp)) {
207+ return;
208+ }
209+
210+ xam->cfg.pcie_mmio.base = value;
211+}
212+
213+static void xen_arm_get_pcie_mmio_size(Object *obj, Visitor *v,
214+ const char *name, void *opaque,
215+ Error **errp)
216+{
217+ XenArmState *xam = XEN_ARM(obj);
218+ uint64_t value = xam->cfg.pcie_mmio.size;
219+
220+ visit_type_uint64(v, name, &value, errp);
221+}
222+
223+static void xen_arm_set_pcie_mmio_size(Object *obj, Visitor *v,
224+ const char *name, void *opaque,
225+ Error **errp)
226+{
227+ XenArmState *xam = XEN_ARM(obj);
228+ uint64_t value;
229+
230+ if (!visit_type_uint64(v, name, &value, errp)) {
231+ return;
232+ }
233+
234+ xam->cfg.pcie_mmio.size = value;
235+}
236+
237+static void xen_arm_get_pcie_prefetch_base_addr(Object *obj, Visitor *v,
238+ const char *name, void *opaque,
239+ Error **errp)
240+{
241+ XenArmState *xam = XEN_ARM(obj);
242+ uint64_t value = xam->cfg.pcie_mmio_high.base;
243+
244+ visit_type_uint64(v, name, &value, errp);
245+}
246+
247+static void xen_arm_set_pcie_prefetch_base_addr(Object *obj, Visitor *v,
248+ const char *name, void *opaque,
249+ Error **errp)
250+{
251+ XenArmState *xam = XEN_ARM(obj);
252+ uint64_t value;
253+
254+ if (!visit_type_uint64(v, name, &value, errp)) {
255+ return;
256+ }
257+
258+ xam->cfg.pcie_mmio_high.base = value;
259+}
260+
261+static void xen_arm_get_pcie_prefetch_size(Object *obj, Visitor *v,
262+ const char *name, void *opaque,
263+ Error **errp)
264+{
265+ XenArmState *xam = XEN_ARM(obj);
266+ uint64_t value = xam->cfg.pcie_mmio_high.size;
267+
268+ visit_type_uint64(v, name, &value, errp);
269+}
270+
271+static void xen_arm_set_pcie_prefetch_size(Object *obj, Visitor *v,
272+ const char *name, void *opaque,
273+ Error **errp)
274+{
275+ XenArmState *xam = XEN_ARM(obj);
276+ uint64_t value;
277+
278+ if (!visit_type_uint64(v, name, &value, errp)) {
279+ return;
280+ }
281+
282+ xam->cfg.pcie_mmio_high.size = value;
283+}
284+
285 static void xen_arm_machine_class_init(ObjectClass *oc, void *data)
286 {
287
288@@ -249,6 +478,48 @@ static void xen_arm_machine_class_init(ObjectClass *oc, void *data)
289
290 machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS);
291 #endif
292+
293+ object_class_property_add(oc, "pci-ecam-base-addr", "uint64_t",
294+ xen_arm_get_pcie_ecam_base_addr,
295+ xen_arm_set_pcie_ecam_base_addr,
296+ NULL, NULL);
297+ object_class_property_set_description(oc, "pci-ecam-base-addr",
298+ "Set Base address for PCI ECAM.");
299+
300+ object_class_property_add(oc, "pci-ecam-size", "uint64_t",
301+ xen_arm_get_pcie_ecam_size,
302+ xen_arm_set_pcie_ecam_size,
303+ NULL, NULL);
304+ object_class_property_set_description(oc, "pci-ecam-size",
305+ "Set Size for PCI ECAM.");
306+
307+ object_class_property_add(oc, "pci-mmio-base-addr", "uint64_t",
308+ xen_arm_get_pcie_mmio_base_addr,
309+ xen_arm_set_pcie_mmio_base_addr,
310+ NULL, NULL);
311+ object_class_property_set_description(oc, "pci-mmio-base-addr",
312+ "Set Base address for PCI MMIO.");
313+
314+ object_class_property_add(oc, "pci-mmio-size", "uint64_t",
315+ xen_arm_get_pcie_mmio_size,
316+ xen_arm_set_pcie_mmio_size,
317+ NULL, NULL);
318+ object_class_property_set_description(oc, "pci-mmio-size",
319+ "Set size for PCI MMIO.");
320+
321+ object_class_property_add(oc, "pci-prefetch-base-addr", "uint64_t",
322+ xen_arm_get_pcie_prefetch_base_addr,
323+ xen_arm_set_pcie_prefetch_base_addr,
324+ NULL, NULL);
325+ object_class_property_set_description(oc, "pci-prefetch-base-addr",
326+ "Set Prefetch Base address for PCI.");
327+
328+ object_class_property_add(oc, "pci-prefetch-size", "uint64_t",
329+ xen_arm_get_pcie_prefetch_size,
330+ xen_arm_set_pcie_prefetch_size,
331+ NULL, NULL);
332+ object_class_property_set_description(oc, "pci-prefetch-size",
333+ "Set Prefetch size for PCI.");
334 }
335
336 static const TypeInfo xen_arm_machine_type = {
337diff --git a/include/hw/xen/xen_native.h b/include/hw/xen/xen_native.h
338index 6f09c48823..1e81189a27 100644
339--- a/include/hw/xen/xen_native.h
340+++ b/include/hw/xen/xen_native.h
341@@ -539,6 +539,9 @@ static inline int xendevicemodel_set_irq_level(xendevicemodel_handle *dmod,
342 #define GUEST_VIRTIO_MMIO_SPI_LAST 43
343 #endif
344
345+#define GUEST_VIRTIO_PCI_SPI_FIRST 44
346+#define GUEST_VIRTIO_PCI_SPI_LAST 48
347+
348 #if defined(__i386__) || defined(__x86_64__)
349 #define GUEST_RAM_BANKS 2
350 #define GUEST_RAM0_BASE 0x40000000ULL /* 3GB of low RAM @ 1GB */
351--
3522.30.2
353
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0001-xen_arm-Create-virtio-mmio-devices-during-initializa.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0001-xen_arm-Create-virtio-mmio-devices-during-initializa.patch
new file mode 100644
index 00000000..1757e9e2
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0001-xen_arm-Create-virtio-mmio-devices-during-initializa.patch
@@ -0,0 +1,116 @@
1From b9291457ca2eb4340c71d2eed08fde83916c9fa4 Mon Sep 17 00:00:00 2001
2From: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
3Date: Tue, 29 Aug 2023 21:35:17 -0700
4Subject: [PATCH 01/11] xen_arm: Create virtio-mmio devices during
5 initialization
6
7In order to use virtio backends we need to allocate virtio-mmio
8parameters (irq and base) and register corresponding buses.
9
10Use the constants defined in public header arch-arm.h to be
11aligned with the toolstack. So the number of current supported
12virtio-mmio devices is 10.
13
14For the interrupts triggering use already existing on Arm
15device-model hypercall.
16
17The toolstack should then insert the same amount of device nodes
18into guest device-tree.
19
20Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
21Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com>
22Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
23Signed-off-by: Stefano Stabellini <stefano.stabellini@amd.com>
24---
25 hw/arm/xen_arm.c | 35 +++++++++++++++++++++++++++++++++++
26 include/hw/xen/xen_native.h | 16 ++++++++++++++++
27 2 files changed, 51 insertions(+)
28
29diff --git a/hw/arm/xen_arm.c b/hw/arm/xen_arm.c
30index 1d3e6d481a..7393b37355 100644
31--- a/hw/arm/xen_arm.c
32+++ b/hw/arm/xen_arm.c
33@@ -26,6 +26,7 @@
34 #include "qapi/qapi-commands-migration.h"
35 #include "qapi/visitor.h"
36 #include "hw/boards.h"
37+#include "hw/irq.h"
38 #include "hw/sysbus.h"
39 #include "sysemu/block-backend.h"
40 #include "sysemu/tpm_backend.h"
41@@ -59,6 +60,38 @@ struct XenArmState {
42 } cfg;
43 };
44
45+/*
46+ * VIRTIO_MMIO_DEV_SIZE is imported from tools/libs/light/libxl_arm.c under Xen
47+ * repository.
48+ *
49+ * Origin: git://xenbits.xen.org/xen.git 2128143c114c
50+ */
51+#define VIRTIO_MMIO_DEV_SIZE 0x200
52+
53+#define NR_VIRTIO_MMIO_DEVICES \
54+ (GUEST_VIRTIO_MMIO_SPI_LAST - GUEST_VIRTIO_MMIO_SPI_FIRST)
55+
56+static void xen_set_irq(void *opaque, int irq, int level)
57+{
58+ xendevicemodel_set_irq_level(xen_dmod, xen_domid, irq, level);
59+}
60+
61+static void xen_create_virtio_mmio_devices(XenArmState *xam)
62+{
63+ int i;
64+
65+ for (i = 0; i < NR_VIRTIO_MMIO_DEVICES; i++) {
66+ hwaddr base = GUEST_VIRTIO_MMIO_BASE + i * VIRTIO_MMIO_DEV_SIZE;
67+ qemu_irq irq = qemu_allocate_irq(xen_set_irq, NULL,
68+ GUEST_VIRTIO_MMIO_SPI_FIRST + i);
69+
70+ sysbus_create_simple("virtio-mmio", base, irq);
71+
72+ DPRINTF("Created virtio-mmio device %d: irq %d base 0x%lx\n",
73+ i, GUEST_VIRTIO_MMIO_SPI_FIRST + i, base);
74+ }
75+}
76+
77 void arch_handle_ioreq(XenIOState *state, ioreq_t *req)
78 {
79 hw_error("Invalid ioreq type 0x%x\n", req->type);
80@@ -110,6 +143,8 @@ static void xen_arm_init(MachineState *machine)
81
82 xen_register_ioreq(xam->state, machine->smp.cpus, &xen_memory_listener);
83
84+ xen_create_virtio_mmio_devices(xam);
85+
86 #ifdef CONFIG_TPM
87 if (xam->cfg.tpm_base_addr) {
88 xen_enable_tpm(xam);
89diff --git a/include/hw/xen/xen_native.h b/include/hw/xen/xen_native.h
90index 4dce905fde..a4b1aa9e5d 100644
91--- a/include/hw/xen/xen_native.h
92+++ b/include/hw/xen/xen_native.h
93@@ -523,4 +523,20 @@ static inline int xen_set_ioreq_server_state(domid_t dom,
94 enable);
95 }
96
97+#if CONFIG_XEN_CTRL_INTERFACE_VERSION <= 41500
98+static inline int xendevicemodel_set_irq_level(xendevicemodel_handle *dmod,
99+ domid_t domid, uint32_t irq,
100+ unsigned int level)
101+{
102+ return 0;
103+}
104+#endif
105+
106+#if CONFIG_XEN_CTRL_INTERFACE_VERSION <= 41700
107+#define GUEST_VIRTIO_MMIO_BASE xen_mk_ullong(0x02000000)
108+#define GUEST_VIRTIO_MMIO_SIZE xen_mk_ullong(0x00100000)
109+#define GUEST_VIRTIO_MMIO_SPI_FIRST 33
110+#define GUEST_VIRTIO_MMIO_SPI_LAST 43
111+#endif
112+
113 #endif /* QEMU_HW_XEN_NATIVE_H */
114--
1152.39.2
116
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0002-xen_arm-Initialize-RAM-and-add-hi-low-memory-regions.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0002-xen_arm-Initialize-RAM-and-add-hi-low-memory-regions.patch
new file mode 100644
index 00000000..f88db620
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0002-xen_arm-Initialize-RAM-and-add-hi-low-memory-regions.patch
@@ -0,0 +1,124 @@
1From 70a74795c5071bf591e6e557b7c8c492ead0e675 Mon Sep 17 00:00:00 2001
2From: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
3Date: Tue, 29 Aug 2023 21:35:18 -0700
4Subject: [PATCH 02/11] xen_arm: Initialize RAM and add hi/low memory regions
5
6In order to use virtio backends we need to initialize RAM for the
7xen-mapcache (which is responsible for mapping guest memory using foreign
8mapping) to work. Calculate and add hi/low memory regions based on
9machine->ram_size.
10
11Use the constants defined in public header arch-arm.h to be aligned with the xen
12toolstack.
13
14While using this machine, the toolstack should then pass real ram_size using
15"-m" arg. If "-m" is not given, create a QEMU machine without IOREQ and other
16emulated devices like TPM and VIRTIO. This is done to keep this QEMU machine
17usable for /etc/init.d/xencommons.
18
19Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
20Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com>
21Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
22Signed-off-by: Stefano Stabellini <stefano.stabellini@amd.com>
23---
24 hw/arm/xen_arm.c | 45 +++++++++++++++++++++++++++++++++++++
25 include/hw/xen/xen_native.h | 8 +++++++
26 2 files changed, 53 insertions(+)
27
28diff --git a/hw/arm/xen_arm.c b/hw/arm/xen_arm.c
29index 7393b37355..f83b983ec5 100644
30--- a/hw/arm/xen_arm.c
31+++ b/hw/arm/xen_arm.c
32@@ -60,6 +60,8 @@ struct XenArmState {
33 } cfg;
34 };
35
36+static MemoryRegion ram_lo, ram_hi;
37+
38 /*
39 * VIRTIO_MMIO_DEV_SIZE is imported from tools/libs/light/libxl_arm.c under Xen
40 * repository.
41@@ -92,6 +94,39 @@ static void xen_create_virtio_mmio_devices(XenArmState *xam)
42 }
43 }
44
45+static void xen_init_ram(MachineState *machine)
46+{
47+ MemoryRegion *sysmem = get_system_memory();
48+ ram_addr_t block_len, ram_size[GUEST_RAM_BANKS];
49+
50+ if (machine->ram_size <= GUEST_RAM0_SIZE) {
51+ ram_size[0] = machine->ram_size;
52+ ram_size[1] = 0;
53+ block_len = GUEST_RAM0_BASE + ram_size[0];
54+ } else {
55+ ram_size[0] = GUEST_RAM0_SIZE;
56+ ram_size[1] = machine->ram_size - GUEST_RAM0_SIZE;
57+ block_len = GUEST_RAM1_BASE + ram_size[1];
58+ }
59+
60+ memory_region_init_ram(&ram_memory, NULL, "xen.ram", block_len,
61+ &error_fatal);
62+
63+ memory_region_init_alias(&ram_lo, NULL, "xen.ram.lo", &ram_memory,
64+ GUEST_RAM0_BASE, ram_size[0]);
65+ memory_region_add_subregion(sysmem, GUEST_RAM0_BASE, &ram_lo);
66+ DPRINTF("Initialized region xen.ram.lo: base 0x%llx size 0x%lx\n",
67+ GUEST_RAM0_BASE, ram_size[0]);
68+
69+ if (ram_size[1] > 0) {
70+ memory_region_init_alias(&ram_hi, NULL, "xen.ram.hi", &ram_memory,
71+ GUEST_RAM1_BASE, ram_size[1]);
72+ memory_region_add_subregion(sysmem, GUEST_RAM1_BASE, &ram_hi);
73+ DPRINTF("Initialized region xen.ram.hi: base 0x%llx size 0x%lx\n",
74+ GUEST_RAM1_BASE, ram_size[1]);
75+ }
76+}
77+
78 void arch_handle_ioreq(XenIOState *state, ioreq_t *req)
79 {
80 hw_error("Invalid ioreq type 0x%x\n", req->type);
81@@ -141,6 +176,14 @@ static void xen_arm_init(MachineState *machine)
82
83 xam->state = g_new0(XenIOState, 1);
84
85+ if (machine->ram_size == 0) {
86+ DPRINTF("ram_size not specified. QEMU machine started without IOREQ"
87+ "(no emulated devices including Virtio)\n");
88+ return;
89+ }
90+
91+ xen_init_ram(machine);
92+
93 xen_register_ioreq(xam->state, machine->smp.cpus, &xen_memory_listener);
94
95 xen_create_virtio_mmio_devices(xam);
96@@ -188,6 +231,8 @@ static void xen_arm_machine_class_init(ObjectClass *oc, void *data)
97 mc->init = xen_arm_init;
98 mc->max_cpus = 1;
99 mc->default_machine_opts = "accel=xen";
100+ /* Set explicitly here to make sure that real ram_size is passed */
101+ mc->default_ram_size = 0;
102
103 #ifdef CONFIG_TPM
104 object_class_property_add(oc, "tpm-base-addr", "uint64_t",
105diff --git a/include/hw/xen/xen_native.h b/include/hw/xen/xen_native.h
106index a4b1aa9e5d..5d2718261f 100644
107--- a/include/hw/xen/xen_native.h
108+++ b/include/hw/xen/xen_native.h
109@@ -539,4 +539,12 @@ static inline int xendevicemodel_set_irq_level(xendevicemodel_handle *dmod,
110 #define GUEST_VIRTIO_MMIO_SPI_LAST 43
111 #endif
112
113+#if defined(__i386__) || defined(__x86_64__)
114+#define GUEST_RAM_BANKS 2
115+#define GUEST_RAM0_BASE 0x40000000ULL /* 3GB of low RAM @ 1GB */
116+#define GUEST_RAM0_SIZE 0xc0000000ULL
117+#define GUEST_RAM1_BASE 0x0200000000ULL /* 1016GB of RAM @ 8GB */
118+#define GUEST_RAM1_SIZE 0xfe00000000ULL
119+#endif
120+
121 #endif /* QEMU_HW_XEN_NATIVE_H */
122--
1232.39.2
124
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0003-Xen-Fix-xen_set_irq-and-xendevicemodel_set_irq_level.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0003-Xen-Fix-xen_set_irq-and-xendevicemodel_set_irq_level.patch
new file mode 100644
index 00000000..c6945d54
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0003-Xen-Fix-xen_set_irq-and-xendevicemodel_set_irq_level.patch
@@ -0,0 +1,55 @@
1From 14b9dbd7f0261ae7a36bef251924ba211beef17a Mon Sep 17 00:00:00 2001
2From: Vikram Garhwal <vikram.garhwal@amd.com>
3Date: Wed, 1 Nov 2023 14:07:23 -0700
4Subject: [PATCH 03/11] Xen: Fix xen_set_irq() and
5 xendevicemodel_set_irq_level()
6
7Remove '=' from 'if CONFIG_XEN_CTRL_INTERFACE_VERSION <= 41500'.
8Because xendevicemodel_set_irq_level() was introduced in 4.15 version.
9
10Also, update xendevicemodel_set_irq_level() to return -1 for older versions.
11
12Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com>
13Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
14---
15 hw/arm/xen_arm.c | 4 +++-
16 include/hw/xen/xen_native.h | 4 ++--
17 2 files changed, 5 insertions(+), 3 deletions(-)
18
19diff --git a/hw/arm/xen_arm.c b/hw/arm/xen_arm.c
20index f83b983ec5..a5631529d0 100644
21--- a/hw/arm/xen_arm.c
22+++ b/hw/arm/xen_arm.c
23@@ -75,7 +75,9 @@ static MemoryRegion ram_lo, ram_hi;
24
25 static void xen_set_irq(void *opaque, int irq, int level)
26 {
27- xendevicemodel_set_irq_level(xen_dmod, xen_domid, irq, level);
28+ if (xendevicemodel_set_irq_level(xen_dmod, xen_domid, irq, level)) {
29+ error_report("xendevicemodel_set_irq_level failed");
30+ }
31 }
32
33 static void xen_create_virtio_mmio_devices(XenArmState *xam)
34diff --git a/include/hw/xen/xen_native.h b/include/hw/xen/xen_native.h
35index 5d2718261f..6f09c48823 100644
36--- a/include/hw/xen/xen_native.h
37+++ b/include/hw/xen/xen_native.h
38@@ -523,12 +523,12 @@ static inline int xen_set_ioreq_server_state(domid_t dom,
39 enable);
40 }
41
42-#if CONFIG_XEN_CTRL_INTERFACE_VERSION <= 41500
43+#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 41500
44 static inline int xendevicemodel_set_irq_level(xendevicemodel_handle *dmod,
45 domid_t domid, uint32_t irq,
46 unsigned int level)
47 {
48- return 0;
49+ return -1;
50 }
51 #endif
52
53--
542.39.2
55
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0004-xen-when-unplugging-emulated-devices-skip-virtio-dev.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0004-xen-when-unplugging-emulated-devices-skip-virtio-dev.patch
new file mode 100644
index 00000000..da2f042b
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0004-xen-when-unplugging-emulated-devices-skip-virtio-dev.patch
@@ -0,0 +1,70 @@
1From 02507086b3ad9beb9c669aae54fcb4857cd61ef8 Mon Sep 17 00:00:00 2001
2From: Juergen Gross <jgross@suse.com>
3Date: Tue, 16 Mar 2021 14:00:33 +0100
4Subject: [PATCH 04/11] xen: when unplugging emulated devices skip virtio
5 devices
6
7Virtio devices should never be unplugged at boot time, as they are
8similar to pci passthrough devices.
9
10Signed-off-by: Juergen Gross <jgross@suse.com>
11Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com>
12---
13 docs/system/i386/xen.rst | 3 ---
14 hw/i386/xen/xen_platform.c | 10 ++++++++--
15 2 files changed, 8 insertions(+), 5 deletions(-)
16
17diff --git a/docs/system/i386/xen.rst b/docs/system/i386/xen.rst
18index f06765e88c..b86d57af6e 100644
19--- a/docs/system/i386/xen.rst
20+++ b/docs/system/i386/xen.rst
21@@ -52,9 +52,6 @@ It is necessary to use the pc machine type, as the q35 machine uses AHCI instead
22 of legacy IDE, and AHCI disks are not unplugged through the Xen PV unplug
23 mechanism.
24
25-VirtIO devices can also be used; Linux guests may need to be dissuaded from
26-umplugging them by adding 'xen_emul_unplug=never' on their command line.
27-
28 Properties
29 ----------
30
31diff --git a/hw/i386/xen/xen_platform.c b/hw/i386/xen/xen_platform.c
32index 17457ff3de..0187b73eeb 100644
33--- a/hw/i386/xen/xen_platform.c
34+++ b/hw/i386/xen/xen_platform.c
35@@ -28,6 +28,7 @@
36 #include "hw/ide/pci.h"
37 #include "hw/pci/pci.h"
38 #include "migration/vmstate.h"
39+#include "hw/virtio/virtio-bus.h"
40 #include "net/net.h"
41 #include "trace.h"
42 #include "sysemu/xen.h"
43@@ -129,10 +130,11 @@ static bool pci_device_is_passthrough(PCIDevice *d)
44
45 static void unplug_nic(PCIBus *b, PCIDevice *d, void *o)
46 {
47- /* We have to ignore passthrough devices */
48+ /* We have to ignore passthrough devices and virtio devices. */
49 if (pci_get_word(d->config + PCI_CLASS_DEVICE) ==
50 PCI_CLASS_NETWORK_ETHERNET
51- && !pci_device_is_passthrough(d)) {
52+ && !pci_device_is_passthrough(d)
53+ && !qdev_get_child_bus(&d->qdev, TYPE_VIRTIO_BUS)) {
54 object_unparent(OBJECT(d));
55 }
56 }
57@@ -208,6 +210,10 @@ static void unplug_disks(PCIBus *b, PCIDevice *d, void *opaque)
58 /* We have to ignore passthrough devices */
59 if (pci_device_is_passthrough(d))
60 return;
61+ /* Ignore virtio devices */
62+ if (qdev_get_child_bus(&d->qdev, TYPE_VIRTIO_BUS)) {
63+ return;
64+ }
65
66 switch (pci_get_word(d->config + PCI_CLASS_DEVICE)) {
67 case PCI_CLASS_STORAGE_IDE:
68--
692.39.2
70
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0005-softmmu-physmem-Split-ram_block_add.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0005-softmmu-physmem-Split-ram_block_add.patch
new file mode 100644
index 00000000..3c39dd19
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0005-softmmu-physmem-Split-ram_block_add.patch
@@ -0,0 +1,117 @@
1From d4774a0e5e1ebed605c5d49e81433fd371d0b680 Mon Sep 17 00:00:00 2001
2From: Vikram Garhwal <vikram.garhwal@amd.com>
3Date: Tue, 17 Oct 2023 20:22:26 +0000
4Subject: [PATCH 05/11] softmmu: physmem: Split ram_block_add()
5
6Extract ram block list update to a new function ram_block_add_list(). This is
7done to support grant mappings which adds a memory region for granted memory and
8updates the ram_block list.
9
10Signed-off-by: Juergen Gross <jgross@suse.com>
11Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com>
12Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
13---
14 include/exec/ram_addr.h | 1 +
15 softmmu/physmem.c | 62 ++++++++++++++++++++++++++---------------
16 2 files changed, 40 insertions(+), 23 deletions(-)
17
18diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
19index 9f2e3893f5..76fa360463 100644
20--- a/include/exec/ram_addr.h
21+++ b/include/exec/ram_addr.h
22@@ -139,6 +139,7 @@ void qemu_ram_free(RAMBlock *block);
23 int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp);
24
25 void qemu_ram_msync(RAMBlock *block, ram_addr_t start, ram_addr_t length);
26+void ram_block_add_list(RAMBlock *new_block);
27
28 /* Clear whole block of mem */
29 static inline void qemu_ram_block_writeback(RAMBlock *block)
30diff --git a/softmmu/physmem.c b/softmmu/physmem.c
31index 3df73542e1..f73629733e 100644
32--- a/softmmu/physmem.c
33+++ b/softmmu/physmem.c
34@@ -1786,12 +1786,47 @@ static void dirty_memory_extend(ram_addr_t old_ram_size,
35 }
36 }
37
38+static void ram_block_add_list_locked(RAMBlock *new_block)
39+ {
40+ RAMBlock *block;
41+ RAMBlock *last_block = NULL;
42+
43+ /*
44+ * Keep the list sorted from biggest to smallest block. Unlike QTAILQ,
45+ * QLIST (which has an RCU-friendly variant) does not have insertion at
46+ * tail, so save the last element in last_block.
47+ */
48+ RAMBLOCK_FOREACH(block) {
49+ last_block = block;
50+ if (block->max_length < new_block->max_length) {
51+ break;
52+ }
53+ }
54+ if (block) {
55+ QLIST_INSERT_BEFORE_RCU(block, new_block, next);
56+ } else if (last_block) {
57+ QLIST_INSERT_AFTER_RCU(last_block, new_block, next);
58+ } else { /* list is empty */
59+ QLIST_INSERT_HEAD_RCU(&ram_list.blocks, new_block, next);
60+ }
61+ ram_list.mru_block = NULL;
62+
63+ /* Write list before version */
64+ smp_wmb();
65+ ram_list.version++;
66+}
67+
68+void ram_block_add_list(RAMBlock *new_block)
69+{
70+ qemu_mutex_lock_ramlist();
71+ ram_block_add_list_locked(new_block);
72+ qemu_mutex_unlock_ramlist();
73+}
74+
75 static void ram_block_add(RAMBlock *new_block, Error **errp)
76 {
77 const bool noreserve = qemu_ram_is_noreserve(new_block);
78 const bool shared = qemu_ram_is_shared(new_block);
79- RAMBlock *block;
80- RAMBlock *last_block = NULL;
81 ram_addr_t old_ram_size, new_ram_size;
82 Error *err = NULL;
83
84@@ -1829,28 +1864,9 @@ static void ram_block_add(RAMBlock *new_block, Error **errp)
85 if (new_ram_size > old_ram_size) {
86 dirty_memory_extend(old_ram_size, new_ram_size);
87 }
88- /* Keep the list sorted from biggest to smallest block. Unlike QTAILQ,
89- * QLIST (which has an RCU-friendly variant) does not have insertion at
90- * tail, so save the last element in last_block.
91- */
92- RAMBLOCK_FOREACH(block) {
93- last_block = block;
94- if (block->max_length < new_block->max_length) {
95- break;
96- }
97- }
98- if (block) {
99- QLIST_INSERT_BEFORE_RCU(block, new_block, next);
100- } else if (last_block) {
101- QLIST_INSERT_AFTER_RCU(last_block, new_block, next);
102- } else { /* list is empty */
103- QLIST_INSERT_HEAD_RCU(&ram_list.blocks, new_block, next);
104- }
105- ram_list.mru_block = NULL;
106+
107+ ram_block_add_list_locked(new_block);
108
109- /* Write list before version */
110- smp_wmb();
111- ram_list.version++;
112 qemu_mutex_unlock_ramlist();
113
114 cpu_physical_memory_set_dirty_range(new_block->offset,
115--
1162.39.2
117
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0006-xen-add-pseudo-RAM-region-for-grant-mappings.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0006-xen-add-pseudo-RAM-region-for-grant-mappings.patch
new file mode 100644
index 00000000..a43748fe
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0006-xen-add-pseudo-RAM-region-for-grant-mappings.patch
@@ -0,0 +1,153 @@
1From 637d10471fef76a7ab0e8f5631ea3c85ff5ce9db Mon Sep 17 00:00:00 2001
2From: Juergen Gross <jgross@suse.com>
3Date: Thu, 20 May 2021 11:19:58 +0200
4Subject: [PATCH 06/11] xen: add pseudo RAM region for grant mappings
5
6Add a memory region which can be used to automatically map granted
7memory. It is starting at 0x8000000000000000ULL in order to be able to
8distinguish it from normal RAM.
9
10For this reason the xen.ram memory region is expanded, which has no
11further impact as it is used just as a container of the real RAM
12regions and now the grant region.
13
14Signed-off-by: Juergen Gross <jgross@suse.com>
15Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com>
16Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
17---
18 hw/i386/xen/xen-hvm.c | 3 +++
19 hw/xen/xen-hvm-common.c | 4 ++--
20 hw/xen/xen-mapcache.c | 27 +++++++++++++++++++++++++++
21 include/hw/xen/xen-hvm-common.h | 2 ++
22 include/hw/xen/xen_pvdev.h | 3 +++
23 include/sysemu/xen-mapcache.h | 3 +++
24 6 files changed, 40 insertions(+), 2 deletions(-)
25
26diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
27index f42621e674..67a55558a6 100644
28--- a/hw/i386/xen/xen-hvm.c
29+++ b/hw/i386/xen/xen-hvm.c
30@@ -172,6 +172,9 @@ static void xen_ram_init(PCMachineState *pcms,
31 x86ms->above_4g_mem_size);
32 memory_region_add_subregion(sysmem, 0x100000000ULL, &ram_hi);
33 }
34+
35+ /* Add grant mappings as a pseudo RAM region. */
36+ ram_grants = *xen_init_grant_ram();
37 }
38
39 static XenPhysmap *get_physmapping(hwaddr start_addr, ram_addr_t size)
40diff --git a/hw/xen/xen-hvm-common.c b/hw/xen/xen-hvm-common.c
41index 565dc39c8f..b7255977a5 100644
42--- a/hw/xen/xen-hvm-common.c
43+++ b/hw/xen/xen-hvm-common.c
44@@ -9,7 +9,7 @@
45 #include "hw/boards.h"
46 #include "hw/xen/arch_hvm.h"
47
48-MemoryRegion ram_memory;
49+MemoryRegion ram_memory, ram_grants;
50
51 void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr,
52 Error **errp)
53@@ -26,7 +26,7 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr,
54 return;
55 }
56
57- if (mr == &ram_memory) {
58+ if (mr == &ram_memory || mr == &ram_grants) {
59 return;
60 }
61
62diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
63index f7d974677d..8115c44c00 100644
64--- a/hw/xen/xen-mapcache.c
65+++ b/hw/xen/xen-mapcache.c
66@@ -14,7 +14,9 @@
67
68 #include <sys/resource.h>
69
70+#include "hw/xen/xen-hvm-common.h"
71 #include "hw/xen/xen_native.h"
72+#include "hw/xen/xen_pvdev.h"
73 #include "qemu/bitmap.h"
74
75 #include "sysemu/runstate.h"
76@@ -597,3 +599,28 @@ uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
77 mapcache_unlock();
78 return p;
79 }
80+
81+MemoryRegion *xen_init_grant_ram(void)
82+{
83+ RAMBlock *block;
84+
85+ memory_region_init(&ram_grants, NULL, "xen.grants",
86+ XEN_MAX_VIRTIO_GRANTS * XC_PAGE_SIZE);
87+ block = g_malloc0(sizeof(*block));
88+ block->mr = &ram_grants;
89+ block->used_length = XEN_MAX_VIRTIO_GRANTS * XC_PAGE_SIZE;
90+ block->max_length = XEN_MAX_VIRTIO_GRANTS * XC_PAGE_SIZE;
91+ block->fd = -1;
92+ block->page_size = XC_PAGE_SIZE;
93+ block->host = (void *)XEN_GRANT_ADDR_OFF;
94+ block->offset = XEN_GRANT_ADDR_OFF;
95+ block->flags = RAM_PREALLOC;
96+ ram_grants.ram_block = block;
97+ ram_grants.ram = true;
98+ ram_grants.terminates = true;
99+ ram_block_add_list(block);
100+ memory_region_add_subregion(get_system_memory(), XEN_GRANT_ADDR_OFF,
101+ &ram_grants);
102+
103+ return &ram_grants;
104+}
105diff --git a/include/hw/xen/xen-hvm-common.h b/include/hw/xen/xen-hvm-common.h
106index 4e9904f1a6..0d300ba898 100644
107--- a/include/hw/xen/xen-hvm-common.h
108+++ b/include/hw/xen/xen-hvm-common.h
109@@ -17,6 +17,8 @@
110 #include <xen/hvm/ioreq.h>
111
112 extern MemoryRegion ram_memory;
113+
114+extern MemoryRegion ram_grants;
115 extern MemoryListener xen_io_listener;
116 extern DeviceListener xen_device_listener;
117
118diff --git a/include/hw/xen/xen_pvdev.h b/include/hw/xen/xen_pvdev.h
119index ddad4b9f36..0f1b5edfa9 100644
120--- a/include/hw/xen/xen_pvdev.h
121+++ b/include/hw/xen/xen_pvdev.h
122@@ -80,4 +80,7 @@ int xen_pv_send_notify(struct XenLegacyDevice *xendev);
123 void xen_pv_printf(struct XenLegacyDevice *xendev, int msg_level,
124 const char *fmt, ...) G_GNUC_PRINTF(3, 4);
125
126+#define XEN_GRANT_ADDR_OFF 0x8000000000000000ULL
127+#define XEN_MAX_VIRTIO_GRANTS 65536
128+
129 #endif /* QEMU_HW_XEN_PVDEV_H */
130diff --git a/include/sysemu/xen-mapcache.h b/include/sysemu/xen-mapcache.h
131index c8e7c2f6cf..f4bedb1c11 100644
132--- a/include/sysemu/xen-mapcache.h
133+++ b/include/sysemu/xen-mapcache.h
134@@ -10,6 +10,7 @@
135 #define XEN_MAPCACHE_H
136
137 #include "exec/cpu-common.h"
138+#include "exec/ram_addr.h"
139
140 typedef hwaddr (*phys_offset_to_gaddr_t)(hwaddr phys_offset,
141 ram_addr_t size);
142@@ -25,6 +26,8 @@ void xen_invalidate_map_cache(void);
143 uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
144 hwaddr new_phys_addr,
145 hwaddr size);
146+MemoryRegion *xen_init_grant_ram(void);
147+
148 #else
149
150 static inline void xen_map_cache_init(phys_offset_to_gaddr_t f,
151--
1522.39.2
153
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0007-softmmu-let-qemu_map_ram_ptr-use-qemu_ram_ptr_length.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0007-softmmu-let-qemu_map_ram_ptr-use-qemu_ram_ptr_length.patch
new file mode 100644
index 00000000..ee400e2c
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0007-softmmu-let-qemu_map_ram_ptr-use-qemu_ram_ptr_length.patch
@@ -0,0 +1,117 @@
1From 82139e7e4bdcf5ca51b2ac90c63e4af699e3eb6f Mon Sep 17 00:00:00 2001
2From: Juergen Gross <jgross@suse.com>
3Date: Thu, 20 May 2021 11:54:48 +0200
4Subject: [PATCH 07/11] softmmu: let qemu_map_ram_ptr() use
5 qemu_ram_ptr_length()
6
7qemu_map_ram_ptr() and qemu_ram_ptr_length() share quite some code, so
8modify qemu_ram_ptr_length() a little bit and use it for
9qemu_map_ram_ptr(), too.
10
11Signed-off-by: Juergen Gross <jgross@suse.com>
12Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com>
13Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
14---
15 softmmu/physmem.c | 58 +++++++++++++++++++----------------------------
16 1 file changed, 23 insertions(+), 35 deletions(-)
17
18diff --git a/softmmu/physmem.c b/softmmu/physmem.c
19index f73629733e..a934e44fe7 100644
20--- a/softmmu/physmem.c
21+++ b/softmmu/physmem.c
22@@ -2123,38 +2123,8 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
23 }
24 #endif /* !_WIN32 */
25
26-/* Return a host pointer to ram allocated with qemu_ram_alloc.
27- * This should not be used for general purpose DMA. Use address_space_map
28- * or address_space_rw instead. For local memory (e.g. video ram) that the
29- * device owns, use memory_region_get_ram_ptr.
30- *
31- * Called within RCU critical section.
32- */
33-void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr)
34-{
35- RAMBlock *block = ram_block;
36-
37- if (block == NULL) {
38- block = qemu_get_ram_block(addr);
39- addr -= block->offset;
40- }
41-
42- if (xen_enabled() && block->host == NULL) {
43- /* We need to check if the requested address is in the RAM
44- * because we don't want to map the entire memory in QEMU.
45- * In that case just map until the end of the page.
46- */
47- if (block->offset == 0) {
48- return xen_map_cache(addr, 0, 0, false);
49- }
50-
51- block->host = xen_map_cache(block->offset, block->max_length, 1, false);
52- }
53- return ramblock_ptr(block, addr);
54-}
55-
56-/* Return a host pointer to guest's ram. Similar to qemu_map_ram_ptr
57- * but takes a size argument.
58+/*
59+ * Return a host pointer to guest's ram.
60 *
61 * Called within RCU critical section.
62 */
63@@ -2162,7 +2132,9 @@ static void *qemu_ram_ptr_length(RAMBlock *ram_block, ram_addr_t addr,
64 hwaddr *size, bool lock)
65 {
66 RAMBlock *block = ram_block;
67- if (*size == 0) {
68+ hwaddr len = 0;
69+
70+ if (size && *size == 0) {
71 return NULL;
72 }
73
74@@ -2170,7 +2142,10 @@ static void *qemu_ram_ptr_length(RAMBlock *ram_block, ram_addr_t addr,
75 block = qemu_get_ram_block(addr);
76 addr -= block->offset;
77 }
78- *size = MIN(*size, block->max_length - addr);
79+ if (size) {
80+ *size = MIN(*size, block->max_length - addr);
81+ len = *size;
82+ }
83
84 if (xen_enabled() && block->host == NULL) {
85 /* We need to check if the requested address is in the RAM
86@@ -2178,7 +2153,7 @@ static void *qemu_ram_ptr_length(RAMBlock *ram_block, ram_addr_t addr,
87 * In that case just map the requested area.
88 */
89 if (block->offset == 0) {
90- return xen_map_cache(addr, *size, lock, lock);
91+ return xen_map_cache(addr, len, lock, lock);
92 }
93
94 block->host = xen_map_cache(block->offset, block->max_length, 1, lock);
95@@ -2187,6 +2162,19 @@ static void *qemu_ram_ptr_length(RAMBlock *ram_block, ram_addr_t addr,
96 return ramblock_ptr(block, addr);
97 }
98
99+/*
100+ * Return a host pointer to ram allocated with qemu_ram_alloc.
101+ * This should not be used for general purpose DMA. Use address_space_map
102+ * or address_space_rw instead. For local memory (e.g. video ram) that the
103+ * device owns, use memory_region_get_ram_ptr.
104+ *
105+ * Called within RCU critical section.
106+ */
107+void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr)
108+{
109+ return qemu_ram_ptr_length(ram_block, addr, NULL, false);
110+}
111+
112 /* Return the offset of a hostpointer within a ramblock */
113 ram_addr_t qemu_ram_block_host_offset(RAMBlock *rb, void *host)
114 {
115--
1162.39.2
117
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0008-xen-let-xen_ram_addr_from_mapcache-return-1-in-case-.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0008-xen-let-xen_ram_addr_from_mapcache-return-1-in-case-.patch
new file mode 100644
index 00000000..c1e9abd9
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0008-xen-let-xen_ram_addr_from_mapcache-return-1-in-case-.patch
@@ -0,0 +1,49 @@
1From 857bcafe8beb5a0cd78c070f432108049661a56d Mon Sep 17 00:00:00 2001
2From: Juergen Gross <jgross@suse.com>
3Date: Thu, 20 May 2021 13:31:32 +0200
4Subject: [PATCH 08/11] xen: let xen_ram_addr_from_mapcache() return -1 in case
5 of not found entry
6
7Today xen_ram_addr_from_mapcache() will either abort() or return 0 in
8case it can't find a matching entry for a pointer value. Both cases
9are bad, so change that to return an invalid address instead.
10
11Signed-off-by: Juergen Gross <jgross@suse.com>
12Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
13---
14 hw/xen/xen-mapcache.c | 12 +++---------
15 1 file changed, 3 insertions(+), 9 deletions(-)
16
17diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
18index 8115c44c00..8a61c7dde6 100644
19--- a/hw/xen/xen-mapcache.c
20+++ b/hw/xen/xen-mapcache.c
21@@ -404,13 +404,8 @@ ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
22 }
23 }
24 if (!found) {
25- fprintf(stderr, "%s, could not find %p\n", __func__, ptr);
26- QTAILQ_FOREACH(reventry, &mapcache->locked_entries, next) {
27- DPRINTF(" "HWADDR_FMT_plx" -> %p is present\n", reventry->paddr_index,
28- reventry->vaddr_req);
29- }
30- abort();
31- return 0;
32+ mapcache_unlock();
33+ return RAM_ADDR_INVALID;
34 }
35
36 entry = &mapcache->entry[paddr_index % mapcache->nr_buckets];
37@@ -418,8 +413,7 @@ ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
38 entry = entry->next;
39 }
40 if (!entry) {
41- DPRINTF("Trying to find address %p that is not in the mapcache!\n", ptr);
42- raddr = 0;
43+ raddr = RAM_ADDR_INVALID;
44 } else {
45 raddr = (reventry->paddr_index << MCACHE_BUCKET_SHIFT) +
46 ((unsigned long) ptr - (unsigned long) entry->vaddr_base);
47--
482.39.2
49
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0009-memory-add-MemoryRegion-map-and-unmap-callbacks.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0009-memory-add-MemoryRegion-map-and-unmap-callbacks.patch
new file mode 100644
index 00000000..fa18ef16
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0009-memory-add-MemoryRegion-map-and-unmap-callbacks.patch
@@ -0,0 +1,155 @@
1From 364a11be6274336ec9b0f06f3272f964d27c9349 Mon Sep 17 00:00:00 2001
2From: Juergen Gross <jgross@suse.com>
3Date: Thu, 27 May 2021 15:27:55 +0200
4Subject: [PATCH 09/11] memory: add MemoryRegion map and unmap callbacks
5
6In order to support mapping and unmapping guest memory dynamically to
7and from qemu during address_space_[un]map() operations add the map()
8and unmap() callbacks to MemoryRegionOps.
9
10Those will be used e.g. for Xen grant mappings when performing guest
11I/Os.
12
13Signed-off-by: Juergen Gross <jgross@suse.com>
14Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com>
15---
16 include/exec/memory.h | 21 ++++++++++++++++++
17 softmmu/physmem.c | 50 +++++++++++++++++++++++++++++++++----------
18 2 files changed, 60 insertions(+), 11 deletions(-)
19
20diff --git a/include/exec/memory.h b/include/exec/memory.h
21index 68284428f8..55414417ab 100644
22--- a/include/exec/memory.h
23+++ b/include/exec/memory.h
24@@ -274,6 +274,27 @@ struct MemoryRegionOps {
25 unsigned size,
26 MemTxAttrs attrs);
27
28+ /*
29+ * Dynamically create mapping. @addr is the guest address to map; @plen
30+ * is the pointer to the usable length of the buffer.
31+ * @mr contents can be changed in case a new memory region is created for
32+ * the mapping.
33+ * Returns the buffer address for accessing the data.
34+ */
35+ void *(*map)(MemoryRegion **mr,
36+ hwaddr addr,
37+ hwaddr *plen,
38+ bool is_write,
39+ MemTxAttrs attrs);
40+
41+ /* Unmap an area obtained via map() before. */
42+ void (*unmap)(MemoryRegion *mr,
43+ void *buffer,
44+ ram_addr_t addr,
45+ hwaddr len,
46+ bool is_write,
47+ hwaddr access_len);
48+
49 enum device_endian endianness;
50 /* Guest-visible constraints: */
51 struct {
52diff --git a/softmmu/physmem.c b/softmmu/physmem.c
53index a934e44fe7..a1e2030424 100644
54--- a/softmmu/physmem.c
55+++ b/softmmu/physmem.c
56@@ -3070,6 +3070,7 @@ void *address_space_map(AddressSpace *as,
57 hwaddr len = *plen;
58 hwaddr l, xlat;
59 MemoryRegion *mr;
60+ void *ptr = NULL;
61 FlatView *fv;
62
63 if (len == 0) {
64@@ -3103,12 +3104,20 @@ void *address_space_map(AddressSpace *as,
65 return bounce.buffer;
66 }
67
68-
69 memory_region_ref(mr);
70+
71+ if (mr->ops && mr->ops->map) {
72+ ptr = mr->ops->map(&mr, addr, plen, is_write, attrs);
73+ }
74+
75 *plen = flatview_extend_translation(fv, addr, len, mr, xlat,
76 l, is_write, attrs);
77 fuzz_dma_read_cb(addr, *plen, mr);
78- return qemu_ram_ptr_length(mr->ram_block, xlat, plen, true);
79+ if (ptr == NULL) {
80+ ptr = qemu_ram_ptr_length(mr->ram_block, xlat, plen, true);
81+ }
82+
83+ return ptr;
84 }
85
86 /* Unmaps a memory region previously mapped by address_space_map().
87@@ -3124,11 +3133,16 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
88
89 mr = memory_region_from_host(buffer, &addr1);
90 assert(mr != NULL);
91- if (is_write) {
92- invalidate_and_set_dirty(mr, addr1, access_len);
93- }
94- if (xen_enabled()) {
95- xen_invalidate_map_cache_entry(buffer);
96+
97+ if (mr->ops && mr->ops->unmap) {
98+ mr->ops->unmap(mr, buffer, addr1, len, is_write, access_len);
99+ } else {
100+ if (is_write) {
101+ invalidate_and_set_dirty(mr, addr1, access_len);
102+ }
103+ if (xen_enabled()) {
104+ xen_invalidate_map_cache_entry(buffer);
105+ }
106 }
107 memory_region_unref(mr);
108 return;
109@@ -3201,10 +3215,18 @@ int64_t address_space_cache_init(MemoryRegionCache *cache,
110 * doing this if we found actual RAM, which behaves the same
111 * regardless of attributes; so UNSPECIFIED is fine.
112 */
113+ if (mr->ops && mr->ops->map) {
114+ cache->ptr = mr->ops->map(&mr, addr, &l, is_write,
115+ MEMTXATTRS_UNSPECIFIED);
116+ }
117+
118 l = flatview_extend_translation(cache->fv, addr, len, mr,
119 cache->xlat, l, is_write,
120 MEMTXATTRS_UNSPECIFIED);
121- cache->ptr = qemu_ram_ptr_length(mr->ram_block, cache->xlat, &l, true);
122+ if (!cache->ptr) {
123+ cache->ptr = qemu_ram_ptr_length(mr->ram_block, cache->xlat, &l,
124+ true);
125+ }
126 } else {
127 cache->ptr = NULL;
128 }
129@@ -3226,14 +3248,20 @@ void address_space_cache_invalidate(MemoryRegionCache *cache,
130
131 void address_space_cache_destroy(MemoryRegionCache *cache)
132 {
133- if (!cache->mrs.mr) {
134+ MemoryRegion *mr = cache->mrs.mr;
135+
136+ if (!mr) {
137 return;
138 }
139
140- if (xen_enabled()) {
141+ if (mr->ops && mr->ops->unmap) {
142+ mr->ops->unmap(mr, cache->ptr, cache->xlat, cache->len,
143+ cache->is_write, cache->len);
144+ } else if (xen_enabled()) {
145 xen_invalidate_map_cache_entry(cache->ptr);
146 }
147- memory_region_unref(cache->mrs.mr);
148+
149+ memory_region_unref(mr);
150 flatview_unref(cache->fv);
151 cache->mrs.mr = NULL;
152 cache->fv = NULL;
153--
1542.39.2
155
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0010-xen-add-map-and-unmap-callbacks-for-grant-region.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0010-xen-add-map-and-unmap-callbacks-for-grant-region.patch
new file mode 100644
index 00000000..48dcf7d7
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0010-xen-add-map-and-unmap-callbacks-for-grant-region.patch
@@ -0,0 +1,262 @@
1From 90496d4c71e3b9334aebca118661bf72631ed0f0 Mon Sep 17 00:00:00 2001
2From: Juergen Gross <jgross@suse.com>
3Date: Fri, 26 Aug 2022 13:57:06 +0200
4Subject: [PATCH 10/11] xen: add map and unmap callbacks for grant region
5
6Add the callbacks for mapping/unmapping guest memory via grants to the
7special grant memory region.
8
9Signed-off-by: Juergen Gross <jgross@suse.com>
10Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com>
11---
12 hw/xen/xen-mapcache.c | 176 +++++++++++++++++++++++++++++++++++++++++-
13 softmmu/physmem.c | 11 ++-
14 2 files changed, 182 insertions(+), 5 deletions(-)
15
16diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
17index 8a61c7dde6..e071328fc5 100644
18--- a/hw/xen/xen-mapcache.c
19+++ b/hw/xen/xen-mapcache.c
20@@ -9,6 +9,8 @@
21 */
22
23 #include "qemu/osdep.h"
24+#include "qemu/queue.h"
25+#include "qemu/thread.h"
26 #include "qemu/units.h"
27 #include "qemu/error-report.h"
28
29@@ -23,6 +25,8 @@
30 #include "sysemu/xen-mapcache.h"
31 #include "trace.h"
32
33+#include <xenevtchn.h>
34+#include <xengnttab.h>
35
36 //#define MAPCACHE_DEBUG
37
38@@ -385,7 +389,7 @@ uint8_t *xen_map_cache(hwaddr phys_addr, hwaddr size,
39 return p;
40 }
41
42-ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
43+static ram_addr_t xen_ram_addr_from_mapcache_try(void *ptr)
44 {
45 MapCacheEntry *entry = NULL;
46 MapCacheRev *reventry;
47@@ -594,10 +598,179 @@ uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
48 return p;
49 }
50
51+struct XENMappedGrantRegion {
52+ void *addr;
53+ unsigned int pages;
54+ unsigned int refs;
55+ unsigned int prot;
56+ uint32_t idx;
57+ QLIST_ENTRY(XENMappedGrantRegion) list;
58+};
59+
60+static xengnttab_handle *xen_region_gnttabdev;
61+static QLIST_HEAD(GrantRegionList, XENMappedGrantRegion) xen_grant_mappings =
62+ QLIST_HEAD_INITIALIZER(xen_grant_mappings);
63+static QemuMutex xen_map_mutex;
64+
65+static void *xen_map_grant_dyn(MemoryRegion **mr, hwaddr addr, hwaddr *plen,
66+ bool is_write, MemTxAttrs attrs)
67+{
68+ unsigned int page_off = addr & (XC_PAGE_SIZE - 1);
69+ unsigned int i;
70+ unsigned int total_grants = 0;
71+ unsigned int nrefs = (page_off + *plen + XC_PAGE_SIZE - 1) >> XC_PAGE_SHIFT;
72+ uint32_t ref = (addr - XEN_GRANT_ADDR_OFF) >> XC_PAGE_SHIFT;
73+ uint32_t *refs = NULL;
74+ unsigned int prot = PROT_READ;
75+ struct XENMappedGrantRegion *mgr = NULL;
76+
77+ if (is_write) {
78+ prot |= PROT_WRITE;
79+ }
80+
81+ qemu_mutex_lock(&xen_map_mutex);
82+
83+ QLIST_FOREACH(mgr, &xen_grant_mappings, list) {
84+ if (mgr->idx == ref &&
85+ mgr->pages == nrefs &&
86+ (mgr->prot & prot) == prot) {
87+ break;
88+ }
89+
90+ total_grants += mgr->pages;
91+ }
92+
93+ if (!mgr) {
94+ if (nrefs + total_grants >= XEN_MAX_VIRTIO_GRANTS) {
95+ qemu_mutex_unlock(&xen_map_mutex);
96+ return NULL;
97+ }
98+
99+ mgr = g_new(struct XENMappedGrantRegion, 1);
100+
101+ if (nrefs == 1) {
102+ refs = &ref;
103+ } else {
104+ refs = g_new(uint32_t, nrefs);
105+ for (i = 0; i < nrefs; i++) {
106+ refs[i] = ref + i;
107+ }
108+ }
109+ mgr->addr = xengnttab_map_domain_grant_refs(xen_region_gnttabdev, nrefs,
110+ xen_domid, refs, prot);
111+ if (mgr->addr) {
112+ mgr->pages = nrefs;
113+ mgr->refs = 1;
114+ mgr->prot = prot;
115+ mgr->idx = ref;
116+
117+ QLIST_INSERT_HEAD(&xen_grant_mappings, mgr, list);
118+ } else {
119+ g_free(mgr);
120+ mgr = NULL;
121+ }
122+ } else {
123+ mgr->refs++;
124+ }
125+
126+ qemu_mutex_unlock(&xen_map_mutex);
127+
128+ if (nrefs > 1) {
129+ g_free(refs);
130+ }
131+
132+ return mgr ? mgr->addr + page_off : NULL;
133+}
134+
135+static void xen_unmap_grant_dyn(MemoryRegion *mr, void *buffer, ram_addr_t addr,
136+ hwaddr len, bool is_write, hwaddr access_len)
137+{
138+ unsigned int page_off = (unsigned long)buffer & (XC_PAGE_SIZE - 1);
139+ unsigned int nrefs = (page_off + len + XC_PAGE_SIZE - 1) >> XC_PAGE_SHIFT;
140+ unsigned int prot = PROT_READ;
141+ struct XENMappedGrantRegion *mgr = NULL;
142+
143+ if (is_write) {
144+ prot |= PROT_WRITE;
145+ }
146+
147+ qemu_mutex_lock(&xen_map_mutex);
148+
149+ QLIST_FOREACH(mgr, &xen_grant_mappings, list) {
150+ if (mgr->addr == buffer - page_off &&
151+ mgr->pages == nrefs &&
152+ (mgr->prot & prot) == prot) {
153+ break;
154+ }
155+ }
156+ if (mgr) {
157+ mgr->refs--;
158+ if (!mgr->refs) {
159+ xengnttab_unmap(xen_region_gnttabdev, mgr->addr, nrefs);
160+
161+ QLIST_REMOVE(mgr, list);
162+ g_free(mgr);
163+ }
164+ } else {
165+ error_report("xen_unmap_grant_dyn() trying to unmap unknown buffer");
166+ }
167+
168+ qemu_mutex_unlock(&xen_map_mutex);
169+}
170+
171+static ram_addr_t xen_ram_addr_from_grant_cache(void *ptr)
172+{
173+ unsigned int page_off = (unsigned long)ptr & (XC_PAGE_SIZE - 1);
174+ struct XENMappedGrantRegion *mgr = NULL;
175+ ram_addr_t raddr = RAM_ADDR_INVALID;
176+
177+ qemu_mutex_lock(&xen_map_mutex);
178+
179+ QLIST_FOREACH(mgr, &xen_grant_mappings, list) {
180+ if (mgr->addr == ptr - page_off) {
181+ break;
182+ }
183+ }
184+
185+ if (mgr) {
186+ raddr = (mgr->idx << XC_PAGE_SHIFT) + page_off + XEN_GRANT_ADDR_OFF;
187+ }
188+
189+ qemu_mutex_unlock(&xen_map_mutex);
190+
191+ return raddr;
192+}
193+
194+ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
195+{
196+ ram_addr_t raddr;
197+
198+ raddr = xen_ram_addr_from_mapcache_try(ptr);
199+ if (raddr == RAM_ADDR_INVALID) {
200+ raddr = xen_ram_addr_from_grant_cache(ptr);
201+ }
202+
203+ return raddr;
204+}
205+
206+static const struct MemoryRegionOps xen_grant_mr_ops = {
207+ .map = xen_map_grant_dyn,
208+ .unmap = xen_unmap_grant_dyn,
209+ .endianness = DEVICE_LITTLE_ENDIAN,
210+};
211+
212 MemoryRegion *xen_init_grant_ram(void)
213 {
214 RAMBlock *block;
215
216+ qemu_mutex_init(&xen_map_mutex);
217+
218+ xen_region_gnttabdev = xengnttab_open(NULL, 0);
219+ if (xen_region_gnttabdev == NULL) {
220+ fprintf(stderr, "can't open gnttab device\n");
221+ return NULL;
222+ }
223+
224 memory_region_init(&ram_grants, NULL, "xen.grants",
225 XEN_MAX_VIRTIO_GRANTS * XC_PAGE_SIZE);
226 block = g_malloc0(sizeof(*block));
227@@ -612,6 +785,7 @@ MemoryRegion *xen_init_grant_ram(void)
228 ram_grants.ram_block = block;
229 ram_grants.ram = true;
230 ram_grants.terminates = true;
231+ ram_grants.ops = &xen_grant_mr_ops;
232 ram_block_add_list(block);
233 memory_region_add_subregion(get_system_memory(), XEN_GRANT_ADDR_OFF,
234 &ram_grants);
235diff --git a/softmmu/physmem.c b/softmmu/physmem.c
236index a1e2030424..e1057304f1 100644
237--- a/softmmu/physmem.c
238+++ b/softmmu/physmem.c
239@@ -2210,13 +2210,16 @@ RAMBlock *qemu_ram_block_from_host(void *ptr, bool round_offset,
240
241 if (xen_enabled()) {
242 ram_addr_t ram_addr;
243+
244 RCU_READ_LOCK_GUARD();
245 ram_addr = xen_ram_addr_from_mapcache(ptr);
246- block = qemu_get_ram_block(ram_addr);
247- if (block) {
248- *offset = ram_addr - block->offset;
249+ if (ram_addr != RAM_ADDR_INVALID) {
250+ block = qemu_get_ram_block(ram_addr);
251+ if (block) {
252+ *offset = ram_addr - block->offset;
253+ }
254+ return block;
255 }
256- return block;
257 }
258
259 RCU_READ_LOCK_GUARD();
260--
2612.39.2
262
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0011-hw-arm-Add-grant-mapping.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0011-hw-arm-Add-grant-mapping.patch
new file mode 100644
index 00000000..fb5450e6
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0011-hw-arm-Add-grant-mapping.patch
@@ -0,0 +1,30 @@
1From b1eaba758a9000061fc53a934c348d6ef8dcdf64 Mon Sep 17 00:00:00 2001
2From: Vikram Garhwal <vikram.garhwal@amd.com>
3Date: Tue, 31 Jan 2023 21:46:43 +0000
4Subject: [PATCH 11/11] hw: arm: Add grant mapping.
5
6Enable grant ram mapping support for Xenpvh machine on ARM.
7
8Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com>
9Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
10---
11 hw/arm/xen_arm.c | 3 +++
12 1 file changed, 3 insertions(+)
13
14diff --git a/hw/arm/xen_arm.c b/hw/arm/xen_arm.c
15index a5631529d0..1587e2a43b 100644
16--- a/hw/arm/xen_arm.c
17+++ b/hw/arm/xen_arm.c
18@@ -127,6 +127,9 @@ static void xen_init_ram(MachineState *machine)
19 DPRINTF("Initialized region xen.ram.hi: base 0x%llx size 0x%lx\n",
20 GUEST_RAM1_BASE, ram_size[1]);
21 }
22+
23+ DPRINTF("init grant ram mapping for XEN\n");
24+ ram_grants = *xen_init_grant_ram();
25 }
26
27 void arch_handle_ioreq(XenIOState *state, ioreq_t *req)
28--
292.39.2
30
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-native_%.bbappend b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-native_%.bbappend
new file mode 100644
index 00000000..e84844cf
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-native_%.bbappend
@@ -0,0 +1 @@
require qemu-tpm.inc
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-system-native_%.bbappend b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-system-native_%.bbappend
new file mode 100644
index 00000000..e84844cf
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-system-native_%.bbappend
@@ -0,0 +1 @@
require qemu-tpm.inc
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx_2023%.bbappend b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx_2023%.bbappend
new file mode 100644
index 00000000..5cb9f0d0
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx_2023%.bbappend
@@ -0,0 +1,5 @@
1require qemu-tpm.inc
2require qemu-xen_7.1.inc
3
4# We do not want QEMU, on the target to be configured with OpenGL
5PACKAGECONFIG:remove:class-target = "virglrenderer epoxy gtk+"
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx_2024%.bbappend b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx_2024%.bbappend
new file mode 100644
index 00000000..2f8e55aa
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx_2024%.bbappend
@@ -0,0 +1,5 @@
1require qemu-tpm.inc
2require qemu-xen_8.1.inc
3
4# We do not want QEMU, on the target to be configured with OpenGL
5PACKAGECONFIG:remove:class-target:petalinux = "virglrenderer epoxy gtk+"
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu_7.1%.bbappend b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu_7.1%.bbappend
new file mode 100644
index 00000000..5cb9f0d0
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu_7.1%.bbappend
@@ -0,0 +1,5 @@
1require qemu-tpm.inc
2require qemu-xen_7.1.inc
3
4# We do not want QEMU, on the target to be configured with OpenGL
5PACKAGECONFIG:remove:class-target = "virglrenderer epoxy gtk+"
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu_8.1%.bbappend b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu_8.1%.bbappend
new file mode 100644
index 00000000..95b1902b
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu_8.1%.bbappend
@@ -0,0 +1,5 @@
1require qemu-tpm.inc
2require qemu-xen_8.1.inc
3
4# We do not want QEMU, on the target to be configured with OpenGL
5PACKAGECONFIG:remove:class-target = "virglrenderer epoxy gtk+"
diff --git a/meta-xilinx-virtualization/recipes-extended/xen/files/0001-menuconfig-mconf-cfg-Allow-specification-of-ncurses-location.patch b/meta-xilinx-virtualization/recipes-extended/xen/files/0001-menuconfig-mconf-cfg-Allow-specification-of-ncurses-location.patch
new file mode 100644
index 00000000..135860ab
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-extended/xen/files/0001-menuconfig-mconf-cfg-Allow-specification-of-ncurses-location.patch
@@ -0,0 +1,57 @@
1From b300c18ab899b3c899e5405c96c20a32e51d77c8 Mon Sep 17 00:00:00 2001
2From: Bruce Ashfield <bruce.ashfield@windriver.com>
3Date: Mon, 2 Jul 2018 23:10:28 -0400
4Subject: [PATCH] xen: Fix menuconfig and add support for config fragments and
5
6Upstream-Status: Xen: Inappropriate [oe specific, cross compile issue]
7Upstream-Status: Kernel: Pending
8Signed-off-by: Diego Sueiro <diego.sueiro@arm.com>
9commit e6972e689a980ab28637e94e48c77eeace6abde5
10
11 xen/kconfig,menuconfig,mconf-cfg: Allow specification of ncurses location
12
13 In some cross build environments such as the Yocto Project build
14 environment it provides an ncurses library that is compiled
15 differently than the host's version. This causes display corruption
16 problems when the host's curses includes are used instead of the
17 includes from the provided compiler are overridden. There is a second
18 case where there is no curses libraries at all on the host system and
19 menuconfig will just fail entirely.
20
21 The solution is simply to allow an override variable in
22 check-lxdialog.sh for environments such as the Yocto Project. Adding
23 a CROSS_CURSES_LIB and CROSS_CURSES_INC solves the issue and allowing
24 compiling and linking against the right headers and libraries.
25
26 Change-Id: Ibe8dfafc90655e3be2671dbbb0cb7f5631fc4d44
27 Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
28 cc: Michal Marek <mmarek@suse.cz>
29 cc: linux-kbuild@vger.kernel.org
30 Signed-off-by: Bruce Ashfield <bruce.ashfield@windriver.com>
31
32---
33 xen/tools/kconfig/mconf-cfg.sh | 8 ++++++++
34 1 file changed, 8 insertions(+)
35 mode change 100755 => 100644 xen/tools/kconfig/mconf-cfg.sh
36
37diff --git a/xen/tools/kconfig/mconf-cfg.sh b/xen/tools/kconfig/mconf-cfg.sh
38old mode 100755
39new mode 100644
40index c812872d7f..56eb4fc79f
41--- a/xen/tools/kconfig/mconf-cfg.sh
42+++ b/xen/tools/kconfig/mconf-cfg.sh
43@@ -4,6 +4,14 @@
44 PKG="ncursesw"
45 PKG2="ncurses"
46
47+if [ "$CROSS_CURSES_LIB" != "" ]; then
48+ echo libs=\'$CROSS_CURSES_LIB\'
49+ if [ x"$CROSS_CURSES_INC" != x ]; then
50+ echo cflags=\'$CROSS_CURSES_INC\'
51+ fi
52+ exit 0
53+fi
54+
55 if [ -n "$(command -v pkg-config)" ]; then
56 if pkg-config --exists $PKG; then
57 echo cflags=\"$(pkg-config --cflags $PKG)\"
diff --git a/meta-xilinx-virtualization/recipes-extended/xen/files/0001-python-pygrub-pass-DISTUTILS-xen-4.15.patch b/meta-xilinx-virtualization/recipes-extended/xen/files/0001-python-pygrub-pass-DISTUTILS-xen-4.15.patch
new file mode 100644
index 00000000..35cd9a81
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-extended/xen/files/0001-python-pygrub-pass-DISTUTILS-xen-4.15.patch
@@ -0,0 +1,73 @@
1From 6db88791d923167f160afbcadeffad84a4cbdbc5 Mon Sep 17 00:00:00 2001
2Message-Id: <6db88791d923167f160afbcadeffad84a4cbdbc5.1612262706.git.bertrand.marquis@arm.com>
3From: Maciej Pijanowski <maciej.pijanowski@3mdeb.com>
4Date: Fri, 19 Oct 2018 11:01:37 +0200
5Subject: [PATCH] python,pygrub: pass DISTUTILS env vars as setup.py args
6
7Upstream-Status: Xen: Inappropriate [oe specific, python install issues]
8
9Allow to respect the target install dir (PYTHON_SITEPACKAGES_DIR)
10as well as other parameters set by the OpenEmbedded build system.
11This is especially useful when the target libdir is not the default one
12(/usr/lib), but for example /usr/lib64.
13
14Signed-off-by: Maciej Pijanowski <maciej.pijanowski@3mdeb.com>
15
16Forward-ported to Xen 4.12.0
17Signed-off-by: Christopher Clark <christopher.clark6@baesystems.com>
18
19Modified to support pygrub installation with python 3
20Signed-off-by: Christopher Clark <christopher.clark6@baesystems.com>
21
22Forward-ported to Xen 4.14.0
23Signed-off-by: Christopher Clark <christopher.clark6@baesystems.com>
24
25Forward-ported to Xen 4.15.0
26Signed-off-by: Bertrand Marquis <bertrand.marquis@arm.com>
27
28---
29 tools/pygrub/Makefile | 7 +++++--
30 tools/python/Makefile | 2 +-
31 2 files changed, 6 insertions(+), 3 deletions(-)
32
33diff --git a/tools/pygrub/Makefile b/tools/pygrub/Makefile
34index 37b2146214..ffb9270065 100644
35--- a/tools/pygrub/Makefile
36+++ b/tools/pygrub/Makefile
37@@ -10,7 +10,7 @@ INSTALL_LOG = build/installed_files.txt
38 all: build
39 .PHONY: build
40 build:
41- CC="$(CC)" CFLAGS="$(PY_CFLAGS)" LDSHARED="$(CC)" LDFLAGS="$(PY_LDFLAGS)" $(PYTHON) setup.py build
42+ CC="$(CC)" CFLAGS="$(PY_CFLAGS)" LDSHARED="$(CC)" LDFLAGS="$(PY_LDFLAGS)" $(PYTHON) setup.py build $(DISTUTILS_BUILD_ARGS)
43
44 .PHONY: install
45 install: all
46@@ -18,7 +18,10 @@ install: all
47 CC="$(CC)" CFLAGS="$(PY_CFLAGS)" LDSHARED="$(CC)" \
48 LDFLAGS="$(PY_LDFLAGS)" $(PYTHON) setup.py install \
49 --record $(INSTALL_LOG) $(PYTHON_PREFIX_ARG) \
50- --root="$(DESTDIR)" --install-scripts=$(LIBEXEC_BIN) --force
51+ --root="$(DESTDIR)" --install-scripts=$(LIBEXEC_BIN) --force \
52+ $(DISTUTILS_INSTALL_ARGS)
53+ rm -f $(DESTDIR)/$(LIBEXEC_BIN)/pygrub
54+ $(INSTALL_PYTHON_PROG) src/pygrub $(DESTDIR)/$(LIBEXEC_BIN)/pygrub
55 set -e; if [ $(bindir) != $(LIBEXEC_BIN) -a \
56 "`readlink -f $(DESTDIR)/$(bindir)`" != \
57 "`readlink -f $(LIBEXEC_BIN)`" ]; then \
58diff --git a/tools/python/Makefile b/tools/python/Makefile
59index cc76423647..5cb11ae453 100644
60--- a/tools/python/Makefile
61+++ b/tools/python/Makefile
62@@ -12,7 +12,7 @@ setup.py = CC="$(CC)" CFLAGS="$(PY_CFLAGS)" LDSHARED="$(CC)" LDFLAGS="$(PY_LDFLA
63 SHLIB_libxenctrl="$(SHLIB_libxenctrl)" \
64 SHLIB_libxenguest="$(SHLIB_libxenguest)" \
65 SHLIB_libxenstore="$(SHLIB_libxenstore)" \
66- $(PYTHON) setup.py
67+ $(PYTHON) setup.py $(DISTUTILS_BUILD_ARGS)
68
69 .PHONY: build
70 build:
71--
722.17.1
73
diff --git a/meta-xilinx-virtualization/recipes-extended/xen/files/0001-python-pygrub-pass-DISTUTILS-xen-4.18.patch b/meta-xilinx-virtualization/recipes-extended/xen/files/0001-python-pygrub-pass-DISTUTILS-xen-4.18.patch
new file mode 100644
index 00000000..7ac1a399
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-extended/xen/files/0001-python-pygrub-pass-DISTUTILS-xen-4.18.patch
@@ -0,0 +1,43 @@
1Upstream-Status: Pending
2
3diff --git a/tools/pygrub/Makefile b/tools/pygrub/Makefile
4index 4963bc89c6..c1c05eb421 100644
5--- a/tools/pygrub/Makefile
6+++ b/tools/pygrub/Makefile
7@@ -13,14 +13,14 @@ setup.py = CC="$(CC)" CFLAGS="$(PY_CFLAGS)" LDSHARED="$(CC)" LDFLAGS="$(PY_LDFLA
8 all: build
9 .PHONY: build
10 build:
11- $(setup.py) build
12+ $(setup.py) build $(DISTUTILS_BUILD_ARGS)
13
14 .PHONY: install
15 install: all
16 $(INSTALL_DIR) $(DESTDIR)/$(bindir)
17 $(INSTALL_DIR) $(DESTDIR)/$(LIBEXEC_BIN)
18 $(setup.py) install --record $(INSTALL_LOG) $(PYTHON_PREFIX_ARG) \
19- --root="$(DESTDIR)" --force
20+ --root="$(DESTDIR)" --force $(DISTUTILS_INSTALL_ARGS)
21 $(INSTALL_PYTHON_PROG) src/pygrub $(DESTDIR)/$(LIBEXEC_BIN)/pygrub
22 set -e; if [ $(bindir) != $(LIBEXEC_BIN) -a \
23 "`readlink -f $(DESTDIR)/$(bindir)`" != \
24diff --git a/tools/python/Makefile b/tools/python/Makefile
25index 437431c48e..0a99c2067e 100644
26--- a/tools/python/Makefile
27+++ b/tools/python/Makefile
28@@ -16,13 +16,13 @@ setup.py = CC="$(CC)" CFLAGS="$(PY_CFLAGS)" LDSHARED="$(CC)" LDFLAGS="$(PY_LDFLA
29
30 .PHONY: build
31 build:
32- $(setup.py) build
33+ $(setup.py) build $(DISTUTILS_BUILD_ARGS)
34
35 .PHONY: install
36 install:
37 $(INSTALL_DIR) $(DESTDIR)$(LIBEXEC_BIN)
38 $(setup.py) install --record $(INSTALL_LOG) $(PYTHON_PREFIX_ARG) \
39- --root="$(DESTDIR)" --force
40+ --root="$(DESTDIR)" --force $(DISTUTILS_INSTALL_ARGS)
41 $(INSTALL_PYTHON_PROG) scripts/convert-legacy-stream $(DESTDIR)$(LIBEXEC_BIN)
42 $(INSTALL_PYTHON_PROG) scripts/verify-stream-v2 $(DESTDIR)$(LIBEXEC_BIN)
43
diff --git a/meta-xilinx-virtualization/recipes-extended/xen/files/xen-flask-race-fix.patch b/meta-xilinx-virtualization/recipes-extended/xen/files/xen-flask-race-fix.patch
new file mode 100644
index 00000000..fa2a82ff
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-extended/xen/files/xen-flask-race-fix.patch
@@ -0,0 +1,54 @@
1From mboxrd@z Thu Jan 1 00:00:00 1970
2From: Anthony PERARD <anthony.perard@citrix.com>
3Subject: [XEN PATCH] build: fix building flask headers before descending in flask/ss/
4Date: Fri, 20 Jan 2023 13:36:26 +0000
5Message-ID: <20230120133626.55680-1-anthony.perard@citrix.com>
6X-Mailer: git-send-email 2.30.2
7MIME-Version: 1.0
8Content-Transfer-Encoding: 8bit
9Content-Type: text/plain
10
11Unfortunatly, adding prerequisite to "$(obj)/ss/built_in.o" doesn't
12work because we have "$(obj)/%/built_in.o: $(obj)/% ;" in Rules.mk.
13So, make is allow to try to build objects in "xsm/flask/ss/" before
14generating the headers.
15
16Adding a prerequisite on "$(obj)/ss" instead will fix the issue has
17that the target used to run make in this subdirectory.
18
19Unfortunatly, that target is also used when running `make clean`, so
20we need to ignore it in this case. $(MAKECMDGOALS) can't be used in
21this case as it is empty, but we can guess which operation is done by
22looking at the list of loaded makefiles.
23
24Upstream-Status: backport [https://lore.kernel.org/xen-devel/20230120133626.55680-1-anthony.perard@citrix.com/T/#u]
25
26Fixes: 7a3bcd2babcc ("build: build everything from the root dir, use obj=$subdir")
27Reported-by: "Daniel P. Smith" <dpsmith@apertussolutions.com>
28Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
29---
30 xen/xsm/flask/Makefile | 6 +++++-
31 1 file changed, 5 insertions(+), 1 deletion(-)
32
33diff --git a/xen/xsm/flask/Makefile b/xen/xsm/flask/Makefile
34index d25312f4fa..2d24346ee3 100644
35--- a/xen/xsm/flask/Makefile
36+++ b/xen/xsm/flask/Makefile
37@@ -16,7 +16,11 @@ FLASK_H_FILES := flask.h class_to_string.h initial_sid_to_string.h
38 AV_H_FILES := av_perm_to_string.h av_permissions.h
39 ALL_H_FILES := $(addprefix include/,$(FLASK_H_FILES) $(AV_H_FILES))
40
41-$(addprefix $(obj)/,$(obj-y)) $(obj)/ss/built_in.o: $(addprefix $(obj)/,$(ALL_H_FILES))
42+# Adding prerequisite to descending into ss/ folder only when not running `make
43+# clean`.
44+ifeq ($(filter %/Makefile.clean,$(MAKEFILE_LIST)),)
45+$(addprefix $(obj)/,$(obj-y)) $(obj)/ss: $(addprefix $(obj)/,$(ALL_H_FILES))
46+endif
47 extra-y += $(ALL_H_FILES)
48
49 mkflask := $(srcdir)/policy/mkflask.sh
50--
51Anthony PERARD
52
53
54
diff --git a/meta-xilinx-virtualization/recipes-extended/xen/xen-arch.inc b/meta-xilinx-virtualization/recipes-extended/xen/xen-arch.inc
new file mode 100644
index 00000000..fb0093e3
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-extended/xen/xen-arch.inc
@@ -0,0 +1,18 @@
1
2valid_xen_archs = " \
3 x86_64 x86_32 \
4 arm32 arm64 \
5 "
6
7def map_xen_arch(a, d):
8 import re
9 valid_archs = d.getVar('valid_xen_archs').split()
10
11 if re.match("i.86", a): return "x86_32"
12 elif re.match("x86.64", a): return "x86_64"
13 elif re.match("arm.*", a): return "arm32"
14 elif re.match("aarch64.*", a): return "arm64"
15 elif a in valid_archs: return a
16 else:
17 return "INVALID"
18
diff --git a/meta-xilinx-virtualization/recipes-extended/xen/xen-blktap.inc b/meta-xilinx-virtualization/recipes-extended/xen/xen-blktap.inc
new file mode 100644
index 00000000..ad9d5fdb
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-extended/xen/xen-blktap.inc
@@ -0,0 +1,76 @@
1# The Xen block tap components are packaged separately here to support
2# the option to build them in a separate recipe from xen-tools.
3
4BLKTAP_PACKAGES ?= " \
5 ${PN}-blktap \
6 ${PN}-libblktap \
7 ${PN}-libblktapctl \
8 ${PN}-libblktapctl-dev \
9 ${PN}-libblktap-dev \
10 ${PN}-libvhd \
11 ${PN}-libvhd-dev \
12 ${PN}-blktap-staticdev \
13 "
14
15BLKTAP_PROVIDES ?= " \
16 virtual/blktap \
17 virtual/libblktap \
18 virtual/libblktapctl \
19 virtual/libvhd \
20 "
21
22BLKTAP_RRECOMMENDS ?= " \
23 virtual/blktap \
24 virtual/libblktap \
25 virtual/libblktapctl \
26 virtual/libvhd \
27 "
28
29RPROVIDES:${PN}-blktap = "virtual/blktap"
30RPROVIDES:${PN}-libblktap = "virtual/libblktap"
31RPROVIDES:${PN}-libblktapctl = "virtual/libblktapctl"
32RPROVIDES:${PN}-libvhd = "virtual/libvhd"
33
34FILES:${PN}-blktap-staticdev += "\
35 ${libdir}/libblktapctl.a \
36 ${libdir}/libvhd.a \
37 ${libdir}/libblktap.a \
38 "
39
40FILES:${PN}-libblktapctl = "${libdir}/libblktapctl.so.*"
41FILES:${PN}-libblktapctl-dev = " \
42 ${libdir}/libblktapctl.so \
43 ${libdir}/pkgconfig/xenblktapctl.pc \
44 ${datadir}/pkgconfig/xenblktapctl.pc \
45 "
46
47FILES:${PN}-libvhd = "${libdir}/libvhd.so.*"
48FILES:${PN}-libvhd-dev = " \
49 ${libdir}/libvhd.so \
50 ${libdir}/pkgconfig/vhd.pc \
51 ${datadir}/pkgconfig/vhd.pc \
52 "
53
54FILES:${PN}-libblktap = "${libdir}/libblktap.so.*"
55FILES:${PN}-libblktap-dev = " \
56 ${libdir}/libblktap.so \
57 ${libdir}/pkgconfig/blktap.pc \
58 ${datadir}/pkgconfig/blktap.pc \
59 "
60
61FILES:${PN}-blktap = "\
62 ${sbindir}/blktapctrl \
63 ${sbindir}/img2qcow \
64 ${sbindir}/lock-util \
65 ${sbindir}/qcow2raw \
66 ${sbindir}/qcow-create \
67 ${sbindir}/tap-ctl \
68 ${sbindir}/tapdisk \
69 ${sbindir}/tapdisk2 \
70 ${sbindir}/tapdisk-client \
71 ${sbindir}/tapdisk-diff \
72 ${sbindir}/tapdisk-stream \
73 ${sbindir}/td-util \
74 ${sbindir}/vhd-update \
75 ${sbindir}/vhd-util \
76 "
diff --git a/meta-xilinx-virtualization/recipes-extended/xen/xen-hypervisor.inc b/meta-xilinx-virtualization/recipes-extended/xen/xen-hypervisor.inc
new file mode 100644
index 00000000..6f3d24d0
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-extended/xen/xen-hypervisor.inc
@@ -0,0 +1,117 @@
1SUMMARY = "Xen hypervisor"
2DESCRIPTION = "The Xen hypervisor"
3
4# This recipe is for just the Xen hypervisor.
5# Separate recipes are used to build Xen and its components:
6# this allows for varying the target architecture or toolchain used
7# to build the different components. eg. 32-bit tools and a 64-bit hypervisor.
8
9# The Xen hypervisor has a narrower compatible platform range than the Xen tools
10COMPATIBLE_HOST = '(x86_64.*).*-linux|aarch64.*-linux|arm-.*-linux-gnueabi'
11
12inherit deploy python3native cml1
13
14PACKAGES = " \
15 ${PN} \
16 ${PN}-dbg \
17 ${PN}-efi \
18 "
19
20FILES:${PN} = " \
21 /boot/xen-* \
22 /boot/xen \
23 /boot/xen-*.gz \
24 /boot/xen.gz \
25 /boot/xen-syms-* \
26 "
27
28FILES:${PN}-dbg += "${libdir}/debug/*"
29
30FILES:${PN}-efi = " \
31 /boot/xen.efi \
32 ${exec_prefix}/lib64/efi/xen* \
33 "
34
35do_configure() {
36 do_configure_common
37
38 # Handle the config fragments
39 cfgs="${@' '.join(find_cfgs(d))}"
40 if [ -n "${cfgs}" ]; then
41 # If .config is not present generate one in order
42 # to use the merge_config.sh
43 if [ ! -f "${S}/xen/.config" ] ; then
44 oe_runmake -C ${S}/xen defconfig
45 fi
46 ${S}/xen/tools/kconfig/merge_config.sh -m -O \
47 ${S}/xen ${S}/xen/.config "${cfgs}"
48 fi
49}
50
51# The hypervisor binary for arm must not be built with the hard floating point
52# ABI. Override CC and CPP when invoking make so that they do not contain
53# TUNE_CCARGS.
54EXTRA_OEMAKE:arm += "CC='${CCACHE}${HOST_PREFIX}gcc ${TOOLCHAIN_OPTIONS} \
55 ${CC_REPRODUCIBLE_OPTIONS}' \
56 CPP='${CCACHE}${HOST_PREFIX}gcc -E ${TOOLCHAIN_OPTIONS} \
57 ${CC_REPRODUCIBLE_OPTIONS}'"
58
59do_compile() {
60 oe_runmake xen PYTHON="${PYTHON}" \
61 EXTRA_CFLAGS_XEN_CORE="${EXTRA_CFLAGS_XEN_CORE}"
62}
63
64do_install() {
65 oe_runmake DESTDIR="${D}" install-xen
66}
67# The do_install also ships files in /boot and /usr/lib64
68SYSROOT_DIRS += "/boot ${exec_prefix}/lib64"
69
70do_deploy() {
71 install -d ${DEPLOYDIR}
72
73 if [ -f ${B}/xen/xen ]; then
74 install -m 0644 ${B}/xen/xen ${DEPLOYDIR}/xen-${MACHINE}
75 fi
76
77 if [ -f ${B}/xen/xen.gz ]; then
78 install -m 0644 ${B}/xen/xen.gz ${DEPLOYDIR}/xen-${MACHINE}.gz
79 fi
80
81 if [ -f ${B}/xen/xen.efi ]; then
82 install -m 0644 ${B}/xen/xen.efi ${DEPLOYDIR}/xen-${MACHINE}.efi
83 fi
84}
85# Scheduling the do_deploy task:
86# - deploy copies files from ${B} that are written during do_compile so must
87# at least run afer that task has completed
88# - the hypervisor binaries may be included in the image filesystem, so we
89# must ensure that the binaries deployed match what is staged in the sysroot:
90# so do_deploy must run after do_populate_sysroot and after do_compile is
91# also needed for when having rm_work and bitbake needs to re-run do_deploy,
92# we ensure that the ${B} is re-generated, otherwise the deploy-xen will be
93# empty
94# - add the task before do_build to ensure that deployment has completed when
95# the recipe build done stamp is written
96addtask deploy after do_compile do_populate_sysroot before do_build
97# To ensure that a deployed hypervisor has matching tools, add a dependency to
98# make sure that the tools have built and been staged:
99do_deploy[depends] += "xen-tools:do_populate_sysroot"
100# Also ensure anything that the tools recipe needs to deploy, such as a
101# XSM policy file, has been deployed first:
102do_deploy[depends] += "xen-tools:do_deploy"
103
104# Enable use of menuconfig directly from bitbake and also within the devshell
105do_devshell[depends] += "ncurses-native:do_populate_sysroot"
106
107# Pass the native library path for kconfig build when running the do_menuconfig
108# task
109CROSS_CURSES_LIB += "-L${STAGING_LIBDIR_NATIVE}"
110
111# Specify the root dir of the .config file for do_menuconfig and do_diffconfig
112# tasks
113KCONFIG_CONFIG_ROOTDIR = "${S}/xen"
114
115# Xen is setting all CC flags on its own. Make sure that they are not modified
116# for aarch64, e.g. with architecture-specific optimizations.
117TUNE_CCARGS:aarch64=""
diff --git a/meta-xilinx-virtualization/recipes-extended/xen/xen-tools-xilinx.inc b/meta-xilinx-virtualization/recipes-extended/xen/xen-tools-xilinx.inc
new file mode 100644
index 00000000..e7bc8d7e
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-extended/xen/xen-tools-xilinx.inc
@@ -0,0 +1,25 @@
1# Only include the sysvinit scripts if sysvinit is enabled.
2do_install:append () {
3 if [ -e ${D}/usr/lib/xen/bin/pygrub ]; then
4 sed -i -e '1c#!/usr/bin/env python3' ${D}/usr/lib/xen/bin/pygrub
5 fi
6
7 if [ "${@bb.utils.contains('DISTRO_FEATURES', 'sysvinit', 'sysvinit', '', d)}" != 'sysvinit' ]; then
8 rm -f ${D}/etc/init.d/xendomains
9 rm -f ${D}/etc/init.d/xencommons
10 rm -f ${D}/etc/init.d/xendriverdomain
11 rm -f ${D}/etc/init.d/xen-watchdog
12 fi
13}
14
15# If we're in a hybrid configuration, we want to stop the system from
16# running any Xen sysvinit scripts
17# This has a side effect of, on a hybrid system, if the init manager is
18# sysvinit, the user will need to manually enable Xen.
19INHIBIT_UPDATERCD_BBCLASS = "${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '1', '', d)}"
20
21FILES:${PN} += " \
22 ${libdir}/xen/bin/init-dom0less \
23 ${libdir}/xen/bin/get_overlay \
24 ${libdir}/xen/bin/get_overlay.sh \
25 "
diff --git a/meta-xilinx-virtualization/recipes-extended/xen/xen-tools.inc b/meta-xilinx-virtualization/recipes-extended/xen/xen-tools.inc
new file mode 100644
index 00000000..f770eec2
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-extended/xen/xen-tools.inc
@@ -0,0 +1,861 @@
1SUMMARY = "Xen hypervisor tools"
2DESCRIPTION = "Tools and utility software for the Xen hypervisor"
3
4COMPATIBLE_HOST = 'i686-.*-linux|(x86_64.*).*-linux|aarch64.*-linux|arm-.*-linux-gnueabi'
5
6inherit setuptools3 update-rc.d systemd deploy
7require xen-blktap.inc
8
9RDEPENDS:${PN} = "\
10 bash perl xz \
11 ${PN}-console \
12 ${PN}-libxenguest \
13 ${PN}-libxenlight \
14 ${PN}-libxenvchan \
15 ${PN}-libxenctrl \
16 ${PN}-libxlutil \
17 ${PN}-libxenstat \
18 ${PN}-libxenstore \
19 ${PN}-libfsimage \
20 ${PN}-fsimage \
21 ${PN}-scripts-block \
22 ${PN}-scripts-network \
23 ${PN}-xen-watchdog \
24 ${PN}-xencommons \
25 ${PN}-xendomains \
26 ${PN}-xenstore \
27 virtual/xenstored \
28 ${PN}-xl \
29 "
30
31RDEPENDS:${PN}-dev = ""
32
33RRECOMMENDS:${PN} = " \
34 qemu \
35 ${@bb.utils.contains('XEN_TARGET_ARCH', 'x86_64', 'seabios ipxe vgabios', '', d)} \
36 ${@bb.utils.contains('PACKAGECONFIG', 'externalblktap', '', '${BLKTAP_RRECOMMENDS}', d)} \
37 ${PN}-flask \
38 ${PN}-hvmloader \
39 ${PN}-libxenhypfs \
40 ${PN}-shim \
41 ${PN}-ucode \
42 ${PN}-vchan \
43 ${PN}-xenpaging \
44 ${PN}-xenhypfs \
45 "
46
47RDEPENDS:${PN}-devd = " \
48 ${PN}-xl \
49 "
50
51RDEPENDS:${PN}-fsimage = " \
52 libext2fs \
53 "
54
55RDEPENDS:${PN}-misc = " \
56 perl \
57 python3 \
58 ${PN}-xencov \
59 "
60
61RSUGGESTS:${PN}-misc = " \
62 ${PN}-xencons \
63 ${PN}-xenpvnetboot \
64 "
65
66RDEPENDS:${PN}-python = " \
67 python3 \
68 "
69
70RDEPENDS:${PN}-pygrub = " \
71 python3 \
72 ${PN}-python \
73 "
74
75RDEPENDS:${PN}-remus = "bash"
76
77RDEPENDS:${PN}-scripts-block = "\
78 bash \
79 ${PN}-scripts-common \
80 ${PN}-volatiles \
81 "
82
83RDEPENDS:${PN}-scripts-common = "bash"
84
85RDEPENDS:${PN}-scripts-network = "\
86 bash \
87 bridge-utils \
88 ${PN}-scripts-common \
89 ${PN}-volatiles \
90 "
91
92RRECOMMENDS:${PN}-scripts-network = "\
93 ifupdown \
94 "
95
96RSUGGESTS:${PN}-xencov = "${PN}-xencov-split"
97
98RDEPENDS:${PN}-xencommons = "\
99 bash \
100 util-linux-prlimit \
101 ${PN}-console \
102 ${PN}-xenstore \
103 virtual/xenstored \
104 ${PN}-xl \
105 ${PN}-scripts-common \
106 "
107
108RDEPENDS:${PN}-xendomains = "\
109 bash \
110 ${PN}-console \
111 ${PN}-scripts-block \
112 ${PN}-scripts-common \
113 virtual/xenstored \
114 "
115
116RDEPENDS:${PN}-xenhypfs = " \
117 ${PN}-libxenhypfs \
118 "
119
120RDEPENDS:${PN}-xl = "libgcc"
121
122RDEPENDS:${PN}-xenmon = " \
123 python3 \
124 "
125
126RSUGGESTS:${PN}-xentrace = "${PN}-xentrace-format"
127
128RDEPENDS:${PN}-xen-watchdog = "bash"
129
130PACKAGES = " \
131 ${PN} \
132 ${@bb.utils.contains('PACKAGECONFIG', 'externalblktap', '', '${BLKTAP_PACKAGES}', d)} \
133 ${PN}-console \
134 ${PN}-cpuid \
135 ${PN}-dbg \
136 ${PN}-dev \
137 ${PN}-devd \
138 ${PN}-doc \
139 ${PN}-flask \
140 ${PN}-flask-tools \
141 ${PN}-fsimage \
142 ${PN}-gdbsx \
143 ${PN}-hvmloader \
144 ${PN}-init-xenstore-dom \
145 ${PN}-kdd \
146 ${PN}-libfsimage \
147 ${PN}-libfsimage-dev \
148 ${PN}-libxencall \
149 ${PN}-libxencall-dev \
150 ${PN}-libxenctrl \
151 ${PN}-libxenctrl-dev \
152 ${PN}-libxendevicemodel \
153 ${PN}-libxendevicemodel-dev \
154 ${PN}-libxenevtchn \
155 ${PN}-libxenevtchn-dev \
156 ${PN}-libxenforeignmemory \
157 ${PN}-libxenforeignmemory-dev \
158 ${PN}-libxengnttab \
159 ${PN}-libxengnttab-dev \
160 ${PN}-libxenguest \
161 ${PN}-libxenguest-dev \
162 ${PN}-libxenhypfs \
163 ${PN}-libxenhypfs-dev \
164 ${PN}-libxenlight \
165 ${PN}-libxenlight-dev \
166 ${PN}-libxenstat \
167 ${PN}-libxenstat-dev \
168 ${PN}-libxenstore \
169 ${PN}-libxenstore-dev \
170 ${PN}-libxentoolcore \
171 ${PN}-libxentoolcore-dev \
172 ${PN}-libxentoollog \
173 ${PN}-libxentoollog-dev \
174 ${PN}-libxenvchan \
175 ${PN}-libxenvchan-dev \
176 ${PN}-libxlutil \
177 ${PN}-libxlutil-dev \
178 ${PN}-livepatch \
179 ${PN}-misc \
180 ${PN}-pygrub \
181 ${PN}-python \
182 ${PN}-remus \
183 ${PN}-scripts-block \
184 ${PN}-scripts-common \
185 ${PN}-scripts-network \
186 ${PN}-shim \
187 ${PN}-staticdev \
188 ${PN}-ucode \
189 ${PN}-vchan \
190 ${PN}-volatiles \
191 ${PN}-xcutils \
192 ${PN}-xencommons \
193 ${PN}-xencov \
194 ${PN}-xend \
195 ${PN}-xend-examples \
196 ${PN}-xendomains \
197 ${PN}-xenhypfs \
198 ${PN}-xenmon \
199 ${PN}-xenpaging \
200 ${PN}-xenpmd \
201 ${PN}-xenstat \
202 ${PN}-xenstore \
203 ${PN}-xenstored \
204 ${PN}-xentrace \
205 ${PN}-xen-watchdog \
206 ${PN}-xl \
207 ${PN}-xl-examples \
208 ${PN}-xm \
209 ${PN}-xm-examples \
210 ${PN}-xen-access \
211 ${PN}-xen-memshare \
212 ${PN}-test \
213 ${PN}-xen-vmtrace \
214 ${PN}-xen-mceinj \
215 "
216
217PROVIDES =+ " \
218 virtual/xenstored \
219 ${@bb.utils.contains('PACKAGECONFIG', 'externalblktap', '', '${BLKTAP_PROVIDES}', d)} \
220 "
221
222# There are multiple implementations of the XenStore daemon, so we use a
223# virtual package to allow for substitution.
224RPROVIDES:${PN}-xenstored = "virtual/xenstored"
225
226FILES:${PN}-dbg += "\
227 ${libdir}/xen/bin/.debug \
228 ${nonarch_libdir}/${PYTHON_DIR}/site-packages/.debug \
229 ${nonarch_libdir}/${PYTHON_DIR}/site-packages/xen/lowlevel/.debug \
230 ${libdir}/fs/xfs/.debug \
231 ${libdir}/fs/ufs/.debug \
232 ${libdir}/fs/ext2fs-lib/.debug \
233 ${libdir}/fs/fat/.debug \
234 ${libdir}/fs/zfs/.debug \
235 ${libdir}/fs/reiserfs/.debug \
236 ${libdir}/fs/iso9660/.debug \
237 ${libdir}/fs/**/.debug \
238 ${sbindir}/.debug \
239 ${libdir}exec/.debug \
240 ${libdir}/xen/libexec/.debug \
241 ${bindir}/.debug \
242 ${nonarch_libdir}/${PYTHON_DIR}/dist-packages/.debug \
243 ${nonarch_libdir}/${PYTHON_DIR}/dist-packages/xen/lowlevel/.debug \
244 "
245
246FILES:${PN}-dev = "\
247 ${includedir} \
248 "
249
250FILES:${PN}-doc = "\
251 ${sysconfdir}/xen/README \
252 ${sysconfdir}/xen/README.incompatibilities \
253 ${datadir}/doc \
254 ${datadir}/man \
255 "
256
257FILES:${PN}-staticdev += "\
258 ${libdir}/libxenguest.a \
259 ${libdir}/libxenlight.a \
260 ${libdir}/libxenvchan.a \
261 ${libdir}/libxenctrl.a \
262 ${libdir}/libxlutil.a \
263 ${libdir}/libxenstat.a \
264 ${libdir}/libxenstore.a \
265 "
266
267FILES:${PN}-libxencall = "${libdir}/libxencall.so.*"
268FILES:${PN}-libxencall-dev = " \
269 ${libdir}/libxencall.so \
270 ${libdir}/pkgconfig/xencall.pc \
271 ${datadir}/pkgconfig/xencall.pc \
272 "
273
274FILES:${PN}-libxenctrl = "${libdir}/libxenctrl.so.*"
275FILES:${PN}-libxenctrl-dev = " \
276 ${libdir}/libxenctrl.so \
277 ${libdir}/pkgconfig/xencontrol.pc \
278 ${datadir}/pkgconfig/xencontrol.pc \
279 "
280
281FILES:${PN}-libxendevicemodel = "${libdir}/libxendevicemodel.so.*"
282FILES:${PN}-libxendevicemodel-dev = " \
283 ${libdir}/libxendevicemodel.so \
284 ${libdir}/pkgconfig/xendevicemodel.pc \
285 ${datadir}/pkgconfig/xendevicemodel.pc \
286 "
287
288FILES:${PN}-libxenevtchn = "${libdir}/libxenevtchn.so.*"
289FILES:${PN}-libxenevtchn-dev = " \
290 ${libdir}/libxenevtchn.so \
291 ${libdir}/pkgconfig/xenevtchn.pc \
292 ${datadir}/pkgconfig/xenevtchn.pc \
293 "
294
295FILES:${PN}-libxenforeignmemory = "${libdir}/libxenforeignmemory.so.*"
296FILES:${PN}-libxenforeignmemory-dev = " \
297 ${libdir}/libxenforeignmemory.so \
298 ${libdir}/pkgconfig/xenforeignmemory.pc \
299 ${datadir}/pkgconfig/xenforeignmemory.pc \
300 "
301
302FILES:${PN}-libxengnttab = "${libdir}/libxengnttab.so.*"
303FILES:${PN}-libxengnttab-dev = " \
304 ${libdir}/libxengnttab.so \
305 ${libdir}/pkgconfig/xengnttab.pc \
306 ${datadir}/pkgconfig/xengnttab.pc \
307 "
308
309FILES:${PN}-libxenguest = "${libdir}/libxenguest.so.*"
310FILES:${PN}-libxenguest-dev = " \
311 ${libdir}/libxenguest.so \
312 ${libdir}/pkgconfig/xenguest.pc \
313 ${datadir}/pkgconfig/xenguest.pc \
314 "
315
316FILES:${PN}-libxenhypfs = "${libdir}/libxenhypfs.so.*"
317FILES:${PN}-libxenhypfs-dev = " \
318 ${libdir}/libxenhypfs.so \
319 ${libdir}/pkgconfig/xenhypfs.pc \
320 "
321
322FILES:${PN}-libxenlight = "${libdir}/libxenlight.so.*"
323FILES:${PN}-libxenlight-dev = " \
324 ${libdir}/libxenlight.so \
325 ${libdir}/pkgconfig/xenlight.pc \
326 ${datadir}/pkgconfig/xenlight.pc \
327 "
328
329FILES:${PN}-libxenstat = "${libdir}/libxenstat.so.*"
330FILES:${PN}-libxenstat-dev = " \
331 ${libdir}/libxenstat.so \
332 ${libdir}/pkgconfig/xenstat.pc \
333 ${datadir}/pkgconfig/xenstat.pc \
334 "
335
336FILES:${PN}-libxenstore = "${libdir}/libxenstore.so.*"
337FILES:${PN}-libxenstore-dev = " \
338 ${libdir}/libxenstore.so \
339 ${libdir}/pkgconfig/xenstore.pc \
340 ${datadir}/pkgconfig/xenstore.pc \
341 "
342
343FILES:${PN}-libxentoolcore = "${libdir}/libxentoolcore.so.*"
344FILES:${PN}-libxentoolcore-dev = " \
345 ${libdir}/libxentoolcore.so \
346 ${libdir}/pkgconfig/xentoolcore.pc \
347 ${datadir}/pkgconfig/xentoolcore.pc \
348 "
349
350FILES:${PN}-libxentoollog = "${libdir}/libxentoollog.so.*"
351FILES:${PN}-libxentoollog-dev = " \
352 ${libdir}/libxentoollog.so \
353 ${libdir}/pkgconfig/xentoollog.pc \
354 ${datadir}/pkgconfig/xentoollog.pc \
355 "
356
357FILES:${PN}-libxenvchan = "${libdir}/libxenvchan.so.*"
358FILES:${PN}-libxenvchan-dev = " \
359 ${libdir}/libxenvchan.so \
360 ${libdir}/pkgconfig/xenvchan.pc \
361 ${datadir}/pkgconfig/xenvchan.pc \
362 "
363
364FILES:${PN}-libxlutil = "${libdir}/libxlutil.so.*"
365FILES:${PN}-libxlutil-dev = " \
366 ${libdir}/libxlutil.so \
367 ${libdir}/pkgconfig/xlutil.pc \
368 ${datadir}/pkgconfig/xlutil.pc \
369 "
370FILES:${PN}-libvhd = "${libdir}/libvhd.so.*"
371FILES:${PN}-libvhd-dev = " \
372 ${libdir}/libvhd.so \
373 ${libdir}/pkgconfig/vhd.pc \
374 ${datadir}/pkgconfig/vhd.pc \
375 "
376
377FILES:${PN}-libfsimage = " \
378 ${libdir}/libfsimage.so.* \
379 ${libdir}/libxenfsimage.so.* \
380 "
381
382FILES:${PN}-libfsimage-dev = " \
383 ${libdir}/libfsimage.so \
384 ${libdir}/libxenfsimage.so \
385 ${libdir}/pkgconfig/fsimage.pc \
386 ${datadir}/pkgconfig/fsimage.pc \
387 ${libdir}/pkgconfig/xenfsimage.pc \
388 ${datadir}/pkgconfig/xenfsimage.pc \
389 "
390
391FILES:${PN}-fsimage = " \
392 ${libdir}/fs/**/[a-z]*fsimage.so \
393 ${libdir}/xenfsimage/**/fsimage.so \
394 "
395
396FILES:${PN}-init-xenstore-dom = "${libdir}/xen/bin/init-xenstore-domain"
397
398FILES:${PN} = "\
399 ${sysconfdir}/xen/auto \
400 ${sysconfdir}/xen/cpupool \
401 ${localstatedir}/xen/dump \
402 "
403
404FILES:${PN}-console = "\
405 ${libdir}/xen/bin/xenconsole \
406 ${sbindir}/xenconsoled \
407 "
408
409FILES:${PN}-cpuid = "\
410 ${bindir}/xen-cpuid \
411 "
412
413FILES:${PN}-devd = "\
414 ${sysconfdir}/init.d/xendriverdomain \
415 ${systemd_unitdir}/system/xendriverdomain.service \
416 "
417
418FILES:${PN}-flask = "\
419 /boot/xenpolicy-* \
420 "
421
422FILES:${PN}-flask-tools = "\
423 ${sbindir}/flask-get-bool \
424 ${sbindir}/flask-getenforce \
425 ${sbindir}/flask-label-pci \
426 ${sbindir}/flask-loadpolicy \
427 ${sbindir}/flask-set-bool \
428 ${sbindir}/flask-setenforce \
429 "
430
431FILES:${PN}-gdbsx = "\
432 ${sbindir}/gdbsx \
433 "
434
435INSANE_SKIP:${PN}-hvmloader = "arch"
436FILES:${PN}-hvmloader = "\
437 ${libdir}/xen/boot/hvmloader \
438 "
439
440FILES:${PN}-kdd = "\
441 ${sbindir}/kdd \
442 ${sbindir}/xen-kdd \
443 "
444
445FILES:${PN}-livepatch += " \
446 ${sbindir}/xen-livepatch \
447 "
448
449FILES:${PN}-misc = "\
450 ${bindir}/xen-detect \
451 ${libdir}/xen/bin/depriv-fd-checker \
452 ${sbindir}/gtracestat \
453 ${sbindir}/gtraceview \
454 ${sbindir}/xen-bugtool \
455 ${sbindir}/xenperf \
456 ${sbindir}/xenpm \
457 ${sbindir}/xsview \
458 ${sbindir}/xen-diag \
459 ${sbindir}/xen-tmem-list-parse \
460 ${sbindir}/xen-python-path \
461 ${sbindir}/xen-ringwatch \
462 ${sbindir}/xen-hptool \
463 ${sbindir}/xen-hvmcrash \
464 ${sbindir}/xen-hvmctx \
465 ${sbindir}/xenlockprof \
466 ${sbindir}/xen-lowmemd \
467 ${sbindir}/xen-mfndump \
468 ${libdir}/xen/bin/verify-stream-v2 \
469 ${libdir}/xen/bin/convert-legacy-stream \
470 "
471
472FILES:${PN}-pygrub = "\
473 ${bindir}/pygrub \
474 ${libdir}/xen/bin/pygrub \
475 "
476
477# Depending on the version of Xen libdir or nonarch libdir is used
478FILES:${PN}-python = "\
479 ${libdir}/${PYTHON_DIR} \
480 ${nonarch_libdir}/${PYTHON_DIR} \
481 "
482
483FILES:${PN}-remus = "\
484 ${sysconfdir}/xen/scripts/remus-netbuf-setup \
485 "
486
487FILES:${PN}-scripts-network = " \
488 ${sysconfdir}/xen/scripts/colo-proxy-setup \
489 ${sysconfdir}/xen/scripts/network-bridge \
490 ${sysconfdir}/xen/scripts/network-nat \
491 ${sysconfdir}/xen/scripts/network-route \
492 ${sysconfdir}/xen/scripts/qemu-ifup \
493 ${sysconfdir}/xen/scripts/vif2 \
494 ${sysconfdir}/xen/scripts/vif-bridge \
495 ${sysconfdir}/xen/scripts/vif-common.sh \
496 ${sysconfdir}/xen/scripts/vif-nat \
497 ${sysconfdir}/xen/scripts/vif-openvswitch \
498 ${sysconfdir}/xen/scripts/vif-route \
499 ${sysconfdir}/xen/scripts/vif-setup \
500 "
501
502FILES:${PN}-scripts-block = " \
503 ${sysconfdir}/xen/scripts/blktap \
504 ${sysconfdir}/xen/scripts/block \
505 ${sysconfdir}/xen/scripts/block-common.sh \
506 ${sysconfdir}/xen/scripts/block-dummy \
507 ${sysconfdir}/xen/scripts/block-enbd \
508 ${sysconfdir}/xen/scripts/block-iscsi \
509 ${sysconfdir}/xen/scripts/block-nbd \
510 ${sysconfdir}/xen/scripts/block-drbd-probe \
511 ${sysconfdir}/xen/scripts/block-tap \
512 ${sysconfdir}/xen/scripts/vscsi \
513 "
514
515FILES:${PN}-scripts-common = " \
516 ${sysconfdir}/xen/scripts/external-device-migrate \
517 ${sysconfdir}/xen/scripts/hotplugpath.sh \
518 ${sysconfdir}/xen/scripts/locking.sh \
519 ${sysconfdir}/xen/scripts/logging.sh \
520 ${sysconfdir}/xen/scripts/xen-hotplug-cleanup \
521 ${sysconfdir}/xen/scripts/xen-hotplug-common.sh \
522 ${sysconfdir}/xen/scripts/xen-network-common.sh \
523 ${sysconfdir}/xen/scripts/xen-script-common.sh \
524 "
525
526INSANE_SKIP:${PN}-shim = "arch"
527FILES:${PN}-shim = " \
528 ${libdir}/xen/boot/xen-shim \
529 "
530
531FILES:${PN}-ucode = "\
532 ${sbindir}/xen-ucode \
533 "
534
535FILES:${PN}-vchan = "\
536 ${bindir}/vchan-socket-proxy \
537 "
538
539FILES:${PN}-volatiles = "\
540 ${sysconfdir}/default/volatiles/99_xen \
541 ${sysconfdir}/tmpfiles.d/xen.conf \
542 "
543
544FILES:${PN}-xcutils = "\
545 ${libdir}/xen/bin/lsevtchn \
546 ${libdir}/xen/bin/readnotes \
547 ${libdir}/xen/bin/xc_restore \
548 ${libdir}/xen/bin/xc_save \
549 "
550
551FILES:${PN}-xencov = "\
552 ${sbindir}/xencov \
553 "
554
555FILES:${PN}-xend-examples = "\
556 ${sysconfdir}/xen/xend-config.sxp \
557 ${sysconfdir}/xen/xend-pci-permissive.sxp \
558 ${sysconfdir}/xen/xend-pci-quirks.sxp \
559 "
560
561FILES:${PN}-xenhypfs = "\
562 ${sbindir}/xenhypfs \
563 "
564
565FILES:${PN}-xenpaging = "\
566 ${libdir}/xen/bin/xenpaging \
567 ${localstatedir}/lib/xen/xenpaging \
568 "
569
570FILES:${PN}-xenpmd = "\
571 ${sbindir}/xenpmd \
572 "
573
574FILES:${PN}-xenstat = "\
575 ${sbindir}/xentop \
576 "
577
578FILES:${PN}-xenstore = "\
579 ${bindir}/xenstore \
580 ${bindir}/xenstore-chmod \
581 ${bindir}/xenstore-control \
582 ${bindir}/xenstore-exists \
583 ${bindir}/xenstore-list \
584 ${bindir}/xenstore-ls \
585 ${bindir}/xenstore-read \
586 ${bindir}/xenstore-rm \
587 ${bindir}/xenstore-watch \
588 ${bindir}/xenstore-write \
589 "
590
591FILES:${PN}-xenstored = "\
592 ${sbindir}/xenstored \
593 ${localstatedir}/lib/xenstored \
594 "
595
596FILES:${PN}-xentrace = "\
597 ${bindir}/xentrace \
598 ${bindir}/xentrace_setsize \
599 ${libdir}/xen/bin/xenctx \
600 ${bindir}/xenalyze \
601 ${sbindir}/xentrace \
602 ${sbindir}/xentrace_setsize \
603 ${sbindir}/xentrace_setmask \
604 "
605
606FILES:${PN}-xen-watchdog = "\
607 ${sbindir}/xenwatchdogd \
608 ${sysconfdir}/init.d/xen-watchdog \
609 ${systemd_unitdir}/system/xen-watchdog.service \
610 "
611
612FILES:${PN}-xl = "\
613 ${sysconfdir}/bash_completion.d/xl.sh \
614 ${sysconfdir}/bash_completion.d/xl \
615 ${sysconfdir}/xen/xl.conf \
616 ${libdir}/xen/bin/libxl-save-helper \
617 ${sbindir}/xl \
618 ${libdir}/xen/bin/xen-init-dom0 \
619 ${libdir}/xen/bin/init-dom0less \
620 "
621
622FILES:${PN}-xl-examples = "\
623 ${sysconfdir}/xen/xlexample.hvm \
624 ${sysconfdir}/xen/xlexample.pvlinux \
625 ${sysconfdir}/xen/xlexample.pvhlinux \
626 "
627
628FILES:${PN}-xm-examples = "\
629 ${sysconfdir}/xen/xmexample1 \
630 ${sysconfdir}/xen/xmexample2 \
631 ${sysconfdir}/xen/xmexample3 \
632 ${sysconfdir}/xen/xmexample.hvm \
633 ${sysconfdir}/xen/xmexample.hvm-stubdom \
634 ${sysconfdir}/xen/xmexample.nbd \
635 ${sysconfdir}/xen/xmexample.pv-grub \
636 ${sysconfdir}/xen/xmexample.vti \
637 "
638
639FILES:${PN}-xenmon = "\
640 ${sbindir}/xenbaked \
641 ${sbindir}/xenmon.py \
642 ${sbindir}/xenmon \
643 "
644
645FILES:${PN}-xm = "\
646 ${sysconfdir}/xen/xm-config.xml \
647 ${datadir}/xen/create.dtd \
648 ${sbindir}/xm \
649 "
650
651FILES:${PN}-xencommons += "\
652 ${nonarch_libdir}/modules-load.d/xen.conf \
653 ${sysconfdir}/default/xencommons \
654 ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '', '${sysconfdir}/init.d/xencommons', d)} \
655 ${sysconfdir}/xen/scripts/launch-xenstore \
656 ${systemd_unitdir}/system/proc-xen.mount \
657 ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '${systemd_unitdir}/system/xen-qemu-dom0-disk-backend.service', '', d)} \
658 ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '${systemd_unitdir}/system/xenconsoled.service', '', d)} \
659 ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '${systemd_unitdir}/system/xen-init-dom0.service', '', d)} \
660 ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '${systemd_unitdir}/system/xenstored.service', '', d)} \
661 ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '${systemd_unitdir}/system/var-lib-xenstored.mount', '', d)} \
662 ${localstatedir} \
663 "
664
665FILES:${PN}-xend += " \
666 ${sysconfdir}/init.d/xend \
667 ${sbindir}/xend \
668 "
669
670FILES:${PN}-xendomains += "\
671 ${libdir}/xen/bin/xendomains \
672 ${sysconfdir}/default/xendomains \
673 ${sysconfdir}/init.d/xendomains \
674 ${sysconfdir}/sysconfig/xendomains \
675 ${systemd_unitdir}/system/xendomains.service \
676 "
677FILES:${PN}-xen-access += "\
678 ${sbindir}/xen-access \
679 "
680
681FILES:${PN}-xen-memshare += "\
682 ${sbindir}/xen-memshare \
683 "
684
685# memshare is only built for x86, so allow empty package for other archs
686ALLOW_EMPTY:${PN}-xen-memshare = "1"
687
688FILES:${PN}-test += "\
689 ${libdir}/xen/bin/test-xenstore \
690 ${libdir}/xen/bin/test-resource \
691 ${libdir}/xen/bin/test-cpu-policy \
692 ${libdir}/xen/bin/test-tsx \
693 ${libdir}/xen/bin/test-paging-mempool \
694 "
695
696# test-xenstore and test-resource currently only exist in 4.16
697# test-cpu-policy and test-tsx only exist in 4.16 for x86
698ALLOW_EMPTY:${PN}-test = "1"
699
700FILES:${PN}-xen-mceinj +="\
701 ${sbindir}/xen-mceinj \
702 "
703
704# xen-mceinj is only built for x86 4.16, so allow empty package
705ALLOW_EMPTY:${PN}-xen-mceinj = "1"
706
707FILES:${PN}-xen-vmtrace +="\
708 ${sbindir}/xen-vmtrace \
709 "
710
711# xen-vmtrace is only built for x86 4.16, so allow empty package
712ALLOW_EMPTY:${PN}-xen-vmtrace = "1"
713
714INSANE_SKIP:${PN} = "already-stripped"
715
716# configure init.d scripts
717INITSCRIPT_PACKAGES = "${PN}-xend ${PN}-xen-watchdog ${PN}-xendomains ${PN}-devd"
718INITSCRIPT_PACKAGES += "${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '', '${PN}-xencommons', d)}"
719INITSCRIPT_NAME:${PN}-xencommons = "xencommons"
720INITSCRIPT_PARAMS:${PN}-xencommons = "defaults 80"
721INITSCRIPT_NAME:${PN}-xen-watchdog = "xen-watchdog"
722INITSCRIPT_PARAMS:${PN}-xen-watchdog = "defaults 81"
723INITSCRIPT_NAME:${PN}-xend = "xend"
724INITSCRIPT_PARAMS:${PN}-xend = "defaults 82"
725INITSCRIPT_NAME:${PN}-xendomains = "xendomains"
726INITSCRIPT_PARAMS:${PN}-xendomains = "defaults 83"
727INITSCRIPT_NAME:${PN}-devd = "xendriverdomain"
728INITSCRIPT_PARAMS:${PN}-devd = "defaults 82"
729
730# systemd packages
731SYSTEMD_PACKAGES = "${PN}-xen-watchdog ${PN}-xencommons ${PN}-xendomains ${PN}-devd"
732SYSTEMD_SERVICE:${PN}-devd = "xendriverdomain.service"
733SYSTEMD_SERVICE:${PN}-xen-watchdog = "xen-watchdog.service"
734SYSTEMD_SERVICE:${PN}-xencommons = " \
735 proc-xen.mount \
736 xen-qemu-dom0-disk-backend.service \
737 xenconsoled.service \
738 xen-init-dom0.service \
739 xenstored.service \
740 "
741SYSTEMD_SERVICE:${PN}-xendomains = "xendomains.service"
742
743QEMU_ARCH = "i386"
744QEMU_ARCH:aarch64 = "aarch64"
745
746EXTRA_OECONF += " \
747 --with-systemd=${systemd_unitdir}/system \
748 --with-initddir=${INIT_D_DIR} \
749 --with-sysconfig-leaf-dir=default \
750 --with-system-qemu=${bindir}/qemu-system-${QEMU_ARCH} \
751 "
752
753do_configure() {
754 do_configure_common
755}
756
757do_compile() {
758 cd ${S}
759 oe_runmake tools PYTHON="${PYTHON}" \
760 EXTRA_CFLAGS_XEN_TOOLS="${EXTRA_CFLAGS_XEN_TOOLS}"
761}
762
763do_install() {
764 cd ${S}
765 oe_runmake DESTDIR="${D}" install-tools
766
767 # Remove unported python 2 scripts -- see the separate xen-python2 recipe
768 rm -f ${D}${bindir}/xentrace_format \
769 ${D}${bindir}/xencons \
770 ${D}${bindir}/xencov_split \
771 ${D}${libdir}/xen/bin/xenpvnetboot
772
773 # remove installed volatiles
774 rm -rf ${D}${base_prefix}/run \
775 ${D}${localstatedir}/run \
776 ${D}${localstatedir}/lock \
777 ${D}${localstatedir}/log \
778 ${D}${localstatedir}/volatile \
779 ${D}${localstatedir}/lib/xen
780
781 VOLATILE_DIRS=" \
782 ${base_prefix}/run/xenstored \
783 ${base_prefix}/run/xend \
784 ${base_prefix}/run/xend/boot \
785 ${base_prefix}/run/xen \
786 ${localstatedir}/log/xen \
787 ${localstatedir}/lock/xen \
788 ${localstatedir}/lock/subsys \
789 ${localstatedir}/lib/xen \
790 "
791
792 # install volatiles using populate_volatiles mechanism
793 install -d ${D}${sysconfdir}/default/volatiles
794 for i in $VOLATILE_DIRS; do
795 echo "d root root 0755 $i none" >> ${D}${sysconfdir}/default/volatiles/99_xen
796 done
797
798 # workaround for xendomains script which searchs sysconfig if directory exists
799 install -d ${D}${sysconfdir}/sysconfig
800 ln -sf ${sysconfdir}/default/xendomains ${D}${sysconfdir}/sysconfig/xendomains
801
802 # systemd
803 if ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'true', 'false', d)}; then
804 # install volatiles using systemd tmpfiles.d
805 install -d ${D}${sysconfdir}/tmpfiles.d
806 for i in $VOLATILE_DIRS; do
807 echo "d $i 0755 root root - -" >> ${D}${sysconfdir}/tmpfiles.d/xen.conf
808 done
809 fi
810
811 if [ -e ${D}${systemd_unitdir}/system/xen-qemu-dom0-disk-backend.service ]; then
812 sed -i 's#ExecStart=.*qemu-system-i386\(.*\)$#ExecStart=/usr/bin/qemu-system-i386\1#' \
813 ${D}${systemd_unitdir}/system/xen-qemu-dom0-disk-backend.service
814 fi
815
816 if ${@bb.utils.contains('DISTRO_FEATURES','systemd','true','false',d)}; then
817 rm -f ${D}/${sysconfdir}/init.d/xencommons
818 else
819 # fixup default path to qemu-system-i386
820 sed -i 's#\(test -z "$QEMU_XEN" && QEMU_XEN=\).*$#\1"/usr/bin/qemu-system-i386"#' ${D}/etc/init.d/xencommons
821
822 # remove the uncondiontally installed systemd service files
823 rm -f ${D}/${systemd_unitdir}/system/xen-qemu-dom0-disk-backend.service
824 rm -f ${D}/${systemd_unitdir}/system/xenconsoled.service
825 rm -f ${D}/${systemd_unitdir}/system/xen-init-dom0.service
826 rm -f ${D}/${systemd_unitdir}/system/xenstored.service
827 rm -f ${D}/${systemd_unitdir}/system/var-lib-xenstored.mount
828 fi
829}
830
831pkg_postinst:${PN}-volatiles() {
832 if [ -z "$D" ]; then
833 if command -v systemd-tmpfiles >/dev/null; then
834 systemd-tmpfiles --create ${sysconfdir}/tmpfiles.d/xen.conf
835 elif [ -e ${sysconfdir}/init.d/populate-volatile.sh ]; then
836 ${sysconfdir}/init.d/populate-volatile.sh update
837 fi
838 fi
839}
840
841do_deploy() {
842 XEN_FULLVERSION=$(oe_runmake -C ${S}/xen xenversion --no-print-directory)
843 FLASK_POLICY_FILE="xenpolicy-${XEN_FULLVERSION}"
844
845 install -d ${DEPLOYDIR}
846
847 # Install the flask policy in the deploy directory if it exists
848 if [ -f ${D}/boot/${FLASK_POLICY_FILE} ]; then
849 install -m 0644 ${D}/boot/${FLASK_POLICY_FILE} ${DEPLOYDIR}
850 ln -sf ${FLASK_POLICY_FILE} ${DEPLOYDIR}/xenpolicy-${MACHINE}
851 fi
852}
853# Scheduling the do_deploy task:
854# - deploy copies files from ${D} that are written during do_install so must run
855# after that task
856# - the tools binaries are included in the image filesystem, so we must ensure
857# that the binaries deployed match what is staged in the sysroot:
858# so do_deploy must run after do_populate_sysroot
859# - add the task before do_build to ensure that deployment has completed when
860# the recipe build done stamp is written
861addtask deploy after do_install do_populate_sysroot before do_build
diff --git a/meta-xilinx-virtualization/recipes-extended/xen/xen-tools_4.17.bb b/meta-xilinx-virtualization/recipes-extended/xen/xen-tools_4.17.bb
new file mode 100644
index 00000000..acc9184b
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-extended/xen/xen-tools_4.17.bb
@@ -0,0 +1,18 @@
1# xen 4.17.0 release sha
2SRCREV ?= "11560248ffda3f00f20bbdf3ae088af474f7f2a3"
3
4XEN_URI ?= "git://xenbits.xen.org/xen.git"
5XEN_REL ?= "4.17"
6XEN_BRANCH ?= "stable-${XEN_REL}"
7
8SRC_URI = " \
9 ${XEN_URI};branch=${XEN_BRANCH} \
10 file://0001-python-pygrub-pass-DISTUTILS-xen-4.15.patch \
11 "
12
13LIC_FILES_CHKSUM ?= "file://COPYING;md5=d1a1e216f80b6d8da95fec897d0dbec9"
14
15S = "${WORKDIR}/git"
16
17require xen.inc
18require xen-tools.inc
diff --git a/meta-xilinx-virtualization/recipes-extended/xen/xen-tools_4.17.bbappend b/meta-xilinx-virtualization/recipes-extended/xen/xen-tools_4.17.bbappend
new file mode 100644
index 00000000..d033e1d2
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-extended/xen/xen-tools_4.17.bbappend
@@ -0,0 +1,2 @@
1require xen-xilinx_4.17.inc
2require xen-tools-xilinx.inc
diff --git a/meta-xilinx-virtualization/recipes-extended/xen/xen-tools_4.18.bb b/meta-xilinx-virtualization/recipes-extended/xen/xen-tools_4.18.bb
new file mode 100644
index 00000000..8baa2f53
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-extended/xen/xen-tools_4.18.bb
@@ -0,0 +1,18 @@
1# tag: RELEASE-4.18.0
2SRCREV ?= "d75f1e9b74314cea91ce435730d4e3539ecca77d"
3
4XEN_URI ?= "git://xenbits.xen.org/xen.git"
5XEN_REL ?= "4.18"
6XEN_BRANCH ?= "stable-4.18"
7
8SRC_URI = " \
9 ${XEN_URI};branch=${XEN_BRANCH} \
10 file://0001-python-pygrub-pass-DISTUTILS-xen-4.18.patch \
11 "
12
13LIC_FILES_CHKSUM ?= "file://COPYING;md5=d1a1e216f80b6d8da95fec897d0dbec9"
14
15S = "${WORKDIR}/git"
16
17require xen.inc
18require xen-tools.inc
diff --git a/meta-xilinx-virtualization/recipes-extended/xen/xen-tools_4.18.bbappend b/meta-xilinx-virtualization/recipes-extended/xen/xen-tools_4.18.bbappend
new file mode 100644
index 00000000..86702979
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-extended/xen/xen-tools_4.18.bbappend
@@ -0,0 +1,2 @@
1require xen-xilinx_4.18.inc
2require xen-tools-xilinx.inc
diff --git a/meta-xilinx-virtualization/recipes-extended/xen/xen-xilinx_4.17.inc b/meta-xilinx-virtualization/recipes-extended/xen/xen-xilinx_4.17.inc
new file mode 100644
index 00000000..d7810b27
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-extended/xen/xen-xilinx_4.17.inc
@@ -0,0 +1,7 @@
1SRCREV = "38eebc6e5c6f7aa9180672a56d33217bf1ef1ca6"
2XEN_URI = "git://github.com/Xilinx/xen.git;protocol=https"
3XEN_BRANCH = "xlnx_rebase_4.17"
4
5PV .= "-xilinx+git${SRCPV}"
6
7DEFAULT_PREFERENCE = "+1"
diff --git a/meta-xilinx-virtualization/recipes-extended/xen/xen-xilinx_4.18.inc b/meta-xilinx-virtualization/recipes-extended/xen/xen-xilinx_4.18.inc
new file mode 100644
index 00000000..2290a418
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-extended/xen/xen-xilinx_4.18.inc
@@ -0,0 +1,7 @@
1SRCREV = "7cb7aac7f570757b67bcd43aec67e0cda9f58b14"
2XEN_URI = "git://github.com/Xilinx/xen.git;protocol=https"
3XEN_BRANCH = "xlnx_rebase_4.18"
4
5PV .= "-xilinx+git${SRCPV}"
6
7DEFAULT_PREFERENCE = "+1"
diff --git a/meta-xilinx-virtualization/recipes-extended/xen/xen.inc b/meta-xilinx-virtualization/recipes-extended/xen/xen.inc
new file mode 100644
index 00000000..5937763a
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-extended/xen/xen.inc
@@ -0,0 +1,233 @@
1HOMEPAGE = "http://xen.org"
2LICENSE = "GPL-2.0-only"
3SECTION = "console/tools"
4
5inherit autotools-brokensep pkgconfig
6
7require xen-arch.inc
8
9PACKAGECONFIG ??= " \
10 ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'systemd', '', d)} \
11 "
12
13PACKAGECONFIG[lzo] = ",,lzo"
14PACKAGECONFIG[xsm] = "--enable-xsmpolicy,--disable-xsmpolicy,checkpolicy-native,"
15PACKAGECONFIG[systemd] = "--enable-systemd,--disable-systemd,systemd,"
16PACKAGECONFIG[externalblktap] = ",,,"
17
18DEPENDS = " \
19 ${@bb.utils.contains('XEN_TARGET_ARCH', 'x86_64', 'dev86-native', '', d)} \
20 bison-native \
21 flex-native \
22 file-native \
23 gettext-native \
24 acpica-native \
25 ncurses-native \
26 util-linux-native \
27 xz-native \
28 bridge-utils \
29 curl \
30 dtc \
31 gettext \
32 glib-2.0 \
33 gnutls \
34 iproute2 \
35 libnl \
36 ncurses \
37 openssl \
38 pciutils \
39 pixman \
40 procps \
41 python3 \
42 libaio \
43 util-linux \
44 xz \
45 yajl \
46 zlib \
47 gnu-efi \
48 "
49
50#### REQUIRED ENVIRONMENT VARIABLES ####
51export BUILD_SYS
52export HOST_SYS
53export STAGING_INCDIR
54export STAGING_LIBDIR
55
56# specify xen hypervisor to build/target
57export XEN_TARGET_ARCH = "${@map_xen_arch(d.getVar('TARGET_ARCH'), d)}"
58export XEN_COMPILE_ARCH = "${@map_xen_arch(d.getVar('BUILD_ARCH'), d)}"
59
60python () {
61 if d.getVar('XEN_TARGET_ARCH') == 'INVALID':
62 raise bb.parse.SkipPackage('Cannot map `%s` to a xen architecture' % d.getVar('TARGET_ARCH'))
63}
64
65# Yocto appends ${PN} to libexecdir by default and Xen appends 'xen' as well
66# the result is a nested xen/xen/ so let's avoid that by shunning Yocto's
67# extra ${PN} appended.
68libexecdir = "${libdir}"
69
70# hardcoded as Linux, as the only compatible hosts are Linux.
71export XEN_OS = "Linux"
72
73# this is used for the header (#!${bindir}/python) of the install python scripts
74export PYTHONPATH="${bindir}/env python3"
75export ac_cv_path_PYTHONPATH="${bindir}/env python3"
76export DISTUTILS_BUILD_ARGS
77export DISTUTILS_INSTALL_ARGS
78
79# xen and seabios require HOSTCC and HOSTCXX set to cross-compile
80export HOSTCC="${BUILD_CC}"
81export HOSTCXX="${BUILD_CXX}"
82
83# make xen requires CROSS_COMPILE set by hand as it does not abide by ./configure
84export CROSS_COMPILE="${TARGET_PREFIX}"
85
86# overide LDFLAGS to allow xen to build without: "x86_64-oe-linux-ld: unrecognized option '-Wl,-O1'"
87export LDFLAGS=""
88
89# No additional C flags for the main hypervisor build
90EXTRA_CFLAGS_XEN_CORE ?= ""
91# Add prefix maps to support buildpaths QA test and reproducibility
92DEBUG_PREFIX_MAP:append = " \
93 -ffile-prefix-map=${S}=${PN}-source \
94 -fdebug-prefix-map=${WORKDIR}=${PN} \
95 "
96
97# - The Xen tools build for x86 systems with HVM-mode enabled includes hvmloader
98# which fails to build when "-m64" is included in flags set via the
99# EXTRA_CFLAGS_XEN_TOOLS: so clear TUNE_CCARGS on x86 to prevent that.
100TUNE_CCARGS:x86-64=""
101
102# - Yocto supplies the _FORTIFY_SOURCE flag via CC/CPP/CXX but then passes the
103# optimization -O via C*FLAGS which is problematic when the CFLAGS are cleared
104# within the build because compilation fails with the compiler stating
105# "_FORTIFY_SOURCE requires compiling with optimization (-O)".
106# - Move HOST_CC_ARCH into the Xen-provided CFLAGS variables and keep
107# TOOLCHAIN_OPTIONS set via CC: this enables hvmloader to be built correctly.
108# It must not be compiled with SSE compiler options enabled and the Xen build
109# explicitly clears CFLAGS to ensure that, so such options must not be passed
110# in via the tool variable. hvmloader is required to run HVM-mode guest VMs.
111CC="${CCACHE}${HOST_PREFIX}gcc ${TOOLCHAIN_OPTIONS} ${DEBUG_PREFIX_MAP} ${CC_REPRODUCIBLE_OPTIONS}"
112EXTRA_CFLAGS_XEN_TOOLS="${HOST_CC_ARCH} ${CFLAGS}"
113# 32-bit ARM needs the TUNE_CCARGS component of HOST_CC_ARCH to be passed
114# in CC to ensure that configure can compile binaries for the right arch.
115CC:arm="${CCACHE}${HOST_PREFIX}gcc ${TUNE_CCARGS} ${TOOLCHAIN_OPTIONS} ${DEBUG_PREFIX_MAP} ${CC_REPRODUCIBLE_OPTIONS}"
116
117# There are no Xen-provided variables for C++, so append to the tool variables:
118CPP:append = " ${CPPFLAGS}"
119CXX:append = " ${CXXFLAGS}"
120
121EXTRA_OECONF += " \
122 --exec-prefix=${prefix} \
123 --prefix=${prefix} \
124 --host=${HOST_SYS} \
125 --disable-stubdom \
126 --disable-ioemu-stubdom \
127 --disable-pv-grub \
128 --disable-xenstore-stubdom \
129 --disable-rombios \
130 --disable-ocamltools \
131 --disable-qemu-traditional \
132 ${@bb.utils.contains('XEN_TARGET_ARCH', 'x86_64', \
133 '--enable-pvshim --with-system-seabios="/usr/share/firmware/bios.bin"', \
134 '--disable-pvshim --disable-seabios', d)} \
135 "
136
137EXTRA_OEMAKE += "STDVGA_ROM=${STAGING_DIR_HOST}/usr/share/firmware/vgabios-0.8a.bin"
138EXTRA_OEMAKE += "CIRRUSVGA_ROM=${STAGING_DIR_HOST}/usr/share/firmware/vgabios-0.8a.cirrus.bin"
139EXTRA_OEMAKE += "SEABIOS_ROM=${STAGING_DIR_HOST}/usr/share/firmware/bios.bin"
140EXTRA_OEMAKE += "ETHERBOOT_ROMS=${STAGING_DIR_HOST}/usr/share/firmware/rtl8139.rom"
141
142# prevent the Xen build scripts from fetching things during the build
143# all dependencies should be reflected in the Yocto recipe
144EXTRA_OEMAKE += "WGET=/bin/false"
145EXTRA_OEMAKE += "GIT=/bin/false"
146
147# Improve build reproducibility: provide values for build variables.
148def get_build_time_vars(d):
149 source_date_epoch = d.getVar('SOURCE_DATE_EPOCH')
150 if source_date_epoch is not None:
151 import datetime
152 utc_datetime = datetime.datetime.utcfromtimestamp(float(source_date_epoch))
153 return " XEN_BUILD_DATE=" + utc_datetime.strftime("%Y-%m-%d") + \
154 " XEN_BUILD_TIME=" + utc_datetime.strftime("%H:%M:%S")
155 return ""
156EXTRA_OEMAKE += "${@['', 'XEN_WHOAMI=${PF} XEN_DOMAIN=${DISTRO} XEN_BUILD_HOST=${PN}-buildhost'] \
157 [d.getVar('BUILD_REPRODUCIBLE_BINARIES') == '1']}${@get_build_time_vars(d)}"
158
159# Improve build reproducibility: compiler flags to remove filesystem differences.
160CC_REPRODUCIBLE_OPTIONS = "${@['', '-gno-record-gcc-switches'] \
161 [d.getVar('BUILD_REPRODUCIBLE_BINARIES') == '1']}"
162
163# check for XSM in package config to allow XSM_ENABLE to be set
164python () {
165 pkgconfig = d.getVar('PACKAGECONFIG')
166 if ('xsm') in pkgconfig.split():
167 d.setVar('XSM_ENABLED', '1')
168 else:
169 d.setVar('XSM_ENABLED', '0')
170}
171
172do_post_patch() {
173 # fixup AS/CC/CCP/etc variable within StdGNU.mk
174 for i in LD CC CPP CXX; do
175 sed -i "s/^\($i\s\s*\).*=/\1?=/" ${S}/config/StdGNU.mk
176 done
177 # fixup environment passing in some makefiles
178 sed -i 's#\(\w*\)=\(\$.\w*.\)#\1="\2"#' ${S}/tools/firmware/Makefile
179
180 # libsystemd-daemon -> libsystemd for newer systemd versions
181 sed -i 's#libsystemd-daemon#libsystemd#' ${S}/tools/configure
182
183 # Improve build reproducibility: disable insertion of the build timestamp
184 # into the x86 EFI hypervisor binary.
185 # binutils should allow a user-supplied timestamp or use SOURCE_DATE_EPOCH
186 # for PE but currently does not.
187 if [ "${BUILD_REPRODUCIBLE_BINARIES}" = "1" ] ; then
188 sed '/^EFI_LDFLAGS = /{a EFI_LDFLAGS += --no-insert-timestamp
189}' -i "${S}/xen/arch/x86/Makefile"
190 fi
191}
192
193addtask post_patch after do_patch before do_configure
194
195# Allow all hypervisor settings in a defconfig
196EXTRA_OEMAKE += "XEN_CONFIG_EXPERT=y"
197# Build release versions always. Technically since we track release
198# tarballs this always happens but occasionally people pull in patches
199# from staging that reverts this
200EXTRA_OEMAKE += "debug=n"
201
202do_configure_common() {
203 cd ${S}
204
205 #./configure --enable-xsmpolicy does not set XSM_ENABLE must be done manually
206 if [ "${XSM_ENABLED}" = "1" ]; then
207 echo "XSM_ENABLE := y" > ${S}/.config
208 fi
209
210 if [ -f "${WORKDIR}/defconfig" ]; then
211 cp "${WORKDIR}/defconfig" "${S}/xen/.config" || \
212 bbfatal "Unable to copy defconfig to .config"
213 fi
214
215 unset CFLAGS
216
217 # do configure
218 oe_runconf EXTRA_CFLAGS_XEN_CORE="${EXTRA_CFLAGS_XEN_CORE}" \
219 EXTRA_CFLAGS_XEN_TOOLS="${EXTRA_CFLAGS_XEN_TOOLS}" \
220 PYTHON="${PYTHON}"
221}
222
223do_compile:prepend() {
224 # workaround for build bug when CFLAGS is exported
225 # https://www.mail-archive.com/xen-devel@lists.xen.org/msg67822.html
226 unset CFLAGS
227}
228
229do_install:prepend() {
230 # CFLAGS is used to set PY_CFLAGS which affects the pygrub install
231 # so also need to unset CFLAGS here:
232 unset CFLAGS
233}
diff --git a/meta-xilinx-virtualization/recipes-extended/xen/xen_4.17.bb b/meta-xilinx-virtualization/recipes-extended/xen/xen_4.17.bb
new file mode 100644
index 00000000..41cf2a15
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-extended/xen/xen_4.17.bb
@@ -0,0 +1,19 @@
1# xen 4.17.0 release sha
2SRCREV ?= "11560248ffda3f00f20bbdf3ae088af474f7f2a3"
3
4XEN_URI ?= "git://xenbits.xen.org/xen.git"
5XEN_REL ?= "4.17"
6XEN_BRANCH ?= "stable-${XEN_REL}"
7
8SRC_URI = " \
9 ${XEN_URI};branch=${XEN_BRANCH} \
10 file://0001-menuconfig-mconf-cfg-Allow-specification-of-ncurses-location.patch \
11 file://xen-flask-race-fix.patch \
12 "
13
14LIC_FILES_CHKSUM ?= "file://COPYING;md5=d1a1e216f80b6d8da95fec897d0dbec9"
15
16S = "${WORKDIR}/git"
17
18require xen.inc
19require xen-hypervisor.inc
diff --git a/meta-xilinx-virtualization/recipes-extended/xen/xen_4.17.bbappend b/meta-xilinx-virtualization/recipes-extended/xen/xen_4.17.bbappend
new file mode 100644
index 00000000..a569a96d
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-extended/xen/xen_4.17.bbappend
@@ -0,0 +1,20 @@
1require xen-xilinx_4.17.inc
2
3FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
4
5RDEPENDS:${PN}-efi += "bash python3"
6
7do_deploy:append() {
8 # Mimic older behavior for compatibility
9 if [ -f ${DEPLOYDIR}/xen-${MACHINE} ]; then
10 ln -s xen-${MACHINE} ${DEPLOYDIR}/xen
11 fi
12
13 if [ -f ${DEPLOYDIR}/xen-${MACHINE}.gz ]; then
14 ln -s xen-${MACHINE}.gz ${DEPLOYDIR}/xen.gz
15 fi
16
17 if [ -f ${DEPLOYDIR}/xen-${MACHINE}.efi ]; then
18 ln -s xen-${MACHINE}.efi ${DEPLOYDIR}/xen.efi
19 fi
20}
diff --git a/meta-xilinx-virtualization/recipes-extended/xen/xen_4.18.bb b/meta-xilinx-virtualization/recipes-extended/xen/xen_4.18.bb
new file mode 100644
index 00000000..daa27b5b
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-extended/xen/xen_4.18.bb
@@ -0,0 +1,18 @@
1# tag: RELEASE-4.18.0
2SRCREV ?= "7cb7aac7f570757b67bcd43aec67e0cda9f58b14"
3
4XEN_URI ?= "git://xenbits.xen.org/xen.git"
5XEN_REL ?= "4.18"
6XEN_BRANCH ?= "stable-4.18"
7
8SRC_URI = " \
9 ${XEN_URI};branch=${XEN_BRANCH} \
10 file://0001-menuconfig-mconf-cfg-Allow-specification-of-ncurses-location.patch \
11 "
12
13LIC_FILES_CHKSUM ?= "file://COPYING;md5=d1a1e216f80b6d8da95fec897d0dbec9"
14
15S = "${WORKDIR}/git"
16
17require xen.inc
18require xen-hypervisor.inc
diff --git a/meta-xilinx-virtualization/recipes-extended/xen/xen_4.18.bbappend b/meta-xilinx-virtualization/recipes-extended/xen/xen_4.18.bbappend
new file mode 100644
index 00000000..e2c75566
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-extended/xen/xen_4.18.bbappend
@@ -0,0 +1,20 @@
1require xen-xilinx_4.18.inc
2
3FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
4
5RDEPENDS:${PN}-efi += "bash python3"
6
7do_deploy:append() {
8 # Mimic older behavior for compatibility
9 if [ -f ${DEPLOYDIR}/xen-${MACHINE} ]; then
10 ln -s xen-${MACHINE} ${DEPLOYDIR}/xen
11 fi
12
13 if [ -f ${DEPLOYDIR}/xen-${MACHINE}.gz ]; then
14 ln -s xen-${MACHINE}.gz ${DEPLOYDIR}/xen.gz
15 fi
16
17 if [ -f ${DEPLOYDIR}/xen-${MACHINE}.efi ]; then
18 ln -s xen-${MACHINE}.efi ${DEPLOYDIR}/xen.efi
19 fi
20}
diff --git a/meta-xilinx-virtualization/recipes-graphics/xorg-xserver/xserver-xorg_%.bbappend b/meta-xilinx-virtualization/recipes-graphics/xorg-xserver/xserver-xorg_%.bbappend
new file mode 100644
index 00000000..298b1dc8
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-graphics/xorg-xserver/xserver-xorg_%.bbappend
@@ -0,0 +1,8 @@
1# See meta-virtualization recipes-graphics/xorg-xserver/xserver-xorg_xen.inc
2
3# We want the configuration to remain optimized, if a user wants the removal
4# behavior, then they can set one of the below using 'glamor' as in the
5# xserver-xorg_xen.inc file.
6XEN_REMOVED_OPENGL_PKGCONFIGS:zynqmp ?= ""
7XEN_REMOVED_OPENGL_PKGCONFIGS:versal ?= ""
8