diff options
| author | Mark Hatle <mark.hatle@amd.com> | 2024-03-22 15:53:37 -0600 |
|---|---|---|
| committer | Mark Hatle <mark.hatle@amd.com> | 2024-03-26 19:02:44 -0600 |
| commit | d3bb371f8a8063f59dc9b3a654530063da967627 (patch) | |
| tree | 395cfa9a3bb1b1030548be573c6fc9734288055a /meta-xilinx-virtualization | |
| parent | 13e2e08f028da93469d6a0ee18a153e9b5ae303d (diff) | |
| parent | 8b38759ff39db98c29651a2d80eedb2fb1a105aa (diff) | |
| download | meta-xilinx-d3bb371f8a8063f59dc9b3a654530063da967627.tar.gz | |
Merge remote-tracking branch 'xilinx/rel-v2024.1' into master-next
Signed-off-by: Mark Hatle <mark.hatle@amd.com>
Diffstat (limited to 'meta-xilinx-virtualization')
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 @@ | |||
| 1 | Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| 2 | of this software and associated documentation files (the "Software"), to deal | ||
| 3 | in the Software without restriction, including without limitation the rights | ||
| 4 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| 5 | copies of the Software, and to permit persons to whom the Software is | ||
| 6 | furnished to do so, subject to the following conditions: | ||
| 7 | |||
| 8 | The above copyright notice and this permission notice shall be included in | ||
| 9 | all copies or substantial portions of the Software. | ||
| 10 | |||
| 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| 14 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 15 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| 16 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| 17 | THE 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 | |||
| 3 | This layer enables AMD Xilinx Xen configurations and features for ZynqMP and | ||
| 4 | Versal devices and also provides related metadata. | ||
| 5 | |||
| 6 | ## Xen Build Instructions | ||
| 7 | |||
| 8 | The Yocto Project setup for AMD Xilinx Xen configurations workflow is as follows. | ||
| 9 | Be sure to read everything below. | ||
| 10 | |||
| 11 | 1. Follow [Building Instructions](../README.building.md) upto step 2. | ||
| 12 | |||
| 13 | 2. Clone the meta-security repository. | ||
| 14 | |||
| 15 | ``` | ||
| 16 | $ git clone -b <release-branch> https://git.yoctoproject.org/meta-security | ||
| 17 | ``` | ||
| 18 | |||
| 19 | 3. 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 | |||
| 24 | 4. 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 | |||
| 30 | 5. The following variables needs to be added to the end of the conf/local.conf file. | ||
| 31 | |||
| 32 | ``` | ||
| 33 | # Xen variables | ||
| 34 | BOOTMODE = "xen" | ||
| 35 | ENABLE_XEN_UBOOT_SCR = "1" | ||
| 36 | ENABLE_XEN_DTSI = "1" | ||
| 37 | ENABLE_XEN_QEMU_DTSI = "1" | ||
| 38 | |||
| 39 | DISTRO_FEATURES:append = " multiarch security tpm virtualization vmsep xen" | ||
| 40 | |||
| 41 | IMAGE_FEATURES += "ssh-server-openssh" | ||
| 42 | |||
| 43 | DISTRO_FEATURES:append = " systemd" | ||
| 44 | VIRTUAL-RUNTIME_init_manager = "systemd" | ||
| 45 | DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit" | ||
| 46 | |||
| 47 | IMAGE_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 | |||
| 60 | 6. 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 | |||
| 67 | 1. Follow [Booting Instructions](../README.booting.md) upto step 2. | ||
| 68 | |||
| 69 | 2. Verify Xen Dom0 is up and running on QEMU or target as shown below. | ||
| 70 | |||
| 71 | ``` | ||
| 72 | Poky (Yocto Project Reference Distro) 4.1.4 zynqmp-generic hvc0 | ||
| 73 | |||
| 74 | zynqmp-generic login: root | ||
| 75 | root@zynqmp-generic:~# xl list | ||
| 76 | Name ID Mem VCPUs State Time(s) | ||
| 77 | Domain-0 0 1500 1 r----- 123.5 | ||
| 78 | root@zynqmp-generic:~# xl info | ||
| 79 | host : zynqmp-generic | ||
| 80 | release : 6.1.0-xilinx-v2024.1 | ||
| 81 | version : #1 SMP Thu Dec 21 07:00:11 UTC 2023 | ||
| 82 | machine : aarch64 | ||
| 83 | nr_cpus : 4 | ||
| 84 | max_cpu_id : 3 | ||
| 85 | nr_nodes : 1 | ||
| 86 | cores_per_socket : 1 | ||
| 87 | threads_per_core : 1 | ||
| 88 | cpu_mhz : 99.990 | ||
| 89 | hw_caps : 00000000:00000000:00000000:00000000:00000000:00000000:00000000:00000000 | ||
| 90 | virt_caps : hvm hvm_directio hap iommu_hap_pt_share vpmu gnttab-v1 | ||
| 91 | total_memory : 4095 | ||
| 92 | free_memory : 2529 | ||
| 93 | sharing_freed_memory : 0 | ||
| 94 | sharing_used_memory : 0 | ||
| 95 | outstanding_claims : 0 | ||
| 96 | free_cpus : 0 | ||
| 97 | xen_major : 4 | ||
| 98 | xen_minor : 17 | ||
| 99 | xen_extra : .0 | ||
| 100 | xen_version : 4.17.0 | ||
| 101 | xen_caps : xen-3.0-aarch64 xen-3.0-armv7l | ||
| 102 | xen_scheduler : credit2 | ||
| 103 | xen_pagesize : 4096 | ||
| 104 | platform_params : virt_start=0x200000 | ||
| 105 | xen_changeset : Tue Dec 12 10:08:40 2023 +0100 git:38eebc6e5c-dirty | ||
| 106 | xen_commandline : console=dtuart dtuart=serial0 dom0_mem=1500M dom0_max_vcpus=1 bootscrub=0 vwfi=native | ||
| 107 | cc_compiler : aarch64-poky-linux-gcc (GCC) 12.2.0 | ||
| 108 | cc_compile_by : santraju | ||
| 109 | cc_compile_domain : | ||
| 110 | cc_compile_date : 2023-12-12 | ||
| 111 | build_id : 5e2952e1dd06c52a2a09ada7476333c48d88a285 | ||
| 112 | xend_config_format : 4 | ||
| 113 | root@zynqmp-generic:~# | ||
| 114 | ``` | ||
| 115 | |||
| 116 | ## Dependencies | ||
| 117 | |||
| 118 | This 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 | ||
| 2 | BBPATH .= ":${LAYERDIR}" | ||
| 3 | |||
| 4 | # We have packages directories, add to BBFILES | ||
| 5 | BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \ | ||
| 6 | ${LAYERDIR}/recipes-*/*/*.bbappend" | ||
| 7 | |||
| 8 | BBFILE_COLLECTIONS += "xilinx-virtualization" | ||
| 9 | BBFILE_PATTERN_xilinx-virtualization = "^${LAYERDIR}/" | ||
| 10 | BBFILE_PRIORITY_xilinx-virtualization = "5" | ||
| 11 | |||
| 12 | LAYERDEPENDS_xilinx-virtualization = "\ | ||
| 13 | xilinx \ | ||
| 14 | virtualization-layer \ | ||
| 15 | security \ | ||
| 16 | tpm-layer \ | ||
| 17 | " | ||
| 18 | |||
| 19 | LAYERSERIES_COMPAT_xilinx-virtualization = "scarthgap" | ||
| 20 | |||
| 21 | XILINX_XEN_VERSION[v2022.1] = "4.17-xilinx+git%" | ||
| 22 | XILINX_XEN_VERSION[v2022.2] = "4.17-xilinx+git%" | ||
| 23 | XILINX_XEN_VERSION[v2023.1] = "4.17-xilinx+git%" | ||
| 24 | XILINX_XEN_VERSION[v2023.2] = "4.17-xilinx+git%" | ||
| 25 | XILINX_XEN_VERSION[v2024.1] = "4.18-xilinx+git%" | ||
| 26 | PREFERRED_VERSION_xen ?= "${@d.getVarFlag('XILINX_XEN_VERSION', d.getVar('XILINX_RELEASE_VERSION')) or 'undefined'}" | ||
| 27 | PREFERRED_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 @@ | |||
| 1 | PACKAGECONFIG:append = "${@bb.utils.contains('DISTRO_FEATURES', 'tpm', ' tpm', '', d)}" | ||
| 2 | |||
| 3 | PACKAGECONFIG[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 | ||
| 2 | SRC_URI_XEN = "" | ||
| 3 | SRC_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 | |||
| 31 | FILESEXTRAPATHS:prepend:class-target := "${THISDIR}/qemu-xilinx-7.1:" | ||
| 32 | |||
| 33 | SRC_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 | ||
| 2 | SRC_URI_XEN = "" | ||
| 3 | SRC_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 | |||
| 18 | FILESEXTRAPATHS:prepend:class-target := "${THISDIR}/qemu-xilinx-8.1:" | ||
| 19 | |||
| 20 | SRC_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 @@ | |||
| 1 | From ba24456b93a205b728475d5f0880f3ec495e383a Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Chuck Zmudzinski <brchuckz@aol.com> | ||
| 3 | Date: Mon, 31 Oct 2022 17:35:52 -0400 | ||
| 4 | Subject: [PATCH] xen/pt: fix syntax error that causes FTBFS in some | ||
| 5 | configurations | ||
| 6 | MIME-Version: 1.0 | ||
| 7 | Content-Type: text/plain; charset=UTF-8 | ||
| 8 | Content-Transfer-Encoding: 8bit | ||
| 9 | |||
| 10 | When Qemu is built with --enable-xen and --disable-xen-pci-passthrough | ||
| 11 | and the target os is linux, the build fails with: | ||
| 12 | |||
| 13 | meson.build:3477:2: ERROR: File xen_pt_stub.c does not exist. | ||
| 14 | |||
| 15 | Fixes: 582ea95f5f93 ("meson: convert hw/xen") | ||
| 16 | |||
| 17 | Signed-off-by: Chuck Zmudzinski <brchuckz@aol.com> | ||
| 18 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
| 19 | Message-Id: <5f1342a13c09af77b1a7b0aeaba5955bcea89731.1667242033.git.brchuckz@aol.com> | ||
| 20 | Signed-off-by: Laurent Vivier <laurent@vivier.eu> | ||
| 21 | --- | ||
| 22 | hw/xen/meson.build | 2 +- | ||
| 23 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
| 24 | |||
| 25 | diff --git a/hw/xen/meson.build b/hw/xen/meson.build | ||
| 26 | index 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 | -- | ||
| 39 | 2.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 @@ | |||
| 1 | From e2b85efc82bc26a838f666c8282528ee38cf6377 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Juergen Gross <jgross@suse.com> | ||
| 3 | Date: Tue, 16 Mar 2021 14:00:33 +0100 | ||
| 4 | Subject: [PATCH 1/8] xen: when unplugging emulated devices skip virtio devices | ||
| 5 | |||
| 6 | Virtio devices should never be unplugged at boot time, as they are | ||
| 7 | similar to pci passthrough devices. | ||
| 8 | |||
| 9 | Signed-off-by: Juergen Gross <jgross@suse.com> | ||
| 10 | Acked-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 | |||
| 15 | diff --git a/hw/i386/xen/xen_platform.c b/hw/i386/xen/xen_platform.c | ||
| 16 | index 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 | -- | ||
| 50 | 2.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 @@ | |||
| 1 | From ef4d512aff004c62d550cdd64329c6c1acd0f217 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Stefano Stabellini <stefano.stabellini@amd.com> | ||
| 3 | Date: Fri, 1 Jul 2022 18:48:03 -0700 | ||
| 4 | Subject: [PATCH 01/16] xen_common: return error from xen_create_ioreq_server | ||
| 5 | |||
| 6 | Signed-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 | |||
| 11 | diff --git a/include/hw/xen/xen_common.h b/include/hw/xen/xen_common.h | ||
| 12 | index 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 | -- | ||
| 54 | 2.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 @@ | |||
| 1 | From e18daac2f6d3f60c8217f44189a91cf8240a591f Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Juergen Gross <jgross@suse.com> | ||
| 3 | Date: Thu, 20 May 2021 11:19:58 +0200 | ||
| 4 | Subject: [PATCH 2/8] xen: add pseudo RAM region for grant mappings | ||
| 5 | |||
| 6 | Add a memory region which can be used to automatically map granted | ||
| 7 | memory. It is starting at 0x8000000000000000ULL in order to be able to | ||
| 8 | distinguish it from normal RAM. | ||
| 9 | |||
| 10 | For this reason the xen.ram memory region is expanded, which has no | ||
| 11 | further impact as it is used just as a container of the real RAM | ||
| 12 | regions and now the grant region. | ||
| 13 | |||
| 14 | Signed-off-by: Juergen Gross <jgross@suse.com> | ||
| 15 | Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 16 | Acked-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 | |||
| 28 | diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c | ||
| 29 | index 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) | ||
| 42 | diff --git a/hw/xen/xen-hvm-common.c b/hw/xen/xen-hvm-common.c | ||
| 43 | index 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 | |||
| 64 | diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c | ||
| 65 | index 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 | +} | ||
| 108 | diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h | ||
| 109 | index 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) | ||
| 120 | diff --git a/include/hw/xen/xen-hvm-common.h b/include/hw/xen/xen-hvm-common.h | ||
| 121 | index 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 | |||
| 133 | diff --git a/include/hw/xen/xen_pvdev.h b/include/hw/xen/xen_pvdev.h | ||
| 134 | index 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 */ | ||
| 145 | diff --git a/include/sysemu/xen-mapcache.h b/include/sysemu/xen-mapcache.h | ||
| 146 | index 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, | ||
| 166 | diff --git a/softmmu/physmem.c b/softmmu/physmem.c | ||
| 167 | index 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 | -- | ||
| 251 | 2.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 @@ | |||
| 1 | From 423468bdb3728154e95af18ef755bc75c5d59a3a Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 3 | Date: Thu, 30 Jun 2022 18:19:50 -0700 | ||
| 4 | Subject: [PATCH 02/16] xen-mapcache: move xen-mapcache.c to hw/xen | ||
| 5 | |||
| 6 | xen-mapcache.c contains common functions which are useful for Xen on ARM | ||
| 7 | IOREQ handling. Moving it out of i386 to hw/xen for commong access. | ||
| 8 | |||
| 9 | Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 10 | Reviewed-by: Stefano Stabellini <stefano.stabellini@xilinx.com> | ||
| 11 | Signed-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 | |||
| 22 | diff --git a/hw/i386/meson.build b/hw/i386/meson.build | ||
| 23 | index 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} | ||
| 33 | diff --git a/hw/i386/xen/meson.build b/hw/i386/xen/meson.build | ||
| 34 | index 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', | ||
| 44 | diff --git a/hw/i386/xen/trace-events b/hw/i386/xen/trace-events | ||
| 45 | index 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 | - | ||
| 57 | diff --git a/hw/xen/meson.build b/hw/xen/meson.build | ||
| 58 | index 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')) | ||
| 69 | diff --git a/hw/xen/trace-events b/hw/xen/trace-events | ||
| 70 | index 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" | ||
| 82 | diff --git a/hw/i386/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c | ||
| 83 | similarity index 100% | ||
| 84 | rename from hw/i386/xen/xen-mapcache.c | ||
| 85 | rename to hw/xen/xen-mapcache.c | ||
| 86 | -- | ||
| 87 | 2.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 @@ | |||
| 1 | From 4472924c800e9dbf46e4c2432565d3e406b35d27 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 3 | Date: Fri, 1 Jul 2022 16:32:33 -0700 | ||
| 4 | Subject: [PATCH 03/16] hw/i386/xen: rearrange xen_hvm_init_pc | ||
| 5 | |||
| 6 | Move references to: | ||
| 7 | - xen_get_vmport_regs_pfn | ||
| 8 | - xen_suspend_notifier | ||
| 9 | - xen_wakeup_notifier | ||
| 10 | - xen_ram_init | ||
| 11 | |||
| 12 | towards the end of the function. This is done to keep the the common | ||
| 13 | ioreq functions in one place which will be moved to new function in next | ||
| 14 | patch in order to make it useful to ARM machines also. | ||
| 15 | |||
| 16 | Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 17 | Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com> | ||
| 18 | Reviewed-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 | |||
| 23 | diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c | ||
| 24 | index 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 | -- | ||
| 105 | 2.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 @@ | |||
| 1 | From cb4be1f7185c5974523c764f3f6efe3af6633d71 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Juergen Gross <jgross@suse.com> | ||
| 3 | Date: Thu, 20 May 2021 11:54:48 +0200 | ||
| 4 | Subject: [PATCH 3/8] softmmu: let qemu_map_ram_ptr() use qemu_ram_ptr_length() | ||
| 5 | |||
| 6 | qemu_map_ram_ptr() and qemu_ram_ptr_length() share quite some code, so | ||
| 7 | modify qemu_ram_ptr_length() a little bit and use it for | ||
| 8 | qemu_map_ram_ptr(), too. | ||
| 9 | |||
| 10 | Signed-off-by: Juergen Gross <jgross@suse.com> | ||
| 11 | Acked-by: Stefano Stabellini <stefano.stabellini@amd.com> | ||
| 12 | --- | ||
| 13 | softmmu/physmem.c | 56 ++++++++++++++++++----------------------------- | ||
| 14 | 1 file changed, 21 insertions(+), 35 deletions(-) | ||
| 15 | |||
| 16 | diff --git a/softmmu/physmem.c b/softmmu/physmem.c | ||
| 17 | index 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 | -- | ||
| 112 | 2.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 @@ | |||
| 1 | From 2a01fa06d267f68148d3a6df50675edfe090601a Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Stefano Stabellini <stefano.stabellini@amd.com> | ||
| 3 | Date: Fri, 1 Jul 2022 18:16:52 -0700 | ||
| 4 | Subject: [PATCH 04/16] xen-hvm: move x86-specific fields out of XenIOState | ||
| 5 | |||
| 6 | Move: | ||
| 7 | - shared_vmport_page | ||
| 8 | - log_for_dirtybit | ||
| 9 | - dirty_bitmap | ||
| 10 | - suspend | ||
| 11 | - wakeup | ||
| 12 | |||
| 13 | out of XenIOState as they are only used on x86, especially the ones | ||
| 14 | related to dirty logging. | ||
| 15 | |||
| 16 | Remove free_phys_offset that was unused. | ||
| 17 | |||
| 18 | Signed-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 | |||
| 23 | diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c | ||
| 24 | index 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 | -- | ||
| 179 | 2.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 @@ | |||
| 1 | From 7dfa8828bd2e61fc5bf2bf6294aad16b2bf4ff8a Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Juergen Gross <jgross@suse.com> | ||
| 3 | Date: Thu, 20 May 2021 13:31:32 +0200 | ||
| 4 | Subject: [PATCH 4/8] xen: let xen_ram_addr_from_mapcache() return -1 in case | ||
| 5 | of not found entry | ||
| 6 | |||
| 7 | Today xen_ram_addr_from_mapcache() will either abort() or return 0 in | ||
| 8 | case it can't find a matching entry for a pointer value. Both cases | ||
| 9 | are bad, so change that to return an invalid address instead. | ||
| 10 | |||
| 11 | Signed-off-by: Juergen Gross <jgross@suse.com> | ||
| 12 | Acked-by: Stefano Stabellini <stefano.stabellini@amd.com> | ||
| 13 | --- | ||
| 14 | hw/xen/xen-mapcache.c | 12 +++--------- | ||
| 15 | 1 file changed, 3 insertions(+), 9 deletions(-) | ||
| 16 | |||
| 17 | diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c | ||
| 18 | index 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 | -- | ||
| 48 | 2.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 @@ | |||
| 1 | From bd32a130ca633eae7cf0f4ff0fa856004d413df0 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Juergen Gross <jgross@suse.com> | ||
| 3 | Date: Thu, 27 May 2021 15:27:55 +0200 | ||
| 4 | Subject: [PATCH 5/8] memory: add MemoryRegion map and unmap callbacks | ||
| 5 | |||
| 6 | In order to support mapping and unmapping guest memory dynamically to | ||
| 7 | and from qemu during address_space_[un]map() operations add the map() | ||
| 8 | and unmap() callbacks to MemoryRegionOps. | ||
| 9 | |||
| 10 | Those will be used e.g. for Xen grant mappings when performing guest | ||
| 11 | I/Os. | ||
| 12 | |||
| 13 | Signed-off-by: Juergen Gross <jgross@suse.com> | ||
| 14 | Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 15 | Acked-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 | |||
| 21 | diff --git a/include/exec/memory.h b/include/exec/memory.h | ||
| 22 | index 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 { | ||
| 51 | diff --git a/softmmu/physmem.c b/softmmu/physmem.c | ||
| 52 | index 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 | -- | ||
| 149 | 2.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 @@ | |||
| 1 | From c38436434fc888ba8844d99eab451f9b734e5e5b Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Stefano Stabellini <stefano.stabellini@amd.com> | ||
| 3 | Date: Fri, 1 Jul 2022 19:34:39 -0700 | ||
| 4 | Subject: [PATCH 05/16] xen-hvm: create arch_handle_ioreq and | ||
| 5 | arch_xen_set_memory | ||
| 6 | |||
| 7 | In preparation to moving most of xen-hvm code to an arch-neutral | ||
| 8 | location, move the x86-specific portion of xen_set_memory to | ||
| 9 | arch_xen_set_memory. | ||
| 10 | |||
| 11 | Also move handle_vmport_ioreq to arch_handle_ioreq. | ||
| 12 | |||
| 13 | Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com> | ||
| 14 | Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 15 | Reviewed-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 | |||
| 24 | diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c | ||
| 25 | index 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 | +} | ||
| 165 | diff --git a/include/hw/i386/xen_arch_hvm.h b/include/hw/i386/xen_arch_hvm.h | ||
| 166 | new file mode 100644 | ||
| 167 | index 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 | ||
| 181 | diff --git a/include/hw/xen/arch_hvm.h b/include/hw/xen/arch_hvm.h | ||
| 182 | new file mode 100644 | ||
| 183 | index 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 | -- | ||
| 191 | 2.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 @@ | |||
| 1 | From ef94d70d4a22c5282d6955a7ed066ef502e99829 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Juergen Gross <jgross@suse.com> | ||
| 3 | Date: Fri, 26 Aug 2022 13:57:06 +0200 | ||
| 4 | Subject: [PATCH 6/8] xen: add map and unmap callbacks for grant region | ||
| 5 | |||
| 6 | Add the callbacks for mapping/unmapping guest memory via grants to the | ||
| 7 | special grant memory region. | ||
| 8 | |||
| 9 | Signed-off-by: Juergen Gross <jgross@suse.com> | ||
| 10 | Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 11 | Signed-off-by: Stefano Stabellini <stefano.stabellini@amd.com> | ||
| 12 | Acked-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 | |||
| 18 | diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c | ||
| 19 | index 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); | ||
| 228 | diff --git a/softmmu/physmem.c b/softmmu/physmem.c | ||
| 229 | index 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 | -- | ||
| 254 | 2.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 @@ | |||
| 1 | From 87d362e72e65b604da7554657204344a6540d88c Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 3 | Date: Fri, 1 Jul 2022 15:59:47 -0700 | ||
| 4 | Subject: [PATCH 06/16] xen-hvm: move common functions to | ||
| 5 | hw/xen/xen-hvm-common.c | ||
| 6 | |||
| 7 | Extract common functionalities from xen-hvm.c and move them to | ||
| 8 | hw/xen/xen-hvm-common.c. These common functions are useful for creating | ||
| 9 | an IOREQ server. | ||
| 10 | |||
| 11 | Moved the common usable IOREQ creation part to a new function | ||
| 12 | xen_register_ioreq() which can be used by both x86 and ARM machines. | ||
| 13 | |||
| 14 | NOTE: This patch will break the build as the patch only involves moving | ||
| 15 | of functions. Build fixes will be in the next patch. | ||
| 16 | |||
| 17 | Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 18 | Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com> | ||
| 19 | Reviewed-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 | |||
| 32 | diff --git a/hw/i386/xen/trace-events b/hw/i386/xen/trace-events | ||
| 33 | index 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 | - | ||
| 54 | diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c | ||
| 55 | index 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, ©); | ||
| 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)) { | ||
| 1071 | diff --git a/hw/xen/meson.build b/hw/xen/meson.build | ||
| 1072 | index 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 | +)) | ||
| 1084 | diff --git a/hw/xen/trace-events b/hw/xen/trace-events | ||
| 1085 | index 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 | ||
| 1109 | diff --git a/hw/xen/xen-hvm-common.c b/hw/xen/xen-hvm-common.c | ||
| 1110 | new file mode 100644 | ||
| 1111 | index 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, ©); | ||
| 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 | +} | ||
| 1976 | diff --git a/include/hw/i386/xen_arch_hvm.h b/include/hw/i386/xen_arch_hvm.h | ||
| 1977 | index 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, | ||
| 1988 | diff --git a/include/hw/xen/xen-hvm-common.h b/include/hw/xen/xen-hvm-common.h | ||
| 1989 | new file mode 100644 | ||
| 1990 | index 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 | -- | ||
| 2093 | 2.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 @@ | |||
| 1 | From 2aca3ff63a5d5897cd32e0030569623f0c454f2c Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com> | ||
| 3 | Date: Mon, 19 Sep 2022 21:59:55 +0300 | ||
| 4 | Subject: [PATCH 7/8] xen-mapcache: Fix build on Arm | ||
| 5 | MIME-Version: 1.0 | ||
| 6 | Content-Type: text/plain; charset=UTF-8 | ||
| 7 | Content-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 | | ^~~~~~~~~~~~ | ||
| 14 | cc1: all warnings being treated as errors | ||
| 15 | |||
| 16 | Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com> | ||
| 17 | Acked-by: Stefano Stabellini <stefano.stabellini@amd.com> | ||
| 18 | --- | ||
| 19 | hw/xen/xen-mapcache.c | 2 +- | ||
| 20 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
| 21 | |||
| 22 | diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c | ||
| 23 | index 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 | -- | ||
| 36 | 2.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 @@ | |||
| 1 | From fa475ec44fc78ff246e6536c8b9d408abadbb4a4 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Stefano Stabellini <stefano.stabellini@amd.com> | ||
| 3 | Date: Fri, 1 Jul 2022 18:50:59 -0700 | ||
| 4 | Subject: [PATCH 07/16] xen: skip ioreq creation on ioreq registration failure | ||
| 5 | |||
| 6 | On ARM it is possible to have a functioning xenpv machine with only the | ||
| 7 | PV backends and no IOREQ server. If the IOREQ server creation fails | ||
| 8 | continue to the PV backends initialization. | ||
| 9 | |||
| 10 | Signed-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 | |||
| 15 | diff --git a/hw/xen/xen-hvm-common.c b/hw/xen/xen-hvm-common.c | ||
| 16 | index 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 | -- | ||
| 41 | 2.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 @@ | |||
| 1 | From 13443fe86bb100849c55b41873f48e0b121c7bc0 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 3 | Date: Fri, 1 Jul 2022 17:28:14 -0700 | ||
| 4 | Subject: [PATCH 08/16] accel/xen/xen-all: export xenstore_record_dm_state | ||
| 5 | |||
| 6 | Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 7 | Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com> | ||
| 8 | Reviewed-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 | |||
| 14 | diff --git a/accel/xen/xen-all.c b/accel/xen/xen-all.c | ||
| 15 | index 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 | |||
| 27 | diff --git a/include/hw/xen/xen.h b/include/hw/xen/xen.h | ||
| 28 | index 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 | -- | ||
| 47 | 2.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 @@ | |||
| 1 | From b5e5f60de37bb6f71bc34ecb989c31ef5c834272 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 3 | Date: Tue, 31 Jan 2023 21:46:43 +0000 | ||
| 4 | Subject: [PATCH 8/8] hw: arm: Add grant mapping. | ||
| 5 | |||
| 6 | Add support for grant mapping and change qemu machine name to xenpvh. | ||
| 7 | |||
| 8 | Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 9 | Acked-by: Stefano Stabellini <stefano.stabellini@amd.com> | ||
| 10 | --- | ||
| 11 | hw/arm/xen_arm.c | 5 ++++- | ||
| 12 | 1 file changed, 4 insertions(+), 1 deletion(-) | ||
| 13 | |||
| 14 | diff --git a/hw/arm/xen_arm.c b/hw/arm/xen_arm.c | ||
| 15 | index 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 | -- | ||
| 38 | 2.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 @@ | |||
| 1 | From 2e6a9f464fd1f247c41ce3666ff3e3f66920d0b7 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 3 | Date: Fri, 1 Jul 2022 17:28:15 -0700 | ||
| 4 | Subject: [PATCH 09/16] xen-hvm: enable xen-hvm-common build for ARM | ||
| 5 | |||
| 6 | Add CONFIG_XEN for aarch64 device and change xen-hvm-common.c to | ||
| 7 | support build for ARM targets. | ||
| 8 | |||
| 9 | Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 10 | Acked-by: Stefano Stabellini <stefano.stabellini@xilinx.com> | ||
| 11 | Signed-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 | |||
| 17 | diff --git a/hw/arm/meson.build b/hw/arm/meson.build | ||
| 18 | index 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} | ||
| 28 | diff --git a/meson.build b/meson.build | ||
| 29 | index 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 | -- | ||
| 42 | 2.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 @@ | |||
| 1 | From 5618a18b1f12d567a8ef85240d55b841e18ef472 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 3 | Date: Fri, 1 Jul 2022 17:28:16 -0700 | ||
| 4 | Subject: [PATCH 10/16] hw/arm: introduce xenpv machine | ||
| 5 | |||
| 6 | Create a new machine xenpv which creates a IOREQ server to connect | ||
| 7 | with Xen. It also creates a tpm-tis-device which connects to swtpm to | ||
| 8 | support TPM functionalities. | ||
| 9 | |||
| 10 | Xen IOREQ connection expect the TARGET_PAGE_SIZE to 4096, and the xenpv | ||
| 11 | machine on ARM will have no CPU definitions. We need to define | ||
| 12 | TARGET_PAGE_SIZE appropriately ourselves. | ||
| 13 | |||
| 14 | Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 15 | Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com> | ||
| 16 | Reviewed-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 | |||
| 26 | diff --git a/hw/arm/meson.build b/hw/arm/meson.build | ||
| 27 | index 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} | ||
| 38 | diff --git a/hw/arm/xen_arm.c b/hw/arm/xen_arm.c | ||
| 39 | new file mode 100644 | ||
| 40 | index 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) | ||
| 200 | diff --git a/include/hw/arm/xen_arch_hvm.h b/include/hw/arm/xen_arch_hvm.h | ||
| 201 | new file mode 100644 | ||
| 202 | index 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 | ||
| 218 | diff --git a/include/hw/xen/arch_hvm.h b/include/hw/xen/arch_hvm.h | ||
| 219 | index 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 | -- | ||
| 229 | 2.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 @@ | |||
| 1 | From f4ff3490639dea08fb70ec69d60fe73ef479073b Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Stefano Stabellini <stefano.stabellini@amd.com> | ||
| 3 | Date: Thu, 7 Jul 2022 14:03:41 -0700 | ||
| 4 | Subject: [PATCH 11/16] meson.build: do not set have_xen_pci_passthrough for | ||
| 5 | aarch64 targets | ||
| 6 | MIME-Version: 1.0 | ||
| 7 | Content-Type: text/plain; charset=UTF-8 | ||
| 8 | Content-Transfer-Encoding: 8bit | ||
| 9 | |||
| 10 | have_xen_pci_passthrough is only used for Xen x86 VMs. | ||
| 11 | |||
| 12 | Signed-off-by: Stefano Stabellini <stefano.stabellini@amd.com> | ||
| 13 | Reviewed-by: Alex Bennée <alex.bennee@linaro.org> | ||
| 14 | --- | ||
| 15 | meson.build | 2 ++ | ||
| 16 | 1 file changed, 2 insertions(+) | ||
| 17 | |||
| 18 | diff --git a/meson.build b/meson.build | ||
| 19 | index 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 | -- | ||
| 32 | 2.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 @@ | |||
| 1 | From a26982a55fa5f47116b344ca5d411f00c3a2b422 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Stefano Stabellini <stefano.stabellini@amd.com> | ||
| 3 | Date: Thu, 7 Jul 2022 14:35:33 -0700 | ||
| 4 | Subject: [PATCH 12/16] xen-arm: call qemu_find_tpm_be if CONFIG_TPM | ||
| 5 | |||
| 6 | qemu_find_tpm_be is only availablen when CONFIG_TPM is enabled. | ||
| 7 | So #ifdef the call to make sure the code builds correctly even when | ||
| 8 | CONFIG_TPM is not enabled. | ||
| 9 | |||
| 10 | Signed-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 | |||
| 15 | diff --git a/hw/arm/xen_arm.c b/hw/arm/xen_arm.c | ||
| 16 | index 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 | -- | ||
| 71 | 2.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 @@ | |||
| 1 | From c5b128668d9cd1e1cb4da80d5bc8aaebc6ff2e19 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 3 | Date: Fri, 23 Dec 2022 00:06:29 +0000 | ||
| 4 | Subject: [PATCH 13/16] arm: xenpv: fix TPM address print warning | ||
| 5 | |||
| 6 | Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 7 | Acked-by: Stefano Stabellini <stefano.stabellini@amd.com> | ||
| 8 | --- | ||
| 9 | hw/arm/xen_arm.c | 2 +- | ||
| 10 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
| 11 | |||
| 12 | diff --git a/hw/arm/xen_arm.c b/hw/arm/xen_arm.c | ||
| 13 | index 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 | -- | ||
| 26 | 2.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 @@ | |||
| 1 | From 3dc39d71c3652bea37dc955d5dbf8cd391d2aed0 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com> | ||
| 3 | Date: Sat, 30 Jul 2022 17:51:19 +0300 | ||
| 4 | Subject: [PATCH 14/16] xen_arm: Create virtio-mmio devices during | ||
| 5 | initialization | ||
| 6 | |||
| 7 | In order to use virtio backends we need to allocate virtio-mmio | ||
| 8 | parameters (irq and base) and register corresponding buses. | ||
| 9 | |||
| 10 | Use the constants defined in public header arch-arm.h to be | ||
| 11 | aligned with the toolstack. So the number of current supported | ||
| 12 | virtio-mmio devices is 10. | ||
| 13 | |||
| 14 | For the interrupts triggering use already existing on Arm | ||
| 15 | device-model hypercall. | ||
| 16 | |||
| 17 | The toolstack should then insert the same amount of device nodes | ||
| 18 | into guest device-tree. | ||
| 19 | |||
| 20 | Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com> | ||
| 21 | Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 22 | Reviewed-by: Stefano Stabellini <stefano.stabellini@amd.com> | ||
| 23 | --- | ||
| 24 | hw/arm/xen_arm.c | 29 +++++++++++++++++++++++++++++ | ||
| 25 | 1 file changed, 29 insertions(+) | ||
| 26 | |||
| 27 | diff --git a/hw/arm/xen_arm.c b/hw/arm/xen_arm.c | ||
| 28 | index 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 | -- | ||
| 82 | 2.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 @@ | |||
| 1 | From a284a53c5374e19ac37b884f2dd50293e7c8070e Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com> | ||
| 3 | Date: Sat, 30 Jul 2022 17:18:06 +0300 | ||
| 4 | Subject: [PATCH 15/16] xen_arm: Initialize RAM and add hi/low memory regions | ||
| 5 | |||
| 6 | In order to use virtio backends we need to initialize RAM for the | ||
| 7 | xen-mapcache (which is responsible for mapping guest memory using foreign | ||
| 8 | mapping) to work. Calculate and add hi/low memory regions based on | ||
| 9 | machine->ram_size. | ||
| 10 | |||
| 11 | Use the constants defined in public header arch-arm.h to be aligned with the | ||
| 12 | toolstack. | ||
| 13 | |||
| 14 | The toolstack should then pass real ram_size using "-m" arg. | ||
| 15 | If "-m" is not given, create a QEMU machine without IOREQ, TPM and VIRTIO to | ||
| 16 | keep it usable for /etc/init.d/xencommons. | ||
| 17 | |||
| 18 | Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com> | ||
| 19 | Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 20 | Reviewed-by: Stefano Stabellini <stefano.stabellini@amd.com> | ||
| 21 | --- | ||
| 22 | hw/arm/xen_arm.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ | ||
| 23 | 1 file changed, 46 insertions(+) | ||
| 24 | |||
| 25 | diff --git a/hw/arm/xen_arm.c b/hw/arm/xen_arm.c | ||
| 26 | index 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 | -- | ||
| 104 | 2.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 @@ | |||
| 1 | From a730d5ea4a0445a8c694b56583dd06bd000fae74 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 3 | Date: Wed, 4 Jan 2023 23:05:25 +0000 | ||
| 4 | Subject: [PATCH 16/16] xen_arm: Add "accel = xen" and drop extra interface | ||
| 5 | openings | ||
| 6 | |||
| 7 | In order to use virtio backends we need to make sure that Xen accelerator | ||
| 8 | is enabled (xen_enabled() returns true) as the memory/cache systems | ||
| 9 | check for xen_enabled() to perform specific actions. Without that | ||
| 10 | the xen-mapcache (which is needed for mapping guest memory) is not in use. | ||
| 11 | |||
| 12 | Also 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 | ||
| 14 | if device emulation is not available. | ||
| 15 | |||
| 16 | Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com> | ||
| 17 | Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 18 | Reviewed-by: Stefano Stabellini <stefano.stabellini@amd.com> | ||
| 19 | --- | ||
| 20 | hw/arm/xen_arm.c | 29 ++--------------------------- | ||
| 21 | 1 file changed, 2 insertions(+), 27 deletions(-) | ||
| 22 | |||
| 23 | diff --git a/hw/arm/xen_arm.c b/hw/arm/xen_arm.c | ||
| 24 | index 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 | -- | ||
| 78 | 2.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 @@ | |||
| 1 | From 3104d411ee36487ea409ba5a1b474989326f70f2 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 3 | Date: Wed, 15 Nov 2023 14:19:31 -0800 | ||
| 4 | Subject: [PATCH] arm: xenpvh: Introduce virtio-pci support | ||
| 5 | |||
| 6 | The bridge is needed for virtio-pci support, as QEMU can emulate the | ||
| 7 | whole bridge with any virtio-pci devices connected to it. | ||
| 8 | |||
| 9 | NOTE: A few xen-hvm-common.c and xen_native.h changes are cherry-picked from | ||
| 10 | EPAM QEMU patches for xen-arm. This was done to keep least diff with upstream. | ||
| 11 | |||
| 12 | Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 13 | Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com> | ||
| 14 | Signed-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 | |||
| 20 | diff --git a/hw/arm/xen_arm.c b/hw/arm/xen_arm.c | ||
| 21 | index 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 = { | ||
| 337 | diff --git a/include/hw/xen/xen_native.h b/include/hw/xen/xen_native.h | ||
| 338 | index 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 | -- | ||
| 352 | 2.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 @@ | |||
| 1 | From b9291457ca2eb4340c71d2eed08fde83916c9fa4 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com> | ||
| 3 | Date: Tue, 29 Aug 2023 21:35:17 -0700 | ||
| 4 | Subject: [PATCH 01/11] xen_arm: Create virtio-mmio devices during | ||
| 5 | initialization | ||
| 6 | |||
| 7 | In order to use virtio backends we need to allocate virtio-mmio | ||
| 8 | parameters (irq and base) and register corresponding buses. | ||
| 9 | |||
| 10 | Use the constants defined in public header arch-arm.h to be | ||
| 11 | aligned with the toolstack. So the number of current supported | ||
| 12 | virtio-mmio devices is 10. | ||
| 13 | |||
| 14 | For the interrupts triggering use already existing on Arm | ||
| 15 | device-model hypercall. | ||
| 16 | |||
| 17 | The toolstack should then insert the same amount of device nodes | ||
| 18 | into guest device-tree. | ||
| 19 | |||
| 20 | Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com> | ||
| 21 | Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 22 | Reviewed-by: Stefano Stabellini <sstabellini@kernel.org> | ||
| 23 | Signed-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 | |||
| 29 | diff --git a/hw/arm/xen_arm.c b/hw/arm/xen_arm.c | ||
| 30 | index 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); | ||
| 89 | diff --git a/include/hw/xen/xen_native.h b/include/hw/xen/xen_native.h | ||
| 90 | index 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 | -- | ||
| 115 | 2.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 @@ | |||
| 1 | From 70a74795c5071bf591e6e557b7c8c492ead0e675 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com> | ||
| 3 | Date: Tue, 29 Aug 2023 21:35:18 -0700 | ||
| 4 | Subject: [PATCH 02/11] xen_arm: Initialize RAM and add hi/low memory regions | ||
| 5 | |||
| 6 | In order to use virtio backends we need to initialize RAM for the | ||
| 7 | xen-mapcache (which is responsible for mapping guest memory using foreign | ||
| 8 | mapping) to work. Calculate and add hi/low memory regions based on | ||
| 9 | machine->ram_size. | ||
| 10 | |||
| 11 | Use the constants defined in public header arch-arm.h to be aligned with the xen | ||
| 12 | toolstack. | ||
| 13 | |||
| 14 | While 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 | ||
| 16 | emulated devices like TPM and VIRTIO. This is done to keep this QEMU machine | ||
| 17 | usable for /etc/init.d/xencommons. | ||
| 18 | |||
| 19 | Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com> | ||
| 20 | Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 21 | Reviewed-by: Stefano Stabellini <sstabellini@kernel.org> | ||
| 22 | Signed-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 | |||
| 28 | diff --git a/hw/arm/xen_arm.c b/hw/arm/xen_arm.c | ||
| 29 | index 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", | ||
| 105 | diff --git a/include/hw/xen/xen_native.h b/include/hw/xen/xen_native.h | ||
| 106 | index 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 | -- | ||
| 123 | 2.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 @@ | |||
| 1 | From 14b9dbd7f0261ae7a36bef251924ba211beef17a Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 3 | Date: Wed, 1 Nov 2023 14:07:23 -0700 | ||
| 4 | Subject: [PATCH 03/11] Xen: Fix xen_set_irq() and | ||
| 5 | xendevicemodel_set_irq_level() | ||
| 6 | |||
| 7 | Remove '=' from 'if CONFIG_XEN_CTRL_INTERFACE_VERSION <= 41500'. | ||
| 8 | Because xendevicemodel_set_irq_level() was introduced in 4.15 version. | ||
| 9 | |||
| 10 | Also, update xendevicemodel_set_irq_level() to return -1 for older versions. | ||
| 11 | |||
| 12 | Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 13 | Reviewed-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 | |||
| 19 | diff --git a/hw/arm/xen_arm.c b/hw/arm/xen_arm.c | ||
| 20 | index 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) | ||
| 34 | diff --git a/include/hw/xen/xen_native.h b/include/hw/xen/xen_native.h | ||
| 35 | index 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 | -- | ||
| 54 | 2.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 @@ | |||
| 1 | From 02507086b3ad9beb9c669aae54fcb4857cd61ef8 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Juergen Gross <jgross@suse.com> | ||
| 3 | Date: Tue, 16 Mar 2021 14:00:33 +0100 | ||
| 4 | Subject: [PATCH 04/11] xen: when unplugging emulated devices skip virtio | ||
| 5 | devices | ||
| 6 | |||
| 7 | Virtio devices should never be unplugged at boot time, as they are | ||
| 8 | similar to pci passthrough devices. | ||
| 9 | |||
| 10 | Signed-off-by: Juergen Gross <jgross@suse.com> | ||
| 11 | Signed-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 | |||
| 17 | diff --git a/docs/system/i386/xen.rst b/docs/system/i386/xen.rst | ||
| 18 | index 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 | |||
| 31 | diff --git a/hw/i386/xen/xen_platform.c b/hw/i386/xen/xen_platform.c | ||
| 32 | index 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 | -- | ||
| 69 | 2.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 @@ | |||
| 1 | From d4774a0e5e1ebed605c5d49e81433fd371d0b680 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 3 | Date: Tue, 17 Oct 2023 20:22:26 +0000 | ||
| 4 | Subject: [PATCH 05/11] softmmu: physmem: Split ram_block_add() | ||
| 5 | |||
| 6 | Extract ram block list update to a new function ram_block_add_list(). This is | ||
| 7 | done to support grant mappings which adds a memory region for granted memory and | ||
| 8 | updates the ram_block list. | ||
| 9 | |||
| 10 | Signed-off-by: Juergen Gross <jgross@suse.com> | ||
| 11 | Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 12 | Reviewed-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 | |||
| 18 | diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h | ||
| 19 | index 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) | ||
| 30 | diff --git a/softmmu/physmem.c b/softmmu/physmem.c | ||
| 31 | index 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 | -- | ||
| 116 | 2.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 @@ | |||
| 1 | From 637d10471fef76a7ab0e8f5631ea3c85ff5ce9db Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Juergen Gross <jgross@suse.com> | ||
| 3 | Date: Thu, 20 May 2021 11:19:58 +0200 | ||
| 4 | Subject: [PATCH 06/11] xen: add pseudo RAM region for grant mappings | ||
| 5 | |||
| 6 | Add a memory region which can be used to automatically map granted | ||
| 7 | memory. It is starting at 0x8000000000000000ULL in order to be able to | ||
| 8 | distinguish it from normal RAM. | ||
| 9 | |||
| 10 | For this reason the xen.ram memory region is expanded, which has no | ||
| 11 | further impact as it is used just as a container of the real RAM | ||
| 12 | regions and now the grant region. | ||
| 13 | |||
| 14 | Signed-off-by: Juergen Gross <jgross@suse.com> | ||
| 15 | Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 16 | Reviewed-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 | |||
| 26 | diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c | ||
| 27 | index 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) | ||
| 40 | diff --git a/hw/xen/xen-hvm-common.c b/hw/xen/xen-hvm-common.c | ||
| 41 | index 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 | |||
| 62 | diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c | ||
| 63 | index 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 | +} | ||
| 105 | diff --git a/include/hw/xen/xen-hvm-common.h b/include/hw/xen/xen-hvm-common.h | ||
| 106 | index 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 | |||
| 118 | diff --git a/include/hw/xen/xen_pvdev.h b/include/hw/xen/xen_pvdev.h | ||
| 119 | index 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 */ | ||
| 130 | diff --git a/include/sysemu/xen-mapcache.h b/include/sysemu/xen-mapcache.h | ||
| 131 | index 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 | -- | ||
| 152 | 2.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 @@ | |||
| 1 | From 82139e7e4bdcf5ca51b2ac90c63e4af699e3eb6f Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Juergen Gross <jgross@suse.com> | ||
| 3 | Date: Thu, 20 May 2021 11:54:48 +0200 | ||
| 4 | Subject: [PATCH 07/11] softmmu: let qemu_map_ram_ptr() use | ||
| 5 | qemu_ram_ptr_length() | ||
| 6 | |||
| 7 | qemu_map_ram_ptr() and qemu_ram_ptr_length() share quite some code, so | ||
| 8 | modify qemu_ram_ptr_length() a little bit and use it for | ||
| 9 | qemu_map_ram_ptr(), too. | ||
| 10 | |||
| 11 | Signed-off-by: Juergen Gross <jgross@suse.com> | ||
| 12 | Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 13 | Reviewed-by: Stefano Stabellini <sstabellini@kernel.org> | ||
| 14 | --- | ||
| 15 | softmmu/physmem.c | 58 +++++++++++++++++++---------------------------- | ||
| 16 | 1 file changed, 23 insertions(+), 35 deletions(-) | ||
| 17 | |||
| 18 | diff --git a/softmmu/physmem.c b/softmmu/physmem.c | ||
| 19 | index 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 | -- | ||
| 116 | 2.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 @@ | |||
| 1 | From 857bcafe8beb5a0cd78c070f432108049661a56d Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Juergen Gross <jgross@suse.com> | ||
| 3 | Date: Thu, 20 May 2021 13:31:32 +0200 | ||
| 4 | Subject: [PATCH 08/11] xen: let xen_ram_addr_from_mapcache() return -1 in case | ||
| 5 | of not found entry | ||
| 6 | |||
| 7 | Today xen_ram_addr_from_mapcache() will either abort() or return 0 in | ||
| 8 | case it can't find a matching entry for a pointer value. Both cases | ||
| 9 | are bad, so change that to return an invalid address instead. | ||
| 10 | |||
| 11 | Signed-off-by: Juergen Gross <jgross@suse.com> | ||
| 12 | Reviewed-by: Stefano Stabellini <sstabellini@kernel.org> | ||
| 13 | --- | ||
| 14 | hw/xen/xen-mapcache.c | 12 +++--------- | ||
| 15 | 1 file changed, 3 insertions(+), 9 deletions(-) | ||
| 16 | |||
| 17 | diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c | ||
| 18 | index 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 | -- | ||
| 48 | 2.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 @@ | |||
| 1 | From 364a11be6274336ec9b0f06f3272f964d27c9349 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Juergen Gross <jgross@suse.com> | ||
| 3 | Date: Thu, 27 May 2021 15:27:55 +0200 | ||
| 4 | Subject: [PATCH 09/11] memory: add MemoryRegion map and unmap callbacks | ||
| 5 | |||
| 6 | In order to support mapping and unmapping guest memory dynamically to | ||
| 7 | and from qemu during address_space_[un]map() operations add the map() | ||
| 8 | and unmap() callbacks to MemoryRegionOps. | ||
| 9 | |||
| 10 | Those will be used e.g. for Xen grant mappings when performing guest | ||
| 11 | I/Os. | ||
| 12 | |||
| 13 | Signed-off-by: Juergen Gross <jgross@suse.com> | ||
| 14 | Signed-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 | |||
| 20 | diff --git a/include/exec/memory.h b/include/exec/memory.h | ||
| 21 | index 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 { | ||
| 52 | diff --git a/softmmu/physmem.c b/softmmu/physmem.c | ||
| 53 | index 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 | -- | ||
| 154 | 2.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 @@ | |||
| 1 | From 90496d4c71e3b9334aebca118661bf72631ed0f0 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Juergen Gross <jgross@suse.com> | ||
| 3 | Date: Fri, 26 Aug 2022 13:57:06 +0200 | ||
| 4 | Subject: [PATCH 10/11] xen: add map and unmap callbacks for grant region | ||
| 5 | |||
| 6 | Add the callbacks for mapping/unmapping guest memory via grants to the | ||
| 7 | special grant memory region. | ||
| 8 | |||
| 9 | Signed-off-by: Juergen Gross <jgross@suse.com> | ||
| 10 | Signed-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 | |||
| 16 | diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c | ||
| 17 | index 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); | ||
| 235 | diff --git a/softmmu/physmem.c b/softmmu/physmem.c | ||
| 236 | index 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 | -- | ||
| 261 | 2.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 @@ | |||
| 1 | From b1eaba758a9000061fc53a934c348d6ef8dcdf64 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 3 | Date: Tue, 31 Jan 2023 21:46:43 +0000 | ||
| 4 | Subject: [PATCH 11/11] hw: arm: Add grant mapping. | ||
| 5 | |||
| 6 | Enable grant ram mapping support for Xenpvh machine on ARM. | ||
| 7 | |||
| 8 | Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com> | ||
| 9 | Reviewed-by: Stefano Stabellini <sstabellini@kernel.org> | ||
| 10 | --- | ||
| 11 | hw/arm/xen_arm.c | 3 +++ | ||
| 12 | 1 file changed, 3 insertions(+) | ||
| 13 | |||
| 14 | diff --git a/hw/arm/xen_arm.c b/hw/arm/xen_arm.c | ||
| 15 | index 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 | -- | ||
| 29 | 2.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 @@ | |||
| 1 | require qemu-tpm.inc | ||
| 2 | require qemu-xen_7.1.inc | ||
| 3 | |||
| 4 | # We do not want QEMU, on the target to be configured with OpenGL | ||
| 5 | PACKAGECONFIG: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 @@ | |||
| 1 | require qemu-tpm.inc | ||
| 2 | require qemu-xen_8.1.inc | ||
| 3 | |||
| 4 | # We do not want QEMU, on the target to be configured with OpenGL | ||
| 5 | PACKAGECONFIG: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 @@ | |||
| 1 | require qemu-tpm.inc | ||
| 2 | require qemu-xen_7.1.inc | ||
| 3 | |||
| 4 | # We do not want QEMU, on the target to be configured with OpenGL | ||
| 5 | PACKAGECONFIG: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 @@ | |||
| 1 | require qemu-tpm.inc | ||
| 2 | require qemu-xen_8.1.inc | ||
| 3 | |||
| 4 | # We do not want QEMU, on the target to be configured with OpenGL | ||
| 5 | PACKAGECONFIG: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 @@ | |||
| 1 | From b300c18ab899b3c899e5405c96c20a32e51d77c8 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Bruce Ashfield <bruce.ashfield@windriver.com> | ||
| 3 | Date: Mon, 2 Jul 2018 23:10:28 -0400 | ||
| 4 | Subject: [PATCH] xen: Fix menuconfig and add support for config fragments and | ||
| 5 | |||
| 6 | Upstream-Status: Xen: Inappropriate [oe specific, cross compile issue] | ||
| 7 | Upstream-Status: Kernel: Pending | ||
| 8 | Signed-off-by: Diego Sueiro <diego.sueiro@arm.com> | ||
| 9 | commit 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 | |||
| 37 | diff --git a/xen/tools/kconfig/mconf-cfg.sh b/xen/tools/kconfig/mconf-cfg.sh | ||
| 38 | old mode 100755 | ||
| 39 | new mode 100644 | ||
| 40 | index 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 @@ | |||
| 1 | From 6db88791d923167f160afbcadeffad84a4cbdbc5 Mon Sep 17 00:00:00 2001 | ||
| 2 | Message-Id: <6db88791d923167f160afbcadeffad84a4cbdbc5.1612262706.git.bertrand.marquis@arm.com> | ||
| 3 | From: Maciej Pijanowski <maciej.pijanowski@3mdeb.com> | ||
| 4 | Date: Fri, 19 Oct 2018 11:01:37 +0200 | ||
| 5 | Subject: [PATCH] python,pygrub: pass DISTUTILS env vars as setup.py args | ||
| 6 | |||
| 7 | Upstream-Status: Xen: Inappropriate [oe specific, python install issues] | ||
| 8 | |||
| 9 | Allow to respect the target install dir (PYTHON_SITEPACKAGES_DIR) | ||
| 10 | as well as other parameters set by the OpenEmbedded build system. | ||
| 11 | This is especially useful when the target libdir is not the default one | ||
| 12 | (/usr/lib), but for example /usr/lib64. | ||
| 13 | |||
| 14 | Signed-off-by: Maciej Pijanowski <maciej.pijanowski@3mdeb.com> | ||
| 15 | |||
| 16 | Forward-ported to Xen 4.12.0 | ||
| 17 | Signed-off-by: Christopher Clark <christopher.clark6@baesystems.com> | ||
| 18 | |||
| 19 | Modified to support pygrub installation with python 3 | ||
| 20 | Signed-off-by: Christopher Clark <christopher.clark6@baesystems.com> | ||
| 21 | |||
| 22 | Forward-ported to Xen 4.14.0 | ||
| 23 | Signed-off-by: Christopher Clark <christopher.clark6@baesystems.com> | ||
| 24 | |||
| 25 | Forward-ported to Xen 4.15.0 | ||
| 26 | Signed-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 | |||
| 33 | diff --git a/tools/pygrub/Makefile b/tools/pygrub/Makefile | ||
| 34 | index 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 \ | ||
| 58 | diff --git a/tools/python/Makefile b/tools/python/Makefile | ||
| 59 | index 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 | -- | ||
| 72 | 2.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 @@ | |||
| 1 | Upstream-Status: Pending | ||
| 2 | |||
| 3 | diff --git a/tools/pygrub/Makefile b/tools/pygrub/Makefile | ||
| 4 | index 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)`" != \ | ||
| 24 | diff --git a/tools/python/Makefile b/tools/python/Makefile | ||
| 25 | index 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 @@ | |||
| 1 | From mboxrd@z Thu Jan 1 00:00:00 1970 | ||
| 2 | From: Anthony PERARD <anthony.perard@citrix.com> | ||
| 3 | Subject: [XEN PATCH] build: fix building flask headers before descending in flask/ss/ | ||
| 4 | Date: Fri, 20 Jan 2023 13:36:26 +0000 | ||
| 5 | Message-ID: <20230120133626.55680-1-anthony.perard@citrix.com> | ||
| 6 | X-Mailer: git-send-email 2.30.2 | ||
| 7 | MIME-Version: 1.0 | ||
| 8 | Content-Transfer-Encoding: 8bit | ||
| 9 | Content-Type: text/plain | ||
| 10 | |||
| 11 | Unfortunatly, adding prerequisite to "$(obj)/ss/built_in.o" doesn't | ||
| 12 | work because we have "$(obj)/%/built_in.o: $(obj)/% ;" in Rules.mk. | ||
| 13 | So, make is allow to try to build objects in "xsm/flask/ss/" before | ||
| 14 | generating the headers. | ||
| 15 | |||
| 16 | Adding a prerequisite on "$(obj)/ss" instead will fix the issue has | ||
| 17 | that the target used to run make in this subdirectory. | ||
| 18 | |||
| 19 | Unfortunatly, that target is also used when running `make clean`, so | ||
| 20 | we need to ignore it in this case. $(MAKECMDGOALS) can't be used in | ||
| 21 | this case as it is empty, but we can guess which operation is done by | ||
| 22 | looking at the list of loaded makefiles. | ||
| 23 | |||
| 24 | Upstream-Status: backport [https://lore.kernel.org/xen-devel/20230120133626.55680-1-anthony.perard@citrix.com/T/#u] | ||
| 25 | |||
| 26 | Fixes: 7a3bcd2babcc ("build: build everything from the root dir, use obj=$subdir") | ||
| 27 | Reported-by: "Daniel P. Smith" <dpsmith@apertussolutions.com> | ||
| 28 | Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> | ||
| 29 | --- | ||
| 30 | xen/xsm/flask/Makefile | 6 +++++- | ||
| 31 | 1 file changed, 5 insertions(+), 1 deletion(-) | ||
| 32 | |||
| 33 | diff --git a/xen/xsm/flask/Makefile b/xen/xsm/flask/Makefile | ||
| 34 | index 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 | -- | ||
| 51 | Anthony 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 | |||
| 2 | valid_xen_archs = " \ | ||
| 3 | x86_64 x86_32 \ | ||
| 4 | arm32 arm64 \ | ||
| 5 | " | ||
| 6 | |||
| 7 | def 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 | |||
| 4 | BLKTAP_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 | |||
| 15 | BLKTAP_PROVIDES ?= " \ | ||
| 16 | virtual/blktap \ | ||
| 17 | virtual/libblktap \ | ||
| 18 | virtual/libblktapctl \ | ||
| 19 | virtual/libvhd \ | ||
| 20 | " | ||
| 21 | |||
| 22 | BLKTAP_RRECOMMENDS ?= " \ | ||
| 23 | virtual/blktap \ | ||
| 24 | virtual/libblktap \ | ||
| 25 | virtual/libblktapctl \ | ||
| 26 | virtual/libvhd \ | ||
| 27 | " | ||
| 28 | |||
| 29 | RPROVIDES:${PN}-blktap = "virtual/blktap" | ||
| 30 | RPROVIDES:${PN}-libblktap = "virtual/libblktap" | ||
| 31 | RPROVIDES:${PN}-libblktapctl = "virtual/libblktapctl" | ||
| 32 | RPROVIDES:${PN}-libvhd = "virtual/libvhd" | ||
| 33 | |||
| 34 | FILES:${PN}-blktap-staticdev += "\ | ||
| 35 | ${libdir}/libblktapctl.a \ | ||
| 36 | ${libdir}/libvhd.a \ | ||
| 37 | ${libdir}/libblktap.a \ | ||
| 38 | " | ||
| 39 | |||
| 40 | FILES:${PN}-libblktapctl = "${libdir}/libblktapctl.so.*" | ||
| 41 | FILES:${PN}-libblktapctl-dev = " \ | ||
| 42 | ${libdir}/libblktapctl.so \ | ||
| 43 | ${libdir}/pkgconfig/xenblktapctl.pc \ | ||
| 44 | ${datadir}/pkgconfig/xenblktapctl.pc \ | ||
| 45 | " | ||
| 46 | |||
| 47 | FILES:${PN}-libvhd = "${libdir}/libvhd.so.*" | ||
| 48 | FILES:${PN}-libvhd-dev = " \ | ||
| 49 | ${libdir}/libvhd.so \ | ||
| 50 | ${libdir}/pkgconfig/vhd.pc \ | ||
| 51 | ${datadir}/pkgconfig/vhd.pc \ | ||
| 52 | " | ||
| 53 | |||
| 54 | FILES:${PN}-libblktap = "${libdir}/libblktap.so.*" | ||
| 55 | FILES:${PN}-libblktap-dev = " \ | ||
| 56 | ${libdir}/libblktap.so \ | ||
| 57 | ${libdir}/pkgconfig/blktap.pc \ | ||
| 58 | ${datadir}/pkgconfig/blktap.pc \ | ||
| 59 | " | ||
| 60 | |||
| 61 | FILES:${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 @@ | |||
| 1 | SUMMARY = "Xen hypervisor" | ||
| 2 | DESCRIPTION = "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 | ||
| 10 | COMPATIBLE_HOST = '(x86_64.*).*-linux|aarch64.*-linux|arm-.*-linux-gnueabi' | ||
| 11 | |||
| 12 | inherit deploy python3native cml1 | ||
| 13 | |||
| 14 | PACKAGES = " \ | ||
| 15 | ${PN} \ | ||
| 16 | ${PN}-dbg \ | ||
| 17 | ${PN}-efi \ | ||
| 18 | " | ||
| 19 | |||
| 20 | FILES:${PN} = " \ | ||
| 21 | /boot/xen-* \ | ||
| 22 | /boot/xen \ | ||
| 23 | /boot/xen-*.gz \ | ||
| 24 | /boot/xen.gz \ | ||
| 25 | /boot/xen-syms-* \ | ||
| 26 | " | ||
| 27 | |||
| 28 | FILES:${PN}-dbg += "${libdir}/debug/*" | ||
| 29 | |||
| 30 | FILES:${PN}-efi = " \ | ||
| 31 | /boot/xen.efi \ | ||
| 32 | ${exec_prefix}/lib64/efi/xen* \ | ||
| 33 | " | ||
| 34 | |||
| 35 | do_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. | ||
| 54 | EXTRA_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 | |||
| 59 | do_compile() { | ||
| 60 | oe_runmake xen PYTHON="${PYTHON}" \ | ||
| 61 | EXTRA_CFLAGS_XEN_CORE="${EXTRA_CFLAGS_XEN_CORE}" | ||
| 62 | } | ||
| 63 | |||
| 64 | do_install() { | ||
| 65 | oe_runmake DESTDIR="${D}" install-xen | ||
| 66 | } | ||
| 67 | # The do_install also ships files in /boot and /usr/lib64 | ||
| 68 | SYSROOT_DIRS += "/boot ${exec_prefix}/lib64" | ||
| 69 | |||
| 70 | do_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 | ||
| 96 | addtask 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: | ||
| 99 | do_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: | ||
| 102 | do_deploy[depends] += "xen-tools:do_deploy" | ||
| 103 | |||
| 104 | # Enable use of menuconfig directly from bitbake and also within the devshell | ||
| 105 | do_devshell[depends] += "ncurses-native:do_populate_sysroot" | ||
| 106 | |||
| 107 | # Pass the native library path for kconfig build when running the do_menuconfig | ||
| 108 | # task | ||
| 109 | CROSS_CURSES_LIB += "-L${STAGING_LIBDIR_NATIVE}" | ||
| 110 | |||
| 111 | # Specify the root dir of the .config file for do_menuconfig and do_diffconfig | ||
| 112 | # tasks | ||
| 113 | KCONFIG_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. | ||
| 117 | TUNE_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. | ||
| 2 | do_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. | ||
| 19 | INHIBIT_UPDATERCD_BBCLASS = "${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '1', '', d)}" | ||
| 20 | |||
| 21 | FILES:${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 @@ | |||
| 1 | SUMMARY = "Xen hypervisor tools" | ||
| 2 | DESCRIPTION = "Tools and utility software for the Xen hypervisor" | ||
| 3 | |||
| 4 | COMPATIBLE_HOST = 'i686-.*-linux|(x86_64.*).*-linux|aarch64.*-linux|arm-.*-linux-gnueabi' | ||
| 5 | |||
| 6 | inherit setuptools3 update-rc.d systemd deploy | ||
| 7 | require xen-blktap.inc | ||
| 8 | |||
| 9 | RDEPENDS:${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 | |||
| 31 | RDEPENDS:${PN}-dev = "" | ||
| 32 | |||
| 33 | RRECOMMENDS:${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 | |||
| 47 | RDEPENDS:${PN}-devd = " \ | ||
| 48 | ${PN}-xl \ | ||
| 49 | " | ||
| 50 | |||
| 51 | RDEPENDS:${PN}-fsimage = " \ | ||
| 52 | libext2fs \ | ||
| 53 | " | ||
| 54 | |||
| 55 | RDEPENDS:${PN}-misc = " \ | ||
| 56 | perl \ | ||
| 57 | python3 \ | ||
| 58 | ${PN}-xencov \ | ||
| 59 | " | ||
| 60 | |||
| 61 | RSUGGESTS:${PN}-misc = " \ | ||
| 62 | ${PN}-xencons \ | ||
| 63 | ${PN}-xenpvnetboot \ | ||
| 64 | " | ||
| 65 | |||
| 66 | RDEPENDS:${PN}-python = " \ | ||
| 67 | python3 \ | ||
| 68 | " | ||
| 69 | |||
| 70 | RDEPENDS:${PN}-pygrub = " \ | ||
| 71 | python3 \ | ||
| 72 | ${PN}-python \ | ||
| 73 | " | ||
| 74 | |||
| 75 | RDEPENDS:${PN}-remus = "bash" | ||
| 76 | |||
| 77 | RDEPENDS:${PN}-scripts-block = "\ | ||
| 78 | bash \ | ||
| 79 | ${PN}-scripts-common \ | ||
| 80 | ${PN}-volatiles \ | ||
| 81 | " | ||
| 82 | |||
| 83 | RDEPENDS:${PN}-scripts-common = "bash" | ||
| 84 | |||
| 85 | RDEPENDS:${PN}-scripts-network = "\ | ||
| 86 | bash \ | ||
| 87 | bridge-utils \ | ||
| 88 | ${PN}-scripts-common \ | ||
| 89 | ${PN}-volatiles \ | ||
| 90 | " | ||
| 91 | |||
| 92 | RRECOMMENDS:${PN}-scripts-network = "\ | ||
| 93 | ifupdown \ | ||
| 94 | " | ||
| 95 | |||
| 96 | RSUGGESTS:${PN}-xencov = "${PN}-xencov-split" | ||
| 97 | |||
| 98 | RDEPENDS:${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 | |||
| 108 | RDEPENDS:${PN}-xendomains = "\ | ||
| 109 | bash \ | ||
| 110 | ${PN}-console \ | ||
| 111 | ${PN}-scripts-block \ | ||
| 112 | ${PN}-scripts-common \ | ||
| 113 | virtual/xenstored \ | ||
| 114 | " | ||
| 115 | |||
| 116 | RDEPENDS:${PN}-xenhypfs = " \ | ||
| 117 | ${PN}-libxenhypfs \ | ||
| 118 | " | ||
| 119 | |||
| 120 | RDEPENDS:${PN}-xl = "libgcc" | ||
| 121 | |||
| 122 | RDEPENDS:${PN}-xenmon = " \ | ||
| 123 | python3 \ | ||
| 124 | " | ||
| 125 | |||
| 126 | RSUGGESTS:${PN}-xentrace = "${PN}-xentrace-format" | ||
| 127 | |||
| 128 | RDEPENDS:${PN}-xen-watchdog = "bash" | ||
| 129 | |||
| 130 | PACKAGES = " \ | ||
| 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 | |||
| 217 | PROVIDES =+ " \ | ||
| 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. | ||
| 224 | RPROVIDES:${PN}-xenstored = "virtual/xenstored" | ||
| 225 | |||
| 226 | FILES:${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 | |||
| 246 | FILES:${PN}-dev = "\ | ||
| 247 | ${includedir} \ | ||
| 248 | " | ||
| 249 | |||
| 250 | FILES:${PN}-doc = "\ | ||
| 251 | ${sysconfdir}/xen/README \ | ||
| 252 | ${sysconfdir}/xen/README.incompatibilities \ | ||
| 253 | ${datadir}/doc \ | ||
| 254 | ${datadir}/man \ | ||
| 255 | " | ||
| 256 | |||
| 257 | FILES:${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 | |||
| 267 | FILES:${PN}-libxencall = "${libdir}/libxencall.so.*" | ||
| 268 | FILES:${PN}-libxencall-dev = " \ | ||
| 269 | ${libdir}/libxencall.so \ | ||
| 270 | ${libdir}/pkgconfig/xencall.pc \ | ||
| 271 | ${datadir}/pkgconfig/xencall.pc \ | ||
| 272 | " | ||
| 273 | |||
| 274 | FILES:${PN}-libxenctrl = "${libdir}/libxenctrl.so.*" | ||
| 275 | FILES:${PN}-libxenctrl-dev = " \ | ||
| 276 | ${libdir}/libxenctrl.so \ | ||
| 277 | ${libdir}/pkgconfig/xencontrol.pc \ | ||
| 278 | ${datadir}/pkgconfig/xencontrol.pc \ | ||
| 279 | " | ||
| 280 | |||
| 281 | FILES:${PN}-libxendevicemodel = "${libdir}/libxendevicemodel.so.*" | ||
| 282 | FILES:${PN}-libxendevicemodel-dev = " \ | ||
| 283 | ${libdir}/libxendevicemodel.so \ | ||
| 284 | ${libdir}/pkgconfig/xendevicemodel.pc \ | ||
| 285 | ${datadir}/pkgconfig/xendevicemodel.pc \ | ||
| 286 | " | ||
| 287 | |||
| 288 | FILES:${PN}-libxenevtchn = "${libdir}/libxenevtchn.so.*" | ||
| 289 | FILES:${PN}-libxenevtchn-dev = " \ | ||
| 290 | ${libdir}/libxenevtchn.so \ | ||
| 291 | ${libdir}/pkgconfig/xenevtchn.pc \ | ||
| 292 | ${datadir}/pkgconfig/xenevtchn.pc \ | ||
| 293 | " | ||
| 294 | |||
| 295 | FILES:${PN}-libxenforeignmemory = "${libdir}/libxenforeignmemory.so.*" | ||
| 296 | FILES:${PN}-libxenforeignmemory-dev = " \ | ||
| 297 | ${libdir}/libxenforeignmemory.so \ | ||
| 298 | ${libdir}/pkgconfig/xenforeignmemory.pc \ | ||
| 299 | ${datadir}/pkgconfig/xenforeignmemory.pc \ | ||
| 300 | " | ||
| 301 | |||
| 302 | FILES:${PN}-libxengnttab = "${libdir}/libxengnttab.so.*" | ||
| 303 | FILES:${PN}-libxengnttab-dev = " \ | ||
| 304 | ${libdir}/libxengnttab.so \ | ||
| 305 | ${libdir}/pkgconfig/xengnttab.pc \ | ||
| 306 | ${datadir}/pkgconfig/xengnttab.pc \ | ||
| 307 | " | ||
| 308 | |||
| 309 | FILES:${PN}-libxenguest = "${libdir}/libxenguest.so.*" | ||
| 310 | FILES:${PN}-libxenguest-dev = " \ | ||
| 311 | ${libdir}/libxenguest.so \ | ||
| 312 | ${libdir}/pkgconfig/xenguest.pc \ | ||
| 313 | ${datadir}/pkgconfig/xenguest.pc \ | ||
| 314 | " | ||
| 315 | |||
| 316 | FILES:${PN}-libxenhypfs = "${libdir}/libxenhypfs.so.*" | ||
| 317 | FILES:${PN}-libxenhypfs-dev = " \ | ||
| 318 | ${libdir}/libxenhypfs.so \ | ||
| 319 | ${libdir}/pkgconfig/xenhypfs.pc \ | ||
| 320 | " | ||
| 321 | |||
| 322 | FILES:${PN}-libxenlight = "${libdir}/libxenlight.so.*" | ||
| 323 | FILES:${PN}-libxenlight-dev = " \ | ||
| 324 | ${libdir}/libxenlight.so \ | ||
| 325 | ${libdir}/pkgconfig/xenlight.pc \ | ||
| 326 | ${datadir}/pkgconfig/xenlight.pc \ | ||
| 327 | " | ||
| 328 | |||
| 329 | FILES:${PN}-libxenstat = "${libdir}/libxenstat.so.*" | ||
| 330 | FILES:${PN}-libxenstat-dev = " \ | ||
| 331 | ${libdir}/libxenstat.so \ | ||
| 332 | ${libdir}/pkgconfig/xenstat.pc \ | ||
| 333 | ${datadir}/pkgconfig/xenstat.pc \ | ||
| 334 | " | ||
| 335 | |||
| 336 | FILES:${PN}-libxenstore = "${libdir}/libxenstore.so.*" | ||
| 337 | FILES:${PN}-libxenstore-dev = " \ | ||
| 338 | ${libdir}/libxenstore.so \ | ||
| 339 | ${libdir}/pkgconfig/xenstore.pc \ | ||
| 340 | ${datadir}/pkgconfig/xenstore.pc \ | ||
| 341 | " | ||
| 342 | |||
| 343 | FILES:${PN}-libxentoolcore = "${libdir}/libxentoolcore.so.*" | ||
| 344 | FILES:${PN}-libxentoolcore-dev = " \ | ||
| 345 | ${libdir}/libxentoolcore.so \ | ||
| 346 | ${libdir}/pkgconfig/xentoolcore.pc \ | ||
| 347 | ${datadir}/pkgconfig/xentoolcore.pc \ | ||
| 348 | " | ||
| 349 | |||
| 350 | FILES:${PN}-libxentoollog = "${libdir}/libxentoollog.so.*" | ||
| 351 | FILES:${PN}-libxentoollog-dev = " \ | ||
| 352 | ${libdir}/libxentoollog.so \ | ||
| 353 | ${libdir}/pkgconfig/xentoollog.pc \ | ||
| 354 | ${datadir}/pkgconfig/xentoollog.pc \ | ||
| 355 | " | ||
| 356 | |||
| 357 | FILES:${PN}-libxenvchan = "${libdir}/libxenvchan.so.*" | ||
| 358 | FILES:${PN}-libxenvchan-dev = " \ | ||
| 359 | ${libdir}/libxenvchan.so \ | ||
| 360 | ${libdir}/pkgconfig/xenvchan.pc \ | ||
| 361 | ${datadir}/pkgconfig/xenvchan.pc \ | ||
| 362 | " | ||
| 363 | |||
| 364 | FILES:${PN}-libxlutil = "${libdir}/libxlutil.so.*" | ||
| 365 | FILES:${PN}-libxlutil-dev = " \ | ||
| 366 | ${libdir}/libxlutil.so \ | ||
| 367 | ${libdir}/pkgconfig/xlutil.pc \ | ||
| 368 | ${datadir}/pkgconfig/xlutil.pc \ | ||
| 369 | " | ||
| 370 | FILES:${PN}-libvhd = "${libdir}/libvhd.so.*" | ||
| 371 | FILES:${PN}-libvhd-dev = " \ | ||
| 372 | ${libdir}/libvhd.so \ | ||
| 373 | ${libdir}/pkgconfig/vhd.pc \ | ||
| 374 | ${datadir}/pkgconfig/vhd.pc \ | ||
| 375 | " | ||
| 376 | |||
| 377 | FILES:${PN}-libfsimage = " \ | ||
| 378 | ${libdir}/libfsimage.so.* \ | ||
| 379 | ${libdir}/libxenfsimage.so.* \ | ||
| 380 | " | ||
| 381 | |||
| 382 | FILES:${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 | |||
| 391 | FILES:${PN}-fsimage = " \ | ||
| 392 | ${libdir}/fs/**/[a-z]*fsimage.so \ | ||
| 393 | ${libdir}/xenfsimage/**/fsimage.so \ | ||
| 394 | " | ||
| 395 | |||
| 396 | FILES:${PN}-init-xenstore-dom = "${libdir}/xen/bin/init-xenstore-domain" | ||
| 397 | |||
| 398 | FILES:${PN} = "\ | ||
| 399 | ${sysconfdir}/xen/auto \ | ||
| 400 | ${sysconfdir}/xen/cpupool \ | ||
| 401 | ${localstatedir}/xen/dump \ | ||
| 402 | " | ||
| 403 | |||
| 404 | FILES:${PN}-console = "\ | ||
| 405 | ${libdir}/xen/bin/xenconsole \ | ||
| 406 | ${sbindir}/xenconsoled \ | ||
| 407 | " | ||
| 408 | |||
| 409 | FILES:${PN}-cpuid = "\ | ||
| 410 | ${bindir}/xen-cpuid \ | ||
| 411 | " | ||
| 412 | |||
| 413 | FILES:${PN}-devd = "\ | ||
| 414 | ${sysconfdir}/init.d/xendriverdomain \ | ||
| 415 | ${systemd_unitdir}/system/xendriverdomain.service \ | ||
| 416 | " | ||
| 417 | |||
| 418 | FILES:${PN}-flask = "\ | ||
| 419 | /boot/xenpolicy-* \ | ||
| 420 | " | ||
| 421 | |||
| 422 | FILES:${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 | |||
| 431 | FILES:${PN}-gdbsx = "\ | ||
| 432 | ${sbindir}/gdbsx \ | ||
| 433 | " | ||
| 434 | |||
| 435 | INSANE_SKIP:${PN}-hvmloader = "arch" | ||
| 436 | FILES:${PN}-hvmloader = "\ | ||
| 437 | ${libdir}/xen/boot/hvmloader \ | ||
| 438 | " | ||
| 439 | |||
| 440 | FILES:${PN}-kdd = "\ | ||
| 441 | ${sbindir}/kdd \ | ||
| 442 | ${sbindir}/xen-kdd \ | ||
| 443 | " | ||
| 444 | |||
| 445 | FILES:${PN}-livepatch += " \ | ||
| 446 | ${sbindir}/xen-livepatch \ | ||
| 447 | " | ||
| 448 | |||
| 449 | FILES:${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 | |||
| 472 | FILES:${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 | ||
| 478 | FILES:${PN}-python = "\ | ||
| 479 | ${libdir}/${PYTHON_DIR} \ | ||
| 480 | ${nonarch_libdir}/${PYTHON_DIR} \ | ||
| 481 | " | ||
| 482 | |||
| 483 | FILES:${PN}-remus = "\ | ||
| 484 | ${sysconfdir}/xen/scripts/remus-netbuf-setup \ | ||
| 485 | " | ||
| 486 | |||
| 487 | FILES:${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 | |||
| 502 | FILES:${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 | |||
| 515 | FILES:${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 | |||
| 526 | INSANE_SKIP:${PN}-shim = "arch" | ||
| 527 | FILES:${PN}-shim = " \ | ||
| 528 | ${libdir}/xen/boot/xen-shim \ | ||
| 529 | " | ||
| 530 | |||
| 531 | FILES:${PN}-ucode = "\ | ||
| 532 | ${sbindir}/xen-ucode \ | ||
| 533 | " | ||
| 534 | |||
| 535 | FILES:${PN}-vchan = "\ | ||
| 536 | ${bindir}/vchan-socket-proxy \ | ||
| 537 | " | ||
| 538 | |||
| 539 | FILES:${PN}-volatiles = "\ | ||
| 540 | ${sysconfdir}/default/volatiles/99_xen \ | ||
| 541 | ${sysconfdir}/tmpfiles.d/xen.conf \ | ||
| 542 | " | ||
| 543 | |||
| 544 | FILES:${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 | |||
| 551 | FILES:${PN}-xencov = "\ | ||
| 552 | ${sbindir}/xencov \ | ||
| 553 | " | ||
| 554 | |||
| 555 | FILES:${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 | |||
| 561 | FILES:${PN}-xenhypfs = "\ | ||
| 562 | ${sbindir}/xenhypfs \ | ||
| 563 | " | ||
| 564 | |||
| 565 | FILES:${PN}-xenpaging = "\ | ||
| 566 | ${libdir}/xen/bin/xenpaging \ | ||
| 567 | ${localstatedir}/lib/xen/xenpaging \ | ||
| 568 | " | ||
| 569 | |||
| 570 | FILES:${PN}-xenpmd = "\ | ||
| 571 | ${sbindir}/xenpmd \ | ||
| 572 | " | ||
| 573 | |||
| 574 | FILES:${PN}-xenstat = "\ | ||
| 575 | ${sbindir}/xentop \ | ||
| 576 | " | ||
| 577 | |||
| 578 | FILES:${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 | |||
| 591 | FILES:${PN}-xenstored = "\ | ||
| 592 | ${sbindir}/xenstored \ | ||
| 593 | ${localstatedir}/lib/xenstored \ | ||
| 594 | " | ||
| 595 | |||
| 596 | FILES:${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 | |||
| 606 | FILES:${PN}-xen-watchdog = "\ | ||
| 607 | ${sbindir}/xenwatchdogd \ | ||
| 608 | ${sysconfdir}/init.d/xen-watchdog \ | ||
| 609 | ${systemd_unitdir}/system/xen-watchdog.service \ | ||
| 610 | " | ||
| 611 | |||
| 612 | FILES:${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 | |||
| 622 | FILES:${PN}-xl-examples = "\ | ||
| 623 | ${sysconfdir}/xen/xlexample.hvm \ | ||
| 624 | ${sysconfdir}/xen/xlexample.pvlinux \ | ||
| 625 | ${sysconfdir}/xen/xlexample.pvhlinux \ | ||
| 626 | " | ||
| 627 | |||
| 628 | FILES:${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 | |||
| 639 | FILES:${PN}-xenmon = "\ | ||
| 640 | ${sbindir}/xenbaked \ | ||
| 641 | ${sbindir}/xenmon.py \ | ||
| 642 | ${sbindir}/xenmon \ | ||
| 643 | " | ||
| 644 | |||
| 645 | FILES:${PN}-xm = "\ | ||
| 646 | ${sysconfdir}/xen/xm-config.xml \ | ||
| 647 | ${datadir}/xen/create.dtd \ | ||
| 648 | ${sbindir}/xm \ | ||
| 649 | " | ||
| 650 | |||
| 651 | FILES:${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 | |||
| 665 | FILES:${PN}-xend += " \ | ||
| 666 | ${sysconfdir}/init.d/xend \ | ||
| 667 | ${sbindir}/xend \ | ||
| 668 | " | ||
| 669 | |||
| 670 | FILES:${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 | " | ||
| 677 | FILES:${PN}-xen-access += "\ | ||
| 678 | ${sbindir}/xen-access \ | ||
| 679 | " | ||
| 680 | |||
| 681 | FILES:${PN}-xen-memshare += "\ | ||
| 682 | ${sbindir}/xen-memshare \ | ||
| 683 | " | ||
| 684 | |||
| 685 | # memshare is only built for x86, so allow empty package for other archs | ||
| 686 | ALLOW_EMPTY:${PN}-xen-memshare = "1" | ||
| 687 | |||
| 688 | FILES:${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 | ||
| 698 | ALLOW_EMPTY:${PN}-test = "1" | ||
| 699 | |||
| 700 | FILES:${PN}-xen-mceinj +="\ | ||
| 701 | ${sbindir}/xen-mceinj \ | ||
| 702 | " | ||
| 703 | |||
| 704 | # xen-mceinj is only built for x86 4.16, so allow empty package | ||
| 705 | ALLOW_EMPTY:${PN}-xen-mceinj = "1" | ||
| 706 | |||
| 707 | FILES:${PN}-xen-vmtrace +="\ | ||
| 708 | ${sbindir}/xen-vmtrace \ | ||
| 709 | " | ||
| 710 | |||
| 711 | # xen-vmtrace is only built for x86 4.16, so allow empty package | ||
| 712 | ALLOW_EMPTY:${PN}-xen-vmtrace = "1" | ||
| 713 | |||
| 714 | INSANE_SKIP:${PN} = "already-stripped" | ||
| 715 | |||
| 716 | # configure init.d scripts | ||
| 717 | INITSCRIPT_PACKAGES = "${PN}-xend ${PN}-xen-watchdog ${PN}-xendomains ${PN}-devd" | ||
| 718 | INITSCRIPT_PACKAGES += "${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '', '${PN}-xencommons', d)}" | ||
| 719 | INITSCRIPT_NAME:${PN}-xencommons = "xencommons" | ||
| 720 | INITSCRIPT_PARAMS:${PN}-xencommons = "defaults 80" | ||
| 721 | INITSCRIPT_NAME:${PN}-xen-watchdog = "xen-watchdog" | ||
| 722 | INITSCRIPT_PARAMS:${PN}-xen-watchdog = "defaults 81" | ||
| 723 | INITSCRIPT_NAME:${PN}-xend = "xend" | ||
| 724 | INITSCRIPT_PARAMS:${PN}-xend = "defaults 82" | ||
| 725 | INITSCRIPT_NAME:${PN}-xendomains = "xendomains" | ||
| 726 | INITSCRIPT_PARAMS:${PN}-xendomains = "defaults 83" | ||
| 727 | INITSCRIPT_NAME:${PN}-devd = "xendriverdomain" | ||
| 728 | INITSCRIPT_PARAMS:${PN}-devd = "defaults 82" | ||
| 729 | |||
| 730 | # systemd packages | ||
| 731 | SYSTEMD_PACKAGES = "${PN}-xen-watchdog ${PN}-xencommons ${PN}-xendomains ${PN}-devd" | ||
| 732 | SYSTEMD_SERVICE:${PN}-devd = "xendriverdomain.service" | ||
| 733 | SYSTEMD_SERVICE:${PN}-xen-watchdog = "xen-watchdog.service" | ||
| 734 | SYSTEMD_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 | " | ||
| 741 | SYSTEMD_SERVICE:${PN}-xendomains = "xendomains.service" | ||
| 742 | |||
| 743 | QEMU_ARCH = "i386" | ||
| 744 | QEMU_ARCH:aarch64 = "aarch64" | ||
| 745 | |||
| 746 | EXTRA_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 | |||
| 753 | do_configure() { | ||
| 754 | do_configure_common | ||
| 755 | } | ||
| 756 | |||
| 757 | do_compile() { | ||
| 758 | cd ${S} | ||
| 759 | oe_runmake tools PYTHON="${PYTHON}" \ | ||
| 760 | EXTRA_CFLAGS_XEN_TOOLS="${EXTRA_CFLAGS_XEN_TOOLS}" | ||
| 761 | } | ||
| 762 | |||
| 763 | do_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 | |||
| 831 | pkg_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 | |||
| 841 | do_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 | ||
| 861 | addtask 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 | ||
| 2 | SRCREV ?= "11560248ffda3f00f20bbdf3ae088af474f7f2a3" | ||
| 3 | |||
| 4 | XEN_URI ?= "git://xenbits.xen.org/xen.git" | ||
| 5 | XEN_REL ?= "4.17" | ||
| 6 | XEN_BRANCH ?= "stable-${XEN_REL}" | ||
| 7 | |||
| 8 | SRC_URI = " \ | ||
| 9 | ${XEN_URI};branch=${XEN_BRANCH} \ | ||
| 10 | file://0001-python-pygrub-pass-DISTUTILS-xen-4.15.patch \ | ||
| 11 | " | ||
| 12 | |||
| 13 | LIC_FILES_CHKSUM ?= "file://COPYING;md5=d1a1e216f80b6d8da95fec897d0dbec9" | ||
| 14 | |||
| 15 | S = "${WORKDIR}/git" | ||
| 16 | |||
| 17 | require xen.inc | ||
| 18 | require 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 @@ | |||
| 1 | require xen-xilinx_4.17.inc | ||
| 2 | require 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 | ||
| 2 | SRCREV ?= "d75f1e9b74314cea91ce435730d4e3539ecca77d" | ||
| 3 | |||
| 4 | XEN_URI ?= "git://xenbits.xen.org/xen.git" | ||
| 5 | XEN_REL ?= "4.18" | ||
| 6 | XEN_BRANCH ?= "stable-4.18" | ||
| 7 | |||
| 8 | SRC_URI = " \ | ||
| 9 | ${XEN_URI};branch=${XEN_BRANCH} \ | ||
| 10 | file://0001-python-pygrub-pass-DISTUTILS-xen-4.18.patch \ | ||
| 11 | " | ||
| 12 | |||
| 13 | LIC_FILES_CHKSUM ?= "file://COPYING;md5=d1a1e216f80b6d8da95fec897d0dbec9" | ||
| 14 | |||
| 15 | S = "${WORKDIR}/git" | ||
| 16 | |||
| 17 | require xen.inc | ||
| 18 | require 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 @@ | |||
| 1 | require xen-xilinx_4.18.inc | ||
| 2 | require 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 @@ | |||
| 1 | SRCREV = "38eebc6e5c6f7aa9180672a56d33217bf1ef1ca6" | ||
| 2 | XEN_URI = "git://github.com/Xilinx/xen.git;protocol=https" | ||
| 3 | XEN_BRANCH = "xlnx_rebase_4.17" | ||
| 4 | |||
| 5 | PV .= "-xilinx+git${SRCPV}" | ||
| 6 | |||
| 7 | DEFAULT_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 @@ | |||
| 1 | SRCREV = "7cb7aac7f570757b67bcd43aec67e0cda9f58b14" | ||
| 2 | XEN_URI = "git://github.com/Xilinx/xen.git;protocol=https" | ||
| 3 | XEN_BRANCH = "xlnx_rebase_4.18" | ||
| 4 | |||
| 5 | PV .= "-xilinx+git${SRCPV}" | ||
| 6 | |||
| 7 | DEFAULT_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 @@ | |||
| 1 | HOMEPAGE = "http://xen.org" | ||
| 2 | LICENSE = "GPL-2.0-only" | ||
| 3 | SECTION = "console/tools" | ||
| 4 | |||
| 5 | inherit autotools-brokensep pkgconfig | ||
| 6 | |||
| 7 | require xen-arch.inc | ||
| 8 | |||
| 9 | PACKAGECONFIG ??= " \ | ||
| 10 | ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'systemd', '', d)} \ | ||
| 11 | " | ||
| 12 | |||
| 13 | PACKAGECONFIG[lzo] = ",,lzo" | ||
| 14 | PACKAGECONFIG[xsm] = "--enable-xsmpolicy,--disable-xsmpolicy,checkpolicy-native," | ||
| 15 | PACKAGECONFIG[systemd] = "--enable-systemd,--disable-systemd,systemd," | ||
| 16 | PACKAGECONFIG[externalblktap] = ",,," | ||
| 17 | |||
| 18 | DEPENDS = " \ | ||
| 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 #### | ||
| 51 | export BUILD_SYS | ||
| 52 | export HOST_SYS | ||
| 53 | export STAGING_INCDIR | ||
| 54 | export STAGING_LIBDIR | ||
| 55 | |||
| 56 | # specify xen hypervisor to build/target | ||
| 57 | export XEN_TARGET_ARCH = "${@map_xen_arch(d.getVar('TARGET_ARCH'), d)}" | ||
| 58 | export XEN_COMPILE_ARCH = "${@map_xen_arch(d.getVar('BUILD_ARCH'), d)}" | ||
| 59 | |||
| 60 | python () { | ||
| 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. | ||
| 68 | libexecdir = "${libdir}" | ||
| 69 | |||
| 70 | # hardcoded as Linux, as the only compatible hosts are Linux. | ||
| 71 | export XEN_OS = "Linux" | ||
| 72 | |||
| 73 | # this is used for the header (#!${bindir}/python) of the install python scripts | ||
| 74 | export PYTHONPATH="${bindir}/env python3" | ||
| 75 | export ac_cv_path_PYTHONPATH="${bindir}/env python3" | ||
| 76 | export DISTUTILS_BUILD_ARGS | ||
| 77 | export DISTUTILS_INSTALL_ARGS | ||
| 78 | |||
| 79 | # xen and seabios require HOSTCC and HOSTCXX set to cross-compile | ||
| 80 | export HOSTCC="${BUILD_CC}" | ||
| 81 | export HOSTCXX="${BUILD_CXX}" | ||
| 82 | |||
| 83 | # make xen requires CROSS_COMPILE set by hand as it does not abide by ./configure | ||
| 84 | export CROSS_COMPILE="${TARGET_PREFIX}" | ||
| 85 | |||
| 86 | # overide LDFLAGS to allow xen to build without: "x86_64-oe-linux-ld: unrecognized option '-Wl,-O1'" | ||
| 87 | export LDFLAGS="" | ||
| 88 | |||
| 89 | # No additional C flags for the main hypervisor build | ||
| 90 | EXTRA_CFLAGS_XEN_CORE ?= "" | ||
| 91 | # Add prefix maps to support buildpaths QA test and reproducibility | ||
| 92 | DEBUG_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. | ||
| 100 | TUNE_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. | ||
| 111 | CC="${CCACHE}${HOST_PREFIX}gcc ${TOOLCHAIN_OPTIONS} ${DEBUG_PREFIX_MAP} ${CC_REPRODUCIBLE_OPTIONS}" | ||
| 112 | EXTRA_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. | ||
| 115 | CC: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: | ||
| 118 | CPP:append = " ${CPPFLAGS}" | ||
| 119 | CXX:append = " ${CXXFLAGS}" | ||
| 120 | |||
| 121 | EXTRA_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 | |||
| 137 | EXTRA_OEMAKE += "STDVGA_ROM=${STAGING_DIR_HOST}/usr/share/firmware/vgabios-0.8a.bin" | ||
| 138 | EXTRA_OEMAKE += "CIRRUSVGA_ROM=${STAGING_DIR_HOST}/usr/share/firmware/vgabios-0.8a.cirrus.bin" | ||
| 139 | EXTRA_OEMAKE += "SEABIOS_ROM=${STAGING_DIR_HOST}/usr/share/firmware/bios.bin" | ||
| 140 | EXTRA_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 | ||
| 144 | EXTRA_OEMAKE += "WGET=/bin/false" | ||
| 145 | EXTRA_OEMAKE += "GIT=/bin/false" | ||
| 146 | |||
| 147 | # Improve build reproducibility: provide values for build variables. | ||
| 148 | def 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 "" | ||
| 156 | EXTRA_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. | ||
| 160 | CC_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 | ||
| 164 | python () { | ||
| 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 | |||
| 172 | do_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 | |||
| 193 | addtask post_patch after do_patch before do_configure | ||
| 194 | |||
| 195 | # Allow all hypervisor settings in a defconfig | ||
| 196 | EXTRA_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 | ||
| 200 | EXTRA_OEMAKE += "debug=n" | ||
| 201 | |||
| 202 | do_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 | |||
| 223 | do_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 | |||
| 229 | do_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 | ||
| 2 | SRCREV ?= "11560248ffda3f00f20bbdf3ae088af474f7f2a3" | ||
| 3 | |||
| 4 | XEN_URI ?= "git://xenbits.xen.org/xen.git" | ||
| 5 | XEN_REL ?= "4.17" | ||
| 6 | XEN_BRANCH ?= "stable-${XEN_REL}" | ||
| 7 | |||
| 8 | SRC_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 | |||
| 14 | LIC_FILES_CHKSUM ?= "file://COPYING;md5=d1a1e216f80b6d8da95fec897d0dbec9" | ||
| 15 | |||
| 16 | S = "${WORKDIR}/git" | ||
| 17 | |||
| 18 | require xen.inc | ||
| 19 | require 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 @@ | |||
| 1 | require xen-xilinx_4.17.inc | ||
| 2 | |||
| 3 | FILESEXTRAPATHS:prepend := "${THISDIR}/files:" | ||
| 4 | |||
| 5 | RDEPENDS:${PN}-efi += "bash python3" | ||
| 6 | |||
| 7 | do_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 | ||
| 2 | SRCREV ?= "7cb7aac7f570757b67bcd43aec67e0cda9f58b14" | ||
| 3 | |||
| 4 | XEN_URI ?= "git://xenbits.xen.org/xen.git" | ||
| 5 | XEN_REL ?= "4.18" | ||
| 6 | XEN_BRANCH ?= "stable-4.18" | ||
| 7 | |||
| 8 | SRC_URI = " \ | ||
| 9 | ${XEN_URI};branch=${XEN_BRANCH} \ | ||
| 10 | file://0001-menuconfig-mconf-cfg-Allow-specification-of-ncurses-location.patch \ | ||
| 11 | " | ||
| 12 | |||
| 13 | LIC_FILES_CHKSUM ?= "file://COPYING;md5=d1a1e216f80b6d8da95fec897d0dbec9" | ||
| 14 | |||
| 15 | S = "${WORKDIR}/git" | ||
| 16 | |||
| 17 | require xen.inc | ||
| 18 | require 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 @@ | |||
| 1 | require xen-xilinx_4.18.inc | ||
| 2 | |||
| 3 | FILESEXTRAPATHS:prepend := "${THISDIR}/files:" | ||
| 4 | |||
| 5 | RDEPENDS:${PN}-efi += "bash python3" | ||
| 6 | |||
| 7 | do_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. | ||
| 6 | XEN_REMOVED_OPENGL_PKGCONFIGS:zynqmp ?= "" | ||
| 7 | XEN_REMOVED_OPENGL_PKGCONFIGS:versal ?= "" | ||
| 8 | |||
