diff --git a/0001-sgx-stub-fix.patch b/0001-sgx-stub-fix.patch deleted file mode 100644 index ff31973ab889f66c9260ba4b70b4c5cfa041af0a..0000000000000000000000000000000000000000 --- a/0001-sgx-stub-fix.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 509b6078631ad2437e1a452f749831e401fb8afb Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Tue, 1 Feb 2022 20:09:37 +0100 -Subject: [PATCH] target/i386: the sgx_epc_get_section stub is reachable -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The sgx_epc_get_section stub is reachable from cpu_x86_cpuid. It -should not assert, instead it should just return true just like -the "real" sgx_epc_get_section does when SGX is disabled. - -Reported-by: Vladimír Beneš -Cc: qemu-stable@nongnu.org -Signed-off-by: Paolo Bonzini - -diff --git a/hw/i386/sgx-stub.c b/hw/i386/sgx-stub.c -index 26833eb233..16b1dfd90b 100644 ---- a/hw/i386/sgx-stub.c -+++ b/hw/i386/sgx-stub.c -@@ -34,5 +34,5 @@ void pc_machine_init_sgx_epc(PCMachineState *pcms) - - bool sgx_epc_get_section(int section_nr, uint64_t *addr, uint64_t *size) - { -- g_assert_not_reached(); -+ return true; - } diff --git a/0002-Fix-crash-when-loading-snapshot-on-inactive-node.patch b/0002-Fix-crash-when-loading-snapshot-on-inactive-node.patch deleted file mode 100644 index 68b84c683b0dbee768a32ae81cce01dba9f494a1..0000000000000000000000000000000000000000 --- a/0002-Fix-crash-when-loading-snapshot-on-inactive-node.patch +++ /dev/null @@ -1,52 +0,0 @@ -From a629fee99ba2189a7452a212f0a01696a65877ac Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Fri, 1 Dec 2023 15:25:18 +0100 -Subject: [PATCH] block: Fix crash when loading snapshot on inactive node - -bdrv_is_read_only() only checks if the node is configured to be -read-only eventually, but even if it returns false, writing to the node -may not be permitted at the moment (because it's inactive). - -bdrv_is_writable() checks that the node can be written to right now, and -this is what the snapshot operations really need. - -Change bdrv_can_snapshot() to use bdrv_is_writable() to fix crashes like -the following: - -$ ./qemu-system-x86_64 -hda /tmp/test.qcow2 -loadvm foo -incoming defer -qemu-system-x86_64: ../block/io.c:1990: int bdrv_co_write_req_prepare(BdrvChild *, int64_t, int64_t, BdrvTrackedRequest *, int): Assertion `!(bs->open_flags & BDRV_O_INACTIVE)' failed. - -The resulting error message after this patch isn't perfect yet, but at -least it doesn't crash any more: - -$ ./qemu-system-x86_64 -hda /tmp/test.qcow2 -loadvm foo -incoming defer -qemu-system-x86_64: Device 'ide0-hd0' is writable but does not support snapshots - -Signed-off-by: Kevin Wolf -Message-ID: <20231201142520.32255-2-kwolf@redhat.com> -Signed-off-by: Kevin Wolf -(cherry picked from commit d3007d348adaaf04ee8b099a475282034a662414) -Signed-off-by: Michael Tokarev ---- - block/snapshot.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/block/snapshot.c b/block/snapshot.c -index e22ac3eac63..86e29ca59f9 100644 ---- a/block/snapshot.c -+++ b/block/snapshot.c -@@ -190,8 +190,10 @@ static BlockDriverState *bdrv_snapshot_fallback(BlockDriverState *bs) - int bdrv_can_snapshot(BlockDriverState *bs) - { - BlockDriver *drv = bs->drv; -+ - GLOBAL_STATE_CODE(); -- if (!drv || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) { -+ -+ if (!drv || !bdrv_is_inserted(bs) || !bdrv_is_writable(bs)) { - return 0; - } - --- -GitLab - diff --git a/0003-hw-loongarch-virt-Align-high-memory-base-address-wit.patch b/0003-hw-loongarch-virt-Align-high-memory-base-address-wit.patch deleted file mode 100644 index d7b1513f1ffd9645f2d844fc031d797531799b61..0000000000000000000000000000000000000000 --- a/0003-hw-loongarch-virt-Align-high-memory-base-address-wit.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 70e7ffec16e91138309ad3f76588cbd10c084394 Mon Sep 17 00:00:00 2001 -From: Bibo Mao -Date: Mon, 27 Nov 2023 12:02:31 +0800 -Subject: [PATCH] hw/loongarch/virt: Align high memory base address with - super page size - -With LoongArch virt machine, there is low memory space with region -0--0x10000000, and high memory space with started from 0x90000000. -High memory space is aligned with 256M, it will be better if it is -aligned with 1G, which is super page aligned for 4K page size. - -Currently linux kernel and uefi bios has no limitation with high -memory base address, it is ok to set high memory base address -with 0x80000000. - -Signed-off-by: Bibo Mao -Reviewed-by: Song Gao -Message-Id: <20231127040231.4123715-1-maobibo@loongson.cn> -Signed-off-by: Song Gao ---- - include/hw/loongarch/virt.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h -index 674f4655e0..db0831b471 100644 ---- a/include/hw/loongarch/virt.h -+++ b/include/hw/loongarch/virt.h -@@ -25,7 +25,7 @@ - - #define VIRT_LOWMEM_BASE 0 - #define VIRT_LOWMEM_SIZE 0x10000000 --#define VIRT_HIGHMEM_BASE 0x90000000 -+#define VIRT_HIGHMEM_BASE 0x80000000 - #define VIRT_GED_EVT_ADDR 0x100e0000 - #define VIRT_GED_MEM_ADDR (VIRT_GED_EVT_ADDR + ACPI_GED_EVT_SEL_LEN) - #define VIRT_GED_REG_ADDR (VIRT_GED_MEM_ADDR + MEMORY_HOTPLUG_IO_LEN) --- -2.33.0 - diff --git a/0004-target-loongarch-Add-timer-information-dump-support.patch b/0004-target-loongarch-Add-timer-information-dump-support.patch deleted file mode 100644 index 1558ba2b9e2ed7817497dc2b948553d46ea976bb..0000000000000000000000000000000000000000 --- a/0004-target-loongarch-Add-timer-information-dump-support.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 8a43c9379651fbf9d015240d6dc7c4b90ce98683 Mon Sep 17 00:00:00 2001 -From: Bibo Mao -Date: Wed, 6 Dec 2023 16:18:39 +0800 -Subject: [PATCH] target/loongarch: Add timer information dump support - -Timer emulation sometimes is problematic especially when vm is running in -kvm mode. This patch adds registers dump support relative with timer -hardware, so that it is easier to find the problems. - -Signed-off-by: Bibo Mao -Reviewed-by: Song Gao -Message-Id: <20231206081839.2290178-1-maobibo@loongson.cn> -Signed-off-by: Song Gao ---- - target/loongarch/cpu.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c -index fc075952e6..db9a421cc4 100644 ---- a/target/loongarch/cpu.c -+++ b/target/loongarch/cpu.c -@@ -762,6 +762,8 @@ void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int flags) - qemu_fprintf(f, "TLBRENTRY=%016" PRIx64 "\n", env->CSR_TLBRENTRY); - qemu_fprintf(f, "TLBRBADV=%016" PRIx64 "\n", env->CSR_TLBRBADV); - qemu_fprintf(f, "TLBRERA=%016" PRIx64 "\n", env->CSR_TLBRERA); -+ qemu_fprintf(f, "TCFG=%016" PRIx64 "\n", env->CSR_TCFG); -+ qemu_fprintf(f, "TVAL=%016" PRIx64 "\n", env->CSR_TVAL); - - /* fpr */ - if (flags & CPU_DUMP_FPU) { --- -2.33.0 - diff --git a/0005-target-loongarch-meson-move-gdbstub.c-to-loongarch.s.patch b/0005-target-loongarch-meson-move-gdbstub.c-to-loongarch.s.patch deleted file mode 100644 index 7e5f0a94a021895358ac032bc2c63a6b38aafddf..0000000000000000000000000000000000000000 --- a/0005-target-loongarch-meson-move-gdbstub.c-to-loongarch.s.patch +++ /dev/null @@ -1,41 +0,0 @@ -From ae65e1281aa67713bde6bce323a3a8d06f27c636 Mon Sep 17 00:00:00 2001 -From: Song Gao -Date: Tue, 2 Jan 2024 10:01:59 +0800 -Subject: [PATCH] target/loongarch/meson: move gdbstub.c to loongarch.ss -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -gdbstub.c is not specific to TCG and can be used by -other accelerators, such as KVM accelerator - -Reviewed-by: Philippe Mathieu-Daudé -Signed-off-by: Song Gao -Message-Id: <20240102020200.3462097-1-gaosong@loongson.cn> ---- - target/loongarch/meson.build | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/target/loongarch/meson.build b/target/loongarch/meson.build -index 18e8191e2b..b3a0fb12fb 100644 ---- a/target/loongarch/meson.build -+++ b/target/loongarch/meson.build -@@ -3,6 +3,7 @@ gen = decodetree.process('insns.decode') - loongarch_ss = ss.source_set() - loongarch_ss.add(files( - 'cpu.c', -+ 'gdbstub.c', - )) - loongarch_tcg_ss = ss.source_set() - loongarch_tcg_ss.add(gen) -@@ -10,7 +11,6 @@ loongarch_tcg_ss.add(files( - 'fpu_helper.c', - 'op_helper.c', - 'translate.c', -- 'gdbstub.c', - 'vec_helper.c', - )) - loongarch_tcg_ss.add(zlib) --- -2.33.0 - diff --git a/0006-target-loongarch-move-translate-modules-to-tcg.patch b/0006-target-loongarch-move-translate-modules-to-tcg.patch deleted file mode 100644 index 7611ce3e869c306801bcae2bba7d9e16c59c0735..0000000000000000000000000000000000000000 --- a/0006-target-loongarch-move-translate-modules-to-tcg.patch +++ /dev/null @@ -1,215 +0,0 @@ -From eef77dd5b0d292d8a0276c820fc8fee24de0d898 Mon Sep 17 00:00:00 2001 -From: Song Gao -Date: Tue, 2 Jan 2024 10:02:00 +0800 -Subject: [PATCH] target/loongarch: move translate modules to tcg/ -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Introduce the target/loongarch/tcg directory. Its purpose is to hold the TCG -code that is selected by CONFIG_TCG - -Reviewed-by: Philippe Mathieu-Daudé -Signed-off-by: Song Gao -Message-Id: <20240102020200.3462097-2-gaosong@loongson.cn> ---- - target/loongarch/meson.build | 15 +-------------- - target/loongarch/{ => tcg}/constant_timer.c | 0 - target/loongarch/{ => tcg}/csr_helper.c | 0 - target/loongarch/{ => tcg}/fpu_helper.c | 0 - .../{ => tcg}/insn_trans/trans_arith.c.inc | 0 - .../{ => tcg}/insn_trans/trans_atomic.c.inc | 0 - .../{ => tcg}/insn_trans/trans_bit.c.inc | 0 - .../{ => tcg}/insn_trans/trans_branch.c.inc | 0 - .../{ => tcg}/insn_trans/trans_extra.c.inc | 0 - .../{ => tcg}/insn_trans/trans_farith.c.inc | 0 - .../{ => tcg}/insn_trans/trans_fcmp.c.inc | 0 - .../{ => tcg}/insn_trans/trans_fcnv.c.inc | 0 - .../{ => tcg}/insn_trans/trans_fmemory.c.inc | 0 - .../{ => tcg}/insn_trans/trans_fmov.c.inc | 0 - .../{ => tcg}/insn_trans/trans_memory.c.inc | 0 - .../insn_trans/trans_privileged.c.inc | 0 - .../{ => tcg}/insn_trans/trans_shift.c.inc | 0 - .../{ => tcg}/insn_trans/trans_vec.c.inc | 0 - target/loongarch/{ => tcg}/iocsr_helper.c | 0 - target/loongarch/tcg/meson.build | 19 +++++++++++++++++++ - target/loongarch/{ => tcg}/op_helper.c | 0 - target/loongarch/{ => tcg}/tlb_helper.c | 0 - target/loongarch/{ => tcg}/translate.c | 0 - target/loongarch/{ => tcg}/vec_helper.c | 0 - 24 files changed, 20 insertions(+), 14 deletions(-) - rename target/loongarch/{ => tcg}/constant_timer.c (100%) - rename target/loongarch/{ => tcg}/csr_helper.c (100%) - rename target/loongarch/{ => tcg}/fpu_helper.c (100%) - rename target/loongarch/{ => tcg}/insn_trans/trans_arith.c.inc (100%) - rename target/loongarch/{ => tcg}/insn_trans/trans_atomic.c.inc (100%) - rename target/loongarch/{ => tcg}/insn_trans/trans_bit.c.inc (100%) - rename target/loongarch/{ => tcg}/insn_trans/trans_branch.c.inc (100%) - rename target/loongarch/{ => tcg}/insn_trans/trans_extra.c.inc (100%) - rename target/loongarch/{ => tcg}/insn_trans/trans_farith.c.inc (100%) - rename target/loongarch/{ => tcg}/insn_trans/trans_fcmp.c.inc (100%) - rename target/loongarch/{ => tcg}/insn_trans/trans_fcnv.c.inc (100%) - rename target/loongarch/{ => tcg}/insn_trans/trans_fmemory.c.inc (100%) - rename target/loongarch/{ => tcg}/insn_trans/trans_fmov.c.inc (100%) - rename target/loongarch/{ => tcg}/insn_trans/trans_memory.c.inc (100%) - rename target/loongarch/{ => tcg}/insn_trans/trans_privileged.c.inc (100%) - rename target/loongarch/{ => tcg}/insn_trans/trans_shift.c.inc (100%) - rename target/loongarch/{ => tcg}/insn_trans/trans_vec.c.inc (100%) - rename target/loongarch/{ => tcg}/iocsr_helper.c (100%) - create mode 100644 target/loongarch/tcg/meson.build - rename target/loongarch/{ => tcg}/op_helper.c (100%) - rename target/loongarch/{ => tcg}/tlb_helper.c (100%) - rename target/loongarch/{ => tcg}/translate.c (100%) - rename target/loongarch/{ => tcg}/vec_helper.c (100%) - -diff --git a/target/loongarch/meson.build b/target/loongarch/meson.build -index b3a0fb12fb..e84e4c51f4 100644 ---- a/target/loongarch/meson.build -+++ b/target/loongarch/meson.build -@@ -5,29 +5,16 @@ loongarch_ss.add(files( - 'cpu.c', - 'gdbstub.c', - )) --loongarch_tcg_ss = ss.source_set() --loongarch_tcg_ss.add(gen) --loongarch_tcg_ss.add(files( -- 'fpu_helper.c', -- 'op_helper.c', -- 'translate.c', -- 'vec_helper.c', --)) --loongarch_tcg_ss.add(zlib) - - loongarch_system_ss = ss.source_set() - loongarch_system_ss.add(files( - 'loongarch-qmp-cmds.c', - 'machine.c', -- 'tlb_helper.c', -- 'constant_timer.c', -- 'csr_helper.c', -- 'iocsr_helper.c', - )) - - common_ss.add(when: 'CONFIG_LOONGARCH_DIS', if_true: [files('disas.c'), gen]) - --loongarch_ss.add_all(when: 'CONFIG_TCG', if_true: [loongarch_tcg_ss]) -+subdir('tcg') - - target_arch += {'loongarch': loongarch_ss} - target_system_arch += {'loongarch': loongarch_system_ss} -diff --git a/target/loongarch/constant_timer.c b/target/loongarch/tcg/constant_timer.c -similarity index 100% -rename from target/loongarch/constant_timer.c -rename to target/loongarch/tcg/constant_timer.c -diff --git a/target/loongarch/csr_helper.c b/target/loongarch/tcg/csr_helper.c -similarity index 100% -rename from target/loongarch/csr_helper.c -rename to target/loongarch/tcg/csr_helper.c -diff --git a/target/loongarch/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c -similarity index 100% -rename from target/loongarch/fpu_helper.c -rename to target/loongarch/tcg/fpu_helper.c -diff --git a/target/loongarch/insn_trans/trans_arith.c.inc b/target/loongarch/tcg/insn_trans/trans_arith.c.inc -similarity index 100% -rename from target/loongarch/insn_trans/trans_arith.c.inc -rename to target/loongarch/tcg/insn_trans/trans_arith.c.inc -diff --git a/target/loongarch/insn_trans/trans_atomic.c.inc b/target/loongarch/tcg/insn_trans/trans_atomic.c.inc -similarity index 100% -rename from target/loongarch/insn_trans/trans_atomic.c.inc -rename to target/loongarch/tcg/insn_trans/trans_atomic.c.inc -diff --git a/target/loongarch/insn_trans/trans_bit.c.inc b/target/loongarch/tcg/insn_trans/trans_bit.c.inc -similarity index 100% -rename from target/loongarch/insn_trans/trans_bit.c.inc -rename to target/loongarch/tcg/insn_trans/trans_bit.c.inc -diff --git a/target/loongarch/insn_trans/trans_branch.c.inc b/target/loongarch/tcg/insn_trans/trans_branch.c.inc -similarity index 100% -rename from target/loongarch/insn_trans/trans_branch.c.inc -rename to target/loongarch/tcg/insn_trans/trans_branch.c.inc -diff --git a/target/loongarch/insn_trans/trans_extra.c.inc b/target/loongarch/tcg/insn_trans/trans_extra.c.inc -similarity index 100% -rename from target/loongarch/insn_trans/trans_extra.c.inc -rename to target/loongarch/tcg/insn_trans/trans_extra.c.inc -diff --git a/target/loongarch/insn_trans/trans_farith.c.inc b/target/loongarch/tcg/insn_trans/trans_farith.c.inc -similarity index 100% -rename from target/loongarch/insn_trans/trans_farith.c.inc -rename to target/loongarch/tcg/insn_trans/trans_farith.c.inc -diff --git a/target/loongarch/insn_trans/trans_fcmp.c.inc b/target/loongarch/tcg/insn_trans/trans_fcmp.c.inc -similarity index 100% -rename from target/loongarch/insn_trans/trans_fcmp.c.inc -rename to target/loongarch/tcg/insn_trans/trans_fcmp.c.inc -diff --git a/target/loongarch/insn_trans/trans_fcnv.c.inc b/target/loongarch/tcg/insn_trans/trans_fcnv.c.inc -similarity index 100% -rename from target/loongarch/insn_trans/trans_fcnv.c.inc -rename to target/loongarch/tcg/insn_trans/trans_fcnv.c.inc -diff --git a/target/loongarch/insn_trans/trans_fmemory.c.inc b/target/loongarch/tcg/insn_trans/trans_fmemory.c.inc -similarity index 100% -rename from target/loongarch/insn_trans/trans_fmemory.c.inc -rename to target/loongarch/tcg/insn_trans/trans_fmemory.c.inc -diff --git a/target/loongarch/insn_trans/trans_fmov.c.inc b/target/loongarch/tcg/insn_trans/trans_fmov.c.inc -similarity index 100% -rename from target/loongarch/insn_trans/trans_fmov.c.inc -rename to target/loongarch/tcg/insn_trans/trans_fmov.c.inc -diff --git a/target/loongarch/insn_trans/trans_memory.c.inc b/target/loongarch/tcg/insn_trans/trans_memory.c.inc -similarity index 100% -rename from target/loongarch/insn_trans/trans_memory.c.inc -rename to target/loongarch/tcg/insn_trans/trans_memory.c.inc -diff --git a/target/loongarch/insn_trans/trans_privileged.c.inc b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc -similarity index 100% -rename from target/loongarch/insn_trans/trans_privileged.c.inc -rename to target/loongarch/tcg/insn_trans/trans_privileged.c.inc -diff --git a/target/loongarch/insn_trans/trans_shift.c.inc b/target/loongarch/tcg/insn_trans/trans_shift.c.inc -similarity index 100% -rename from target/loongarch/insn_trans/trans_shift.c.inc -rename to target/loongarch/tcg/insn_trans/trans_shift.c.inc -diff --git a/target/loongarch/insn_trans/trans_vec.c.inc b/target/loongarch/tcg/insn_trans/trans_vec.c.inc -similarity index 100% -rename from target/loongarch/insn_trans/trans_vec.c.inc -rename to target/loongarch/tcg/insn_trans/trans_vec.c.inc -diff --git a/target/loongarch/iocsr_helper.c b/target/loongarch/tcg/iocsr_helper.c -similarity index 100% -rename from target/loongarch/iocsr_helper.c -rename to target/loongarch/tcg/iocsr_helper.c -diff --git a/target/loongarch/tcg/meson.build b/target/loongarch/tcg/meson.build -new file mode 100644 -index 0000000000..1a3cd589fb ---- /dev/null -+++ b/target/loongarch/tcg/meson.build -@@ -0,0 +1,19 @@ -+if 'CONFIG_TCG' not in config_all -+ subdir_done() -+endif -+ -+loongarch_ss.add([zlib, gen]) -+ -+loongarch_ss.add(files( -+ 'fpu_helper.c', -+ 'op_helper.c', -+ 'translate.c', -+ 'vec_helper.c', -+)) -+ -+loongarch_system_ss.add(files( -+ 'constant_timer.c', -+ 'csr_helper.c', -+ 'iocsr_helper.c', -+ 'tlb_helper.c', -+)) -diff --git a/target/loongarch/op_helper.c b/target/loongarch/tcg/op_helper.c -similarity index 100% -rename from target/loongarch/op_helper.c -rename to target/loongarch/tcg/op_helper.c -diff --git a/target/loongarch/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c -similarity index 100% -rename from target/loongarch/tlb_helper.c -rename to target/loongarch/tcg/tlb_helper.c -diff --git a/target/loongarch/translate.c b/target/loongarch/tcg/translate.c -similarity index 100% -rename from target/loongarch/translate.c -rename to target/loongarch/tcg/translate.c -diff --git a/target/loongarch/vec_helper.c b/target/loongarch/tcg/vec_helper.c -similarity index 100% -rename from target/loongarch/vec_helper.c -rename to target/loongarch/tcg/vec_helper.c --- -2.33.0 - diff --git a/0007-linux-headers-Update-to-Linux-v6.7-rc5.patch b/0007-linux-headers-Update-to-Linux-v6.7-rc5.patch deleted file mode 100644 index 44129bda8915ee338b6bfca0cb291f9c40f8f837..0000000000000000000000000000000000000000 --- a/0007-linux-headers-Update-to-Linux-v6.7-rc5.patch +++ /dev/null @@ -1,1109 +0,0 @@ -From 9904eb7d4559baca2da713346cd505a80af7e776 Mon Sep 17 00:00:00 2001 -From: Daniel Henrique Barboza -Date: Mon, 18 Dec 2023 17:43:18 -0300 -Subject: [PATCH] linux-headers: Update to Linux v6.7-rc5 - -We'll add a new RISC-V linux-header file, but first let's update all -headers. - -Headers for 'asm-loongarch' were added in this update. - -Signed-off-by: Daniel Henrique Barboza -Acked-by: Alistair Francis -Message-ID: <20231218204321.75757-2-dbarboza@ventanamicro.com> -Signed-off-by: Alistair Francis ---- - include/standard-headers/drm/drm_fourcc.h | 2 + - include/standard-headers/linux/pci_regs.h | 24 ++- - include/standard-headers/linux/vhost_types.h | 7 + - .../standard-headers/linux/virtio_config.h | 5 + - include/standard-headers/linux/virtio_pci.h | 11 ++ - linux-headers/asm-arm64/kvm.h | 32 ++++ - linux-headers/asm-generic/unistd.h | 14 +- - linux-headers/asm-loongarch/bitsperlong.h | 1 + - linux-headers/asm-loongarch/kvm.h | 108 +++++++++++ - linux-headers/asm-loongarch/mman.h | 1 + - linux-headers/asm-loongarch/unistd.h | 5 + - linux-headers/asm-mips/unistd_n32.h | 4 + - linux-headers/asm-mips/unistd_n64.h | 4 + - linux-headers/asm-mips/unistd_o32.h | 4 + - linux-headers/asm-powerpc/unistd_32.h | 4 + - linux-headers/asm-powerpc/unistd_64.h | 4 + - linux-headers/asm-riscv/kvm.h | 12 ++ - linux-headers/asm-s390/unistd_32.h | 4 + - linux-headers/asm-s390/unistd_64.h | 4 + - linux-headers/asm-x86/unistd_32.h | 4 + - linux-headers/asm-x86/unistd_64.h | 3 + - linux-headers/asm-x86/unistd_x32.h | 3 + - linux-headers/linux/iommufd.h | 180 +++++++++++++++++- - linux-headers/linux/kvm.h | 11 ++ - linux-headers/linux/psp-sev.h | 1 + - linux-headers/linux/stddef.h | 9 +- - linux-headers/linux/userfaultfd.h | 9 +- - linux-headers/linux/vfio.h | 47 +++-- - linux-headers/linux/vhost.h | 8 + - 29 files changed, 498 insertions(+), 27 deletions(-) - create mode 100644 linux-headers/asm-loongarch/bitsperlong.h - create mode 100644 linux-headers/asm-loongarch/kvm.h - create mode 100644 linux-headers/asm-loongarch/mman.h - create mode 100644 linux-headers/asm-loongarch/unistd.h - -diff --git a/include/standard-headers/drm/drm_fourcc.h b/include/standard-headers/drm/drm_fourcc.h -index 72279f4d25..3afb70160f 100644 ---- a/include/standard-headers/drm/drm_fourcc.h -+++ b/include/standard-headers/drm/drm_fourcc.h -@@ -322,6 +322,8 @@ extern "C" { - * index 1 = Cr:Cb plane, [39:0] Cr1:Cb1:Cr0:Cb0 little endian - */ - #define DRM_FORMAT_NV15 fourcc_code('N', 'V', '1', '5') /* 2x2 subsampled Cr:Cb plane */ -+#define DRM_FORMAT_NV20 fourcc_code('N', 'V', '2', '0') /* 2x1 subsampled Cr:Cb plane */ -+#define DRM_FORMAT_NV30 fourcc_code('N', 'V', '3', '0') /* non-subsampled Cr:Cb plane */ - - /* - * 2 plane YCbCr MSB aligned -diff --git a/include/standard-headers/linux/pci_regs.h b/include/standard-headers/linux/pci_regs.h -index e5f558d964..a39193213f 100644 ---- a/include/standard-headers/linux/pci_regs.h -+++ b/include/standard-headers/linux/pci_regs.h -@@ -80,6 +80,7 @@ - #define PCI_HEADER_TYPE_NORMAL 0 - #define PCI_HEADER_TYPE_BRIDGE 1 - #define PCI_HEADER_TYPE_CARDBUS 2 -+#define PCI_HEADER_TYPE_MFD 0x80 /* Multi-Function Device (possible) */ - - #define PCI_BIST 0x0f /* 8 bits */ - #define PCI_BIST_CODE_MASK 0x0f /* Return result */ -@@ -637,6 +638,7 @@ - #define PCI_EXP_RTCAP 0x1e /* Root Capabilities */ - #define PCI_EXP_RTCAP_CRSVIS 0x0001 /* CRS Software Visibility capability */ - #define PCI_EXP_RTSTA 0x20 /* Root Status */ -+#define PCI_EXP_RTSTA_PME_RQ_ID 0x0000ffff /* PME Requester ID */ - #define PCI_EXP_RTSTA_PME 0x00010000 /* PME status */ - #define PCI_EXP_RTSTA_PENDING 0x00020000 /* PME pending */ - /* -@@ -930,12 +932,13 @@ - - /* Process Address Space ID */ - #define PCI_PASID_CAP 0x04 /* PASID feature register */ --#define PCI_PASID_CAP_EXEC 0x02 /* Exec permissions Supported */ --#define PCI_PASID_CAP_PRIV 0x04 /* Privilege Mode Supported */ -+#define PCI_PASID_CAP_EXEC 0x0002 /* Exec permissions Supported */ -+#define PCI_PASID_CAP_PRIV 0x0004 /* Privilege Mode Supported */ -+#define PCI_PASID_CAP_WIDTH 0x1f00 - #define PCI_PASID_CTRL 0x06 /* PASID control register */ --#define PCI_PASID_CTRL_ENABLE 0x01 /* Enable bit */ --#define PCI_PASID_CTRL_EXEC 0x02 /* Exec permissions Enable */ --#define PCI_PASID_CTRL_PRIV 0x04 /* Privilege Mode Enable */ -+#define PCI_PASID_CTRL_ENABLE 0x0001 /* Enable bit */ -+#define PCI_PASID_CTRL_EXEC 0x0002 /* Exec permissions Enable */ -+#define PCI_PASID_CTRL_PRIV 0x0004 /* Privilege Mode Enable */ - #define PCI_EXT_CAP_PASID_SIZEOF 8 - - /* Single Root I/O Virtualization */ -@@ -975,6 +978,8 @@ - #define PCI_LTR_VALUE_MASK 0x000003ff - #define PCI_LTR_SCALE_MASK 0x00001c00 - #define PCI_LTR_SCALE_SHIFT 10 -+#define PCI_LTR_NOSNOOP_VALUE 0x03ff0000 /* Max No-Snoop Latency Value */ -+#define PCI_LTR_NOSNOOP_SCALE 0x1c000000 /* Scale for Max Value */ - #define PCI_EXT_CAP_LTR_SIZEOF 8 - - /* Access Control Service */ -@@ -1042,9 +1047,16 @@ - #define PCI_EXP_DPC_STATUS 0x08 /* DPC Status */ - #define PCI_EXP_DPC_STATUS_TRIGGER 0x0001 /* Trigger Status */ - #define PCI_EXP_DPC_STATUS_TRIGGER_RSN 0x0006 /* Trigger Reason */ -+#define PCI_EXP_DPC_STATUS_TRIGGER_RSN_UNCOR 0x0000 /* Uncorrectable error */ -+#define PCI_EXP_DPC_STATUS_TRIGGER_RSN_NFE 0x0002 /* Rcvd ERR_NONFATAL */ -+#define PCI_EXP_DPC_STATUS_TRIGGER_RSN_FE 0x0004 /* Rcvd ERR_FATAL */ -+#define PCI_EXP_DPC_STATUS_TRIGGER_RSN_IN_EXT 0x0006 /* Reason in Trig Reason Extension field */ - #define PCI_EXP_DPC_STATUS_INTERRUPT 0x0008 /* Interrupt Status */ - #define PCI_EXP_DPC_RP_BUSY 0x0010 /* Root Port Busy */ - #define PCI_EXP_DPC_STATUS_TRIGGER_RSN_EXT 0x0060 /* Trig Reason Extension */ -+#define PCI_EXP_DPC_STATUS_TRIGGER_RSN_RP_PIO 0x0000 /* RP PIO error */ -+#define PCI_EXP_DPC_STATUS_TRIGGER_RSN_SW_TRIGGER 0x0020 /* DPC SW Trigger bit */ -+#define PCI_EXP_DPC_RP_PIO_FEP 0x1f00 /* RP PIO First Err Ptr */ - - #define PCI_EXP_DPC_SOURCE_ID 0x0A /* DPC Source Identifier */ - -@@ -1088,6 +1100,8 @@ - #define PCI_L1SS_CTL1_LTR_L12_TH_VALUE 0x03ff0000 /* LTR_L1.2_THRESHOLD_Value */ - #define PCI_L1SS_CTL1_LTR_L12_TH_SCALE 0xe0000000 /* LTR_L1.2_THRESHOLD_Scale */ - #define PCI_L1SS_CTL2 0x0c /* Control 2 Register */ -+#define PCI_L1SS_CTL2_T_PWR_ON_SCALE 0x00000003 /* T_POWER_ON Scale */ -+#define PCI_L1SS_CTL2_T_PWR_ON_VALUE 0x000000f8 /* T_POWER_ON Value */ - - /* Designated Vendor-Specific (DVSEC, PCI_EXT_CAP_ID_DVSEC) */ - #define PCI_DVSEC_HEADER1 0x4 /* Designated Vendor-Specific Header1 */ -diff --git a/include/standard-headers/linux/vhost_types.h b/include/standard-headers/linux/vhost_types.h -index 5ad07e134a..fd54044936 100644 ---- a/include/standard-headers/linux/vhost_types.h -+++ b/include/standard-headers/linux/vhost_types.h -@@ -185,5 +185,12 @@ struct vhost_vdpa_iova_range { - * DRIVER_OK - */ - #define VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK 0x6 -+/* Device may expose the virtqueue's descriptor area, driver area and -+ * device area to a different group for ASID binding than where its -+ * buffers may reside. Requires VHOST_BACKEND_F_IOTLB_ASID. -+ */ -+#define VHOST_BACKEND_F_DESC_ASID 0x7 -+/* IOTLB don't flush memory mapping across device reset */ -+#define VHOST_BACKEND_F_IOTLB_PERSIST 0x8 - - #endif -diff --git a/include/standard-headers/linux/virtio_config.h b/include/standard-headers/linux/virtio_config.h -index 8a7d0dc8b0..bfd1ca643e 100644 ---- a/include/standard-headers/linux/virtio_config.h -+++ b/include/standard-headers/linux/virtio_config.h -@@ -103,6 +103,11 @@ - */ - #define VIRTIO_F_NOTIFICATION_DATA 38 - -+/* This feature indicates that the driver uses the data provided by the device -+ * as a virtqueue identifier in available buffer notifications. -+ */ -+#define VIRTIO_F_NOTIF_CONFIG_DATA 39 -+ - /* - * This feature indicates that the driver can reset a queue individually. - */ -diff --git a/include/standard-headers/linux/virtio_pci.h b/include/standard-headers/linux/virtio_pci.h -index be912cfc95..b7fdfd0668 100644 ---- a/include/standard-headers/linux/virtio_pci.h -+++ b/include/standard-headers/linux/virtio_pci.h -@@ -166,6 +166,17 @@ struct virtio_pci_common_cfg { - uint32_t queue_used_hi; /* read-write */ - }; - -+/* -+ * Warning: do not use sizeof on this: use offsetofend for -+ * specific fields you need. -+ */ -+struct virtio_pci_modern_common_cfg { -+ struct virtio_pci_common_cfg cfg; -+ -+ uint16_t queue_notify_data; /* read-write */ -+ uint16_t queue_reset; /* read-write */ -+}; -+ - /* Fields in VIRTIO_PCI_CAP_PCI_CFG: */ - struct virtio_pci_cfg_cap { - struct virtio_pci_cap cap; -diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h -index 38e5957526..c59ea55cd8 100644 ---- a/linux-headers/asm-arm64/kvm.h -+++ b/linux-headers/asm-arm64/kvm.h -@@ -491,6 +491,38 @@ struct kvm_smccc_filter { - #define KVM_HYPERCALL_EXIT_SMC (1U << 0) - #define KVM_HYPERCALL_EXIT_16BIT (1U << 1) - -+/* -+ * Get feature ID registers userspace writable mask. -+ * -+ * From DDI0487J.a, D19.2.66 ("ID_AA64MMFR2_EL1, AArch64 Memory Model -+ * Feature Register 2"): -+ * -+ * "The Feature ID space is defined as the System register space in -+ * AArch64 with op0==3, op1=={0, 1, 3}, CRn==0, CRm=={0-7}, -+ * op2=={0-7}." -+ * -+ * This covers all currently known R/O registers that indicate -+ * anything useful feature wise, including the ID registers. -+ * -+ * If we ever need to introduce a new range, it will be described as -+ * such in the range field. -+ */ -+#define KVM_ARM_FEATURE_ID_RANGE_IDX(op0, op1, crn, crm, op2) \ -+ ({ \ -+ __u64 __op1 = (op1) & 3; \ -+ __op1 -= (__op1 == 3); \ -+ (__op1 << 6 | ((crm) & 7) << 3 | (op2)); \ -+ }) -+ -+#define KVM_ARM_FEATURE_ID_RANGE 0 -+#define KVM_ARM_FEATURE_ID_RANGE_SIZE (3 * 8 * 8) -+ -+struct reg_mask_range { -+ __u64 addr; /* Pointer to mask array */ -+ __u32 range; /* Requested range */ -+ __u32 reserved[13]; -+}; -+ - #endif - - #endif /* __ARM_KVM_H__ */ -diff --git a/linux-headers/asm-generic/unistd.h b/linux-headers/asm-generic/unistd.h -index abe087c53b..756b013fb8 100644 ---- a/linux-headers/asm-generic/unistd.h -+++ b/linux-headers/asm-generic/unistd.h -@@ -71,7 +71,7 @@ __SYSCALL(__NR_fremovexattr, sys_fremovexattr) - #define __NR_getcwd 17 - __SYSCALL(__NR_getcwd, sys_getcwd) - #define __NR_lookup_dcookie 18 --__SC_COMP(__NR_lookup_dcookie, sys_lookup_dcookie, compat_sys_lookup_dcookie) -+__SYSCALL(__NR_lookup_dcookie, sys_ni_syscall) - #define __NR_eventfd2 19 - __SYSCALL(__NR_eventfd2, sys_eventfd2) - #define __NR_epoll_create1 20 -@@ -816,15 +816,21 @@ __SYSCALL(__NR_process_mrelease, sys_process_mrelease) - __SYSCALL(__NR_futex_waitv, sys_futex_waitv) - #define __NR_set_mempolicy_home_node 450 - __SYSCALL(__NR_set_mempolicy_home_node, sys_set_mempolicy_home_node) -- - #define __NR_cachestat 451 - __SYSCALL(__NR_cachestat, sys_cachestat) -- - #define __NR_fchmodat2 452 - __SYSCALL(__NR_fchmodat2, sys_fchmodat2) -+#define __NR_map_shadow_stack 453 -+__SYSCALL(__NR_map_shadow_stack, sys_map_shadow_stack) -+#define __NR_futex_wake 454 -+__SYSCALL(__NR_futex_wake, sys_futex_wake) -+#define __NR_futex_wait 455 -+__SYSCALL(__NR_futex_wait, sys_futex_wait) -+#define __NR_futex_requeue 456 -+__SYSCALL(__NR_futex_requeue, sys_futex_requeue) - - #undef __NR_syscalls --#define __NR_syscalls 453 -+#define __NR_syscalls 457 - - /* - * 32 bit systems traditionally used different -diff --git a/linux-headers/asm-loongarch/bitsperlong.h b/linux-headers/asm-loongarch/bitsperlong.h -new file mode 100644 -index 0000000000..6dc0bb0c13 ---- /dev/null -+++ b/linux-headers/asm-loongarch/bitsperlong.h -@@ -0,0 +1 @@ -+#include -diff --git a/linux-headers/asm-loongarch/kvm.h b/linux-headers/asm-loongarch/kvm.h -new file mode 100644 -index 0000000000..c6ad2ee610 ---- /dev/null -+++ b/linux-headers/asm-loongarch/kvm.h -@@ -0,0 +1,108 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -+/* -+ * Copyright (C) 2020-2023 Loongson Technology Corporation Limited -+ */ -+ -+#ifndef __UAPI_ASM_LOONGARCH_KVM_H -+#define __UAPI_ASM_LOONGARCH_KVM_H -+ -+#include -+ -+/* -+ * KVM LoongArch specific structures and definitions. -+ * -+ * Some parts derived from the x86 version of this file. -+ */ -+ -+#define __KVM_HAVE_READONLY_MEM -+ -+#define KVM_COALESCED_MMIO_PAGE_OFFSET 1 -+#define KVM_DIRTY_LOG_PAGE_OFFSET 64 -+ -+/* -+ * for KVM_GET_REGS and KVM_SET_REGS -+ */ -+struct kvm_regs { -+ /* out (KVM_GET_REGS) / in (KVM_SET_REGS) */ -+ __u64 gpr[32]; -+ __u64 pc; -+}; -+ -+/* -+ * for KVM_GET_FPU and KVM_SET_FPU -+ */ -+struct kvm_fpu { -+ __u32 fcsr; -+ __u64 fcc; /* 8x8 */ -+ struct kvm_fpureg { -+ __u64 val64[4]; -+ } fpr[32]; -+}; -+ -+/* -+ * For LoongArch, we use KVM_SET_ONE_REG and KVM_GET_ONE_REG to access various -+ * registers. The id field is broken down as follows: -+ * -+ * bits[63..52] - As per linux/kvm.h -+ * bits[51..32] - Must be zero. -+ * bits[31..16] - Register set. -+ * -+ * Register set = 0: GP registers from kvm_regs (see definitions below). -+ * -+ * Register set = 1: CSR registers. -+ * -+ * Register set = 2: KVM specific registers (see definitions below). -+ * -+ * Register set = 3: FPU / SIMD registers (see definitions below). -+ * -+ * Other sets registers may be added in the future. Each set would -+ * have its own identifier in bits[31..16]. -+ */ -+ -+#define KVM_REG_LOONGARCH_GPR (KVM_REG_LOONGARCH | 0x00000ULL) -+#define KVM_REG_LOONGARCH_CSR (KVM_REG_LOONGARCH | 0x10000ULL) -+#define KVM_REG_LOONGARCH_KVM (KVM_REG_LOONGARCH | 0x20000ULL) -+#define KVM_REG_LOONGARCH_FPSIMD (KVM_REG_LOONGARCH | 0x30000ULL) -+#define KVM_REG_LOONGARCH_CPUCFG (KVM_REG_LOONGARCH | 0x40000ULL) -+#define KVM_REG_LOONGARCH_MASK (KVM_REG_LOONGARCH | 0x70000ULL) -+#define KVM_CSR_IDX_MASK 0x7fff -+#define KVM_CPUCFG_IDX_MASK 0x7fff -+ -+/* -+ * KVM_REG_LOONGARCH_KVM - KVM specific control registers. -+ */ -+ -+#define KVM_REG_LOONGARCH_COUNTER (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 1) -+#define KVM_REG_LOONGARCH_VCPU_RESET (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 2) -+ -+#define LOONGARCH_REG_SHIFT 3 -+#define LOONGARCH_REG_64(TYPE, REG) (TYPE | KVM_REG_SIZE_U64 | (REG << LOONGARCH_REG_SHIFT)) -+#define KVM_IOC_CSRID(REG) LOONGARCH_REG_64(KVM_REG_LOONGARCH_CSR, REG) -+#define KVM_IOC_CPUCFG(REG) LOONGARCH_REG_64(KVM_REG_LOONGARCH_CPUCFG, REG) -+ -+struct kvm_debug_exit_arch { -+}; -+ -+/* for KVM_SET_GUEST_DEBUG */ -+struct kvm_guest_debug_arch { -+}; -+ -+/* definition of registers in kvm_run */ -+struct kvm_sync_regs { -+}; -+ -+/* dummy definition */ -+struct kvm_sregs { -+}; -+ -+struct kvm_iocsr_entry { -+ __u32 addr; -+ __u32 pad; -+ __u64 data; -+}; -+ -+#define KVM_NR_IRQCHIPS 1 -+#define KVM_IRQCHIP_NUM_PINS 64 -+#define KVM_MAX_CORES 256 -+ -+#endif /* __UAPI_ASM_LOONGARCH_KVM_H */ -diff --git a/linux-headers/asm-loongarch/mman.h b/linux-headers/asm-loongarch/mman.h -new file mode 100644 -index 0000000000..8eebf89f5a ---- /dev/null -+++ b/linux-headers/asm-loongarch/mman.h -@@ -0,0 +1 @@ -+#include -diff --git a/linux-headers/asm-loongarch/unistd.h b/linux-headers/asm-loongarch/unistd.h -new file mode 100644 -index 0000000000..fcb668984f ---- /dev/null -+++ b/linux-headers/asm-loongarch/unistd.h -@@ -0,0 +1,5 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -+#define __ARCH_WANT_SYS_CLONE -+#define __ARCH_WANT_SYS_CLONE3 -+ -+#include -diff --git a/linux-headers/asm-mips/unistd_n32.h b/linux-headers/asm-mips/unistd_n32.h -index 46d8500654..994b6f008f 100644 ---- a/linux-headers/asm-mips/unistd_n32.h -+++ b/linux-headers/asm-mips/unistd_n32.h -@@ -381,5 +381,9 @@ - #define __NR_set_mempolicy_home_node (__NR_Linux + 450) - #define __NR_cachestat (__NR_Linux + 451) - #define __NR_fchmodat2 (__NR_Linux + 452) -+#define __NR_map_shadow_stack (__NR_Linux + 453) -+#define __NR_futex_wake (__NR_Linux + 454) -+#define __NR_futex_wait (__NR_Linux + 455) -+#define __NR_futex_requeue (__NR_Linux + 456) - - #endif /* _ASM_UNISTD_N32_H */ -diff --git a/linux-headers/asm-mips/unistd_n64.h b/linux-headers/asm-mips/unistd_n64.h -index c2f7ac673b..41dcf5877a 100644 ---- a/linux-headers/asm-mips/unistd_n64.h -+++ b/linux-headers/asm-mips/unistd_n64.h -@@ -357,5 +357,9 @@ - #define __NR_set_mempolicy_home_node (__NR_Linux + 450) - #define __NR_cachestat (__NR_Linux + 451) - #define __NR_fchmodat2 (__NR_Linux + 452) -+#define __NR_map_shadow_stack (__NR_Linux + 453) -+#define __NR_futex_wake (__NR_Linux + 454) -+#define __NR_futex_wait (__NR_Linux + 455) -+#define __NR_futex_requeue (__NR_Linux + 456) - - #endif /* _ASM_UNISTD_N64_H */ -diff --git a/linux-headers/asm-mips/unistd_o32.h b/linux-headers/asm-mips/unistd_o32.h -index 757c68f2ad..ae9d334d96 100644 ---- a/linux-headers/asm-mips/unistd_o32.h -+++ b/linux-headers/asm-mips/unistd_o32.h -@@ -427,5 +427,9 @@ - #define __NR_set_mempolicy_home_node (__NR_Linux + 450) - #define __NR_cachestat (__NR_Linux + 451) - #define __NR_fchmodat2 (__NR_Linux + 452) -+#define __NR_map_shadow_stack (__NR_Linux + 453) -+#define __NR_futex_wake (__NR_Linux + 454) -+#define __NR_futex_wait (__NR_Linux + 455) -+#define __NR_futex_requeue (__NR_Linux + 456) - - #endif /* _ASM_UNISTD_O32_H */ -diff --git a/linux-headers/asm-powerpc/unistd_32.h b/linux-headers/asm-powerpc/unistd_32.h -index 8ef94bbac1..b9b23d66d7 100644 ---- a/linux-headers/asm-powerpc/unistd_32.h -+++ b/linux-headers/asm-powerpc/unistd_32.h -@@ -434,6 +434,10 @@ - #define __NR_set_mempolicy_home_node 450 - #define __NR_cachestat 451 - #define __NR_fchmodat2 452 -+#define __NR_map_shadow_stack 453 -+#define __NR_futex_wake 454 -+#define __NR_futex_wait 455 -+#define __NR_futex_requeue 456 - - - #endif /* _ASM_UNISTD_32_H */ -diff --git a/linux-headers/asm-powerpc/unistd_64.h b/linux-headers/asm-powerpc/unistd_64.h -index 0e7ee43e88..cbb4b3e8f7 100644 ---- a/linux-headers/asm-powerpc/unistd_64.h -+++ b/linux-headers/asm-powerpc/unistd_64.h -@@ -406,6 +406,10 @@ - #define __NR_set_mempolicy_home_node 450 - #define __NR_cachestat 451 - #define __NR_fchmodat2 452 -+#define __NR_map_shadow_stack 453 -+#define __NR_futex_wake 454 -+#define __NR_futex_wait 455 -+#define __NR_futex_requeue 456 - - - #endif /* _ASM_UNISTD_64_H */ -diff --git a/linux-headers/asm-riscv/kvm.h b/linux-headers/asm-riscv/kvm.h -index 992c5e4071..60d3b21dea 100644 ---- a/linux-headers/asm-riscv/kvm.h -+++ b/linux-headers/asm-riscv/kvm.h -@@ -80,6 +80,7 @@ struct kvm_riscv_csr { - unsigned long sip; - unsigned long satp; - unsigned long scounteren; -+ unsigned long senvcfg; - }; - - /* AIA CSR registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */ -@@ -93,6 +94,11 @@ struct kvm_riscv_aia_csr { - unsigned long iprio2h; - }; - -+/* Smstateen CSR for KVM_GET_ONE_REG and KVM_SET_ONE_REG */ -+struct kvm_riscv_smstateen_csr { -+ unsigned long sstateen0; -+}; -+ - /* TIMER registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */ - struct kvm_riscv_timer { - __u64 frequency; -@@ -131,6 +137,8 @@ enum KVM_RISCV_ISA_EXT_ID { - KVM_RISCV_ISA_EXT_ZICSR, - KVM_RISCV_ISA_EXT_ZIFENCEI, - KVM_RISCV_ISA_EXT_ZIHPM, -+ KVM_RISCV_ISA_EXT_SMSTATEEN, -+ KVM_RISCV_ISA_EXT_ZICOND, - KVM_RISCV_ISA_EXT_MAX, - }; - -@@ -148,6 +156,7 @@ enum KVM_RISCV_SBI_EXT_ID { - KVM_RISCV_SBI_EXT_PMU, - KVM_RISCV_SBI_EXT_EXPERIMENTAL, - KVM_RISCV_SBI_EXT_VENDOR, -+ KVM_RISCV_SBI_EXT_DBCN, - KVM_RISCV_SBI_EXT_MAX, - }; - -@@ -178,10 +187,13 @@ enum KVM_RISCV_SBI_EXT_ID { - #define KVM_REG_RISCV_CSR (0x03 << KVM_REG_RISCV_TYPE_SHIFT) - #define KVM_REG_RISCV_CSR_GENERAL (0x0 << KVM_REG_RISCV_SUBTYPE_SHIFT) - #define KVM_REG_RISCV_CSR_AIA (0x1 << KVM_REG_RISCV_SUBTYPE_SHIFT) -+#define KVM_REG_RISCV_CSR_SMSTATEEN (0x2 << KVM_REG_RISCV_SUBTYPE_SHIFT) - #define KVM_REG_RISCV_CSR_REG(name) \ - (offsetof(struct kvm_riscv_csr, name) / sizeof(unsigned long)) - #define KVM_REG_RISCV_CSR_AIA_REG(name) \ - (offsetof(struct kvm_riscv_aia_csr, name) / sizeof(unsigned long)) -+#define KVM_REG_RISCV_CSR_SMSTATEEN_REG(name) \ -+ (offsetof(struct kvm_riscv_smstateen_csr, name) / sizeof(unsigned long)) - - /* Timer registers are mapped as type 4 */ - #define KVM_REG_RISCV_TIMER (0x04 << KVM_REG_RISCV_TYPE_SHIFT) -diff --git a/linux-headers/asm-s390/unistd_32.h b/linux-headers/asm-s390/unistd_32.h -index 716fa368ca..c093e6d5f9 100644 ---- a/linux-headers/asm-s390/unistd_32.h -+++ b/linux-headers/asm-s390/unistd_32.h -@@ -425,5 +425,9 @@ - #define __NR_set_mempolicy_home_node 450 - #define __NR_cachestat 451 - #define __NR_fchmodat2 452 -+#define __NR_map_shadow_stack 453 -+#define __NR_futex_wake 454 -+#define __NR_futex_wait 455 -+#define __NR_futex_requeue 456 - - #endif /* _ASM_S390_UNISTD_32_H */ -diff --git a/linux-headers/asm-s390/unistd_64.h b/linux-headers/asm-s390/unistd_64.h -index b2a11b1d13..114c0569a4 100644 ---- a/linux-headers/asm-s390/unistd_64.h -+++ b/linux-headers/asm-s390/unistd_64.h -@@ -373,5 +373,9 @@ - #define __NR_set_mempolicy_home_node 450 - #define __NR_cachestat 451 - #define __NR_fchmodat2 452 -+#define __NR_map_shadow_stack 453 -+#define __NR_futex_wake 454 -+#define __NR_futex_wait 455 -+#define __NR_futex_requeue 456 - - #endif /* _ASM_S390_UNISTD_64_H */ -diff --git a/linux-headers/asm-x86/unistd_32.h b/linux-headers/asm-x86/unistd_32.h -index d749ad1c24..329649c377 100644 ---- a/linux-headers/asm-x86/unistd_32.h -+++ b/linux-headers/asm-x86/unistd_32.h -@@ -443,6 +443,10 @@ - #define __NR_set_mempolicy_home_node 450 - #define __NR_cachestat 451 - #define __NR_fchmodat2 452 -+#define __NR_map_shadow_stack 453 -+#define __NR_futex_wake 454 -+#define __NR_futex_wait 455 -+#define __NR_futex_requeue 456 - - - #endif /* _ASM_UNISTD_32_H */ -diff --git a/linux-headers/asm-x86/unistd_64.h b/linux-headers/asm-x86/unistd_64.h -index cea67282eb..4583606ce6 100644 ---- a/linux-headers/asm-x86/unistd_64.h -+++ b/linux-headers/asm-x86/unistd_64.h -@@ -366,6 +366,9 @@ - #define __NR_cachestat 451 - #define __NR_fchmodat2 452 - #define __NR_map_shadow_stack 453 -+#define __NR_futex_wake 454 -+#define __NR_futex_wait 455 -+#define __NR_futex_requeue 456 - - - #endif /* _ASM_UNISTD_64_H */ -diff --git a/linux-headers/asm-x86/unistd_x32.h b/linux-headers/asm-x86/unistd_x32.h -index 5b2e79bf4c..146d74d8e4 100644 ---- a/linux-headers/asm-x86/unistd_x32.h -+++ b/linux-headers/asm-x86/unistd_x32.h -@@ -318,6 +318,9 @@ - #define __NR_set_mempolicy_home_node (__X32_SYSCALL_BIT + 450) - #define __NR_cachestat (__X32_SYSCALL_BIT + 451) - #define __NR_fchmodat2 (__X32_SYSCALL_BIT + 452) -+#define __NR_futex_wake (__X32_SYSCALL_BIT + 454) -+#define __NR_futex_wait (__X32_SYSCALL_BIT + 455) -+#define __NR_futex_requeue (__X32_SYSCALL_BIT + 456) - #define __NR_rt_sigaction (__X32_SYSCALL_BIT + 512) - #define __NR_rt_sigreturn (__X32_SYSCALL_BIT + 513) - #define __NR_ioctl (__X32_SYSCALL_BIT + 514) -diff --git a/linux-headers/linux/iommufd.h b/linux-headers/linux/iommufd.h -index 218bf7ac98..806d98d09c 100644 ---- a/linux-headers/linux/iommufd.h -+++ b/linux-headers/linux/iommufd.h -@@ -47,6 +47,8 @@ enum { - IOMMUFD_CMD_VFIO_IOAS, - IOMMUFD_CMD_HWPT_ALLOC, - IOMMUFD_CMD_GET_HW_INFO, -+ IOMMUFD_CMD_HWPT_SET_DIRTY_TRACKING, -+ IOMMUFD_CMD_HWPT_GET_DIRTY_BITMAP, - }; - - /** -@@ -347,20 +349,86 @@ struct iommu_vfio_ioas { - }; - #define IOMMU_VFIO_IOAS _IO(IOMMUFD_TYPE, IOMMUFD_CMD_VFIO_IOAS) - -+/** -+ * enum iommufd_hwpt_alloc_flags - Flags for HWPT allocation -+ * @IOMMU_HWPT_ALLOC_NEST_PARENT: If set, allocate a HWPT that can serve as -+ * the parent HWPT in a nesting configuration. -+ * @IOMMU_HWPT_ALLOC_DIRTY_TRACKING: Dirty tracking support for device IOMMU is -+ * enforced on device attachment -+ */ -+enum iommufd_hwpt_alloc_flags { -+ IOMMU_HWPT_ALLOC_NEST_PARENT = 1 << 0, -+ IOMMU_HWPT_ALLOC_DIRTY_TRACKING = 1 << 1, -+}; -+ -+/** -+ * enum iommu_hwpt_vtd_s1_flags - Intel VT-d stage-1 page table -+ * entry attributes -+ * @IOMMU_VTD_S1_SRE: Supervisor request -+ * @IOMMU_VTD_S1_EAFE: Extended access enable -+ * @IOMMU_VTD_S1_WPE: Write protect enable -+ */ -+enum iommu_hwpt_vtd_s1_flags { -+ IOMMU_VTD_S1_SRE = 1 << 0, -+ IOMMU_VTD_S1_EAFE = 1 << 1, -+ IOMMU_VTD_S1_WPE = 1 << 2, -+}; -+ -+/** -+ * struct iommu_hwpt_vtd_s1 - Intel VT-d stage-1 page table -+ * info (IOMMU_HWPT_DATA_VTD_S1) -+ * @flags: Combination of enum iommu_hwpt_vtd_s1_flags -+ * @pgtbl_addr: The base address of the stage-1 page table. -+ * @addr_width: The address width of the stage-1 page table -+ * @__reserved: Must be 0 -+ */ -+struct iommu_hwpt_vtd_s1 { -+ __aligned_u64 flags; -+ __aligned_u64 pgtbl_addr; -+ __u32 addr_width; -+ __u32 __reserved; -+}; -+ -+/** -+ * enum iommu_hwpt_data_type - IOMMU HWPT Data Type -+ * @IOMMU_HWPT_DATA_NONE: no data -+ * @IOMMU_HWPT_DATA_VTD_S1: Intel VT-d stage-1 page table -+ */ -+enum iommu_hwpt_data_type { -+ IOMMU_HWPT_DATA_NONE, -+ IOMMU_HWPT_DATA_VTD_S1, -+}; -+ - /** - * struct iommu_hwpt_alloc - ioctl(IOMMU_HWPT_ALLOC) - * @size: sizeof(struct iommu_hwpt_alloc) -- * @flags: Must be 0 -+ * @flags: Combination of enum iommufd_hwpt_alloc_flags - * @dev_id: The device to allocate this HWPT for -- * @pt_id: The IOAS to connect this HWPT to -+ * @pt_id: The IOAS or HWPT to connect this HWPT to - * @out_hwpt_id: The ID of the new HWPT - * @__reserved: Must be 0 -+ * @data_type: One of enum iommu_hwpt_data_type -+ * @data_len: Length of the type specific data -+ * @data_uptr: User pointer to the type specific data - * - * Explicitly allocate a hardware page table object. This is the same object - * type that is returned by iommufd_device_attach() and represents the - * underlying iommu driver's iommu_domain kernel object. - * -- * A HWPT will be created with the IOVA mappings from the given IOAS. -+ * A kernel-managed HWPT will be created with the mappings from the given -+ * IOAS via the @pt_id. The @data_type for this allocation must be set to -+ * IOMMU_HWPT_DATA_NONE. The HWPT can be allocated as a parent HWPT for a -+ * nesting configuration by passing IOMMU_HWPT_ALLOC_NEST_PARENT via @flags. -+ * -+ * A user-managed nested HWPT will be created from a given parent HWPT via -+ * @pt_id, in which the parent HWPT must be allocated previously via the -+ * same ioctl from a given IOAS (@pt_id). In this case, the @data_type -+ * must be set to a pre-defined type corresponding to an I/O page table -+ * type supported by the underlying IOMMU hardware. -+ * -+ * If the @data_type is set to IOMMU_HWPT_DATA_NONE, @data_len and -+ * @data_uptr should be zero. Otherwise, both @data_len and @data_uptr -+ * must be given. - */ - struct iommu_hwpt_alloc { - __u32 size; -@@ -369,13 +437,26 @@ struct iommu_hwpt_alloc { - __u32 pt_id; - __u32 out_hwpt_id; - __u32 __reserved; -+ __u32 data_type; -+ __u32 data_len; -+ __aligned_u64 data_uptr; - }; - #define IOMMU_HWPT_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_HWPT_ALLOC) - -+/** -+ * enum iommu_hw_info_vtd_flags - Flags for VT-d hw_info -+ * @IOMMU_HW_INFO_VTD_ERRATA_772415_SPR17: If set, disallow read-only mappings -+ * on a nested_parent domain. -+ * https://www.intel.com/content/www/us/en/content-details/772415/content-details.html -+ */ -+enum iommu_hw_info_vtd_flags { -+ IOMMU_HW_INFO_VTD_ERRATA_772415_SPR17 = 1 << 0, -+}; -+ - /** - * struct iommu_hw_info_vtd - Intel VT-d hardware information - * -- * @flags: Must be 0 -+ * @flags: Combination of enum iommu_hw_info_vtd_flags - * @__reserved: Must be 0 - * - * @cap_reg: Value of Intel VT-d capability register defined in VT-d spec -@@ -404,6 +485,20 @@ enum iommu_hw_info_type { - IOMMU_HW_INFO_TYPE_INTEL_VTD, - }; - -+/** -+ * enum iommufd_hw_capabilities -+ * @IOMMU_HW_CAP_DIRTY_TRACKING: IOMMU hardware support for dirty tracking -+ * If available, it means the following APIs -+ * are supported: -+ * -+ * IOMMU_HWPT_GET_DIRTY_BITMAP -+ * IOMMU_HWPT_SET_DIRTY_TRACKING -+ * -+ */ -+enum iommufd_hw_capabilities { -+ IOMMU_HW_CAP_DIRTY_TRACKING = 1 << 0, -+}; -+ - /** - * struct iommu_hw_info - ioctl(IOMMU_GET_HW_INFO) - * @size: sizeof(struct iommu_hw_info) -@@ -415,6 +510,8 @@ enum iommu_hw_info_type { - * the iommu type specific hardware information data - * @out_data_type: Output the iommu hardware info type as defined in the enum - * iommu_hw_info_type. -+ * @out_capabilities: Output the generic iommu capability info type as defined -+ * in the enum iommu_hw_capabilities. - * @__reserved: Must be 0 - * - * Query an iommu type specific hardware information data from an iommu behind -@@ -439,6 +536,81 @@ struct iommu_hw_info { - __aligned_u64 data_uptr; - __u32 out_data_type; - __u32 __reserved; -+ __aligned_u64 out_capabilities; - }; - #define IOMMU_GET_HW_INFO _IO(IOMMUFD_TYPE, IOMMUFD_CMD_GET_HW_INFO) -+ -+/* -+ * enum iommufd_hwpt_set_dirty_tracking_flags - Flags for steering dirty -+ * tracking -+ * @IOMMU_HWPT_DIRTY_TRACKING_ENABLE: Enable dirty tracking -+ */ -+enum iommufd_hwpt_set_dirty_tracking_flags { -+ IOMMU_HWPT_DIRTY_TRACKING_ENABLE = 1, -+}; -+ -+/** -+ * struct iommu_hwpt_set_dirty_tracking - ioctl(IOMMU_HWPT_SET_DIRTY_TRACKING) -+ * @size: sizeof(struct iommu_hwpt_set_dirty_tracking) -+ * @flags: Combination of enum iommufd_hwpt_set_dirty_tracking_flags -+ * @hwpt_id: HW pagetable ID that represents the IOMMU domain -+ * @__reserved: Must be 0 -+ * -+ * Toggle dirty tracking on an HW pagetable. -+ */ -+struct iommu_hwpt_set_dirty_tracking { -+ __u32 size; -+ __u32 flags; -+ __u32 hwpt_id; -+ __u32 __reserved; -+}; -+#define IOMMU_HWPT_SET_DIRTY_TRACKING _IO(IOMMUFD_TYPE, \ -+ IOMMUFD_CMD_HWPT_SET_DIRTY_TRACKING) -+ -+/** -+ * enum iommufd_hwpt_get_dirty_bitmap_flags - Flags for getting dirty bits -+ * @IOMMU_HWPT_GET_DIRTY_BITMAP_NO_CLEAR: Just read the PTEs without clearing -+ * any dirty bits metadata. This flag -+ * can be passed in the expectation -+ * where the next operation is an unmap -+ * of the same IOVA range. -+ * -+ */ -+enum iommufd_hwpt_get_dirty_bitmap_flags { -+ IOMMU_HWPT_GET_DIRTY_BITMAP_NO_CLEAR = 1, -+}; -+ -+/** -+ * struct iommu_hwpt_get_dirty_bitmap - ioctl(IOMMU_HWPT_GET_DIRTY_BITMAP) -+ * @size: sizeof(struct iommu_hwpt_get_dirty_bitmap) -+ * @hwpt_id: HW pagetable ID that represents the IOMMU domain -+ * @flags: Combination of enum iommufd_hwpt_get_dirty_bitmap_flags -+ * @__reserved: Must be 0 -+ * @iova: base IOVA of the bitmap first bit -+ * @length: IOVA range size -+ * @page_size: page size granularity of each bit in the bitmap -+ * @data: bitmap where to set the dirty bits. The bitmap bits each -+ * represent a page_size which you deviate from an arbitrary iova. -+ * -+ * Checking a given IOVA is dirty: -+ * -+ * data[(iova / page_size) / 64] & (1ULL << ((iova / page_size) % 64)) -+ * -+ * Walk the IOMMU pagetables for a given IOVA range to return a bitmap -+ * with the dirty IOVAs. In doing so it will also by default clear any -+ * dirty bit metadata set in the IOPTE. -+ */ -+struct iommu_hwpt_get_dirty_bitmap { -+ __u32 size; -+ __u32 hwpt_id; -+ __u32 flags; -+ __u32 __reserved; -+ __aligned_u64 iova; -+ __aligned_u64 length; -+ __aligned_u64 page_size; -+ __aligned_u64 data; -+}; -+#define IOMMU_HWPT_GET_DIRTY_BITMAP _IO(IOMMUFD_TYPE, \ -+ IOMMUFD_CMD_HWPT_GET_DIRTY_BITMAP) -+ - #endif -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index 0d74ee999a..549fea3a97 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -264,6 +264,7 @@ struct kvm_xen_exit { - #define KVM_EXIT_RISCV_SBI 35 - #define KVM_EXIT_RISCV_CSR 36 - #define KVM_EXIT_NOTIFY 37 -+#define KVM_EXIT_LOONGARCH_IOCSR 38 - - /* For KVM_EXIT_INTERNAL_ERROR */ - /* Emulate instruction failed. */ -@@ -336,6 +337,13 @@ struct kvm_run { - __u32 len; - __u8 is_write; - } mmio; -+ /* KVM_EXIT_LOONGARCH_IOCSR */ -+ struct { -+ __u64 phys_addr; -+ __u8 data[8]; -+ __u32 len; -+ __u8 is_write; -+ } iocsr_io; - /* KVM_EXIT_HYPERCALL */ - struct { - __u64 nr; -@@ -1188,6 +1196,7 @@ struct kvm_ppc_resize_hpt { - #define KVM_CAP_COUNTER_OFFSET 227 - #define KVM_CAP_ARM_EAGER_SPLIT_CHUNK_SIZE 228 - #define KVM_CAP_ARM_SUPPORTED_BLOCK_SIZES 229 -+#define KVM_CAP_ARM_SUPPORTED_REG_MASK_RANGES 230 - - #ifdef KVM_CAP_IRQ_ROUTING - -@@ -1358,6 +1367,7 @@ struct kvm_dirty_tlb { - #define KVM_REG_ARM64 0x6000000000000000ULL - #define KVM_REG_MIPS 0x7000000000000000ULL - #define KVM_REG_RISCV 0x8000000000000000ULL -+#define KVM_REG_LOONGARCH 0x9000000000000000ULL - - #define KVM_REG_SIZE_SHIFT 52 - #define KVM_REG_SIZE_MASK 0x00f0000000000000ULL -@@ -1558,6 +1568,7 @@ struct kvm_s390_ucas_mapping { - #define KVM_ARM_MTE_COPY_TAGS _IOR(KVMIO, 0xb4, struct kvm_arm_copy_mte_tags) - /* Available with KVM_CAP_COUNTER_OFFSET */ - #define KVM_ARM_SET_COUNTER_OFFSET _IOW(KVMIO, 0xb5, struct kvm_arm_counter_offset) -+#define KVM_ARM_GET_REG_WRITABLE_MASKS _IOR(KVMIO, 0xb6, struct reg_mask_range) - - /* ioctl for vm fd */ - #define KVM_CREATE_DEVICE _IOWR(KVMIO, 0xe0, struct kvm_create_device) -diff --git a/linux-headers/linux/psp-sev.h b/linux-headers/linux/psp-sev.h -index 12ccb70099..bcb21339ee 100644 ---- a/linux-headers/linux/psp-sev.h -+++ b/linux-headers/linux/psp-sev.h -@@ -68,6 +68,7 @@ typedef enum { - SEV_RET_INVALID_PARAM, - SEV_RET_RESOURCE_LIMIT, - SEV_RET_SECURE_DATA_INVALID, -+ SEV_RET_INVALID_KEY = 0x27, - SEV_RET_MAX, - } sev_ret_code; - -diff --git a/linux-headers/linux/stddef.h b/linux-headers/linux/stddef.h -index 9bb07083ac..bf9749dd14 100644 ---- a/linux-headers/linux/stddef.h -+++ b/linux-headers/linux/stddef.h -@@ -27,8 +27,13 @@ - union { \ - struct { MEMBERS } ATTRS; \ - struct TAG { MEMBERS } ATTRS NAME; \ -- } -+ } ATTRS - -+#ifdef __cplusplus -+/* sizeof(struct{}) is 1 in C++, not 0, can't use C version of the macro. */ -+#define __DECLARE_FLEX_ARRAY(T, member) \ -+ T member[0] -+#else - /** - * __DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union - * -@@ -49,3 +54,5 @@ - #ifndef __counted_by - #define __counted_by(m) - #endif -+ -+#endif /* _LINUX_STDDEF_H */ -diff --git a/linux-headers/linux/userfaultfd.h b/linux-headers/linux/userfaultfd.h -index 59978fbaae..953c75feda 100644 ---- a/linux-headers/linux/userfaultfd.h -+++ b/linux-headers/linux/userfaultfd.h -@@ -40,7 +40,8 @@ - UFFD_FEATURE_EXACT_ADDRESS | \ - UFFD_FEATURE_WP_HUGETLBFS_SHMEM | \ - UFFD_FEATURE_WP_UNPOPULATED | \ -- UFFD_FEATURE_POISON) -+ UFFD_FEATURE_POISON | \ -+ UFFD_FEATURE_WP_ASYNC) - #define UFFD_API_IOCTLS \ - ((__u64)1 << _UFFDIO_REGISTER | \ - (__u64)1 << _UFFDIO_UNREGISTER | \ -@@ -216,6 +217,11 @@ struct uffdio_api { - * (i.e. empty ptes). This will be the default behavior for shmem - * & hugetlbfs, so this flag only affects anonymous memory behavior - * when userfault write-protection mode is registered. -+ * -+ * UFFD_FEATURE_WP_ASYNC indicates that userfaultfd write-protection -+ * asynchronous mode is supported in which the write fault is -+ * automatically resolved and write-protection is un-set. -+ * It implies UFFD_FEATURE_WP_UNPOPULATED. - */ - #define UFFD_FEATURE_PAGEFAULT_FLAG_WP (1<<0) - #define UFFD_FEATURE_EVENT_FORK (1<<1) -@@ -232,6 +238,7 @@ struct uffdio_api { - #define UFFD_FEATURE_WP_HUGETLBFS_SHMEM (1<<12) - #define UFFD_FEATURE_WP_UNPOPULATED (1<<13) - #define UFFD_FEATURE_POISON (1<<14) -+#define UFFD_FEATURE_WP_ASYNC (1<<15) - __u64 features; - - __u64 ioctls; -diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h -index acf72b4999..8e175ece31 100644 ---- a/linux-headers/linux/vfio.h -+++ b/linux-headers/linux/vfio.h -@@ -277,8 +277,8 @@ struct vfio_region_info { - #define VFIO_REGION_INFO_FLAG_CAPS (1 << 3) /* Info supports caps */ - __u32 index; /* Region index */ - __u32 cap_offset; /* Offset within info struct of first cap */ -- __u64 size; /* Region size (bytes) */ -- __u64 offset; /* Region offset from start of device fd */ -+ __aligned_u64 size; /* Region size (bytes) */ -+ __aligned_u64 offset; /* Region offset from start of device fd */ - }; - #define VFIO_DEVICE_GET_REGION_INFO _IO(VFIO_TYPE, VFIO_BASE + 8) - -@@ -294,8 +294,8 @@ struct vfio_region_info { - #define VFIO_REGION_INFO_CAP_SPARSE_MMAP 1 - - struct vfio_region_sparse_mmap_area { -- __u64 offset; /* Offset of mmap'able area within region */ -- __u64 size; /* Size of mmap'able area */ -+ __aligned_u64 offset; /* Offset of mmap'able area within region */ -+ __aligned_u64 size; /* Size of mmap'able area */ - }; - - struct vfio_region_info_cap_sparse_mmap { -@@ -450,9 +450,9 @@ struct vfio_device_migration_info { - VFIO_DEVICE_STATE_V1_RESUMING) - - __u32 reserved; -- __u64 pending_bytes; -- __u64 data_offset; -- __u64 data_size; -+ __aligned_u64 pending_bytes; -+ __aligned_u64 data_offset; -+ __aligned_u64 data_size; - }; - - /* -@@ -476,7 +476,7 @@ struct vfio_device_migration_info { - - struct vfio_region_info_cap_nvlink2_ssatgt { - struct vfio_info_cap_header header; -- __u64 tgt; -+ __aligned_u64 tgt; - }; - - /* -@@ -816,7 +816,7 @@ struct vfio_device_gfx_plane_info { - __u32 drm_plane_type; /* type of plane: DRM_PLANE_TYPE_* */ - /* out */ - __u32 drm_format; /* drm format of plane */ -- __u64 drm_format_mod; /* tiled mode */ -+ __aligned_u64 drm_format_mod; /* tiled mode */ - __u32 width; /* width of plane */ - __u32 height; /* height of plane */ - __u32 stride; /* stride of plane */ -@@ -829,6 +829,7 @@ struct vfio_device_gfx_plane_info { - __u32 region_index; /* region index */ - __u32 dmabuf_id; /* dma-buf id */ - }; -+ __u32 reserved; - }; - - #define VFIO_DEVICE_QUERY_GFX_PLANE _IO(VFIO_TYPE, VFIO_BASE + 14) -@@ -863,9 +864,10 @@ struct vfio_device_ioeventfd { - #define VFIO_DEVICE_IOEVENTFD_32 (1 << 2) /* 4-byte write */ - #define VFIO_DEVICE_IOEVENTFD_64 (1 << 3) /* 8-byte write */ - #define VFIO_DEVICE_IOEVENTFD_SIZE_MASK (0xf) -- __u64 offset; /* device fd offset of write */ -- __u64 data; /* data to be written */ -+ __aligned_u64 offset; /* device fd offset of write */ -+ __aligned_u64 data; /* data to be written */ - __s32 fd; /* -1 for de-assignment */ -+ __u32 reserved; - }; - - #define VFIO_DEVICE_IOEVENTFD _IO(VFIO_TYPE, VFIO_BASE + 16) -@@ -1434,6 +1436,27 @@ struct vfio_device_feature_mig_data_size { - - #define VFIO_DEVICE_FEATURE_MIG_DATA_SIZE 9 - -+/** -+ * Upon VFIO_DEVICE_FEATURE_SET, set or clear the BUS mastering for the device -+ * based on the operation specified in op flag. -+ * -+ * The functionality is incorporated for devices that needs bus master control, -+ * but the in-band device interface lacks the support. Consequently, it is not -+ * applicable to PCI devices, as bus master control for PCI devices is managed -+ * in-band through the configuration space. At present, this feature is supported -+ * only for CDX devices. -+ * When the device's BUS MASTER setting is configured as CLEAR, it will result in -+ * blocking all incoming DMA requests from the device. On the other hand, configuring -+ * the device's BUS MASTER setting as SET (enable) will grant the device the -+ * capability to perform DMA to the host memory. -+ */ -+struct vfio_device_feature_bus_master { -+ __u32 op; -+#define VFIO_DEVICE_FEATURE_CLEAR_MASTER 0 /* Clear Bus Master */ -+#define VFIO_DEVICE_FEATURE_SET_MASTER 1 /* Set Bus Master */ -+}; -+#define VFIO_DEVICE_FEATURE_BUS_MASTER 10 -+ - /* -------- API for Type1 VFIO IOMMU -------- */ - - /** -@@ -1449,7 +1472,7 @@ struct vfio_iommu_type1_info { - __u32 flags; - #define VFIO_IOMMU_INFO_PGSIZES (1 << 0) /* supported page sizes info */ - #define VFIO_IOMMU_INFO_CAPS (1 << 1) /* Info supports caps */ -- __u64 iova_pgsizes; /* Bitmap of supported page sizes */ -+ __aligned_u64 iova_pgsizes; /* Bitmap of supported page sizes */ - __u32 cap_offset; /* Offset within info struct of first cap */ - __u32 pad; - }; -diff --git a/linux-headers/linux/vhost.h b/linux-headers/linux/vhost.h -index f5c48b61ab..649560c685 100644 ---- a/linux-headers/linux/vhost.h -+++ b/linux-headers/linux/vhost.h -@@ -219,4 +219,12 @@ - */ - #define VHOST_VDPA_RESUME _IO(VHOST_VIRTIO, 0x7E) - -+/* Get the group for the descriptor table including driver & device areas -+ * of a virtqueue: read index, write group in num. -+ * The virtqueue index is stored in the index field of vhost_vring_state. -+ * The group ID of the descriptor table for this specific virtqueue -+ * is returned via num field of vhost_vring_state. -+ */ -+#define VHOST_VDPA_GET_VRING_DESC_GROUP _IOWR(VHOST_VIRTIO, 0x7F, \ -+ struct vhost_vring_state) - #endif --- -2.33.0 - diff --git a/0008-linux-headers-Synchronize-linux-headers-from-linux-v.patch b/0008-linux-headers-Synchronize-linux-headers-from-linux-v.patch deleted file mode 100644 index cf5110889808e1226f10387fbf5a6642098eb1bc..0000000000000000000000000000000000000000 --- a/0008-linux-headers-Synchronize-linux-headers-from-linux-v.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 280cba84e3eaed10f095f0c88dab27b7799558e5 Mon Sep 17 00:00:00 2001 -From: Tianrui Zhao -Date: Fri, 5 Jan 2024 15:57:56 +0800 -Subject: [PATCH] linux-headers: Synchronize linux headers from linux - v6.7.0-rc8 - -Use the scripts/update-linux-headers.sh to synchronize linux -headers from linux v6.7.0-rc8. We mainly want to add the -loongarch linux headers and then add the loongarch kvm support -based on it. - -Signed-off-by: Tianrui Zhao -Acked-by: Song Gao -Message-Id: <20240105075804.1228596-2-zhaotianrui@loongson.cn> -Signed-off-by: Song Gao ---- - include/standard-headers/linux/fuse.h | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - -diff --git a/include/standard-headers/linux/fuse.h b/include/standard-headers/linux/fuse.h -index 6b9793842c..fc0dcd10ae 100644 ---- a/include/standard-headers/linux/fuse.h -+++ b/include/standard-headers/linux/fuse.h -@@ -209,7 +209,7 @@ - * - add FUSE_HAS_EXPIRE_ONLY - * - * 7.39 -- * - add FUSE_DIRECT_IO_RELAX -+ * - add FUSE_DIRECT_IO_ALLOW_MMAP - * - add FUSE_STATX and related structures - */ - -@@ -405,8 +405,7 @@ struct fuse_file_lock { - * FUSE_CREATE_SUPP_GROUP: add supplementary group info to create, mkdir, - * symlink and mknod (single group that matches parent) - * FUSE_HAS_EXPIRE_ONLY: kernel supports expiry-only entry invalidation -- * FUSE_DIRECT_IO_RELAX: relax restrictions in FOPEN_DIRECT_IO mode, for now -- * allow shared mmap -+ * FUSE_DIRECT_IO_ALLOW_MMAP: allow shared mmap in FOPEN_DIRECT_IO mode. - */ - #define FUSE_ASYNC_READ (1 << 0) - #define FUSE_POSIX_LOCKS (1 << 1) -@@ -445,7 +444,10 @@ struct fuse_file_lock { - #define FUSE_HAS_INODE_DAX (1ULL << 33) - #define FUSE_CREATE_SUPP_GROUP (1ULL << 34) - #define FUSE_HAS_EXPIRE_ONLY (1ULL << 35) --#define FUSE_DIRECT_IO_RELAX (1ULL << 36) -+#define FUSE_DIRECT_IO_ALLOW_MMAP (1ULL << 36) -+ -+/* Obsolete alias for FUSE_DIRECT_IO_ALLOW_MMAP */ -+#define FUSE_DIRECT_IO_RELAX FUSE_DIRECT_IO_ALLOW_MMAP - - /** - * CUSE INIT request/reply flags --- -2.33.0 - diff --git a/0009-target-loongarch-Define-some-kvm_arch-interfaces.patch b/0009-target-loongarch-Define-some-kvm_arch-interfaces.patch deleted file mode 100644 index 5e6dcc55644f210018eb9e69fe4b57ffec273b93..0000000000000000000000000000000000000000 --- a/0009-target-loongarch-Define-some-kvm_arch-interfaces.patch +++ /dev/null @@ -1,162 +0,0 @@ -From 623a99084843f47723cb799d4bcef8e1359d59ad Mon Sep 17 00:00:00 2001 -From: Tianrui Zhao -Date: Fri, 5 Jan 2024 15:57:57 +0800 -Subject: [PATCH] target/loongarch: Define some kvm_arch interfaces - -Define some functions in target/loongarch/kvm/kvm.c, -such as kvm_arch_put_registers, kvm_arch_get_registers -and kvm_arch_handle_exit, etc. which are needed by -kvm/kvm-all.c. Now the most functions has no content -and they will be implemented in the next patches. - -Signed-off-by: Tianrui Zhao -Signed-off-by: xianglai li -Reviewed-by: Richard Henderson -Reviewed-by: Song Gao -Message-Id: <20240105075804.1228596-3-zhaotianrui@loongson.cn> -Signed-off-by: Song Gao ---- - target/loongarch/kvm/kvm.c | 131 +++++++++++++++++++++++++++++++++++++ - 1 file changed, 131 insertions(+) - create mode 100644 target/loongarch/kvm/kvm.c - -diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c -new file mode 100644 -index 0000000000..0d67322fd9 ---- /dev/null -+++ b/target/loongarch/kvm/kvm.c -@@ -0,0 +1,131 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+/* -+ * QEMU LoongArch KVM -+ * -+ * Copyright (c) 2023 Loongson Technology Corporation Limited -+ */ -+ -+#include "qemu/osdep.h" -+#include -+#include -+ -+#include "qemu/timer.h" -+#include "qemu/error-report.h" -+#include "qemu/main-loop.h" -+#include "sysemu/sysemu.h" -+#include "sysemu/kvm.h" -+#include "sysemu/kvm_int.h" -+#include "hw/pci/pci.h" -+#include "exec/memattrs.h" -+#include "exec/address-spaces.h" -+#include "hw/boards.h" -+#include "hw/irq.h" -+#include "qemu/log.h" -+#include "hw/loader.h" -+#include "migration/migration.h" -+#include "sysemu/runstate.h" -+#include "cpu-csr.h" -+#include "kvm_loongarch.h" -+ -+static bool cap_has_mp_state; -+const KVMCapabilityInfo kvm_arch_required_capabilities[] = { -+ KVM_CAP_LAST_INFO -+}; -+ -+int kvm_arch_get_registers(CPUState *cs) -+{ -+ return 0; -+} -+int kvm_arch_put_registers(CPUState *cs, int level) -+{ -+ return 0; -+} -+ -+int kvm_arch_init_vcpu(CPUState *cs) -+{ -+ return 0; -+} -+ -+int kvm_arch_destroy_vcpu(CPUState *cs) -+{ -+ return 0; -+} -+ -+unsigned long kvm_arch_vcpu_id(CPUState *cs) -+{ -+ return cs->cpu_index; -+} -+ -+int kvm_arch_release_virq_post(int virq) -+{ -+ return 0; -+} -+ -+int kvm_arch_msi_data_to_gsi(uint32_t data) -+{ -+ abort(); -+} -+ -+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route, -+ uint64_t address, uint32_t data, PCIDevice *dev) -+{ -+ return 0; -+} -+ -+int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route, -+ int vector, PCIDevice *dev) -+{ -+ return 0; -+} -+ -+void kvm_arch_init_irq_routing(KVMState *s) -+{ -+} -+ -+int kvm_arch_get_default_type(MachineState *ms) -+{ -+ return 0; -+} -+ -+int kvm_arch_init(MachineState *ms, KVMState *s) -+{ -+ return 0; -+} -+ -+int kvm_arch_irqchip_create(KVMState *s) -+{ -+ return 0; -+} -+ -+void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run) -+{ -+} -+ -+MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run) -+{ -+ return MEMTXATTRS_UNSPECIFIED; -+} -+ -+int kvm_arch_process_async_events(CPUState *cs) -+{ -+ return cs->halted; -+} -+ -+bool kvm_arch_stop_on_emulation_error(CPUState *cs) -+{ -+ return true; -+} -+ -+bool kvm_arch_cpu_check_are_resettable(void) -+{ -+ return true; -+} -+ -+int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) -+{ -+ return 0; -+} -+ -+void kvm_arch_accel_class_init(ObjectClass *oc) -+{ -+} --- -2.33.0 - diff --git a/0010-target-loongarch-Supplement-vcpu-env-initial-when-vc.patch b/0010-target-loongarch-Supplement-vcpu-env-initial-when-vc.patch deleted file mode 100644 index 4ef4a96ff09cec2b926f798c5b76a14907950ff3..0000000000000000000000000000000000000000 --- a/0010-target-loongarch-Supplement-vcpu-env-initial-when-vc.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 48dae5f461bf2cde206e879d52df6cf1bad3ac6e Mon Sep 17 00:00:00 2001 -From: Tianrui Zhao -Date: Fri, 5 Jan 2024 15:57:58 +0800 -Subject: [PATCH] target/loongarch: Supplement vcpu env initial when vcpu - reset - -Supplement vcpu env initial when vcpu reset, including -init vcpu CSR_CPUID,CSR_TID to cpu->cpu_index. The two -regs will be used in kvm_get/set_csr_ioctl. - -Signed-off-by: Tianrui Zhao -Signed-off-by: xianglai li -Reviewed-by: Song Gao -Message-Id: <20240105075804.1228596-4-zhaotianrui@loongson.cn> -Signed-off-by: Song Gao ---- - target/loongarch/cpu.c | 2 ++ - target/loongarch/cpu.h | 2 +- - 2 files changed, 3 insertions(+), 1 deletion(-) - -diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c -index db9a421cc4..021592798a 100644 ---- a/target/loongarch/cpu.c -+++ b/target/loongarch/cpu.c -@@ -531,10 +531,12 @@ static void loongarch_cpu_reset_hold(Object *obj) - - env->CSR_ESTAT = env->CSR_ESTAT & (~MAKE_64BIT_MASK(0, 2)); - env->CSR_RVACFG = FIELD_DP64(env->CSR_RVACFG, CSR_RVACFG, RBITS, 0); -+ env->CSR_CPUID = cs->cpu_index; - env->CSR_TCFG = FIELD_DP64(env->CSR_TCFG, CSR_TCFG, EN, 0); - env->CSR_LLBCTL = FIELD_DP64(env->CSR_LLBCTL, CSR_LLBCTL, KLO, 0); - env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 0); - env->CSR_MERRCTL = FIELD_DP64(env->CSR_MERRCTL, CSR_MERRCTL, ISMERR, 0); -+ env->CSR_TID = cs->cpu_index; - - env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, TLB_TYPE, 2); - env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, MTLB_ENTRY, 63); -diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h -index 00d1fba597..f6d5ef0852 100644 ---- a/target/loongarch/cpu.h -+++ b/target/loongarch/cpu.h -@@ -319,6 +319,7 @@ typedef struct CPUArchState { - uint64_t CSR_PWCH; - uint64_t CSR_STLBPS; - uint64_t CSR_RVACFG; -+ uint64_t CSR_CPUID; - uint64_t CSR_PRCFG1; - uint64_t CSR_PRCFG2; - uint64_t CSR_PRCFG3; -@@ -350,7 +351,6 @@ typedef struct CPUArchState { - uint64_t CSR_DBG; - uint64_t CSR_DERA; - uint64_t CSR_DSAVE; -- uint64_t CSR_CPUID; - - #ifndef CONFIG_USER_ONLY - LoongArchTLB tlb[LOONGARCH_TLB_MAX]; --- -2.33.0 - diff --git a/0011-target-loongarch-Implement-kvm-get-set-registers.patch b/0011-target-loongarch-Implement-kvm-get-set-registers.patch deleted file mode 100644 index 254e53117e6714645504639bb59896fa9cb5f256..0000000000000000000000000000000000000000 --- a/0011-target-loongarch-Implement-kvm-get-set-registers.patch +++ /dev/null @@ -1,724 +0,0 @@ -From 0884653d8583aaaa5585caf38246518439bcfdfd Mon Sep 17 00:00:00 2001 -From: Tianrui Zhao -Date: Fri, 5 Jan 2024 15:57:59 +0800 -Subject: [PATCH] target/loongarch: Implement kvm get/set registers - -Implement kvm_arch_get/set_registers interfaces, many regs -can be get/set in the function, such as core regs, csr regs, -fpu regs, mp state, etc. - -Signed-off-by: Tianrui Zhao -Signed-off-by: xianglai li -Reviewed-by: Song Gao -Change-Id: Ia8fc48fe08b1768853f7729e77d37cdf270031e4 -Message-Id: <20240105075804.1228596-5-zhaotianrui@loongson.cn> -Signed-off-by: Song Gao ---- - meson.build | 1 + - target/loongarch/cpu.c | 3 + - target/loongarch/cpu.h | 1 + - target/loongarch/internals.h | 5 +- - target/loongarch/kvm/kvm.c | 580 +++++++++++++++++++++++++++++++++- - target/loongarch/trace-events | 11 + - target/loongarch/trace.h | 1 + - 7 files changed, 599 insertions(+), 3 deletions(-) - create mode 100644 target/loongarch/trace-events - create mode 100644 target/loongarch/trace.h - -diff --git a/meson.build b/meson.build -index 6c77d9687d..445f2b7c2b 100644 ---- a/meson.build -+++ b/meson.build -@@ -3358,6 +3358,7 @@ if have_system or have_user - 'target/hppa', - 'target/i386', - 'target/i386/kvm', -+ 'target/loongarch', - 'target/mips/tcg', - 'target/nios2', - 'target/ppc', -diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c -index 021592798a..275833eec8 100644 ---- a/target/loongarch/cpu.c -+++ b/target/loongarch/cpu.c -@@ -553,6 +553,9 @@ static void loongarch_cpu_reset_hold(Object *obj) - #ifndef CONFIG_USER_ONLY - env->pc = 0x1c000000; - memset(env->tlb, 0, sizeof(env->tlb)); -+ if (kvm_enabled()) { -+ kvm_arch_reset_vcpu(env); -+ } - #endif - - restore_fp_status(env); -diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h -index f6d5ef0852..f4a89bd626 100644 ---- a/target/loongarch/cpu.h -+++ b/target/loongarch/cpu.h -@@ -360,6 +360,7 @@ typedef struct CPUArchState { - MemoryRegion iocsr_mem; - bool load_elf; - uint64_t elf_address; -+ uint32_t mp_state; - /* Store ipistate to access from this struct */ - DeviceState *ipistate; - #endif -diff --git a/target/loongarch/internals.h b/target/loongarch/internals.h -index c492863cc5..0beb034748 100644 ---- a/target/loongarch/internals.h -+++ b/target/loongarch/internals.h -@@ -31,8 +31,10 @@ void G_NORETURN do_raise_exception(CPULoongArchState *env, - - const char *loongarch_exception_name(int32_t exception); - -+#ifdef CONFIG_TCG - int ieee_ex_to_loongarch(int xcpt); - void restore_fp_status(CPULoongArchState *env); -+#endif - - #ifndef CONFIG_USER_ONLY - extern const VMStateDescription vmstate_loongarch_cpu; -@@ -44,12 +46,13 @@ uint64_t cpu_loongarch_get_constant_timer_counter(LoongArchCPU *cpu); - uint64_t cpu_loongarch_get_constant_timer_ticks(LoongArchCPU *cpu); - void cpu_loongarch_store_constant_timer_config(LoongArchCPU *cpu, - uint64_t value); -- -+#ifdef CONFIG_TCG - bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size, - MMUAccessType access_type, int mmu_idx, - bool probe, uintptr_t retaddr); - - hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); -+#endif - #endif /* !CONFIG_USER_ONLY */ - - uint64_t read_fcc(CPULoongArchState *env); -diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c -index 0d67322fd9..e7c9ef830c 100644 ---- a/target/loongarch/kvm/kvm.c -+++ b/target/loongarch/kvm/kvm.c -@@ -26,19 +26,595 @@ - #include "sysemu/runstate.h" - #include "cpu-csr.h" - #include "kvm_loongarch.h" -+#include "trace.h" - - static bool cap_has_mp_state; - const KVMCapabilityInfo kvm_arch_required_capabilities[] = { - KVM_CAP_LAST_INFO - }; - -+static int kvm_loongarch_get_regs_core(CPUState *cs) -+{ -+ int ret = 0; -+ int i; -+ struct kvm_regs regs; -+ LoongArchCPU *cpu = LOONGARCH_CPU(cs); -+ CPULoongArchState *env = &cpu->env; -+ -+ /* Get the current register set as KVM seems it */ -+ ret = kvm_vcpu_ioctl(cs, KVM_GET_REGS, ®s); -+ if (ret < 0) { -+ trace_kvm_failed_get_regs_core(strerror(errno)); -+ return ret; -+ } -+ /* gpr[0] value is always 0 */ -+ env->gpr[0] = 0; -+ for (i = 1; i < 32; i++) { -+ env->gpr[i] = regs.gpr[i]; -+ } -+ -+ env->pc = regs.pc; -+ return ret; -+} -+ -+static int kvm_loongarch_put_regs_core(CPUState *cs) -+{ -+ int ret = 0; -+ int i; -+ struct kvm_regs regs; -+ LoongArchCPU *cpu = LOONGARCH_CPU(cs); -+ CPULoongArchState *env = &cpu->env; -+ -+ /* Set the registers based on QEMU's view of things */ -+ for (i = 0; i < 32; i++) { -+ regs.gpr[i] = env->gpr[i]; -+ } -+ -+ regs.pc = env->pc; -+ ret = kvm_vcpu_ioctl(cs, KVM_SET_REGS, ®s); -+ if (ret < 0) { -+ trace_kvm_failed_put_regs_core(strerror(errno)); -+ } -+ -+ return ret; -+} -+ -+static int kvm_loongarch_get_csr(CPUState *cs) -+{ -+ int ret = 0; -+ LoongArchCPU *cpu = LOONGARCH_CPU(cs); -+ CPULoongArchState *env = &cpu->env; -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CRMD), -+ &env->CSR_CRMD); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRMD), -+ &env->CSR_PRMD); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EUEN), -+ &env->CSR_EUEN); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_MISC), -+ &env->CSR_MISC); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ECFG), -+ &env->CSR_ECFG); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ESTAT), -+ &env->CSR_ESTAT); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ERA), -+ &env->CSR_ERA); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADV), -+ &env->CSR_BADV); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADI), -+ &env->CSR_BADI); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EENTRY), -+ &env->CSR_EENTRY); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBIDX), -+ &env->CSR_TLBIDX); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBEHI), -+ &env->CSR_TLBEHI); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO0), -+ &env->CSR_TLBELO0); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO1), -+ &env->CSR_TLBELO1); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ASID), -+ &env->CSR_ASID); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDL), -+ &env->CSR_PGDL); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDH), -+ &env->CSR_PGDH); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGD), -+ &env->CSR_PGD); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCL), -+ &env->CSR_PWCL); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCH), -+ &env->CSR_PWCH); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_STLBPS), -+ &env->CSR_STLBPS); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_RVACFG), -+ &env->CSR_RVACFG); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CPUID), -+ &env->CSR_CPUID); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG1), -+ &env->CSR_PRCFG1); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG2), -+ &env->CSR_PRCFG2); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG3), -+ &env->CSR_PRCFG3); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(0)), -+ &env->CSR_SAVE[0]); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(1)), -+ &env->CSR_SAVE[1]); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(2)), -+ &env->CSR_SAVE[2]); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(3)), -+ &env->CSR_SAVE[3]); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(4)), -+ &env->CSR_SAVE[4]); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(5)), -+ &env->CSR_SAVE[5]); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(6)), -+ &env->CSR_SAVE[6]); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(7)), -+ &env->CSR_SAVE[7]); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TID), -+ &env->CSR_TID); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CNTC), -+ &env->CSR_CNTC); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TICLR), -+ &env->CSR_TICLR); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_LLBCTL), -+ &env->CSR_LLBCTL); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL1), -+ &env->CSR_IMPCTL1); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL2), -+ &env->CSR_IMPCTL2); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRENTRY), -+ &env->CSR_TLBRENTRY); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRBADV), -+ &env->CSR_TLBRBADV); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRERA), -+ &env->CSR_TLBRERA); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRSAVE), -+ &env->CSR_TLBRSAVE); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO0), -+ &env->CSR_TLBRELO0); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO1), -+ &env->CSR_TLBRELO1); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBREHI), -+ &env->CSR_TLBREHI); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRPRMD), -+ &env->CSR_TLBRPRMD); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(0)), -+ &env->CSR_DMW[0]); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(1)), -+ &env->CSR_DMW[1]); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(2)), -+ &env->CSR_DMW[2]); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(3)), -+ &env->CSR_DMW[3]); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TVAL), -+ &env->CSR_TVAL); -+ -+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TCFG), -+ &env->CSR_TCFG); -+ -+ return ret; -+} -+ -+static int kvm_loongarch_put_csr(CPUState *cs) -+{ -+ int ret = 0; -+ LoongArchCPU *cpu = LOONGARCH_CPU(cs); -+ CPULoongArchState *env = &cpu->env; -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CRMD), -+ &env->CSR_CRMD); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRMD), -+ &env->CSR_PRMD); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EUEN), -+ &env->CSR_EUEN); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_MISC), -+ &env->CSR_MISC); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ECFG), -+ &env->CSR_ECFG); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ESTAT), -+ &env->CSR_ESTAT); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ERA), -+ &env->CSR_ERA); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADV), -+ &env->CSR_BADV); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADI), -+ &env->CSR_BADI); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EENTRY), -+ &env->CSR_EENTRY); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBIDX), -+ &env->CSR_TLBIDX); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBEHI), -+ &env->CSR_TLBEHI); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO0), -+ &env->CSR_TLBELO0); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO1), -+ &env->CSR_TLBELO1); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ASID), -+ &env->CSR_ASID); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDL), -+ &env->CSR_PGDL); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDH), -+ &env->CSR_PGDH); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGD), -+ &env->CSR_PGD); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCL), -+ &env->CSR_PWCL); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCH), -+ &env->CSR_PWCH); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_STLBPS), -+ &env->CSR_STLBPS); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_RVACFG), -+ &env->CSR_RVACFG); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CPUID), -+ &env->CSR_CPUID); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG1), -+ &env->CSR_PRCFG1); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG2), -+ &env->CSR_PRCFG2); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG3), -+ &env->CSR_PRCFG3); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(0)), -+ &env->CSR_SAVE[0]); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(1)), -+ &env->CSR_SAVE[1]); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(2)), -+ &env->CSR_SAVE[2]); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(3)), -+ &env->CSR_SAVE[3]); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(4)), -+ &env->CSR_SAVE[4]); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(5)), -+ &env->CSR_SAVE[5]); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(6)), -+ &env->CSR_SAVE[6]); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(7)), -+ &env->CSR_SAVE[7]); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TID), -+ &env->CSR_TID); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CNTC), -+ &env->CSR_CNTC); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TICLR), -+ &env->CSR_TICLR); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_LLBCTL), -+ &env->CSR_LLBCTL); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL1), -+ &env->CSR_IMPCTL1); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL2), -+ &env->CSR_IMPCTL2); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRENTRY), -+ &env->CSR_TLBRENTRY); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRBADV), -+ &env->CSR_TLBRBADV); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRERA), -+ &env->CSR_TLBRERA); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRSAVE), -+ &env->CSR_TLBRSAVE); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO0), -+ &env->CSR_TLBRELO0); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO1), -+ &env->CSR_TLBRELO1); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBREHI), -+ &env->CSR_TLBREHI); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRPRMD), -+ &env->CSR_TLBRPRMD); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(0)), -+ &env->CSR_DMW[0]); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(1)), -+ &env->CSR_DMW[1]); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(2)), -+ &env->CSR_DMW[2]); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(3)), -+ &env->CSR_DMW[3]); -+ /* -+ * timer cfg must be put at last since it is used to enable -+ * guest timer -+ */ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TVAL), -+ &env->CSR_TVAL); -+ -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TCFG), -+ &env->CSR_TCFG); -+ return ret; -+} -+ -+static int kvm_loongarch_get_regs_fp(CPUState *cs) -+{ -+ int ret, i; -+ struct kvm_fpu fpu; -+ -+ LoongArchCPU *cpu = LOONGARCH_CPU(cs); -+ CPULoongArchState *env = &cpu->env; -+ -+ ret = kvm_vcpu_ioctl(cs, KVM_GET_FPU, &fpu); -+ if (ret < 0) { -+ trace_kvm_failed_get_fpu(strerror(errno)); -+ return ret; -+ } -+ -+ env->fcsr0 = fpu.fcsr; -+ for (i = 0; i < 32; i++) { -+ env->fpr[i].vreg.UD[0] = fpu.fpr[i].val64[0]; -+ } -+ for (i = 0; i < 8; i++) { -+ env->cf[i] = fpu.fcc & 0xFF; -+ fpu.fcc = fpu.fcc >> 8; -+ } -+ -+ return ret; -+} -+ -+static int kvm_loongarch_put_regs_fp(CPUState *cs) -+{ -+ int ret, i; -+ struct kvm_fpu fpu; -+ -+ LoongArchCPU *cpu = LOONGARCH_CPU(cs); -+ CPULoongArchState *env = &cpu->env; -+ -+ fpu.fcsr = env->fcsr0; -+ fpu.fcc = 0; -+ for (i = 0; i < 32; i++) { -+ fpu.fpr[i].val64[0] = env->fpr[i].vreg.UD[0]; -+ } -+ -+ for (i = 0; i < 8; i++) { -+ fpu.fcc |= env->cf[i] << (8 * i); -+ } -+ -+ ret = kvm_vcpu_ioctl(cs, KVM_SET_FPU, &fpu); -+ if (ret < 0) { -+ trace_kvm_failed_put_fpu(strerror(errno)); -+ } -+ -+ return ret; -+} -+ -+void kvm_arch_reset_vcpu(CPULoongArchState *env) -+{ -+ env->mp_state = KVM_MP_STATE_RUNNABLE; -+} -+ -+static int kvm_loongarch_get_mpstate(CPUState *cs) -+{ -+ int ret = 0; -+ struct kvm_mp_state mp_state; -+ LoongArchCPU *cpu = LOONGARCH_CPU(cs); -+ CPULoongArchState *env = &cpu->env; -+ -+ if (cap_has_mp_state) { -+ ret = kvm_vcpu_ioctl(cs, KVM_GET_MP_STATE, &mp_state); -+ if (ret) { -+ trace_kvm_failed_get_mpstate(strerror(errno)); -+ return ret; -+ } -+ env->mp_state = mp_state.mp_state; -+ } -+ -+ return ret; -+} -+ -+static int kvm_loongarch_put_mpstate(CPUState *cs) -+{ -+ int ret = 0; -+ -+ LoongArchCPU *cpu = LOONGARCH_CPU(cs); -+ CPULoongArchState *env = &cpu->env; -+ -+ struct kvm_mp_state mp_state = { -+ .mp_state = env->mp_state -+ }; -+ -+ if (cap_has_mp_state) { -+ ret = kvm_vcpu_ioctl(cs, KVM_SET_MP_STATE, &mp_state); -+ if (ret) { -+ trace_kvm_failed_put_mpstate(strerror(errno)); -+ } -+ } -+ -+ return ret; -+} -+ -+static int kvm_loongarch_get_cpucfg(CPUState *cs) -+{ -+ int i, ret = 0; -+ uint64_t val; -+ LoongArchCPU *cpu = LOONGARCH_CPU(cs); -+ CPULoongArchState *env = &cpu->env; -+ -+ for (i = 0; i < 21; i++) { -+ ret = kvm_get_one_reg(cs, KVM_IOC_CPUCFG(i), &val); -+ if (ret < 0) { -+ trace_kvm_failed_get_cpucfg(strerror(errno)); -+ } -+ env->cpucfg[i] = (uint32_t)val; -+ } -+ return ret; -+} -+ -+static int kvm_loongarch_put_cpucfg(CPUState *cs) -+{ -+ int i, ret = 0; -+ LoongArchCPU *cpu = LOONGARCH_CPU(cs); -+ CPULoongArchState *env = &cpu->env; -+ uint64_t val; -+ -+ for (i = 0; i < 21; i++) { -+ val = env->cpucfg[i]; -+ /* LSX and LASX and LBT are not supported in kvm now */ -+ if (i == 2) { -+ val &= ~(BIT(R_CPUCFG2_LSX_SHIFT) | BIT(R_CPUCFG2_LASX_SHIFT)); -+ val &= ~(BIT(R_CPUCFG2_LBT_X86_SHIFT) | -+ BIT(R_CPUCFG2_LBT_ARM_SHIFT) | -+ BIT(R_CPUCFG2_LBT_MIPS_SHIFT)); -+ } -+ ret = kvm_set_one_reg(cs, KVM_IOC_CPUCFG(i), &val); -+ if (ret < 0) { -+ trace_kvm_failed_put_cpucfg(strerror(errno)); -+ } -+ } -+ return ret; -+} -+ - int kvm_arch_get_registers(CPUState *cs) - { -- return 0; -+ int ret; -+ -+ ret = kvm_loongarch_get_regs_core(cs); -+ if (ret) { -+ return ret; -+ } -+ -+ ret = kvm_loongarch_get_csr(cs); -+ if (ret) { -+ return ret; -+ } -+ -+ ret = kvm_loongarch_get_regs_fp(cs); -+ if (ret) { -+ return ret; -+ } -+ -+ ret = kvm_loongarch_get_mpstate(cs); -+ if (ret) { -+ return ret; -+ } -+ -+ ret = kvm_loongarch_get_cpucfg(cs); -+ return ret; - } -+ - int kvm_arch_put_registers(CPUState *cs, int level) - { -- return 0; -+ int ret; -+ -+ ret = kvm_loongarch_put_regs_core(cs); -+ if (ret) { -+ return ret; -+ } -+ -+ ret = kvm_loongarch_put_csr(cs); -+ if (ret) { -+ return ret; -+ } -+ -+ ret = kvm_loongarch_put_regs_fp(cs); -+ if (ret) { -+ return ret; -+ } -+ -+ ret = kvm_loongarch_put_mpstate(cs); -+ if (ret) { -+ return ret; -+ } -+ -+ ret = kvm_loongarch_put_cpucfg(cs); -+ return ret; - } - - int kvm_arch_init_vcpu(CPUState *cs) -diff --git a/target/loongarch/trace-events b/target/loongarch/trace-events -new file mode 100644 -index 0000000000..6827ab566a ---- /dev/null -+++ b/target/loongarch/trace-events -@@ -0,0 +1,11 @@ -+# See docs/devel/tracing.rst for syntax documentation. -+ -+#kvm.c -+kvm_failed_get_regs_core(const char *msg) "Failed to get core regs from KVM: %s" -+kvm_failed_put_regs_core(const char *msg) "Failed to put core regs into KVM: %s" -+kvm_failed_get_fpu(const char *msg) "Failed to get fpu from KVM: %s" -+kvm_failed_put_fpu(const char *msg) "Failed to put fpu into KVM: %s" -+kvm_failed_get_mpstate(const char *msg) "Failed to get mp_state from KVM: %s" -+kvm_failed_put_mpstate(const char *msg) "Failed to put mp_state into KVM: %s" -+kvm_failed_get_cpucfg(const char *msg) "Failed to get cpucfg from KVM: %s" -+kvm_failed_put_cpucfg(const char *msg) "Failed to put cpucfg into KVM: %s" -diff --git a/target/loongarch/trace.h b/target/loongarch/trace.h -new file mode 100644 -index 0000000000..c2ecb78f08 ---- /dev/null -+++ b/target/loongarch/trace.h -@@ -0,0 +1 @@ -+#include "trace/trace-target_loongarch.h" --- -2.33.0 - diff --git a/0012-target-loongarch-Implement-kvm_arch_init-function.patch b/0012-target-loongarch-Implement-kvm_arch_init-function.patch deleted file mode 100644 index 73039706ffc02bef62fcc4fd3da65dd4e11ce44d..0000000000000000000000000000000000000000 --- a/0012-target-loongarch-Implement-kvm_arch_init-function.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 3a87dbd5e0343ee777bac0f18888a5a2d51254db Mon Sep 17 00:00:00 2001 -From: Tianrui Zhao -Date: Fri, 5 Jan 2024 15:58:00 +0800 -Subject: [PATCH] target/loongarch: Implement kvm_arch_init function - -Implement the kvm_arch_init of loongarch, in the function, the -KVM_CAP_MP_STATE cap is checked by kvm ioctl. - -Signed-off-by: Tianrui Zhao -Signed-off-by: xianglai li -Reviewed-by: Richard Henderson -Reviewed-by: Song Gao -Message-Id: <20240105075804.1228596-6-zhaotianrui@loongson.cn> -Signed-off-by: Song Gao ---- - target/loongarch/kvm/kvm.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c -index e7c9ef830c..29944b9ef8 100644 ---- a/target/loongarch/kvm/kvm.c -+++ b/target/loongarch/kvm/kvm.c -@@ -665,6 +665,7 @@ int kvm_arch_get_default_type(MachineState *ms) - - int kvm_arch_init(MachineState *ms, KVMState *s) - { -+ cap_has_mp_state = kvm_check_extension(s, KVM_CAP_MP_STATE); - return 0; - } - --- -2.33.0 - diff --git a/0013-target-loongarch-Implement-kvm_arch_init_vcpu.patch b/0013-target-loongarch-Implement-kvm_arch_init_vcpu.patch deleted file mode 100644 index 28fce6870489e576d8dfb77b1f077326d22abd79..0000000000000000000000000000000000000000 --- a/0013-target-loongarch-Implement-kvm_arch_init_vcpu.patch +++ /dev/null @@ -1,87 +0,0 @@ -From d7d47c044c9854675b75b91ade678d03316d9271 Mon Sep 17 00:00:00 2001 -From: Tianrui Zhao -Date: Fri, 5 Jan 2024 15:58:01 +0800 -Subject: [PATCH] target/loongarch: Implement kvm_arch_init_vcpu - -Implement kvm_arch_init_vcpu interface for loongarch, -in this function, we register VM change state handler. -And when VM state changes to running, the counter value -should be put into kvm to keep consistent with kvm, -and when state change to stop, counter value should be -refreshed from kvm. - -Signed-off-by: Tianrui Zhao -Signed-off-by: xianglai li -Reviewed-by: Song Gao -Message-Id: <20240105075804.1228596-7-zhaotianrui@loongson.cn> -Signed-off-by: Song Gao ---- - target/loongarch/cpu.h | 2 ++ - target/loongarch/kvm/kvm.c | 23 +++++++++++++++++++++++ - target/loongarch/trace-events | 2 ++ - 3 files changed, 27 insertions(+) - -diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h -index f4a89bd626..8ebd6fa1a7 100644 ---- a/target/loongarch/cpu.h -+++ b/target/loongarch/cpu.h -@@ -381,6 +381,8 @@ struct ArchCPU { - - /* 'compatible' string for this CPU for Linux device trees */ - const char *dtb_compatible; -+ /* used by KVM_REG_LOONGARCH_COUNTER ioctl to access guest time counters */ -+ uint64_t kvm_state_counter; - }; - - /** -diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c -index 29944b9ef8..85e7aeb083 100644 ---- a/target/loongarch/kvm/kvm.c -+++ b/target/loongarch/kvm/kvm.c -@@ -617,8 +617,31 @@ int kvm_arch_put_registers(CPUState *cs, int level) - return ret; - } - -+static void kvm_loongarch_vm_stage_change(void *opaque, bool running, -+ RunState state) -+{ -+ int ret; -+ CPUState *cs = opaque; -+ LoongArchCPU *cpu = LOONGARCH_CPU(cs); -+ -+ if (running) { -+ ret = kvm_set_one_reg(cs, KVM_REG_LOONGARCH_COUNTER, -+ &cpu->kvm_state_counter); -+ if (ret < 0) { -+ trace_kvm_failed_put_counter(strerror(errno)); -+ } -+ } else { -+ ret = kvm_get_one_reg(cs, KVM_REG_LOONGARCH_COUNTER, -+ &cpu->kvm_state_counter); -+ if (ret < 0) { -+ trace_kvm_failed_get_counter(strerror(errno)); -+ } -+ } -+} -+ - int kvm_arch_init_vcpu(CPUState *cs) - { -+ qemu_add_vm_change_state_handler(kvm_loongarch_vm_stage_change, cs); - return 0; - } - -diff --git a/target/loongarch/trace-events b/target/loongarch/trace-events -index 6827ab566a..937c3c7c0c 100644 ---- a/target/loongarch/trace-events -+++ b/target/loongarch/trace-events -@@ -7,5 +7,7 @@ kvm_failed_get_fpu(const char *msg) "Failed to get fpu from KVM: %s" - kvm_failed_put_fpu(const char *msg) "Failed to put fpu into KVM: %s" - kvm_failed_get_mpstate(const char *msg) "Failed to get mp_state from KVM: %s" - kvm_failed_put_mpstate(const char *msg) "Failed to put mp_state into KVM: %s" -+kvm_failed_get_counter(const char *msg) "Failed to get counter from KVM: %s" -+kvm_failed_put_counter(const char *msg) "Failed to put counter into KVM: %s" - kvm_failed_get_cpucfg(const char *msg) "Failed to get cpucfg from KVM: %s" - kvm_failed_put_cpucfg(const char *msg) "Failed to put cpucfg into KVM: %s" --- -2.33.0 - diff --git a/0014-target-loongarch-Implement-kvm_arch_handle_exit.patch b/0014-target-loongarch-Implement-kvm_arch_handle_exit.patch deleted file mode 100644 index 46ea9acf4dd1983f0fe66f1192fc32229117fdbf..0000000000000000000000000000000000000000 --- a/0014-target-loongarch-Implement-kvm_arch_handle_exit.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 3feeca228b010716aacdf7159df10ea63f7e34cd Mon Sep 17 00:00:00 2001 -From: Tianrui Zhao -Date: Fri, 5 Jan 2024 15:58:02 +0800 -Subject: [PATCH] target/loongarch: Implement kvm_arch_handle_exit - -Implement kvm_arch_handle_exit for loongarch. In this -function, the KVM_EXIT_LOONGARCH_IOCSR is handled, -we read or write the iocsr address space by the addr, -length and is_write argument in kvm_run. - -Signed-off-by: Tianrui Zhao -Signed-off-by: xianglai li -Reviewed-by: Richard Henderson -Reviewed-by: Song Gao -Message-Id: <20240105075804.1228596-8-zhaotianrui@loongson.cn> -Signed-off-by: Song Gao ---- - target/loongarch/kvm/kvm.c | 24 +++++++++++++++++++++++- - target/loongarch/trace-events | 1 + - 2 files changed, 24 insertions(+), 1 deletion(-) - -diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c -index 85e7aeb083..d2dab3fef4 100644 ---- a/target/loongarch/kvm/kvm.c -+++ b/target/loongarch/kvm/kvm.c -@@ -723,7 +723,29 @@ bool kvm_arch_cpu_check_are_resettable(void) - - int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) - { -- return 0; -+ int ret = 0; -+ LoongArchCPU *cpu = LOONGARCH_CPU(cs); -+ CPULoongArchState *env = &cpu->env; -+ MemTxAttrs attrs = {}; -+ -+ attrs.requester_id = env_cpu(env)->cpu_index; -+ -+ trace_kvm_arch_handle_exit(run->exit_reason); -+ switch (run->exit_reason) { -+ case KVM_EXIT_LOONGARCH_IOCSR: -+ address_space_rw(&env->address_space_iocsr, -+ run->iocsr_io.phys_addr, -+ attrs, -+ run->iocsr_io.data, -+ run->iocsr_io.len, -+ run->iocsr_io.is_write); -+ break; -+ default: -+ ret = -1; -+ warn_report("KVM: unknown exit reason %d", run->exit_reason); -+ break; -+ } -+ return ret; - } - - void kvm_arch_accel_class_init(ObjectClass *oc) -diff --git a/target/loongarch/trace-events b/target/loongarch/trace-events -index 937c3c7c0c..021839880e 100644 ---- a/target/loongarch/trace-events -+++ b/target/loongarch/trace-events -@@ -11,3 +11,4 @@ kvm_failed_get_counter(const char *msg) "Failed to get counter from KVM: %s" - kvm_failed_put_counter(const char *msg) "Failed to put counter into KVM: %s" - kvm_failed_get_cpucfg(const char *msg) "Failed to get cpucfg from KVM: %s" - kvm_failed_put_cpucfg(const char *msg) "Failed to put cpucfg into KVM: %s" -+kvm_arch_handle_exit(int num) "kvm arch handle exit, the reason number: %d" --- -2.33.0 - diff --git a/0015-target-loongarch-Restrict-TCG-specific-code.patch b/0015-target-loongarch-Restrict-TCG-specific-code.patch deleted file mode 100644 index d107009d68ea6289f7e51428d5edc60b4d925adf..0000000000000000000000000000000000000000 --- a/0015-target-loongarch-Restrict-TCG-specific-code.patch +++ /dev/null @@ -1,152 +0,0 @@ -From 773ea71519da1413ca2e0e60857272164e156a47 Mon Sep 17 00:00:00 2001 -From: Tianrui Zhao -Date: Wed, 10 Jan 2024 10:41:51 +0100 -Subject: [PATCH] target/loongarch: Restrict TCG-specific code -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -In preparation of supporting KVM in the next commit. - -Conflict: - -diff --cc target/loongarch/cpu.c -index 275833eec8,70dd4622aa..0000000000 ---- a/target/loongarch/cpu.c -+++ b/target/loongarch/cpu.c -@@@ -17,9 -17,14 +17,17 @@@ - #include "internals.h" - #include "fpu/softfloat-helpers.h" - #include "cpu-csr.h" - -#ifndef CONFIG_USER_ONLY - #include "sysemu/reset.h" -++<<<<<<< HEAD - +#include "tcg/tcg.h" -++======= -+ #endif -++>>>>>>> target/loongarch: Restrict TCG-specific code - #include "vec.h" -+ #ifdef CONFIG_TCG -+ #include "exec/cpu_ldst.h" -+ #include "tcg/tcg.h" -+ #endif - -Solve: - -drop: -++<<<<<<< HEAD - +#include "tcg/tcg.h" -++======= -+ #endif -++>>>>>>> target/loongarch: Restrict TCG-specific code - -Signed-off-by: Tianrui Zhao -Signed-off-by: xianglai li -Reviewed-by: Song Gao -Message-ID: <20240105075804.1228596-9-zhaotianrui@loongson.cn> -[PMD: Split from bigger patch, part 1] -Signed-off-by: Philippe Mathieu-Daudé -Message-Id: <20240110094152.52138-1-philmd@linaro.org> -Signed-off-by: Song Gao ---- - target/loongarch/cpu.c | 30 +++++++++++++++++++++--------- - 1 file changed, 21 insertions(+), 9 deletions(-) - -diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c -index 275833eec8..60f2636b43 100644 ---- a/target/loongarch/cpu.c -+++ b/target/loongarch/cpu.c -@@ -11,15 +11,18 @@ - #include "qapi/error.h" - #include "qemu/module.h" - #include "sysemu/qtest.h" --#include "exec/cpu_ldst.h" -+#include "sysemu/tcg.h" - #include "exec/exec-all.h" - #include "cpu.h" - #include "internals.h" - #include "fpu/softfloat-helpers.h" - #include "cpu-csr.h" - #include "sysemu/reset.h" --#include "tcg/tcg.h" - #include "vec.h" -+#ifdef CONFIG_TCG -+#include "exec/cpu_ldst.h" -+#include "tcg/tcg.h" -+#endif - - const char * const regnames[32] = { - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", -@@ -108,12 +111,13 @@ void loongarch_cpu_set_irq(void *opaque, int irq, int level) - return; - } - -- env->CSR_ESTAT = deposit64(env->CSR_ESTAT, irq, 1, level != 0); -- -- if (FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS)) { -- cpu_interrupt(cs, CPU_INTERRUPT_HARD); -- } else { -- cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); -+ if (tcg_enabled()) { -+ env->CSR_ESTAT = deposit64(env->CSR_ESTAT, irq, 1, level != 0); -+ if (FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS)) { -+ cpu_interrupt(cs, CPU_INTERRUPT_HARD); -+ } else { -+ cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); -+ } - } - } - -@@ -138,7 +142,10 @@ static inline bool cpu_loongarch_hw_interrupts_pending(CPULoongArchState *env) - - return (pending & status) != 0; - } -+#endif - -+#ifdef CONFIG_TCG -+#ifndef CONFIG_USER_ONLY - static void loongarch_cpu_do_interrupt(CPUState *cs) - { - LoongArchCPU *cpu = LOONGARCH_CPU(cs); -@@ -320,7 +327,6 @@ static bool loongarch_cpu_exec_interrupt(CPUState *cs, int interrupt_request) - } - #endif - --#ifdef CONFIG_TCG - static void loongarch_cpu_synchronize_from_tb(CPUState *cs, - const TranslationBlock *tb) - { -@@ -558,7 +564,9 @@ static void loongarch_cpu_reset_hold(Object *obj) - } - #endif - -+#ifdef CONFIG_TCG - restore_fp_status(env); -+#endif - cs->exception_index = -1; - } - -@@ -701,8 +709,10 @@ static void loongarch_cpu_init(Object *obj) - CPULoongArchState *env = &cpu->env; - - qdev_init_gpio_in(DEVICE(cpu), loongarch_cpu_set_irq, N_IRQS); -+#ifdef CONFIG_TCG - timer_init_ns(&cpu->timer, QEMU_CLOCK_VIRTUAL, - &loongarch_constant_timer_cb, cpu); -+#endif - memory_region_init_io(&env->system_iocsr, OBJECT(cpu), NULL, - env, "iocsr", UINT64_MAX); - address_space_init(&env->address_space_iocsr, &env->system_iocsr, "IOCSR"); -@@ -802,7 +812,9 @@ static struct TCGCPUOps loongarch_tcg_ops = { - #include "hw/core/sysemu-cpu-ops.h" - - static const struct SysemuCPUOps loongarch_sysemu_ops = { -+#ifdef CONFIG_TCG - .get_phys_page_debug = loongarch_cpu_get_phys_page_debug, -+#endif - }; - - static int64_t loongarch_cpu_get_arch_id(CPUState *cs) --- -2.33.0 - diff --git a/0016-target-loongarch-Implement-set-vcpu-intr-for-kvm.patch b/0016-target-loongarch-Implement-set-vcpu-intr-for-kvm.patch deleted file mode 100644 index d8a58be33653bdbbcf3484d872ba08c316f7f973..0000000000000000000000000000000000000000 --- a/0016-target-loongarch-Implement-set-vcpu-intr-for-kvm.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 5f4c8b31db442e6ac39fbfe4b29d5479ab3567aa Mon Sep 17 00:00:00 2001 -From: Tianrui Zhao -Date: Wed, 10 Jan 2024 10:41:52 +0100 -Subject: [PATCH] target/loongarch: Implement set vcpu intr for kvm -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Implement loongarch kvm set vcpu interrupt interface, -when a irq is set in vcpu, we use the KVM_INTERRUPT -ioctl to set intr into kvm. - -Signed-off-by: Tianrui Zhao -Signed-off-by: xianglai li -Reviewed-by: Song Gao -Message-ID: <20240105075804.1228596-9-zhaotianrui@loongson.cn> -[PMD: Split from bigger patch, part 2] -Signed-off-by: Philippe Mathieu-Daudé -Message-Id: <20240110094152.52138-2-philmd@linaro.org> -Signed-off-by: Song Gao ---- - target/loongarch/cpu.c | 9 ++++++++- - target/loongarch/kvm/kvm.c | 15 +++++++++++++++ - target/loongarch/kvm/kvm_loongarch.h | 16 ++++++++++++++++ - target/loongarch/trace-events | 1 + - 4 files changed, 40 insertions(+), 1 deletion(-) - create mode 100644 target/loongarch/kvm/kvm_loongarch.h - -diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c -index 60f2636b43..413414392b 100644 ---- a/target/loongarch/cpu.c -+++ b/target/loongarch/cpu.c -@@ -12,6 +12,8 @@ - #include "qemu/module.h" - #include "sysemu/qtest.h" - #include "sysemu/tcg.h" -+#include "sysemu/kvm.h" -+#include "kvm/kvm_loongarch.h" - #include "exec/exec-all.h" - #include "cpu.h" - #include "internals.h" -@@ -19,6 +21,9 @@ - #include "cpu-csr.h" - #include "sysemu/reset.h" - #include "vec.h" -+#ifdef CONFIG_KVM -+#include -+#endif - #ifdef CONFIG_TCG - #include "exec/cpu_ldst.h" - #include "tcg/tcg.h" -@@ -111,7 +116,9 @@ void loongarch_cpu_set_irq(void *opaque, int irq, int level) - return; - } - -- if (tcg_enabled()) { -+ if (kvm_enabled()) { -+ kvm_loongarch_set_interrupt(cpu, irq, level); -+ } else if (tcg_enabled()) { - env->CSR_ESTAT = deposit64(env->CSR_ESTAT, irq, 1, level != 0); - if (FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS)) { - cpu_interrupt(cs, CPU_INTERRUPT_HARD); -diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c -index d2dab3fef4..bd33ec2114 100644 ---- a/target/loongarch/kvm/kvm.c -+++ b/target/loongarch/kvm/kvm.c -@@ -748,6 +748,21 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) - return ret; - } - -+int kvm_loongarch_set_interrupt(LoongArchCPU *cpu, int irq, int level) -+{ -+ struct kvm_interrupt intr; -+ CPUState *cs = CPU(cpu); -+ -+ if (level) { -+ intr.irq = irq; -+ } else { -+ intr.irq = -irq; -+ } -+ -+ trace_kvm_set_intr(irq, level); -+ return kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &intr); -+} -+ - void kvm_arch_accel_class_init(ObjectClass *oc) - { - } -diff --git a/target/loongarch/kvm/kvm_loongarch.h b/target/loongarch/kvm/kvm_loongarch.h -new file mode 100644 -index 0000000000..d945b6bb82 ---- /dev/null -+++ b/target/loongarch/kvm/kvm_loongarch.h -@@ -0,0 +1,16 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+/* -+ * QEMU LoongArch kvm interface -+ * -+ * Copyright (c) 2023 Loongson Technology Corporation Limited -+ */ -+ -+#include "cpu.h" -+ -+#ifndef QEMU_KVM_LOONGARCH_H -+#define QEMU_KVM_LOONGARCH_H -+ -+int kvm_loongarch_set_interrupt(LoongArchCPU *cpu, int irq, int level); -+void kvm_arch_reset_vcpu(CPULoongArchState *env); -+ -+#endif -diff --git a/target/loongarch/trace-events b/target/loongarch/trace-events -index 021839880e..dea11edc0f 100644 ---- a/target/loongarch/trace-events -+++ b/target/loongarch/trace-events -@@ -12,3 +12,4 @@ kvm_failed_put_counter(const char *msg) "Failed to put counter into KVM: %s" - kvm_failed_get_cpucfg(const char *msg) "Failed to get cpucfg from KVM: %s" - kvm_failed_put_cpucfg(const char *msg) "Failed to put cpucfg into KVM: %s" - kvm_arch_handle_exit(int num) "kvm arch handle exit, the reason number: %d" -+kvm_set_intr(int irq, int level) "kvm set interrupt, irq num: %d, level: %d" --- -2.33.0 - diff --git a/0017-target-loongarch-Add-loongarch-kvm-into-meson-build.patch b/0017-target-loongarch-Add-loongarch-kvm-into-meson-build.patch deleted file mode 100644 index 4379887adeb46f6ed2fd1b29534f2b6b06f9d9f4..0000000000000000000000000000000000000000 --- a/0017-target-loongarch-Add-loongarch-kvm-into-meson-build.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 49a7ae85d6ac42f8ef556a0d42802508c28adfcc Mon Sep 17 00:00:00 2001 -From: Tianrui Zhao -Date: Fri, 5 Jan 2024 15:58:04 +0800 -Subject: [PATCH] target/loongarch: Add loongarch kvm into meson build - -Add kvm.c into meson.build to compile it when kvm -is configed. Meanwhile in meson.build, we set the -kvm_targets to loongarch64-softmmu when the cpu is -loongarch. And fix the compiling error when config -is enable-kvm,disable-tcg. - -Signed-off-by: Tianrui Zhao -Signed-off-by: xianglai li -Reviewed-by: Richard Henderson -Reviewed-by: Song Gao -Message-Id: <20240105075804.1228596-10-zhaotianrui@loongson.cn> -Signed-off-by: Song Gao ---- - meson.build | 2 ++ - target/loongarch/kvm/meson.build | 1 + - target/loongarch/meson.build | 1 + - 3 files changed, 4 insertions(+) - create mode 100644 target/loongarch/kvm/meson.build - -diff --git a/meson.build b/meson.build -index 445f2b7c2b..0c62b4156d 100644 ---- a/meson.build -+++ b/meson.build -@@ -114,6 +114,8 @@ elif cpu in ['riscv32'] - kvm_targets = ['riscv32-softmmu'] - elif cpu in ['riscv64'] - kvm_targets = ['riscv64-softmmu'] -+elif cpu in ['loongarch64'] -+ kvm_targets = ['loongarch64-softmmu'] - else - kvm_targets = [] - endif -diff --git a/target/loongarch/kvm/meson.build b/target/loongarch/kvm/meson.build -new file mode 100644 -index 0000000000..2266de6ca9 ---- /dev/null -+++ b/target/loongarch/kvm/meson.build -@@ -0,0 +1 @@ -+loongarch_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c')) -diff --git a/target/loongarch/meson.build b/target/loongarch/meson.build -index e84e4c51f4..db310f6022 100644 ---- a/target/loongarch/meson.build -+++ b/target/loongarch/meson.build -@@ -18,3 +18,4 @@ subdir('tcg') - - target_arch += {'loongarch': loongarch_ss} - target_system_arch += {'loongarch': loongarch_system_ss} -+subdir('kvm') --- -2.33.0 - diff --git a/0018-hw-intc-loongarch_ipi-Use-MemTxAttrs-interface-for-i.patch b/0018-hw-intc-loongarch_ipi-Use-MemTxAttrs-interface-for-i.patch deleted file mode 100644 index d15294229a5a7712f5635bd8f1e5bdf156498af2..0000000000000000000000000000000000000000 --- a/0018-hw-intc-loongarch_ipi-Use-MemTxAttrs-interface-for-i.patch +++ /dev/null @@ -1,287 +0,0 @@ -From b8f53cfa91e86d5163318f8ade1cca18e94f3eb7 Mon Sep 17 00:00:00 2001 -From: Bibo Mao -Date: Wed, 13 Dec 2023 12:12:01 +0800 -Subject: [PATCH] hw/intc/loongarch_ipi: Use MemTxAttrs interface for ipi - ops - -There are two interface pairs for MemoryRegionOps, read/write and -read_with_attrs/write_with_attrs. The later is better for ipi device -emulation since initial cpu can be parsed from attrs.requester_id. - -And requester_id can be overrided for IOCSR_IPI_SEND and mail_send -function when it is to forward message to another vcpu. - -Signed-off-by: Bibo Mao -Reviewed-by: Song Gao -Message-Id: <20231215100333.3933632-2-maobibo@loongson.cn> -Signed-off-by: Song Gao ---- - hw/intc/loongarch_ipi.c | 136 +++++++++++++++++++++++----------------- - 1 file changed, 77 insertions(+), 59 deletions(-) - -diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c -index 67858b521c..221246c5cb 100644 ---- a/hw/intc/loongarch_ipi.c -+++ b/hw/intc/loongarch_ipi.c -@@ -17,14 +17,16 @@ - #include "target/loongarch/internals.h" - #include "trace.h" - --static void loongarch_ipi_writel(void *, hwaddr, uint64_t, unsigned); -- --static uint64_t loongarch_ipi_readl(void *opaque, hwaddr addr, unsigned size) -+static MemTxResult loongarch_ipi_readl(void *opaque, hwaddr addr, -+ uint64_t *data, -+ unsigned size, MemTxAttrs attrs) - { -- IPICore *s = opaque; -+ IPICore *s; -+ LoongArchIPI *ipi = opaque; - uint64_t ret = 0; - int index = 0; - -+ s = &ipi->ipi_core; - addr &= 0xff; - switch (addr) { - case CORE_STATUS_OFF: -@@ -49,10 +51,12 @@ static uint64_t loongarch_ipi_readl(void *opaque, hwaddr addr, unsigned size) - } - - trace_loongarch_ipi_read(size, (uint64_t)addr, ret); -- return ret; -+ *data = ret; -+ return MEMTX_OK; - } - --static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr) -+static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr, -+ MemTxAttrs attrs) - { - int i, mask = 0, data = 0; - -@@ -62,7 +66,7 @@ static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr) - */ - if ((val >> 27) & 0xf) { - data = address_space_ldl(&env->address_space_iocsr, addr, -- MEMTXATTRS_UNSPECIFIED, NULL); -+ attrs, NULL); - for (i = 0; i < 4; i++) { - /* get mask for byte writing */ - if (val & (0x1 << (27 + i))) { -@@ -74,7 +78,7 @@ static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr) - data &= mask; - data |= (val >> 32) & ~mask; - address_space_stl(&env->address_space_iocsr, addr, -- data, MEMTXATTRS_UNSPECIFIED, NULL); -+ data, attrs, NULL); - } - - static int archid_cmp(const void *a, const void *b) -@@ -103,80 +107,72 @@ static CPUState *ipi_getcpu(int arch_id) - CPUArchId *archid; - - archid = find_cpu_by_archid(machine, arch_id); -- return CPU(archid->cpu); --} -- --static void ipi_send(uint64_t val) --{ -- uint32_t cpuid; -- uint8_t vector; -- CPUState *cs; -- LoongArchCPU *cpu; -- LoongArchIPI *s; -- -- cpuid = extract32(val, 16, 10); -- if (cpuid >= LOONGARCH_MAX_CPUS) { -- trace_loongarch_ipi_unsupported_cpuid("IOCSR_IPI_SEND", cpuid); -- return; -+ if (archid) { -+ return CPU(archid->cpu); - } - -- /* IPI status vector */ -- vector = extract8(val, 0, 5); -- -- cs = ipi_getcpu(cpuid); -- cpu = LOONGARCH_CPU(cs); -- s = LOONGARCH_IPI(cpu->env.ipistate); -- loongarch_ipi_writel(&s->ipi_core, CORE_SET_OFF, BIT(vector), 4); -+ return NULL; - } - --static void mail_send(uint64_t val) -+static MemTxResult mail_send(uint64_t val, MemTxAttrs attrs) - { - uint32_t cpuid; - hwaddr addr; -- CPULoongArchState *env; - CPUState *cs; -- LoongArchCPU *cpu; - - cpuid = extract32(val, 16, 10); - if (cpuid >= LOONGARCH_MAX_CPUS) { - trace_loongarch_ipi_unsupported_cpuid("IOCSR_MAIL_SEND", cpuid); -- return; -+ return MEMTX_DECODE_ERROR; - } - -- addr = 0x1020 + (val & 0x1c); - cs = ipi_getcpu(cpuid); -- cpu = LOONGARCH_CPU(cs); -- env = &cpu->env; -- send_ipi_data(env, val, addr); -+ if (cs == NULL) { -+ return MEMTX_DECODE_ERROR; -+ } -+ -+ /* override requester_id */ -+ addr = SMP_IPI_MAILBOX + CORE_BUF_20 + (val & 0x1c); -+ attrs.requester_id = cs->cpu_index; -+ send_ipi_data(&LOONGARCH_CPU(cs)->env, val, addr, attrs); -+ return MEMTX_OK; - } - --static void any_send(uint64_t val) -+static MemTxResult any_send(uint64_t val, MemTxAttrs attrs) - { - uint32_t cpuid; - hwaddr addr; -- CPULoongArchState *env; - CPUState *cs; -- LoongArchCPU *cpu; - - cpuid = extract32(val, 16, 10); - if (cpuid >= LOONGARCH_MAX_CPUS) { - trace_loongarch_ipi_unsupported_cpuid("IOCSR_ANY_SEND", cpuid); -- return; -+ return MEMTX_DECODE_ERROR; - } - -- addr = val & 0xffff; - cs = ipi_getcpu(cpuid); -- cpu = LOONGARCH_CPU(cs); -- env = &cpu->env; -- send_ipi_data(env, val, addr); -+ if (cs == NULL) { -+ return MEMTX_DECODE_ERROR; -+ } -+ -+ /* override requester_id */ -+ addr = val & 0xffff; -+ attrs.requester_id = cs->cpu_index; -+ send_ipi_data(&LOONGARCH_CPU(cs)->env, val, addr, attrs); -+ return MEMTX_OK; - } - --static void loongarch_ipi_writel(void *opaque, hwaddr addr, uint64_t val, -- unsigned size) -+static MemTxResult loongarch_ipi_writel(void *opaque, hwaddr addr, uint64_t val, -+ unsigned size, MemTxAttrs attrs) - { -- IPICore *s = opaque; -+ LoongArchIPI *ipi = opaque; -+ IPICore *s; - int index = 0; -+ uint32_t cpuid; -+ uint8_t vector; -+ CPUState *cs; - -+ s = &ipi->ipi_core; - addr &= 0xff; - trace_loongarch_ipi_write(size, (uint64_t)addr, val); - switch (addr) { -@@ -203,17 +199,35 @@ static void loongarch_ipi_writel(void *opaque, hwaddr addr, uint64_t val, - s->buf[index] = val; - break; - case IOCSR_IPI_SEND: -- ipi_send(val); -+ cpuid = extract32(val, 16, 10); -+ if (cpuid >= LOONGARCH_MAX_CPUS) { -+ trace_loongarch_ipi_unsupported_cpuid("IOCSR_IPI_SEND", cpuid); -+ return MEMTX_DECODE_ERROR; -+ } -+ -+ /* IPI status vector */ -+ vector = extract8(val, 0, 5); -+ cs = ipi_getcpu(cpuid); -+ if (cs == NULL) { -+ return MEMTX_DECODE_ERROR; -+ } -+ -+ /* override requester_id */ -+ attrs.requester_id = cs->cpu_index; -+ ipi = LOONGARCH_IPI(LOONGARCH_CPU(cs)->env.ipistate); -+ loongarch_ipi_writel(ipi, CORE_SET_OFF, BIT(vector), 4, attrs); - break; - default: - qemu_log_mask(LOG_UNIMP, "invalid write: %x", (uint32_t)addr); - break; - } -+ -+ return MEMTX_OK; - } - - static const MemoryRegionOps loongarch_ipi_ops = { -- .read = loongarch_ipi_readl, -- .write = loongarch_ipi_writel, -+ .read_with_attrs = loongarch_ipi_readl, -+ .write_with_attrs = loongarch_ipi_writel, - .impl.min_access_size = 4, - .impl.max_access_size = 4, - .valid.min_access_size = 4, -@@ -222,24 +236,28 @@ static const MemoryRegionOps loongarch_ipi_ops = { - }; - - /* mail send and any send only support writeq */ --static void loongarch_ipi_writeq(void *opaque, hwaddr addr, uint64_t val, -- unsigned size) -+static MemTxResult loongarch_ipi_writeq(void *opaque, hwaddr addr, uint64_t val, -+ unsigned size, MemTxAttrs attrs) - { -+ MemTxResult ret = MEMTX_OK; -+ - addr &= 0xfff; - switch (addr) { - case MAIL_SEND_OFFSET: -- mail_send(val); -+ ret = mail_send(val, attrs); - break; - case ANY_SEND_OFFSET: -- any_send(val); -+ ret = any_send(val, attrs); - break; - default: - break; - } -+ -+ return ret; - } - - static const MemoryRegionOps loongarch_ipi64_ops = { -- .write = loongarch_ipi_writeq, -+ .write_with_attrs = loongarch_ipi_writeq, - .impl.min_access_size = 8, - .impl.max_access_size = 8, - .valid.min_access_size = 8, -@@ -253,7 +271,7 @@ static void loongarch_ipi_init(Object *obj) - SysBusDevice *sbd = SYS_BUS_DEVICE(obj); - - memory_region_init_io(&s->ipi_iocsr_mem, obj, &loongarch_ipi_ops, -- &s->ipi_core, "loongarch_ipi_iocsr", 0x48); -+ s, "loongarch_ipi_iocsr", 0x48); - - /* loongarch_ipi_iocsr performs re-entrant IO through ipi_send */ - s->ipi_iocsr_mem.disable_reentrancy_guard = true; -@@ -261,7 +279,7 @@ static void loongarch_ipi_init(Object *obj) - sysbus_init_mmio(sbd, &s->ipi_iocsr_mem); - - memory_region_init_io(&s->ipi64_iocsr_mem, obj, &loongarch_ipi64_ops, -- &s->ipi_core, "loongarch_ipi64_iocsr", 0x118); -+ s, "loongarch_ipi64_iocsr", 0x118); - sysbus_init_mmio(sbd, &s->ipi64_iocsr_mem); - qdev_init_gpio_out(DEVICE(obj), &s->ipi_core.irq, 1); - } --- -2.33.0 - diff --git a/0019-hw-loongarch-virt-Set-iocsr-address-space-per-board-.patch b/0019-hw-loongarch-virt-Set-iocsr-address-space-per-board-.patch deleted file mode 100644 index 2af282db34fa2b0df1e598446994afb38f1985ae..0000000000000000000000000000000000000000 --- a/0019-hw-loongarch-virt-Set-iocsr-address-space-per-board-.patch +++ /dev/null @@ -1,558 +0,0 @@ -From 43100bba2bfd9de0c3bab7c3e815b02faa69242d Mon Sep 17 00:00:00 2001 -From: Bibo Mao -Date: Wed, 13 Dec 2023 12:13:14 +0800 -Subject: [PATCH] hw/loongarch/virt: Set iocsr address space per-board - rather than percpu - -LoongArch system has iocsr address space, most iocsr registers are -per-board, however some iocsr register spaces banked for percpu such -as ipi mailbox and extioi interrupt status. For banked iocsr space, -each cpu has the same iocsr space, but separate data. - -This patch changes iocsr address space per-board rather percpu, -for iocsr registers specified for cpu, MemTxAttrs.requester_id -can be parsed for the cpu. With this patches, the total address space -on board will be simple, only iocsr address space and system memory, -rather than the number of cpu and system memory. - -confict: - -+<<<<<<< HEAD - + .version_id = 1, - + .minimum_version_id = 1, - + .fields = (VMStateField[]) { - + VMSTATE_STRUCT(ipi_core, LoongArchIPI, 0, vmstate_ipi_core, IPICore), -++======= -+ .version_id = 2, -+ .minimum_version_id = 2, -+ .fields = (const VMStateField[]) { -+ VMSTATE_STRUCT_VARRAY_POINTER_UINT32(cpu, LoongArchIPI, num_cpu, -+ vmstate_ipi_core, IPICore), -++>>>>>>> hw/loongarch/virt: Set iocsr address space per-board rather than percpu - -solve: -save: hw/loongarch/virt: Set iocsr address space per-board rather than percpu - -Signed-off-by: Bibo Mao -Reviewed-by: Song Gao -Message-Id: <20231215100333.3933632-3-maobibo@loongson.cn> -Signed-off-by: Song Gao ---- - hw/intc/loongarch_extioi.c | 3 - - hw/intc/loongarch_ipi.c | 63 +++++++++++++++----- - hw/loongarch/virt.c | 91 +++++++++++++++++++++-------- - include/hw/intc/loongarch_extioi.h | 1 - - include/hw/intc/loongarch_ipi.h | 3 +- - include/hw/loongarch/virt.h | 3 + - target/loongarch/cpu.c | 48 --------------- - target/loongarch/cpu.h | 4 +- - target/loongarch/kvm/kvm.c | 2 +- - target/loongarch/tcg/iocsr_helper.c | 16 ++--- - 10 files changed, 129 insertions(+), 105 deletions(-) - -diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c -index 24fb3af8cc..77b4776958 100644 ---- a/hw/intc/loongarch_extioi.c -+++ b/hw/intc/loongarch_extioi.c -@@ -282,9 +282,6 @@ static void loongarch_extioi_instance_init(Object *obj) - qdev_init_gpio_in(DEVICE(obj), extioi_setirq, EXTIOI_IRQS); - - for (cpu = 0; cpu < EXTIOI_CPUS; cpu++) { -- memory_region_init_io(&s->extioi_iocsr_mem[cpu], OBJECT(s), &extioi_ops, -- s, "extioi_iocsr", 0x900); -- sysbus_init_mmio(dev, &s->extioi_iocsr_mem[cpu]); - for (pin = 0; pin < LS3A_INTC_IP; pin++) { - qdev_init_gpio_out(DEVICE(obj), &s->parent_irq[cpu][pin], 1); - } -diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c -index 221246c5cb..e228669aa5 100644 ---- a/hw/intc/loongarch_ipi.c -+++ b/hw/intc/loongarch_ipi.c -@@ -9,6 +9,7 @@ - #include "hw/sysbus.h" - #include "hw/intc/loongarch_ipi.h" - #include "hw/irq.h" -+#include "hw/qdev-properties.h" - #include "qapi/error.h" - #include "qemu/log.h" - #include "exec/address-spaces.h" -@@ -26,7 +27,7 @@ static MemTxResult loongarch_ipi_readl(void *opaque, hwaddr addr, - uint64_t ret = 0; - int index = 0; - -- s = &ipi->ipi_core; -+ s = &ipi->cpu[attrs.requester_id]; - addr &= 0xff; - switch (addr) { - case CORE_STATUS_OFF: -@@ -65,7 +66,7 @@ static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr, - * if the mask is 0, we need not to do anything. - */ - if ((val >> 27) & 0xf) { -- data = address_space_ldl(&env->address_space_iocsr, addr, -+ data = address_space_ldl(env->address_space_iocsr, addr, - attrs, NULL); - for (i = 0; i < 4; i++) { - /* get mask for byte writing */ -@@ -77,7 +78,7 @@ static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr, - - data &= mask; - data |= (val >> 32) & ~mask; -- address_space_stl(&env->address_space_iocsr, addr, -+ address_space_stl(env->address_space_iocsr, addr, - data, attrs, NULL); - } - -@@ -172,7 +173,7 @@ static MemTxResult loongarch_ipi_writel(void *opaque, hwaddr addr, uint64_t val, - uint8_t vector; - CPUState *cs; - -- s = &ipi->ipi_core; -+ s = &ipi->cpu[attrs.requester_id]; - addr &= 0xff; - trace_loongarch_ipi_write(size, (uint64_t)addr, val); - switch (addr) { -@@ -214,7 +215,6 @@ static MemTxResult loongarch_ipi_writel(void *opaque, hwaddr addr, uint64_t val, - - /* override requester_id */ - attrs.requester_id = cs->cpu_index; -- ipi = LOONGARCH_IPI(LOONGARCH_CPU(cs)->env.ipistate); - loongarch_ipi_writel(ipi, CORE_SET_OFF, BIT(vector), 4, attrs); - break; - default: -@@ -265,12 +265,18 @@ static const MemoryRegionOps loongarch_ipi64_ops = { - .endianness = DEVICE_LITTLE_ENDIAN, - }; - --static void loongarch_ipi_init(Object *obj) -+static void loongarch_ipi_realize(DeviceState *dev, Error **errp) - { -- LoongArchIPI *s = LOONGARCH_IPI(obj); -- SysBusDevice *sbd = SYS_BUS_DEVICE(obj); -+ LoongArchIPI *s = LOONGARCH_IPI(dev); -+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev); -+ int i; -+ -+ if (s->num_cpu == 0) { -+ error_setg(errp, "num-cpu must be at least 1"); -+ return; -+ } - -- memory_region_init_io(&s->ipi_iocsr_mem, obj, &loongarch_ipi_ops, -+ memory_region_init_io(&s->ipi_iocsr_mem, OBJECT(dev), &loongarch_ipi_ops, - s, "loongarch_ipi_iocsr", 0x48); - - /* loongarch_ipi_iocsr performs re-entrant IO through ipi_send */ -@@ -278,10 +284,20 @@ static void loongarch_ipi_init(Object *obj) - - sysbus_init_mmio(sbd, &s->ipi_iocsr_mem); - -- memory_region_init_io(&s->ipi64_iocsr_mem, obj, &loongarch_ipi64_ops, -+ memory_region_init_io(&s->ipi64_iocsr_mem, OBJECT(dev), -+ &loongarch_ipi64_ops, - s, "loongarch_ipi64_iocsr", 0x118); - sysbus_init_mmio(sbd, &s->ipi64_iocsr_mem); -- qdev_init_gpio_out(DEVICE(obj), &s->ipi_core.irq, 1); -+ -+ s->cpu = g_new0(IPICore, s->num_cpu); -+ if (s->cpu == NULL) { -+ error_setg(errp, "Memory allocation for ExtIOICore faile"); -+ return; -+ } -+ -+ for (i = 0; i < s->num_cpu; i++) { -+ qdev_init_gpio_out(dev, &s->cpu[i].irq, 1); -+ } - } - - static const VMStateDescription vmstate_ipi_core = { -@@ -300,27 +316,42 @@ static const VMStateDescription vmstate_ipi_core = { - - static const VMStateDescription vmstate_loongarch_ipi = { - .name = TYPE_LOONGARCH_IPI, -- .version_id = 1, -- .minimum_version_id = 1, -- .fields = (VMStateField[]) { -- VMSTATE_STRUCT(ipi_core, LoongArchIPI, 0, vmstate_ipi_core, IPICore), -+ .version_id = 2, -+ .minimum_version_id = 2, -+ .fields = (const VMStateField[]) { -+ VMSTATE_STRUCT_VARRAY_POINTER_UINT32(cpu, LoongArchIPI, num_cpu, -+ vmstate_ipi_core, IPICore), - VMSTATE_END_OF_LIST() - } - }; - -+static Property ipi_properties[] = { -+ DEFINE_PROP_UINT32("num-cpu", LoongArchIPI, num_cpu, 1), -+ DEFINE_PROP_END_OF_LIST(), -+}; -+ - static void loongarch_ipi_class_init(ObjectClass *klass, void *data) - { - DeviceClass *dc = DEVICE_CLASS(klass); - -+ dc->realize = loongarch_ipi_realize; -+ device_class_set_props(dc, ipi_properties); - dc->vmsd = &vmstate_loongarch_ipi; - } - -+static void loongarch_ipi_finalize(Object *obj) -+{ -+ LoongArchIPI *s = LOONGARCH_IPI(obj); -+ -+ g_free(s->cpu); -+} -+ - static const TypeInfo loongarch_ipi_info = { - .name = TYPE_LOONGARCH_IPI, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(LoongArchIPI), -- .instance_init = loongarch_ipi_init, - .class_init = loongarch_ipi_class_init, -+ .instance_finalize = loongarch_ipi_finalize, - }; - - static void loongarch_ipi_register_types(void) -diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c -index 4b7dc67a2d..13d19b6da3 100644 ---- a/hw/loongarch/virt.c -+++ b/hw/loongarch/virt.c -@@ -535,9 +535,6 @@ static void loongarch_irq_init(LoongArchMachineState *lams) - CPUState *cpu_state; - int cpu, pin, i, start, num; - -- extioi = qdev_new(TYPE_LOONGARCH_EXTIOI); -- sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi), &error_fatal); -- - /* - * The connection of interrupts: - * +-----+ +---------+ +-------+ -@@ -559,36 +556,36 @@ static void loongarch_irq_init(LoongArchMachineState *lams) - * | UARTs | | Devices | | Devices | - * +--------+ +---------+ +---------+ - */ -+ -+ /* Create IPI device */ -+ ipi = qdev_new(TYPE_LOONGARCH_IPI); -+ qdev_prop_set_uint32(ipi, "num-cpu", ms->smp.cpus); -+ sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal); -+ -+ /* IPI iocsr memory region */ -+ memory_region_add_subregion(&lams->system_iocsr, SMP_IPI_MAILBOX, -+ sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 0)); -+ memory_region_add_subregion(&lams->system_iocsr, MAIL_SEND_ADDR, -+ sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 1)); -+ - for (cpu = 0; cpu < ms->smp.cpus; cpu++) { - cpu_state = qemu_get_cpu(cpu); - cpudev = DEVICE(cpu_state); - lacpu = LOONGARCH_CPU(cpu_state); - env = &(lacpu->env); -- -- ipi = qdev_new(TYPE_LOONGARCH_IPI); -- sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal); -+ env->address_space_iocsr = &lams->as_iocsr; - - /* connect ipi irq to cpu irq */ -- qdev_connect_gpio_out(ipi, 0, qdev_get_gpio_in(cpudev, IRQ_IPI)); -- /* IPI iocsr memory region */ -- memory_region_add_subregion(&env->system_iocsr, SMP_IPI_MAILBOX, -- sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), -- 0)); -- memory_region_add_subregion(&env->system_iocsr, MAIL_SEND_ADDR, -- sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), -- 1)); -- /* -- * extioi iocsr memory region -- * only one extioi is added on loongarch virt machine -- * external device interrupt can only be routed to cpu 0-3 -- */ -- if (cpu < EXTIOI_CPUS) -- memory_region_add_subregion(&env->system_iocsr, APIC_BASE, -- sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), -- cpu)); -+ qdev_connect_gpio_out(ipi, cpu, qdev_get_gpio_in(cpudev, IRQ_IPI)); - env->ipistate = ipi; - } - -+ /* Create EXTIOI device */ -+ extioi = qdev_new(TYPE_LOONGARCH_EXTIOI); -+ sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi), &error_fatal); -+ memory_region_add_subregion(&lams->system_iocsr, APIC_BASE, -+ sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 0)); -+ - /* - * connect ext irq to the cpu irq - * cpu_pin[9:2] <= intc_pin[7:0] -@@ -733,6 +730,43 @@ static void loongarch_direct_kernel_boot(LoongArchMachineState *lams, - } - } - -+static void loongarch_qemu_write(void *opaque, hwaddr addr, -+ uint64_t val, unsigned size) -+{ -+} -+ -+static uint64_t loongarch_qemu_read(void *opaque, hwaddr addr, unsigned size) -+{ -+ switch (addr) { -+ case VERSION_REG: -+ return 0x11ULL; -+ case FEATURE_REG: -+ return 1ULL << IOCSRF_MSI | 1ULL << IOCSRF_EXTIOI | -+ 1ULL << IOCSRF_CSRIPI; -+ case VENDOR_REG: -+ return 0x6e6f73676e6f6f4cULL; /* "Loongson" */ -+ case CPUNAME_REG: -+ return 0x303030354133ULL; /* "3A5000" */ -+ case MISC_FUNC_REG: -+ return 1ULL << IOCSRM_EXTIOI_EN; -+ } -+ return 0ULL; -+} -+ -+static const MemoryRegionOps loongarch_qemu_ops = { -+ .read = loongarch_qemu_read, -+ .write = loongarch_qemu_write, -+ .endianness = DEVICE_LITTLE_ENDIAN, -+ .valid = { -+ .min_access_size = 4, -+ .max_access_size = 8, -+ }, -+ .impl = { -+ .min_access_size = 8, -+ .max_access_size = 8, -+ }, -+}; -+ - static void loongarch_init(MachineState *machine) - { - LoongArchCPU *lacpu; -@@ -761,8 +795,17 @@ static void loongarch_init(MachineState *machine) - exit(1); - } - create_fdt(lams); -- /* Init CPUs */ - -+ /* Create IOCSR space */ -+ memory_region_init_io(&lams->system_iocsr, OBJECT(machine), NULL, -+ machine, "iocsr", UINT64_MAX); -+ address_space_init(&lams->as_iocsr, &lams->system_iocsr, "IOCSR"); -+ memory_region_init_io(&lams->iocsr_mem, OBJECT(machine), -+ &loongarch_qemu_ops, -+ machine, "iocsr_misc", 0x428); -+ memory_region_add_subregion(&lams->system_iocsr, 0, &lams->iocsr_mem); -+ -+ /* Init CPUs */ - possible_cpus = mc->possible_cpu_arch_ids(machine); - for (i = 0; i < possible_cpus->len; i++) { - cpu = cpu_create(machine->cpu_type); -diff --git a/include/hw/intc/loongarch_extioi.h b/include/hw/intc/loongarch_extioi.h -index fbdef9a7b3..110e5e8873 100644 ---- a/include/hw/intc/loongarch_extioi.h -+++ b/include/hw/intc/loongarch_extioi.h -@@ -58,7 +58,6 @@ struct LoongArchExtIOI { - uint8_t sw_coremap[EXTIOI_IRQS]; - qemu_irq parent_irq[EXTIOI_CPUS][LS3A_INTC_IP]; - qemu_irq irq[EXTIOI_IRQS]; -- MemoryRegion extioi_iocsr_mem[EXTIOI_CPUS]; - MemoryRegion extioi_system_mem; - }; - #endif /* LOONGARCH_EXTIOI_H */ -diff --git a/include/hw/intc/loongarch_ipi.h b/include/hw/intc/loongarch_ipi.h -index 6c6194786e..1c1e834849 100644 ---- a/include/hw/intc/loongarch_ipi.h -+++ b/include/hw/intc/loongarch_ipi.h -@@ -47,7 +47,8 @@ struct LoongArchIPI { - SysBusDevice parent_obj; - MemoryRegion ipi_iocsr_mem; - MemoryRegion ipi64_iocsr_mem; -- IPICore ipi_core; -+ uint32_t num_cpu; -+ IPICore *cpu; - }; - - #endif -diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h -index db0831b471..6ef9a92394 100644 ---- a/include/hw/loongarch/virt.h -+++ b/include/hw/loongarch/virt.h -@@ -50,6 +50,9 @@ struct LoongArchMachineState { - DeviceState *platform_bus_dev; - PCIBus *pci_bus; - PFlashCFI01 *flash; -+ MemoryRegion system_iocsr; -+ MemoryRegion iocsr_mem; -+ AddressSpace as_iocsr; - }; - - #define TYPE_LOONGARCH_MACHINE MACHINE_TYPE_NAME("virt") -diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c -index 413414392b..6611d137a1 100644 ---- a/target/loongarch/cpu.c -+++ b/target/loongarch/cpu.c -@@ -602,47 +602,6 @@ static void loongarch_cpu_realizefn(DeviceState *dev, Error **errp) - lacc->parent_realize(dev, errp); - } - --#ifndef CONFIG_USER_ONLY --static void loongarch_qemu_write(void *opaque, hwaddr addr, -- uint64_t val, unsigned size) --{ -- qemu_log_mask(LOG_UNIMP, "[%s]: Unimplemented reg 0x%" HWADDR_PRIx "\n", -- __func__, addr); --} -- --static uint64_t loongarch_qemu_read(void *opaque, hwaddr addr, unsigned size) --{ -- switch (addr) { -- case VERSION_REG: -- return 0x11ULL; -- case FEATURE_REG: -- return 1ULL << IOCSRF_MSI | 1ULL << IOCSRF_EXTIOI | -- 1ULL << IOCSRF_CSRIPI; -- case VENDOR_REG: -- return 0x6e6f73676e6f6f4cULL; /* "Loongson" */ -- case CPUNAME_REG: -- return 0x303030354133ULL; /* "3A5000" */ -- case MISC_FUNC_REG: -- return 1ULL << IOCSRM_EXTIOI_EN; -- } -- return 0ULL; --} -- --static const MemoryRegionOps loongarch_qemu_ops = { -- .read = loongarch_qemu_read, -- .write = loongarch_qemu_write, -- .endianness = DEVICE_LITTLE_ENDIAN, -- .valid = { -- .min_access_size = 4, -- .max_access_size = 8, -- }, -- .impl = { -- .min_access_size = 8, -- .max_access_size = 8, -- }, --}; --#endif -- - static bool loongarch_get_lsx(Object *obj, Error **errp) - { - LoongArchCPU *cpu = LOONGARCH_CPU(obj); -@@ -713,19 +672,12 @@ static void loongarch_cpu_init(Object *obj) - { - #ifndef CONFIG_USER_ONLY - LoongArchCPU *cpu = LOONGARCH_CPU(obj); -- CPULoongArchState *env = &cpu->env; - - qdev_init_gpio_in(DEVICE(cpu), loongarch_cpu_set_irq, N_IRQS); - #ifdef CONFIG_TCG - timer_init_ns(&cpu->timer, QEMU_CLOCK_VIRTUAL, - &loongarch_constant_timer_cb, cpu); - #endif -- memory_region_init_io(&env->system_iocsr, OBJECT(cpu), NULL, -- env, "iocsr", UINT64_MAX); -- address_space_init(&env->address_space_iocsr, &env->system_iocsr, "IOCSR"); -- memory_region_init_io(&env->iocsr_mem, OBJECT(cpu), &loongarch_qemu_ops, -- NULL, "iocsr_misc", 0x428); -- memory_region_add_subregion(&env->system_iocsr, 0, &env->iocsr_mem); - #endif - } - -diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h -index 8ebd6fa1a7..4aba8aba4c 100644 ---- a/target/loongarch/cpu.h -+++ b/target/loongarch/cpu.h -@@ -355,9 +355,7 @@ typedef struct CPUArchState { - #ifndef CONFIG_USER_ONLY - LoongArchTLB tlb[LOONGARCH_TLB_MAX]; - -- AddressSpace address_space_iocsr; -- MemoryRegion system_iocsr; -- MemoryRegion iocsr_mem; -+ AddressSpace *address_space_iocsr; - bool load_elf; - uint64_t elf_address; - uint32_t mp_state; -diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c -index bd33ec2114..84bcdf5f86 100644 ---- a/target/loongarch/kvm/kvm.c -+++ b/target/loongarch/kvm/kvm.c -@@ -733,7 +733,7 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) - trace_kvm_arch_handle_exit(run->exit_reason); - switch (run->exit_reason) { - case KVM_EXIT_LOONGARCH_IOCSR: -- address_space_rw(&env->address_space_iocsr, -+ address_space_rw(env->address_space_iocsr, - run->iocsr_io.phys_addr, - attrs, - run->iocsr_io.data, -diff --git a/target/loongarch/tcg/iocsr_helper.c b/target/loongarch/tcg/iocsr_helper.c -index 6cd01d5f09..b6916f53d2 100644 ---- a/target/loongarch/tcg/iocsr_helper.c -+++ b/target/loongarch/tcg/iocsr_helper.c -@@ -17,52 +17,52 @@ - - uint64_t helper_iocsrrd_b(CPULoongArchState *env, target_ulong r_addr) - { -- return address_space_ldub(&env->address_space_iocsr, r_addr, -+ return address_space_ldub(env->address_space_iocsr, r_addr, - GET_MEMTXATTRS(env), NULL); - } - - uint64_t helper_iocsrrd_h(CPULoongArchState *env, target_ulong r_addr) - { -- return address_space_lduw(&env->address_space_iocsr, r_addr, -+ return address_space_lduw(env->address_space_iocsr, r_addr, - GET_MEMTXATTRS(env), NULL); - } - - uint64_t helper_iocsrrd_w(CPULoongArchState *env, target_ulong r_addr) - { -- return address_space_ldl(&env->address_space_iocsr, r_addr, -+ return address_space_ldl(env->address_space_iocsr, r_addr, - GET_MEMTXATTRS(env), NULL); - } - - uint64_t helper_iocsrrd_d(CPULoongArchState *env, target_ulong r_addr) - { -- return address_space_ldq(&env->address_space_iocsr, r_addr, -+ return address_space_ldq(env->address_space_iocsr, r_addr, - GET_MEMTXATTRS(env), NULL); - } - - void helper_iocsrwr_b(CPULoongArchState *env, target_ulong w_addr, - target_ulong val) - { -- address_space_stb(&env->address_space_iocsr, w_addr, -+ address_space_stb(env->address_space_iocsr, w_addr, - val, GET_MEMTXATTRS(env), NULL); - } - - void helper_iocsrwr_h(CPULoongArchState *env, target_ulong w_addr, - target_ulong val) - { -- address_space_stw(&env->address_space_iocsr, w_addr, -+ address_space_stw(env->address_space_iocsr, w_addr, - val, GET_MEMTXATTRS(env), NULL); - } - - void helper_iocsrwr_w(CPULoongArchState *env, target_ulong w_addr, - target_ulong val) - { -- address_space_stl(&env->address_space_iocsr, w_addr, -+ address_space_stl(env->address_space_iocsr, w_addr, - val, GET_MEMTXATTRS(env), NULL); - } - - void helper_iocsrwr_d(CPULoongArchState *env, target_ulong w_addr, - target_ulong val) - { -- address_space_stq(&env->address_space_iocsr, w_addr, -+ address_space_stq(env->address_space_iocsr, w_addr, - val, GET_MEMTXATTRS(env), NULL); - } --- -2.33.0 - diff --git a/0020-hw-intc-loongarch_extioi-Add-dynamic-cpu-number-supp.patch b/0020-hw-intc-loongarch_extioi-Add-dynamic-cpu-number-supp.patch deleted file mode 100644 index 110b4e6f7369e42d8fc046ef463fb92bca8dbcaa..0000000000000000000000000000000000000000 --- a/0020-hw-intc-loongarch_extioi-Add-dynamic-cpu-number-supp.patch +++ /dev/null @@ -1,298 +0,0 @@ -From 4440ab99f7f7b04ef79f6b35b8330edf7fe66002 Mon Sep 17 00:00:00 2001 -From: Bibo Mao -Date: Fri, 15 Dec 2023 11:07:36 +0800 -Subject: [PATCH] hw/intc/loongarch_extioi: Add dynamic cpu number - support - -On LoongArch physical machine, one extioi interrupt controller only -supports 4 cpus. With processor more than 4 cpus, there are multiple -extioi interrupt controllers; if interrupts need to be routed to -other cpus, they are forwarded from extioi node0 to other extioi nodes. - -On virt machine model, there is simple extioi interrupt device model. -All cpus can access register of extioi interrupt controller, however -interrupt can only be route to 4 vcpu for compatible with old kernel. - -This patch adds dynamic cpu number support about extioi interrupt. -With old kernel legacy extioi model is used, however kernel can detect -and choose new route method in future, so that interrupt can be routed to -all vcpus. - -confict: - -++<<<<<<< HEAD - + .fields = (VMStateField[]) { -++======= -+ .fields = (const VMStateField[]) { -+ VMSTATE_UINT32_ARRAY(coreisr, ExtIOICore, EXTIOI_IRQS_GROUP_COUNT), -+ VMSTATE_END_OF_LIST() -+ } -+ }; -+ -+ static const VMStateDescription vmstate_loongarch_extioi = { -+ .name = TYPE_LOONGARCH_EXTIOI, -+ .version_id = 2, -+ .minimum_version_id = 2, -+ .fields = (const VMStateField[]) { -++>>>>>>> hw/intc/loongarch_extioi: Add dynamic cpu number support - -solve: - -save: hw/intc/loongarch_extioi: Add dynamic cpu number support - -Signed-off-by: Bibo Mao -Reviewed-by: Song Gao -Message-Id: <20231215100333.3933632-4-maobibo@loongson.cn> -Signed-off-by: Song Gao ---- - hw/intc/loongarch_extioi.c | 109 +++++++++++++++++++---------- - hw/loongarch/virt.c | 3 +- - include/hw/intc/loongarch_extioi.h | 11 ++- - 3 files changed, 82 insertions(+), 41 deletions(-) - -diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c -index 77b4776958..28802bf3ef 100644 ---- a/hw/intc/loongarch_extioi.c -+++ b/hw/intc/loongarch_extioi.c -@@ -8,6 +8,7 @@ - #include "qemu/osdep.h" - #include "qemu/module.h" - #include "qemu/log.h" -+#include "qapi/error.h" - #include "hw/irq.h" - #include "hw/sysbus.h" - #include "hw/loongarch/virt.h" -@@ -32,23 +33,23 @@ static void extioi_update_irq(LoongArchExtIOI *s, int irq, int level) - if (((s->enable[irq_index]) & irq_mask) == 0) { - return; - } -- s->coreisr[cpu][irq_index] |= irq_mask; -- found = find_first_bit(s->sw_isr[cpu][ipnum], EXTIOI_IRQS); -- set_bit(irq, s->sw_isr[cpu][ipnum]); -+ s->cpu[cpu].coreisr[irq_index] |= irq_mask; -+ found = find_first_bit(s->cpu[cpu].sw_isr[ipnum], EXTIOI_IRQS); -+ set_bit(irq, s->cpu[cpu].sw_isr[ipnum]); - if (found < EXTIOI_IRQS) { - /* other irq is handling, need not update parent irq level */ - return; - } - } else { -- s->coreisr[cpu][irq_index] &= ~irq_mask; -- clear_bit(irq, s->sw_isr[cpu][ipnum]); -- found = find_first_bit(s->sw_isr[cpu][ipnum], EXTIOI_IRQS); -+ s->cpu[cpu].coreisr[irq_index] &= ~irq_mask; -+ clear_bit(irq, s->cpu[cpu].sw_isr[ipnum]); -+ found = find_first_bit(s->cpu[cpu].sw_isr[ipnum], EXTIOI_IRQS); - if (found < EXTIOI_IRQS) { - /* other irq is handling, need not update parent irq level */ - return; - } - } -- qemu_set_irq(s->parent_irq[cpu][ipnum], level); -+ qemu_set_irq(s->cpu[cpu].parent_irq[ipnum], level); - } - - static void extioi_setirq(void *opaque, int irq, int level) -@@ -96,7 +97,7 @@ static MemTxResult extioi_readw(void *opaque, hwaddr addr, uint64_t *data, - index = (offset - EXTIOI_COREISR_START) >> 2; - /* using attrs to get current cpu index */ - cpu = attrs.requester_id; -- *data = s->coreisr[cpu][index]; -+ *data = s->cpu[cpu].coreisr[index]; - break; - case EXTIOI_COREMAP_START ... EXTIOI_COREMAP_END - 1: - index = (offset - EXTIOI_COREMAP_START) >> 2; -@@ -189,8 +190,8 @@ static MemTxResult extioi_writew(void *opaque, hwaddr addr, - index = (offset - EXTIOI_COREISR_START) >> 2; - /* using attrs to get current cpu index */ - cpu = attrs.requester_id; -- old_data = s->coreisr[cpu][index]; -- s->coreisr[cpu][index] = old_data & ~val; -+ old_data = s->cpu[cpu].coreisr[index]; -+ s->cpu[cpu].coreisr[index] = old_data & ~val; - /* write 1 to clear interrupt */ - old_data &= val; - irq = ctz32(old_data); -@@ -248,14 +249,61 @@ static const MemoryRegionOps extioi_ops = { - .endianness = DEVICE_LITTLE_ENDIAN, - }; - --static const VMStateDescription vmstate_loongarch_extioi = { -- .name = TYPE_LOONGARCH_EXTIOI, -+static void loongarch_extioi_realize(DeviceState *dev, Error **errp) -+{ -+ LoongArchExtIOI *s = LOONGARCH_EXTIOI(dev); -+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev); -+ int i, pin; -+ -+ if (s->num_cpu == 0) { -+ error_setg(errp, "num-cpu must be at least 1"); -+ return; -+ } -+ -+ for (i = 0; i < EXTIOI_IRQS; i++) { -+ sysbus_init_irq(sbd, &s->irq[i]); -+ } -+ -+ qdev_init_gpio_in(dev, extioi_setirq, EXTIOI_IRQS); -+ memory_region_init_io(&s->extioi_system_mem, OBJECT(s), &extioi_ops, -+ s, "extioi_system_mem", 0x900); -+ sysbus_init_mmio(sbd, &s->extioi_system_mem); -+ s->cpu = g_new0(ExtIOICore, s->num_cpu); -+ if (s->cpu == NULL) { -+ error_setg(errp, "Memory allocation for ExtIOICore faile"); -+ return; -+ } -+ -+ for (i = 0; i < s->num_cpu; i++) { -+ for (pin = 0; pin < LS3A_INTC_IP; pin++) { -+ qdev_init_gpio_out(dev, &s->cpu[i].parent_irq[pin], 1); -+ } -+ } -+} -+ -+static void loongarch_extioi_finalize(Object *obj) -+{ -+ LoongArchExtIOI *s = LOONGARCH_EXTIOI(obj); -+ -+ g_free(s->cpu); -+} -+ -+static const VMStateDescription vmstate_extioi_core = { -+ .name = "extioi-core", - .version_id = 1, - .minimum_version_id = 1, -- .fields = (VMStateField[]) { -+ .fields = (const VMStateField[]) { -+ VMSTATE_UINT32_ARRAY(coreisr, ExtIOICore, EXTIOI_IRQS_GROUP_COUNT), -+ VMSTATE_END_OF_LIST() -+ } -+}; -+ -+static const VMStateDescription vmstate_loongarch_extioi = { -+ .name = TYPE_LOONGARCH_EXTIOI, -+ .version_id = 2, -+ .minimum_version_id = 2, -+ .fields = (const VMStateField[]) { - VMSTATE_UINT32_ARRAY(bounce, LoongArchExtIOI, EXTIOI_IRQS_GROUP_COUNT), -- VMSTATE_UINT32_2DARRAY(coreisr, LoongArchExtIOI, EXTIOI_CPUS, -- EXTIOI_IRQS_GROUP_COUNT), - VMSTATE_UINT32_ARRAY(nodetype, LoongArchExtIOI, - EXTIOI_IRQS_NODETYPE_COUNT / 2), - VMSTATE_UINT32_ARRAY(enable, LoongArchExtIOI, EXTIOI_IRQS / 32), -@@ -265,45 +313,32 @@ static const VMStateDescription vmstate_loongarch_extioi = { - VMSTATE_UINT8_ARRAY(sw_ipmap, LoongArchExtIOI, EXTIOI_IRQS_IPMAP_SIZE), - VMSTATE_UINT8_ARRAY(sw_coremap, LoongArchExtIOI, EXTIOI_IRQS), - -+ VMSTATE_STRUCT_VARRAY_POINTER_UINT32(cpu, LoongArchExtIOI, num_cpu, -+ vmstate_extioi_core, ExtIOICore), - VMSTATE_END_OF_LIST() - } - }; - --static void loongarch_extioi_instance_init(Object *obj) --{ -- SysBusDevice *dev = SYS_BUS_DEVICE(obj); -- LoongArchExtIOI *s = LOONGARCH_EXTIOI(obj); -- int i, cpu, pin; -- -- for (i = 0; i < EXTIOI_IRQS; i++) { -- sysbus_init_irq(dev, &s->irq[i]); -- } -- -- qdev_init_gpio_in(DEVICE(obj), extioi_setirq, EXTIOI_IRQS); -- -- for (cpu = 0; cpu < EXTIOI_CPUS; cpu++) { -- for (pin = 0; pin < LS3A_INTC_IP; pin++) { -- qdev_init_gpio_out(DEVICE(obj), &s->parent_irq[cpu][pin], 1); -- } -- } -- memory_region_init_io(&s->extioi_system_mem, OBJECT(s), &extioi_ops, -- s, "extioi_system_mem", 0x900); -- sysbus_init_mmio(dev, &s->extioi_system_mem); --} -+static Property extioi_properties[] = { -+ DEFINE_PROP_UINT32("num-cpu", LoongArchExtIOI, num_cpu, 1), -+ DEFINE_PROP_END_OF_LIST(), -+}; - - static void loongarch_extioi_class_init(ObjectClass *klass, void *data) - { - DeviceClass *dc = DEVICE_CLASS(klass); - -+ dc->realize = loongarch_extioi_realize; -+ device_class_set_props(dc, extioi_properties); - dc->vmsd = &vmstate_loongarch_extioi; - } - - static const TypeInfo loongarch_extioi_info = { - .name = TYPE_LOONGARCH_EXTIOI, - .parent = TYPE_SYS_BUS_DEVICE, -- .instance_init = loongarch_extioi_instance_init, - .instance_size = sizeof(struct LoongArchExtIOI), - .class_init = loongarch_extioi_class_init, -+ .instance_finalize = loongarch_extioi_finalize, - }; - - static void loongarch_extioi_register_types(void) -diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c -index 13d19b6da3..c9a680e61a 100644 ---- a/hw/loongarch/virt.c -+++ b/hw/loongarch/virt.c -@@ -582,6 +582,7 @@ static void loongarch_irq_init(LoongArchMachineState *lams) - - /* Create EXTIOI device */ - extioi = qdev_new(TYPE_LOONGARCH_EXTIOI); -+ qdev_prop_set_uint32(extioi, "num-cpu", ms->smp.cpus); - sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi), &error_fatal); - memory_region_add_subregion(&lams->system_iocsr, APIC_BASE, - sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 0)); -@@ -590,7 +591,7 @@ static void loongarch_irq_init(LoongArchMachineState *lams) - * connect ext irq to the cpu irq - * cpu_pin[9:2] <= intc_pin[7:0] - */ -- for (cpu = 0; cpu < MIN(ms->smp.cpus, EXTIOI_CPUS); cpu++) { -+ for (cpu = 0; cpu < ms->smp.cpus; cpu++) { - cpudev = DEVICE(qemu_get_cpu(cpu)); - for (pin = 0; pin < LS3A_INTC_IP; pin++) { - qdev_connect_gpio_out(extioi, (cpu * 8 + pin), -diff --git a/include/hw/intc/loongarch_extioi.h b/include/hw/intc/loongarch_extioi.h -index 110e5e8873..a0a46b888c 100644 ---- a/include/hw/intc/loongarch_extioi.h -+++ b/include/hw/intc/loongarch_extioi.h -@@ -40,24 +40,29 @@ - #define EXTIOI_COREMAP_START (0xC00 - APIC_OFFSET) - #define EXTIOI_COREMAP_END (0xD00 - APIC_OFFSET) - -+typedef struct ExtIOICore { -+ uint32_t coreisr[EXTIOI_IRQS_GROUP_COUNT]; -+ DECLARE_BITMAP(sw_isr[LS3A_INTC_IP], EXTIOI_IRQS); -+ qemu_irq parent_irq[LS3A_INTC_IP]; -+} ExtIOICore; -+ - #define TYPE_LOONGARCH_EXTIOI "loongarch.extioi" - OBJECT_DECLARE_SIMPLE_TYPE(LoongArchExtIOI, LOONGARCH_EXTIOI) - struct LoongArchExtIOI { - SysBusDevice parent_obj; -+ uint32_t num_cpu; - /* hardware state */ - uint32_t nodetype[EXTIOI_IRQS_NODETYPE_COUNT / 2]; - uint32_t bounce[EXTIOI_IRQS_GROUP_COUNT]; - uint32_t isr[EXTIOI_IRQS / 32]; -- uint32_t coreisr[EXTIOI_CPUS][EXTIOI_IRQS_GROUP_COUNT]; - uint32_t enable[EXTIOI_IRQS / 32]; - uint32_t ipmap[EXTIOI_IRQS_IPMAP_SIZE / 4]; - uint32_t coremap[EXTIOI_IRQS / 4]; - uint32_t sw_pending[EXTIOI_IRQS / 32]; -- DECLARE_BITMAP(sw_isr[EXTIOI_CPUS][LS3A_INTC_IP], EXTIOI_IRQS); - uint8_t sw_ipmap[EXTIOI_IRQS_IPMAP_SIZE]; - uint8_t sw_coremap[EXTIOI_IRQS]; -- qemu_irq parent_irq[EXTIOI_CPUS][LS3A_INTC_IP]; - qemu_irq irq[EXTIOI_IRQS]; -+ ExtIOICore *cpu; - MemoryRegion extioi_system_mem; - }; - #endif /* LOONGARCH_EXTIOI_H */ --- -2.33.0 - diff --git a/0021-hw-intc-loongarch_extioi-Add-vmstate-post_load-suppo.patch b/0021-hw-intc-loongarch_extioi-Add-vmstate-post_load-suppo.patch deleted file mode 100644 index 45385d3daba4738aec1a83ca1f15554c469ea804..0000000000000000000000000000000000000000 --- a/0021-hw-intc-loongarch_extioi-Add-vmstate-post_load-suppo.patch +++ /dev/null @@ -1,193 +0,0 @@ -From db8c355d923c218c5ca373c4acd5d13493152889 Mon Sep 17 00:00:00 2001 -From: Bibo Mao -Date: Fri, 15 Dec 2023 17:42:58 +0800 -Subject: [PATCH] hw/intc/loongarch_extioi: Add vmstate post_load support - -There are elements sw_ipmap and sw_coremap, which is usd to speed -up irq injection flow. They are saved and restored in vmstate during -migration, indeed they can calculated from hw registers. Here -post_load is added for get sw_ipmap and sw_coremap from extioi hw -state. - -Signed-off-by: Bibo Mao -Reviewed-by: Song Gao -Message-Id: <20231215100333.3933632-5-maobibo@loongson.cn> -Signed-off-by: Song Gao ---- - hw/intc/loongarch_extioi.c | 120 +++++++++++++++++++++++-------------- - 1 file changed, 76 insertions(+), 44 deletions(-) - -diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c -index 28802bf3ef..bdfa3b481e 100644 ---- a/hw/intc/loongarch_extioi.c -+++ b/hw/intc/loongarch_extioi.c -@@ -130,12 +130,66 @@ static inline void extioi_enable_irq(LoongArchExtIOI *s, int index,\ - } - } - -+static inline void extioi_update_sw_coremap(LoongArchExtIOI *s, int irq, -+ uint64_t val, bool notify) -+{ -+ int i, cpu; -+ -+ /* -+ * loongarch only support little endian, -+ * so we paresd the value with little endian. -+ */ -+ val = cpu_to_le64(val); -+ -+ for (i = 0; i < 4; i++) { -+ cpu = val & 0xff; -+ cpu = ctz32(cpu); -+ cpu = (cpu >= 4) ? 0 : cpu; -+ val = val >> 8; -+ -+ if (s->sw_coremap[irq + i] == cpu) { -+ continue; -+ } -+ -+ if (notify && test_bit(irq, (unsigned long *)s->isr)) { -+ /* -+ * lower irq at old cpu and raise irq at new cpu -+ */ -+ extioi_update_irq(s, irq + i, 0); -+ s->sw_coremap[irq + i] = cpu; -+ extioi_update_irq(s, irq + i, 1); -+ } else { -+ s->sw_coremap[irq + i] = cpu; -+ } -+ } -+} -+ -+static inline void extioi_update_sw_ipmap(LoongArchExtIOI *s, int index, -+ uint64_t val) -+{ -+ int i; -+ uint8_t ipnum; -+ -+ /* -+ * loongarch only support little endian, -+ * so we paresd the value with little endian. -+ */ -+ val = cpu_to_le64(val); -+ for (i = 0; i < 4; i++) { -+ ipnum = val & 0xff; -+ ipnum = ctz32(ipnum); -+ ipnum = (ipnum >= 4) ? 0 : ipnum; -+ s->sw_ipmap[index * 4 + i] = ipnum; -+ val = val >> 8; -+ } -+} -+ - static MemTxResult extioi_writew(void *opaque, hwaddr addr, - uint64_t val, unsigned size, - MemTxAttrs attrs) - { - LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque); -- int i, cpu, index, old_data, irq; -+ int cpu, index, old_data, irq; - uint32_t offset; - - trace_loongarch_extioi_writew(addr, val); -@@ -153,20 +207,7 @@ static MemTxResult extioi_writew(void *opaque, hwaddr addr, - */ - index = (offset - EXTIOI_IPMAP_START) >> 2; - s->ipmap[index] = val; -- /* -- * loongarch only support little endian, -- * so we paresd the value with little endian. -- */ -- val = cpu_to_le64(val); -- for (i = 0; i < 4; i++) { -- uint8_t ipnum; -- ipnum = val & 0xff; -- ipnum = ctz32(ipnum); -- ipnum = (ipnum >= 4) ? 0 : ipnum; -- s->sw_ipmap[index * 4 + i] = ipnum; -- val = val >> 8; -- } -- -+ extioi_update_sw_ipmap(s, index, val); - break; - case EXTIOI_ENABLE_START ... EXTIOI_ENABLE_END - 1: - index = (offset - EXTIOI_ENABLE_START) >> 2; -@@ -205,33 +246,8 @@ static MemTxResult extioi_writew(void *opaque, hwaddr addr, - irq = offset - EXTIOI_COREMAP_START; - index = irq / 4; - s->coremap[index] = val; -- /* -- * loongarch only support little endian, -- * so we paresd the value with little endian. -- */ -- val = cpu_to_le64(val); -- -- for (i = 0; i < 4; i++) { -- cpu = val & 0xff; -- cpu = ctz32(cpu); -- cpu = (cpu >= 4) ? 0 : cpu; -- val = val >> 8; -- -- if (s->sw_coremap[irq + i] == cpu) { -- continue; -- } -- -- if (test_bit(irq, (unsigned long *)s->isr)) { -- /* -- * lower irq at old cpu and raise irq at new cpu -- */ -- extioi_update_irq(s, irq + i, 0); -- s->sw_coremap[irq + i] = cpu; -- extioi_update_irq(s, irq + i, 1); -- } else { -- s->sw_coremap[irq + i] = cpu; -- } -- } -+ -+ extioi_update_sw_coremap(s, irq, val, true); - break; - default: - break; -@@ -288,6 +304,23 @@ static void loongarch_extioi_finalize(Object *obj) - g_free(s->cpu); - } - -+static int vmstate_extioi_post_load(void *opaque, int version_id) -+{ -+ LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque); -+ int i, start_irq; -+ -+ for (i = 0; i < (EXTIOI_IRQS / 4); i++) { -+ start_irq = i * 4; -+ extioi_update_sw_coremap(s, start_irq, s->coremap[i], false); -+ } -+ -+ for (i = 0; i < (EXTIOI_IRQS_IPMAP_SIZE / 4); i++) { -+ extioi_update_sw_ipmap(s, i, s->ipmap[i]); -+ } -+ -+ return 0; -+} -+ - static const VMStateDescription vmstate_extioi_core = { - .name = "extioi-core", - .version_id = 1, -@@ -302,6 +335,7 @@ static const VMStateDescription vmstate_loongarch_extioi = { - .name = TYPE_LOONGARCH_EXTIOI, - .version_id = 2, - .minimum_version_id = 2, -+ .post_load = vmstate_extioi_post_load, - .fields = (const VMStateField[]) { - VMSTATE_UINT32_ARRAY(bounce, LoongArchExtIOI, EXTIOI_IRQS_GROUP_COUNT), - VMSTATE_UINT32_ARRAY(nodetype, LoongArchExtIOI, -@@ -310,8 +344,6 @@ static const VMStateDescription vmstate_loongarch_extioi = { - VMSTATE_UINT32_ARRAY(isr, LoongArchExtIOI, EXTIOI_IRQS / 32), - VMSTATE_UINT32_ARRAY(ipmap, LoongArchExtIOI, EXTIOI_IRQS_IPMAP_SIZE / 4), - VMSTATE_UINT32_ARRAY(coremap, LoongArchExtIOI, EXTIOI_IRQS / 4), -- VMSTATE_UINT8_ARRAY(sw_ipmap, LoongArchExtIOI, EXTIOI_IRQS_IPMAP_SIZE), -- VMSTATE_UINT8_ARRAY(sw_coremap, LoongArchExtIOI, EXTIOI_IRQS), - - VMSTATE_STRUCT_VARRAY_POINTER_UINT32(cpu, LoongArchExtIOI, num_cpu, - vmstate_extioi_core, ExtIOICore), --- -2.33.0 - diff --git a/0022-configure-Add-linux-header-compile-support-for-Loong.patch b/0022-configure-Add-linux-header-compile-support-for-Loong.patch deleted file mode 100644 index ceb5a37de9380bc59271514a63f046fa4bc36650..0000000000000000000000000000000000000000 --- a/0022-configure-Add-linux-header-compile-support-for-Loong.patch +++ /dev/null @@ -1,41 +0,0 @@ -From b21a705562867cc9dcbf0012ffa200caad8458ba Mon Sep 17 00:00:00 2001 -From: Bibo Mao -Date: Tue, 16 Jan 2024 09:39:52 +0800 -Subject: [PATCH] configure: Add linux header compile support for - LoongArch -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -When compiling qemu with system KVM mode for LoongArch, header files -in directory linux-headers/asm-loongarch should be used firstly. -Otherwise it fails to find kvm.h on system with old glibc, since -latest kernel header files are not installed. - -This patch adds linux_arch definition for LoongArch system so that -header files in directory linux-headers/asm-loongarch can be included. - -Fixes: 714b03c125 ("target/loongarch: Add loongarch kvm into meson build") -Signed-off-by: Bibo Mao -Reviewed-by: Philippe Mathieu-Daudé -Message-ID: <20240116013952.264474-1-maobibo@loongson.cn> -Signed-off-by: Philippe Mathieu-Daudé ---- - configure | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/configure b/configure -index bdda912f36..6036de83a4 100755 ---- a/configure -+++ b/configure -@@ -445,6 +445,7 @@ case "$cpu" in - loongarch*) - cpu=loongarch64 - host_arch=loongarch64 -+ linux_arch=loongarch - ;; - - mips64*) --- -2.33.0 - diff --git a/0023-target-loongarch-Set-cpuid-CSR-register-only-once-wi.patch b/0023-target-loongarch-Set-cpuid-CSR-register-only-once-wi.patch deleted file mode 100644 index e008764d76f3a8aa130eca6d0d5b28b1ee1e93ce..0000000000000000000000000000000000000000 --- a/0023-target-loongarch-Set-cpuid-CSR-register-only-once-wi.patch +++ /dev/null @@ -1,57 +0,0 @@ -From d271f623205c2984a30cfb12e160e219b2bbe974 Mon Sep 17 00:00:00 2001 -From: Bibo Mao -Date: Mon, 15 Jan 2024 16:51:21 +0800 -Subject: [PATCH] target/loongarch: Set cpuid CSR register only once with - kvm mode - -CSR cpuid register is used for routing irq to different vcpus, its -value is kept unchanged since poweron. So it is not necessary to -set CSR cpuid register after system resets, and it is only set at -vm creation stage. - -Signed-off-by: Bibo Mao -Reviewed-by: Song Gao -Message-Id: <20240115085121.180524-1-maobibo@loongson.cn> -Signed-off-by: Song Gao ---- - target/loongarch/kvm/kvm.c | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - -diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c -index 84bcdf5f86..2230f029d0 100644 ---- a/target/loongarch/kvm/kvm.c -+++ b/target/loongarch/kvm/kvm.c -@@ -250,7 +250,7 @@ static int kvm_loongarch_get_csr(CPUState *cs) - return ret; - } - --static int kvm_loongarch_put_csr(CPUState *cs) -+static int kvm_loongarch_put_csr(CPUState *cs, int level) - { - int ret = 0; - LoongArchCPU *cpu = LOONGARCH_CPU(cs); -@@ -322,8 +322,11 @@ static int kvm_loongarch_put_csr(CPUState *cs) - ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_RVACFG), - &env->CSR_RVACFG); - -- ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CPUID), -+ /* CPUID is constant after poweron, it should be set only once */ -+ if (level >= KVM_PUT_FULL_STATE) { -+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CPUID), - &env->CSR_CPUID); -+ } - - ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG1), - &env->CSR_PRCFG1); -@@ -598,7 +601,7 @@ int kvm_arch_put_registers(CPUState *cs, int level) - return ret; - } - -- ret = kvm_loongarch_put_csr(cs); -+ ret = kvm_loongarch_put_csr(cs, level); - if (ret) { - return ret; - } --- -2.33.0 - diff --git a/0024-target-loongarch-kvm-Enable-LSX-LASX-extension.patch b/0024-target-loongarch-kvm-Enable-LSX-LASX-extension.patch deleted file mode 100644 index 6d08d3e8ad09ce3bd1dd65b2884a3e7a3db0255a..0000000000000000000000000000000000000000 --- a/0024-target-loongarch-kvm-Enable-LSX-LASX-extension.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 6e503b590e42ad7c522cf937b83e1f8f715dbd1a Mon Sep 17 00:00:00 2001 -From: Song Gao -Date: Mon, 22 Jan 2024 17:02:06 +0800 -Subject: [PATCH] target/loongarch/kvm: Enable LSX/LASX extension - -The kernel had already support LSX and LASX [1], -but QEMU is disable LSX/LASX for kvm. This patch adds -kvm_check_cpucfg2() to check CPUCFG2. - -[1]: https://lore.kernel.org/all/CABgObfZHRf7E_7Jk4uPRmSyxTy3EiuuYwHC35jQncNL9s-zTDA@mail.gmail.com/ - -Signed-off-by: Song Gao -Reviewed-by: Bibo Mao -Message-Id: <20240122090206.1083584-1-gaosong@loongson.cn> ---- - linux-headers/asm-loongarch/kvm.h | 1 + - target/loongarch/kvm/kvm.c | 45 ++++++++++++++++++++++++++----- - 2 files changed, 39 insertions(+), 7 deletions(-) - -diff --git a/linux-headers/asm-loongarch/kvm.h b/linux-headers/asm-loongarch/kvm.h -index c6ad2ee610..923d0bd382 100644 ---- a/linux-headers/asm-loongarch/kvm.h -+++ b/linux-headers/asm-loongarch/kvm.h -@@ -79,6 +79,7 @@ struct kvm_fpu { - #define LOONGARCH_REG_64(TYPE, REG) (TYPE | KVM_REG_SIZE_U64 | (REG << LOONGARCH_REG_SHIFT)) - #define KVM_IOC_CSRID(REG) LOONGARCH_REG_64(KVM_REG_LOONGARCH_CSR, REG) - #define KVM_IOC_CPUCFG(REG) LOONGARCH_REG_64(KVM_REG_LOONGARCH_CPUCFG, REG) -+#define KVM_LOONGARCH_VCPU_CPUCFG 0 - - struct kvm_debug_exit_arch { - }; -diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c -index 2230f029d0..c19978a970 100644 ---- a/target/loongarch/kvm/kvm.c -+++ b/target/loongarch/kvm/kvm.c -@@ -540,6 +540,38 @@ static int kvm_loongarch_get_cpucfg(CPUState *cs) - return ret; - } - -+static int kvm_check_cpucfg2(CPUState *cs) -+{ -+ int ret; -+ uint64_t val; -+ struct kvm_device_attr attr = { -+ .group = KVM_LOONGARCH_VCPU_CPUCFG, -+ .attr = 2, -+ .addr = (uint64_t)&val, -+ }; -+ LoongArchCPU *cpu = LOONGARCH_CPU(cs); -+ CPULoongArchState *env = &cpu->env; -+ -+ ret = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, &attr); -+ -+ if (!ret) { -+ kvm_vcpu_ioctl(cs, KVM_GET_DEVICE_ATTR, &attr); -+ env->cpucfg[2] &= val; -+ -+ if (FIELD_EX32(env->cpucfg[2], CPUCFG2, FP)) { -+ /* The FP minimal version is 1. */ -+ env->cpucfg[2] = FIELD_DP32(env->cpucfg[2], CPUCFG2, FP_VER, 1); -+ } -+ -+ if (FIELD_EX32(env->cpucfg[2], CPUCFG2, LLFTP)) { -+ /* The LLFTP minimal version is 1. */ -+ env->cpucfg[2] = FIELD_DP32(env->cpucfg[2], CPUCFG2, LLFTP_VER, 1); -+ } -+ } -+ -+ return ret; -+} -+ - static int kvm_loongarch_put_cpucfg(CPUState *cs) - { - int i, ret = 0; -@@ -548,14 +580,13 @@ static int kvm_loongarch_put_cpucfg(CPUState *cs) - uint64_t val; - - for (i = 0; i < 21; i++) { -+ if (i == 2) { -+ ret = kvm_check_cpucfg2(cs); -+ if (ret) { -+ return ret; -+ } -+ } - val = env->cpucfg[i]; -- /* LSX and LASX and LBT are not supported in kvm now */ -- if (i == 2) { -- val &= ~(BIT(R_CPUCFG2_LSX_SHIFT) | BIT(R_CPUCFG2_LASX_SHIFT)); -- val &= ~(BIT(R_CPUCFG2_LBT_X86_SHIFT) | -- BIT(R_CPUCFG2_LBT_ARM_SHIFT) | -- BIT(R_CPUCFG2_LBT_MIPS_SHIFT)); -- } - ret = kvm_set_one_reg(cs, KVM_IOC_CPUCFG(i), &val); - if (ret < 0) { - trace_kvm_failed_put_cpucfg(strerror(errno)); --- -2.33.0 - diff --git a/0025-target-loongarch-Fix-qtest-test-hmp-error-when-KVM-o.patch b/0025-target-loongarch-Fix-qtest-test-hmp-error-when-KVM-o.patch deleted file mode 100644 index 4c4a84ce256078da58609911feec782d24a1266e..0000000000000000000000000000000000000000 --- a/0025-target-loongarch-Fix-qtest-test-hmp-error-when-KVM-o.patch +++ /dev/null @@ -1,570 +0,0 @@ -From d2381abc2c78de68e765a29a55282707541e315d Mon Sep 17 00:00:00 2001 -From: Song Gao -Date: Thu, 25 Jan 2024 14:14:01 +0800 -Subject: [PATCH] target/loongarch: Fix qtest test-hmp error when - KVM-only build - -The cc->sysemu_ops->get_phys_page_debug() is NULL when -KVM-only build. this patch fixes it. - -Signed-off-by: Song Gao -Tested-by: Bibo Mao -Message-Id: <20240125061401.52526-1-gaosong@loongson.cn> ---- - target/loongarch/cpu.c | 2 - - target/loongarch/cpu_helper.c | 231 ++++++++++++++++++++++++++++++ - target/loongarch/internals.h | 20 ++- - target/loongarch/meson.build | 1 + - target/loongarch/tcg/tlb_helper.c | 230 ----------------------------- - 5 files changed, 250 insertions(+), 234 deletions(-) - create mode 100644 target/loongarch/cpu_helper.c - -diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c -index 6611d137a1..b098b1c6f3 100644 ---- a/target/loongarch/cpu.c -+++ b/target/loongarch/cpu.c -@@ -771,9 +771,7 @@ static struct TCGCPUOps loongarch_tcg_ops = { - #include "hw/core/sysemu-cpu-ops.h" - - static const struct SysemuCPUOps loongarch_sysemu_ops = { --#ifdef CONFIG_TCG - .get_phys_page_debug = loongarch_cpu_get_phys_page_debug, --#endif - }; - - static int64_t loongarch_cpu_get_arch_id(CPUState *cs) -diff --git a/target/loongarch/cpu_helper.c b/target/loongarch/cpu_helper.c -new file mode 100644 -index 0000000000..f68d63f466 ---- /dev/null -+++ b/target/loongarch/cpu_helper.c -@@ -0,0 +1,231 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+/* -+ * LoongArch CPU helpers for qemu -+ * -+ * Copyright (c) 2024 Loongson Technology Corporation Limited -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include "cpu.h" -+#include "internals.h" -+#include "cpu-csr.h" -+ -+static int loongarch_map_tlb_entry(CPULoongArchState *env, hwaddr *physical, -+ int *prot, target_ulong address, -+ int access_type, int index, int mmu_idx) -+{ -+ LoongArchTLB *tlb = &env->tlb[index]; -+ uint64_t plv = mmu_idx; -+ uint64_t tlb_entry, tlb_ppn; -+ uint8_t tlb_ps, n, tlb_v, tlb_d, tlb_plv, tlb_nx, tlb_nr, tlb_rplv; -+ -+ if (index >= LOONGARCH_STLB) { -+ tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS); -+ } else { -+ tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS); -+ } -+ n = (address >> tlb_ps) & 0x1;/* Odd or even */ -+ -+ tlb_entry = n ? tlb->tlb_entry1 : tlb->tlb_entry0; -+ tlb_v = FIELD_EX64(tlb_entry, TLBENTRY, V); -+ tlb_d = FIELD_EX64(tlb_entry, TLBENTRY, D); -+ tlb_plv = FIELD_EX64(tlb_entry, TLBENTRY, PLV); -+ if (is_la64(env)) { -+ tlb_ppn = FIELD_EX64(tlb_entry, TLBENTRY_64, PPN); -+ tlb_nx = FIELD_EX64(tlb_entry, TLBENTRY_64, NX); -+ tlb_nr = FIELD_EX64(tlb_entry, TLBENTRY_64, NR); -+ tlb_rplv = FIELD_EX64(tlb_entry, TLBENTRY_64, RPLV); -+ } else { -+ tlb_ppn = FIELD_EX64(tlb_entry, TLBENTRY_32, PPN); -+ tlb_nx = 0; -+ tlb_nr = 0; -+ tlb_rplv = 0; -+ } -+ -+ /* Remove sw bit between bit12 -- bit PS*/ -+ tlb_ppn = tlb_ppn & ~(((0x1UL << (tlb_ps - 12)) -1)); -+ -+ /* Check access rights */ -+ if (!tlb_v) { -+ return TLBRET_INVALID; -+ } -+ -+ if (access_type == MMU_INST_FETCH && tlb_nx) { -+ return TLBRET_XI; -+ } -+ -+ if (access_type == MMU_DATA_LOAD && tlb_nr) { -+ return TLBRET_RI; -+ } -+ -+ if (((tlb_rplv == 0) && (plv > tlb_plv)) || -+ ((tlb_rplv == 1) && (plv != tlb_plv))) { -+ return TLBRET_PE; -+ } -+ -+ if ((access_type == MMU_DATA_STORE) && !tlb_d) { -+ return TLBRET_DIRTY; -+ } -+ -+ *physical = (tlb_ppn << R_TLBENTRY_64_PPN_SHIFT) | -+ (address & MAKE_64BIT_MASK(0, tlb_ps)); -+ *prot = PAGE_READ; -+ if (tlb_d) { -+ *prot |= PAGE_WRITE; -+ } -+ if (!tlb_nx) { -+ *prot |= PAGE_EXEC; -+ } -+ return TLBRET_MATCH; -+} -+ -+/* -+ * One tlb entry holds an adjacent odd/even pair, the vpn is the -+ * content of the virtual page number divided by 2. So the -+ * compare vpn is bit[47:15] for 16KiB page. while the vppn -+ * field in tlb entry contains bit[47:13], so need adjust. -+ * virt_vpn = vaddr[47:13] -+ */ -+bool loongarch_tlb_search(CPULoongArchState *env, target_ulong vaddr, -+ int *index) -+{ -+ LoongArchTLB *tlb; -+ uint16_t csr_asid, tlb_asid, stlb_idx; -+ uint8_t tlb_e, tlb_ps, tlb_g, stlb_ps; -+ int i, compare_shift; -+ uint64_t vpn, tlb_vppn; -+ -+ csr_asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID); -+ stlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS); -+ vpn = (vaddr & TARGET_VIRT_MASK) >> (stlb_ps + 1); -+ stlb_idx = vpn & 0xff; /* VA[25:15] <==> TLBIDX.index for 16KiB Page */ -+ compare_shift = stlb_ps + 1 - R_TLB_MISC_VPPN_SHIFT; -+ -+ /* Search STLB */ -+ for (i = 0; i < 8; ++i) { -+ tlb = &env->tlb[i * 256 + stlb_idx]; -+ tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E); -+ if (tlb_e) { -+ tlb_vppn = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN); -+ tlb_asid = FIELD_EX64(tlb->tlb_misc, TLB_MISC, ASID); -+ tlb_g = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, G); -+ -+ if ((tlb_g == 1 || tlb_asid == csr_asid) && -+ (vpn == (tlb_vppn >> compare_shift))) { -+ *index = i * 256 + stlb_idx; -+ return true; -+ } -+ } -+ } -+ -+ /* Search MTLB */ -+ for (i = LOONGARCH_STLB; i < LOONGARCH_TLB_MAX; ++i) { -+ tlb = &env->tlb[i]; -+ tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E); -+ if (tlb_e) { -+ tlb_vppn = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN); -+ tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS); -+ tlb_asid = FIELD_EX64(tlb->tlb_misc, TLB_MISC, ASID); -+ tlb_g = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, G); -+ compare_shift = tlb_ps + 1 - R_TLB_MISC_VPPN_SHIFT; -+ vpn = (vaddr & TARGET_VIRT_MASK) >> (tlb_ps + 1); -+ if ((tlb_g == 1 || tlb_asid == csr_asid) && -+ (vpn == (tlb_vppn >> compare_shift))) { -+ *index = i; -+ return true; -+ } -+ } -+ } -+ return false; -+} -+ -+static int loongarch_map_address(CPULoongArchState *env, hwaddr *physical, -+ int *prot, target_ulong address, -+ MMUAccessType access_type, int mmu_idx) -+{ -+ int index, match; -+ -+ match = loongarch_tlb_search(env, address, &index); -+ if (match) { -+ return loongarch_map_tlb_entry(env, physical, prot, -+ address, access_type, index, mmu_idx); -+ } -+ -+ return TLBRET_NOMATCH; -+} -+ -+static hwaddr dmw_va2pa(CPULoongArchState *env, target_ulong va, -+ target_ulong dmw) -+{ -+ if (is_la64(env)) { -+ return va & TARGET_VIRT_MASK; -+ } else { -+ uint32_t pseg = FIELD_EX32(dmw, CSR_DMW_32, PSEG); -+ return (va & MAKE_64BIT_MASK(0, R_CSR_DMW_32_VSEG_SHIFT)) | \ -+ (pseg << R_CSR_DMW_32_VSEG_SHIFT); -+ } -+} -+ -+int get_physical_address(CPULoongArchState *env, hwaddr *physical, -+ int *prot, target_ulong address, -+ MMUAccessType access_type, int mmu_idx) -+{ -+ int user_mode = mmu_idx == MMU_IDX_USER; -+ int kernel_mode = mmu_idx == MMU_IDX_KERNEL; -+ uint32_t plv, base_c, base_v; -+ int64_t addr_high; -+ uint8_t da = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, DA); -+ uint8_t pg = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG); -+ -+ /* Check PG and DA */ -+ if (da & !pg) { -+ *physical = address & TARGET_PHYS_MASK; -+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; -+ return TLBRET_MATCH; -+ } -+ -+ plv = kernel_mode | (user_mode << R_CSR_DMW_PLV3_SHIFT); -+ if (is_la64(env)) { -+ base_v = address >> R_CSR_DMW_64_VSEG_SHIFT; -+ } else { -+ base_v = address >> R_CSR_DMW_32_VSEG_SHIFT; -+ } -+ /* Check direct map window */ -+ for (int i = 0; i < 4; i++) { -+ if (is_la64(env)) { -+ base_c = FIELD_EX64(env->CSR_DMW[i], CSR_DMW_64, VSEG); -+ } else { -+ base_c = FIELD_EX64(env->CSR_DMW[i], CSR_DMW_32, VSEG); -+ } -+ if ((plv & env->CSR_DMW[i]) && (base_c == base_v)) { -+ *physical = dmw_va2pa(env, address, env->CSR_DMW[i]); -+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; -+ return TLBRET_MATCH; -+ } -+ } -+ -+ /* Check valid extension */ -+ addr_high = sextract64(address, TARGET_VIRT_ADDR_SPACE_BITS, 16); -+ if (!(addr_high == 0 || addr_high == -1)) { -+ return TLBRET_BADADDR; -+ } -+ -+ /* Mapped address */ -+ return loongarch_map_address(env, physical, prot, address, -+ access_type, mmu_idx); -+} -+ -+hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) -+{ -+ LoongArchCPU *cpu = LOONGARCH_CPU(cs); -+ CPULoongArchState *env = &cpu->env; -+ hwaddr phys_addr; -+ int prot; -+ -+ if (get_physical_address(env, &phys_addr, &prot, addr, MMU_DATA_LOAD, -+ cpu_mmu_index(env, false)) != 0) { -+ return -1; -+ } -+ return phys_addr; -+} -diff --git a/target/loongarch/internals.h b/target/loongarch/internals.h -index 0beb034748..a2fc54c8a7 100644 ---- a/target/loongarch/internals.h -+++ b/target/loongarch/internals.h -@@ -37,6 +37,17 @@ void restore_fp_status(CPULoongArchState *env); - #endif - - #ifndef CONFIG_USER_ONLY -+enum { -+ TLBRET_MATCH = 0, -+ TLBRET_BADADDR = 1, -+ TLBRET_NOMATCH = 2, -+ TLBRET_INVALID = 3, -+ TLBRET_DIRTY = 4, -+ TLBRET_RI = 5, -+ TLBRET_XI = 6, -+ TLBRET_PE = 7, -+}; -+ - extern const VMStateDescription vmstate_loongarch_cpu; - - void loongarch_cpu_set_irq(void *opaque, int irq, int level); -@@ -46,12 +57,17 @@ uint64_t cpu_loongarch_get_constant_timer_counter(LoongArchCPU *cpu); - uint64_t cpu_loongarch_get_constant_timer_ticks(LoongArchCPU *cpu); - void cpu_loongarch_store_constant_timer_config(LoongArchCPU *cpu, - uint64_t value); -+bool loongarch_tlb_search(CPULoongArchState *env, target_ulong vaddr, -+ int *index); -+int get_physical_address(CPULoongArchState *env, hwaddr *physical, -+ int *prot, target_ulong address, -+ MMUAccessType access_type, int mmu_idx); -+hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); -+ - #ifdef CONFIG_TCG - bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size, - MMUAccessType access_type, int mmu_idx, - bool probe, uintptr_t retaddr); -- --hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); - #endif - #endif /* !CONFIG_USER_ONLY */ - -diff --git a/target/loongarch/meson.build b/target/loongarch/meson.build -index db310f6022..e002e9aaf6 100644 ---- a/target/loongarch/meson.build -+++ b/target/loongarch/meson.build -@@ -8,6 +8,7 @@ loongarch_ss.add(files( - - loongarch_system_ss = ss.source_set() - loongarch_system_ss.add(files( -+ 'cpu_helper.c', - 'loongarch-qmp-cmds.c', - 'machine.c', - )) -diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c -index 449043c68b..804ab7a263 100644 ---- a/target/loongarch/tcg/tlb_helper.c -+++ b/target/loongarch/tcg/tlb_helper.c -@@ -17,236 +17,6 @@ - #include "exec/log.h" - #include "cpu-csr.h" - --enum { -- TLBRET_MATCH = 0, -- TLBRET_BADADDR = 1, -- TLBRET_NOMATCH = 2, -- TLBRET_INVALID = 3, -- TLBRET_DIRTY = 4, -- TLBRET_RI = 5, -- TLBRET_XI = 6, -- TLBRET_PE = 7, --}; -- --static int loongarch_map_tlb_entry(CPULoongArchState *env, hwaddr *physical, -- int *prot, target_ulong address, -- int access_type, int index, int mmu_idx) --{ -- LoongArchTLB *tlb = &env->tlb[index]; -- uint64_t plv = mmu_idx; -- uint64_t tlb_entry, tlb_ppn; -- uint8_t tlb_ps, n, tlb_v, tlb_d, tlb_plv, tlb_nx, tlb_nr, tlb_rplv; -- -- if (index >= LOONGARCH_STLB) { -- tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS); -- } else { -- tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS); -- } -- n = (address >> tlb_ps) & 0x1;/* Odd or even */ -- -- tlb_entry = n ? tlb->tlb_entry1 : tlb->tlb_entry0; -- tlb_v = FIELD_EX64(tlb_entry, TLBENTRY, V); -- tlb_d = FIELD_EX64(tlb_entry, TLBENTRY, D); -- tlb_plv = FIELD_EX64(tlb_entry, TLBENTRY, PLV); -- if (is_la64(env)) { -- tlb_ppn = FIELD_EX64(tlb_entry, TLBENTRY_64, PPN); -- tlb_nx = FIELD_EX64(tlb_entry, TLBENTRY_64, NX); -- tlb_nr = FIELD_EX64(tlb_entry, TLBENTRY_64, NR); -- tlb_rplv = FIELD_EX64(tlb_entry, TLBENTRY_64, RPLV); -- } else { -- tlb_ppn = FIELD_EX64(tlb_entry, TLBENTRY_32, PPN); -- tlb_nx = 0; -- tlb_nr = 0; -- tlb_rplv = 0; -- } -- -- /* Remove sw bit between bit12 -- bit PS*/ -- tlb_ppn = tlb_ppn & ~(((0x1UL << (tlb_ps - 12)) -1)); -- -- /* Check access rights */ -- if (!tlb_v) { -- return TLBRET_INVALID; -- } -- -- if (access_type == MMU_INST_FETCH && tlb_nx) { -- return TLBRET_XI; -- } -- -- if (access_type == MMU_DATA_LOAD && tlb_nr) { -- return TLBRET_RI; -- } -- -- if (((tlb_rplv == 0) && (plv > tlb_plv)) || -- ((tlb_rplv == 1) && (plv != tlb_plv))) { -- return TLBRET_PE; -- } -- -- if ((access_type == MMU_DATA_STORE) && !tlb_d) { -- return TLBRET_DIRTY; -- } -- -- *physical = (tlb_ppn << R_TLBENTRY_64_PPN_SHIFT) | -- (address & MAKE_64BIT_MASK(0, tlb_ps)); -- *prot = PAGE_READ; -- if (tlb_d) { -- *prot |= PAGE_WRITE; -- } -- if (!tlb_nx) { -- *prot |= PAGE_EXEC; -- } -- return TLBRET_MATCH; --} -- --/* -- * One tlb entry holds an adjacent odd/even pair, the vpn is the -- * content of the virtual page number divided by 2. So the -- * compare vpn is bit[47:15] for 16KiB page. while the vppn -- * field in tlb entry contains bit[47:13], so need adjust. -- * virt_vpn = vaddr[47:13] -- */ --static bool loongarch_tlb_search(CPULoongArchState *env, target_ulong vaddr, -- int *index) --{ -- LoongArchTLB *tlb; -- uint16_t csr_asid, tlb_asid, stlb_idx; -- uint8_t tlb_e, tlb_ps, tlb_g, stlb_ps; -- int i, compare_shift; -- uint64_t vpn, tlb_vppn; -- -- csr_asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID); -- stlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS); -- vpn = (vaddr & TARGET_VIRT_MASK) >> (stlb_ps + 1); -- stlb_idx = vpn & 0xff; /* VA[25:15] <==> TLBIDX.index for 16KiB Page */ -- compare_shift = stlb_ps + 1 - R_TLB_MISC_VPPN_SHIFT; -- -- /* Search STLB */ -- for (i = 0; i < 8; ++i) { -- tlb = &env->tlb[i * 256 + stlb_idx]; -- tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E); -- if (tlb_e) { -- tlb_vppn = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN); -- tlb_asid = FIELD_EX64(tlb->tlb_misc, TLB_MISC, ASID); -- tlb_g = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, G); -- -- if ((tlb_g == 1 || tlb_asid == csr_asid) && -- (vpn == (tlb_vppn >> compare_shift))) { -- *index = i * 256 + stlb_idx; -- return true; -- } -- } -- } -- -- /* Search MTLB */ -- for (i = LOONGARCH_STLB; i < LOONGARCH_TLB_MAX; ++i) { -- tlb = &env->tlb[i]; -- tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E); -- if (tlb_e) { -- tlb_vppn = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN); -- tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS); -- tlb_asid = FIELD_EX64(tlb->tlb_misc, TLB_MISC, ASID); -- tlb_g = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, G); -- compare_shift = tlb_ps + 1 - R_TLB_MISC_VPPN_SHIFT; -- vpn = (vaddr & TARGET_VIRT_MASK) >> (tlb_ps + 1); -- if ((tlb_g == 1 || tlb_asid == csr_asid) && -- (vpn == (tlb_vppn >> compare_shift))) { -- *index = i; -- return true; -- } -- } -- } -- return false; --} -- --static int loongarch_map_address(CPULoongArchState *env, hwaddr *physical, -- int *prot, target_ulong address, -- MMUAccessType access_type, int mmu_idx) --{ -- int index, match; -- -- match = loongarch_tlb_search(env, address, &index); -- if (match) { -- return loongarch_map_tlb_entry(env, physical, prot, -- address, access_type, index, mmu_idx); -- } -- -- return TLBRET_NOMATCH; --} -- --static hwaddr dmw_va2pa(CPULoongArchState *env, target_ulong va, -- target_ulong dmw) --{ -- if (is_la64(env)) { -- return va & TARGET_VIRT_MASK; -- } else { -- uint32_t pseg = FIELD_EX32(dmw, CSR_DMW_32, PSEG); -- return (va & MAKE_64BIT_MASK(0, R_CSR_DMW_32_VSEG_SHIFT)) | \ -- (pseg << R_CSR_DMW_32_VSEG_SHIFT); -- } --} -- --static int get_physical_address(CPULoongArchState *env, hwaddr *physical, -- int *prot, target_ulong address, -- MMUAccessType access_type, int mmu_idx) --{ -- int user_mode = mmu_idx == MMU_IDX_USER; -- int kernel_mode = mmu_idx == MMU_IDX_KERNEL; -- uint32_t plv, base_c, base_v; -- int64_t addr_high; -- uint8_t da = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, DA); -- uint8_t pg = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG); -- -- /* Check PG and DA */ -- if (da & !pg) { -- *physical = address & TARGET_PHYS_MASK; -- *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; -- return TLBRET_MATCH; -- } -- -- plv = kernel_mode | (user_mode << R_CSR_DMW_PLV3_SHIFT); -- if (is_la64(env)) { -- base_v = address >> R_CSR_DMW_64_VSEG_SHIFT; -- } else { -- base_v = address >> R_CSR_DMW_32_VSEG_SHIFT; -- } -- /* Check direct map window */ -- for (int i = 0; i < 4; i++) { -- if (is_la64(env)) { -- base_c = FIELD_EX64(env->CSR_DMW[i], CSR_DMW_64, VSEG); -- } else { -- base_c = FIELD_EX64(env->CSR_DMW[i], CSR_DMW_32, VSEG); -- } -- if ((plv & env->CSR_DMW[i]) && (base_c == base_v)) { -- *physical = dmw_va2pa(env, address, env->CSR_DMW[i]); -- *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; -- return TLBRET_MATCH; -- } -- } -- -- /* Check valid extension */ -- addr_high = sextract64(address, TARGET_VIRT_ADDR_SPACE_BITS, 16); -- if (!(addr_high == 0 || addr_high == -1)) { -- return TLBRET_BADADDR; -- } -- -- /* Mapped address */ -- return loongarch_map_address(env, physical, prot, address, -- access_type, mmu_idx); --} -- --hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) --{ -- LoongArchCPU *cpu = LOONGARCH_CPU(cs); -- CPULoongArchState *env = &cpu->env; -- hwaddr phys_addr; -- int prot; -- -- if (get_physical_address(env, &phys_addr, &prot, addr, MMU_DATA_LOAD, -- cpu_mmu_index(env, false)) != 0) { -- return -1; -- } -- return phys_addr; --} -- - static void raise_mmu_exception(CPULoongArchState *env, target_ulong address, - MMUAccessType access_type, int tlb_error) - { --- -2.33.0 - diff --git a/0026-loongarch-Change-the-UEFI-loading-mode-to-loongarch.patch b/0026-loongarch-Change-the-UEFI-loading-mode-to-loongarch.patch deleted file mode 100644 index e4f939a2b46eb1bdb8107eba482b609bef5b410c..0000000000000000000000000000000000000000 --- a/0026-loongarch-Change-the-UEFI-loading-mode-to-loongarch.patch +++ /dev/null @@ -1,287 +0,0 @@ -From 4a5a9bef6eff5837dcccd216172957d8470b6245 Mon Sep 17 00:00:00 2001 -From: Xianglai Li -Date: Mon, 19 Feb 2024 18:34:14 +0800 -Subject: [PATCH] loongarch: Change the UEFI loading mode to loongarch -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The UEFI loading mode in loongarch is very different -from that in other architectures:loongarch's UEFI code -is in rom, while other architectures' UEFI code is in flash. - -loongarch UEFI can be loaded as follows: --machine virt,pflash=pflash0-format --bios ./QEMU_EFI.fd - -Other architectures load UEFI using the following methods: --machine virt,pflash0=pflash0-format,pflash1=pflash1-format - -loongarch's UEFI loading method makes qemu and libvirt incompatible -when using NVRAM, and the cost of loongarch's current loading method -far outweighs the benefits, so we decided to use the same UEFI loading -scheme as other architectures. - -Cc: Andrea Bolognani -Cc: maobibo@loongson.cn -Cc: Philippe Mathieu-Daudé -Cc: Song Gao -Cc: zhaotianrui@loongson.cn -Signed-off-by: Xianglai Li -Tested-by: Andrea Bolognani -Reviewed-by: Song Gao -Message-Id: <0bd892aa9b88e0f4cc904cb70efd0251fc1cde29.1708336919.git.lixianglai@loongson.cn> -Signed-off-by: Song Gao ---- - hw/loongarch/acpi-build.c | 29 +++++++++-- - hw/loongarch/virt.c | 101 ++++++++++++++++++++++++++---------- - include/hw/loongarch/virt.h | 10 ++-- - 3 files changed, 107 insertions(+), 33 deletions(-) - -diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c -index ae292fc543..f990405d04 100644 ---- a/hw/loongarch/acpi-build.c -+++ b/hw/loongarch/acpi-build.c -@@ -314,16 +314,39 @@ static void build_pci_device_aml(Aml *scope, LoongArchMachineState *lams) - static void build_flash_aml(Aml *scope, LoongArchMachineState *lams) - { - Aml *dev, *crs; -+ MemoryRegion *flash_mem; - -- hwaddr flash_base = VIRT_FLASH_BASE; -- hwaddr flash_size = VIRT_FLASH_SIZE; -+ hwaddr flash0_base; -+ hwaddr flash0_size; -+ -+ hwaddr flash1_base; -+ hwaddr flash1_size; -+ -+ flash_mem = pflash_cfi01_get_memory(lams->flash[0]); -+ flash0_base = flash_mem->addr; -+ flash0_size = memory_region_size(flash_mem); -+ -+ flash_mem = pflash_cfi01_get_memory(lams->flash[1]); -+ flash1_base = flash_mem->addr; -+ flash1_size = memory_region_size(flash_mem); - - dev = aml_device("FLS0"); - aml_append(dev, aml_name_decl("_HID", aml_string("LNRO0015"))); - aml_append(dev, aml_name_decl("_UID", aml_int(0))); - - crs = aml_resource_template(); -- aml_append(crs, aml_memory32_fixed(flash_base, flash_size, AML_READ_WRITE)); -+ aml_append(crs, aml_memory32_fixed(flash0_base, flash0_size, -+ AML_READ_WRITE)); -+ aml_append(dev, aml_name_decl("_CRS", crs)); -+ aml_append(scope, dev); -+ -+ dev = aml_device("FLS1"); -+ aml_append(dev, aml_name_decl("_HID", aml_string("LNRO0015"))); -+ aml_append(dev, aml_name_decl("_UID", aml_int(1))); -+ -+ crs = aml_resource_template(); -+ aml_append(crs, aml_memory32_fixed(flash1_base, flash1_size, -+ AML_READ_WRITE)); - aml_append(dev, aml_name_decl("_CRS", crs)); - aml_append(scope, dev); - } -diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c -index c9a680e61a..6ef40fa24a 100644 ---- a/hw/loongarch/virt.c -+++ b/hw/loongarch/virt.c -@@ -54,7 +54,9 @@ struct loaderparams { - const char *initrd_filename; - }; - --static void virt_flash_create(LoongArchMachineState *lams) -+static PFlashCFI01 *virt_flash_create1(LoongArchMachineState *lams, -+ const char *name, -+ const char *alias_prop_name) - { - DeviceState *dev = qdev_new(TYPE_PFLASH_CFI01); - -@@ -66,45 +68,78 @@ static void virt_flash_create(LoongArchMachineState *lams) - qdev_prop_set_uint16(dev, "id1", 0x18); - qdev_prop_set_uint16(dev, "id2", 0x00); - qdev_prop_set_uint16(dev, "id3", 0x00); -- qdev_prop_set_string(dev, "name", "virt.flash"); -- object_property_add_child(OBJECT(lams), "virt.flash", OBJECT(dev)); -- object_property_add_alias(OBJECT(lams), "pflash", -+ qdev_prop_set_string(dev, "name", name); -+ object_property_add_child(OBJECT(lams), name, OBJECT(dev)); -+ object_property_add_alias(OBJECT(lams), alias_prop_name, - OBJECT(dev), "drive"); -+ return PFLASH_CFI01(dev); -+} - -- lams->flash = PFLASH_CFI01(dev); -+static void virt_flash_create(LoongArchMachineState *lams) -+{ -+ lams->flash[0] = virt_flash_create1(lams, "virt.flash0", "pflash0"); -+ lams->flash[1] = virt_flash_create1(lams, "virt.flash1", "pflash1"); - } - --static void virt_flash_map(LoongArchMachineState *lams, -- MemoryRegion *sysmem) -+static void virt_flash_map1(PFlashCFI01 *flash, -+ hwaddr base, hwaddr size, -+ MemoryRegion *sysmem) - { -- PFlashCFI01 *flash = lams->flash; - DeviceState *dev = DEVICE(flash); -- hwaddr base = VIRT_FLASH_BASE; -- hwaddr size = VIRT_FLASH_SIZE; -+ BlockBackend *blk; -+ hwaddr real_size = size; -+ -+ blk = pflash_cfi01_get_blk(flash); -+ if (blk) { -+ real_size = blk_getlength(blk); -+ assert(real_size && real_size <= size); -+ } - -- assert(QEMU_IS_ALIGNED(size, VIRT_FLASH_SECTOR_SIZE)); -- assert(size / VIRT_FLASH_SECTOR_SIZE <= UINT32_MAX); -+ assert(QEMU_IS_ALIGNED(real_size, VIRT_FLASH_SECTOR_SIZE)); -+ assert(real_size / VIRT_FLASH_SECTOR_SIZE <= UINT32_MAX); - -- qdev_prop_set_uint32(dev, "num-blocks", size / VIRT_FLASH_SECTOR_SIZE); -+ qdev_prop_set_uint32(dev, "num-blocks", real_size / VIRT_FLASH_SECTOR_SIZE); - sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); - memory_region_add_subregion(sysmem, base, - sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0)); -+} - -+static void virt_flash_map(LoongArchMachineState *lams, -+ MemoryRegion *sysmem) -+{ -+ PFlashCFI01 *flash0 = lams->flash[0]; -+ PFlashCFI01 *flash1 = lams->flash[1]; -+ -+ virt_flash_map1(flash0, VIRT_FLASH0_BASE, VIRT_FLASH0_SIZE, sysmem); -+ virt_flash_map1(flash1, VIRT_FLASH1_BASE, VIRT_FLASH1_SIZE, sysmem); - } - - static void fdt_add_flash_node(LoongArchMachineState *lams) - { - MachineState *ms = MACHINE(lams); - char *nodename; -+ MemoryRegion *flash_mem; -+ -+ hwaddr flash0_base; -+ hwaddr flash0_size; - -- hwaddr flash_base = VIRT_FLASH_BASE; -- hwaddr flash_size = VIRT_FLASH_SIZE; -+ hwaddr flash1_base; -+ hwaddr flash1_size; - -- nodename = g_strdup_printf("/flash@%" PRIx64, flash_base); -+ flash_mem = pflash_cfi01_get_memory(lams->flash[0]); -+ flash0_base = flash_mem->addr; -+ flash0_size = memory_region_size(flash_mem); -+ -+ flash_mem = pflash_cfi01_get_memory(lams->flash[1]); -+ flash1_base = flash_mem->addr; -+ flash1_size = memory_region_size(flash_mem); -+ -+ nodename = g_strdup_printf("/flash@%" PRIx64, flash0_base); - qemu_fdt_add_subnode(ms->fdt, nodename); - qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "cfi-flash"); - qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", -- 2, flash_base, 2, flash_size); -+ 2, flash0_base, 2, flash0_size, -+ 2, flash1_base, 2, flash1_size); - qemu_fdt_setprop_cell(ms->fdt, nodename, "bank-width", 4); - g_free(nodename); - } -@@ -639,12 +674,32 @@ static void loongarch_firmware_init(LoongArchMachineState *lams) - { - char *filename = MACHINE(lams)->firmware; - char *bios_name = NULL; -- int bios_size; -+ int bios_size, i; -+ BlockBackend *pflash_blk0; -+ MemoryRegion *mr; - - lams->bios_loaded = false; - -+ /* Map legacy -drive if=pflash to machine properties */ -+ for (i = 0; i < ARRAY_SIZE(lams->flash); i++) { -+ pflash_cfi01_legacy_drive(lams->flash[i], -+ drive_get(IF_PFLASH, 0, i)); -+ } -+ - virt_flash_map(lams, get_system_memory()); - -+ pflash_blk0 = pflash_cfi01_get_blk(lams->flash[0]); -+ -+ if (pflash_blk0) { -+ if (filename) { -+ error_report("cannot use both '-bios' and '-drive if=pflash'" -+ "options at once"); -+ exit(1); -+ } -+ lams->bios_loaded = true; -+ return; -+ } -+ - if (filename) { - bios_name = qemu_find_file(QEMU_FILE_TYPE_BIOS, filename); - if (!bios_name) { -@@ -652,21 +707,15 @@ static void loongarch_firmware_init(LoongArchMachineState *lams) - exit(1); - } - -- bios_size = load_image_targphys(bios_name, VIRT_BIOS_BASE, VIRT_BIOS_SIZE); -+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(lams->flash[0]), 0); -+ bios_size = load_image_mr(bios_name, mr); - if (bios_size < 0) { - error_report("Could not load ROM image '%s'", bios_name); - exit(1); - } -- - g_free(bios_name); -- -- memory_region_init_ram(&lams->bios, NULL, "loongarch.bios", -- VIRT_BIOS_SIZE, &error_fatal); -- memory_region_set_readonly(&lams->bios, true); -- memory_region_add_subregion(get_system_memory(), VIRT_BIOS_BASE, &lams->bios); - lams->bios_loaded = true; - } -- - } - - static void reset_load_elf(void *opaque) -diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h -index 6ef9a92394..252f7df7f4 100644 ---- a/include/hw/loongarch/virt.h -+++ b/include/hw/loongarch/virt.h -@@ -18,10 +18,12 @@ - - #define VIRT_FWCFG_BASE 0x1e020000UL - #define VIRT_BIOS_BASE 0x1c000000UL --#define VIRT_BIOS_SIZE (4 * MiB) -+#define VIRT_BIOS_SIZE (16 * MiB) - #define VIRT_FLASH_SECTOR_SIZE (128 * KiB) --#define VIRT_FLASH_BASE 0x1d000000UL --#define VIRT_FLASH_SIZE (16 * MiB) -+#define VIRT_FLASH0_BASE VIRT_BIOS_BASE -+#define VIRT_FLASH0_SIZE VIRT_BIOS_SIZE -+#define VIRT_FLASH1_BASE 0x1d000000UL -+#define VIRT_FLASH1_SIZE (16 * MiB) - - #define VIRT_LOWMEM_BASE 0 - #define VIRT_LOWMEM_SIZE 0x10000000 -@@ -49,7 +51,7 @@ struct LoongArchMachineState { - int fdt_size; - DeviceState *platform_bus_dev; - PCIBus *pci_bus; -- PFlashCFI01 *flash; -+ PFlashCFI01 *flash[2]; - MemoryRegion system_iocsr; - MemoryRegion iocsr_mem; - AddressSpace as_iocsr; --- -2.33.0 - diff --git a/0027-target-loongarch-Fix-tlb-huge-page-loading-issue.patch b/0027-target-loongarch-Fix-tlb-huge-page-loading-issue.patch deleted file mode 100644 index e351c35e80ff28dee910d5e9cbd1652317e9fc71..0000000000000000000000000000000000000000 --- a/0027-target-loongarch-Fix-tlb-huge-page-loading-issue.patch +++ /dev/null @@ -1,208 +0,0 @@ -From f6872e0691c293cdc11353457f5aa89d3fc6fd6a Mon Sep 17 00:00:00 2001 -From: Xianglai Li -Date: Mon, 18 Mar 2024 15:03:32 +0800 -Subject: [PATCH] target/loongarch: Fix tlb huge page loading issue - -When we use qemu tcg simulation, the page size of bios is 4KB. -When using the level 2 super huge page (page size is 1G) to create the page table, -it is found that the content of the corresponding address space is abnormal, -resulting in the bios can not start the operating system and graphical interface normally. - -The lddir and ldpte instruction emulation has -a problem with the use of super huge page processing above level 2. -The page size is not correctly calculated, -resulting in the wrong page size of the table entry found by tlb. - -Signed-off-by: Xianglai Li -Reviewed-by: Richard Henderson -Signed-off-by: Song Gao -Message-Id: <20240318070332.1273939-1-lixianglai@loongson.cn> ---- - target/loongarch/cpu-csr.h | 3 + - target/loongarch/internals.h | 5 -- - target/loongarch/tcg/tlb_helper.c | 113 +++++++++++++++++++++--------- - 3 files changed, 82 insertions(+), 39 deletions(-) - -diff --git a/target/loongarch/cpu-csr.h b/target/loongarch/cpu-csr.h -index c59d7a9fcb..0834e91f30 100644 ---- a/target/loongarch/cpu-csr.h -+++ b/target/loongarch/cpu-csr.h -@@ -67,6 +67,9 @@ FIELD(TLBENTRY, D, 1, 1) - FIELD(TLBENTRY, PLV, 2, 2) - FIELD(TLBENTRY, MAT, 4, 2) - FIELD(TLBENTRY, G, 6, 1) -+FIELD(TLBENTRY, HUGE, 6, 1) -+FIELD(TLBENTRY, HGLOBAL, 12, 1) -+FIELD(TLBENTRY, LEVEL, 13, 2) - FIELD(TLBENTRY_32, PPN, 8, 24) - FIELD(TLBENTRY_64, PPN, 12, 36) - FIELD(TLBENTRY_64, NR, 61, 1) -diff --git a/target/loongarch/internals.h b/target/loongarch/internals.h -index a2fc54c8a7..944153b180 100644 ---- a/target/loongarch/internals.h -+++ b/target/loongarch/internals.h -@@ -16,11 +16,6 @@ - #define TARGET_PHYS_MASK MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS) - #define TARGET_VIRT_MASK MAKE_64BIT_MASK(0, TARGET_VIRT_ADDR_SPACE_BITS) - --/* Global bit used for lddir/ldpte */ --#define LOONGARCH_PAGE_HUGE_SHIFT 6 --/* Global bit for huge page */ --#define LOONGARCH_HGLOBAL_SHIFT 12 -- - void loongarch_translate_init(void); - - void loongarch_cpu_dump_state(CPUState *cpu, FILE *f, int flags); -diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c -index 804ab7a263..eedd1ac376 100644 ---- a/target/loongarch/tcg/tlb_helper.c -+++ b/target/loongarch/tcg/tlb_helper.c -@@ -17,6 +17,34 @@ - #include "exec/log.h" - #include "cpu-csr.h" - -+static void get_dir_base_width(CPULoongArchState *env, uint64_t *dir_base, -+ uint64_t *dir_width, target_ulong level) -+{ -+ switch (level) { -+ case 1: -+ *dir_base = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR1_BASE); -+ *dir_width = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR1_WIDTH); -+ break; -+ case 2: -+ *dir_base = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR2_BASE); -+ *dir_width = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR2_WIDTH); -+ break; -+ case 3: -+ *dir_base = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR3_BASE); -+ *dir_width = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR3_WIDTH); -+ break; -+ case 4: -+ *dir_base = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR4_BASE); -+ *dir_width = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR4_WIDTH); -+ break; -+ default: -+ /* level may be zero for ldpte */ -+ *dir_base = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTBASE); -+ *dir_width = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTWIDTH); -+ break; -+ } -+} -+ - static void raise_mmu_exception(CPULoongArchState *env, target_ulong address, - MMUAccessType access_type, int tlb_error) - { -@@ -486,7 +514,25 @@ target_ulong helper_lddir(CPULoongArchState *env, target_ulong base, - target_ulong badvaddr, index, phys, ret; - int shift; - uint64_t dir_base, dir_width; -- bool huge = (base >> LOONGARCH_PAGE_HUGE_SHIFT) & 0x1; -+ -+ if (unlikely((level == 0) || (level > 4))) { -+ qemu_log_mask(LOG_GUEST_ERROR, -+ "Attepted LDDIR with level %"PRId64"\n", level); -+ return base; -+ } -+ -+ if (FIELD_EX64(base, TLBENTRY, HUGE)) { -+ if (unlikely(level == 4)) { -+ qemu_log_mask(LOG_GUEST_ERROR, -+ "Attempted use of level 4 huge page\n"); -+ } -+ -+ if (FIELD_EX64(base, TLBENTRY, LEVEL)) { -+ return base; -+ } else { -+ return FIELD_DP64(base, TLBENTRY, LEVEL, level); -+ } -+ } - - badvaddr = env->CSR_TLBRBADV; - base = base & TARGET_PHYS_MASK; -@@ -495,30 +541,7 @@ target_ulong helper_lddir(CPULoongArchState *env, target_ulong base, - shift = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTEWIDTH); - shift = (shift + 1) * 3; - -- if (huge) { -- return base; -- } -- switch (level) { -- case 1: -- dir_base = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR1_BASE); -- dir_width = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR1_WIDTH); -- break; -- case 2: -- dir_base = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR2_BASE); -- dir_width = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR2_WIDTH); -- break; -- case 3: -- dir_base = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR3_BASE); -- dir_width = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR3_WIDTH); -- break; -- case 4: -- dir_base = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR4_BASE); -- dir_width = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR4_WIDTH); -- break; -- default: -- do_raise_exception(env, EXCCODE_INE, GETPC()); -- return 0; -- } -+ get_dir_base_width(env, &dir_base, &dir_width, level); - index = (badvaddr >> dir_base) & ((1 << dir_width) - 1); - phys = base | index << shift; - ret = ldq_phys(cs->as, phys) & TARGET_PHYS_MASK; -@@ -531,20 +554,42 @@ void helper_ldpte(CPULoongArchState *env, target_ulong base, target_ulong odd, - CPUState *cs = env_cpu(env); - target_ulong phys, tmp0, ptindex, ptoffset0, ptoffset1, ps, badv; - int shift; -- bool huge = (base >> LOONGARCH_PAGE_HUGE_SHIFT) & 0x1; - uint64_t ptbase = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTBASE); - uint64_t ptwidth = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTWIDTH); -+ uint64_t dir_base, dir_width; - -+ /* -+ * The parameter "base" has only two types, -+ * one is the page table base address, -+ * whose bit 6 should be 0, -+ * and the other is the huge page entry, -+ * whose bit 6 should be 1. -+ */ - base = base & TARGET_PHYS_MASK; -+ if (FIELD_EX64(base, TLBENTRY, HUGE)) { -+ /* -+ * Gets the huge page level and Gets huge page size. -+ * Clears the huge page level information in the entry. -+ * Clears huge page bit. -+ * Move HGLOBAL bit to GLOBAL bit. -+ */ -+ get_dir_base_width(env, &dir_base, &dir_width, -+ FIELD_EX64(base, TLBENTRY, LEVEL)); -+ -+ base = FIELD_DP64(base, TLBENTRY, LEVEL, 0); -+ base = FIELD_DP64(base, TLBENTRY, HUGE, 0); -+ if (FIELD_EX64(base, TLBENTRY, HGLOBAL)) { -+ base = FIELD_DP64(base, TLBENTRY, HGLOBAL, 0); -+ base = FIELD_DP64(base, TLBENTRY, G, 1); -+ } - -- if (huge) { -- /* Huge Page. base is paddr */ -- tmp0 = base ^ (1 << LOONGARCH_PAGE_HUGE_SHIFT); -- /* Move Global bit */ -- tmp0 = ((tmp0 & (1 << LOONGARCH_HGLOBAL_SHIFT)) >> -- LOONGARCH_HGLOBAL_SHIFT) << R_TLBENTRY_G_SHIFT | -- (tmp0 & (~(1 << LOONGARCH_HGLOBAL_SHIFT))); -- ps = ptbase + ptwidth - 1; -+ ps = dir_base + dir_width - 1; -+ /* -+ * Huge pages are evenly split into parity pages -+ * when loaded into the tlb, -+ * so the tlb page size needs to be divided by 2. -+ */ -+ tmp0 = base; - if (odd) { - tmp0 += MAKE_64BIT_MASK(ps, 1); - } --- -2.33.0 - diff --git a/0028-target-loongarch-Fix-qemu-loongarch64-hang-when-exec.patch b/0028-target-loongarch-Fix-qemu-loongarch64-hang-when-exec.patch deleted file mode 100644 index f49bf1b9f98ca15b74519c4ba3188c7f056e2b0e..0000000000000000000000000000000000000000 --- a/0028-target-loongarch-Fix-qemu-loongarch64-hang-when-exec.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 00cba740b912937535a0ad70b968bc94cd1ba4e5 Mon Sep 17 00:00:00 2001 -From: Song Gao -Date: Wed, 20 Mar 2024 09:39:55 +0800 -Subject: [PATCH] target/loongarch: Fix qemu-loongarch64 hang when - executing 'll.d $t0, $t0, 0' - -On gen_ll, if a->imm is zero, make_address_x return src1, -but the load to destination may clobber src1. We use a new -destination to fix this problem. - -Fixes: c5af6628f4be (target/loongarch: Extract make_address_i() helper) -Reviewed-by: Richard Henderson -Suggested-by: Richard Henderson -Signed-off-by: Song Gao -Message-Id: <20240320013955.1561311-1-gaosong@loongson.cn> ---- - target/loongarch/tcg/insn_trans/trans_atomic.c.inc | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/target/loongarch/tcg/insn_trans/trans_atomic.c.inc b/target/loongarch/tcg/insn_trans/trans_atomic.c.inc -index 80c2e286fd..974bc2a70f 100644 ---- a/target/loongarch/tcg/insn_trans/trans_atomic.c.inc -+++ b/target/loongarch/tcg/insn_trans/trans_atomic.c.inc -@@ -5,14 +5,14 @@ - - static bool gen_ll(DisasContext *ctx, arg_rr_i *a, MemOp mop) - { -- TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); -+ TCGv t1 = tcg_temp_new(); - TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); - TCGv t0 = make_address_i(ctx, src1, a->imm); - -- tcg_gen_qemu_ld_i64(dest, t0, ctx->mem_idx, mop); -+ tcg_gen_qemu_ld_i64(t1, t0, ctx->mem_idx, mop); - tcg_gen_st_tl(t0, tcg_env, offsetof(CPULoongArchState, lladdr)); -- tcg_gen_st_tl(dest, tcg_env, offsetof(CPULoongArchState, llval)); -- gen_set_gpr(a->rd, dest, EXT_NONE); -+ tcg_gen_st_tl(t1, tcg_env, offsetof(CPULoongArchState, llval)); -+ gen_set_gpr(a->rd, t1, EXT_NONE); - - return true; - } --- -2.33.0 - diff --git a/0029-target-loongarch-kvm-Add-software-breakpoint-support.patch b/0029-target-loongarch-kvm-Add-software-breakpoint-support.patch deleted file mode 100644 index 32a8ca81905192bf0b2c47e71f2ddba61c8b14ce..0000000000000000000000000000000000000000 --- a/0029-target-loongarch-kvm-Add-software-breakpoint-support.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 3be9d3c66430bb9152bcfc8e2c042292d7450527 Mon Sep 17 00:00:00 2001 -From: Bibo Mao -Date: Sun, 18 Feb 2024 15:00:25 +0800 -Subject: [PATCH] target/loongarch/kvm: Add software breakpoint support - -With KVM virtualization, debug exception is passthrough to -to guest kernel rather than host mode. Here hypercall -instruction with special hypercall code is used for sw -breakpoint usage. - -Now only software breakpoint is supported, and itt is allowed -to insert/remove software breakpoint. Later hardware breakpoint -will be added. - -Signed-off-by: Bibo Mao ---- - target/loongarch/kvm/kvm.c | 77 ++++++++++++++++++++++++++++++++++++++ - 1 file changed, 77 insertions(+) - -diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c -index c19978a970..49d02076ad 100644 ---- a/target/loongarch/kvm/kvm.c -+++ b/target/loongarch/kvm/kvm.c -@@ -29,6 +29,7 @@ - #include "trace.h" - - static bool cap_has_mp_state; -+static unsigned int brk_insn; - const KVMCapabilityInfo kvm_arch_required_capabilities[] = { - KVM_CAP_LAST_INFO - }; -@@ -675,7 +676,14 @@ static void kvm_loongarch_vm_stage_change(void *opaque, bool running, - - int kvm_arch_init_vcpu(CPUState *cs) - { -+ uint64_t val; -+ - qemu_add_vm_change_state_handler(kvm_loongarch_vm_stage_change, cs); -+ -+ if (!kvm_get_one_reg(cs, KVM_REG_LOONGARCH_DEBUG_INST, &val)) { -+ brk_insn = val; -+ } -+ - return 0; - } - -@@ -755,6 +763,68 @@ bool kvm_arch_cpu_check_are_resettable(void) - return true; - } - -+ -+void kvm_arch_update_guest_debug(CPUState *cpu, struct kvm_guest_debug *dbg) -+{ -+ if (kvm_sw_breakpoints_active(cpu)) { -+ dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP; -+ } -+} -+ -+int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) -+{ -+ if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 0) || -+ cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk_insn, 4, 1)) { -+ error_report("%s failed", __func__); -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) -+{ -+ static uint32_t brk; -+ -+ if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk, 4, 0) || -+ brk != brk_insn || -+ cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 1)) { -+ error_report("%s failed", __func__); -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+int kvm_arch_insert_hw_breakpoint(vaddr addr, vaddr len, int type) -+{ -+ return -ENOSYS; -+} -+ -+int kvm_arch_remove_hw_breakpoint(vaddr addr, vaddr len, int type) -+{ -+ return -ENOSYS; -+} -+ -+void kvm_arch_remove_all_hw_breakpoints(void) -+{ -+} -+ -+static bool kvm_loongarch_handle_debug(CPUState *cs, struct kvm_run *run) -+{ -+ LoongArchCPU *cpu = LOONGARCH_CPU(cs); -+ CPULoongArchState *env = &cpu->env; -+ -+ kvm_cpu_synchronize_state(cs); -+ if (cs->singlestep_enabled) { -+ return true; -+ } -+ -+ if (kvm_find_sw_breakpoint(cs, env->pc)) { -+ return true; -+ } -+ -+ return false; -+} -+ - int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) - { - int ret = 0; -@@ -774,6 +844,13 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) - run->iocsr_io.len, - run->iocsr_io.is_write); - break; -+ -+ case KVM_EXIT_DEBUG: -+ if (kvm_loongarch_handle_debug(cs, run)) { -+ ret = EXCP_DEBUG; -+ } -+ break; -+ - default: - ret = -1; - warn_report("KVM: unknown exit reason %d", run->exit_reason); --- -2.33.0 - diff --git a/0030-hw-intc-loongarch_extioi-Add-virt-extension-support.patch b/0030-hw-intc-loongarch_extioi-Add-virt-extension-support.patch deleted file mode 100644 index eb41cbfa8dee4fdc0d82c6a01f7837df2e70d8fe..0000000000000000000000000000000000000000 --- a/0030-hw-intc-loongarch_extioi-Add-virt-extension-support.patch +++ /dev/null @@ -1,452 +0,0 @@ -From a13ffd86213dc98d8ed5bf255f3e0c61dd32aa08 Mon Sep 17 00:00:00 2001 -From: Bibo Mao -Date: Mon, 11 Mar 2024 15:01:31 +0800 -Subject: [PATCH] hw/intc/loongarch_extioi: Add virt extension support - -With hardware extioi, irq can be routed to four vcpus with hardware -extioi. This patch adds virt extension support, sot that irq can -be routed to 256 vcpus. - -Signed-off-by: Song Gao -Signed-off-by: Bibo Mao ---- - hw/intc/loongarch_extioi.c | 98 ++++++++++++++++++++++++- - hw/loongarch/virt.c | 114 ++++++++++++++++++++++++++--- - include/hw/intc/loongarch_extioi.h | 22 +++++- - include/hw/loongarch/virt.h | 3 + - target/loongarch/cpu.h | 1 + - 5 files changed, 221 insertions(+), 17 deletions(-) - -diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c -index bdfa3b481e..a892edcabb 100644 ---- a/hw/intc/loongarch_extioi.c -+++ b/hw/intc/loongarch_extioi.c -@@ -55,6 +55,11 @@ static void extioi_update_irq(LoongArchExtIOI *s, int irq, int level) - static void extioi_setirq(void *opaque, int irq, int level) - { - LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque); -+ -+ if (s->status & BIT(EXTIOI_ENABLE)) { -+ return; -+ } -+ - trace_loongarch_extioi_setirq(irq, level); - if (level) { - /* -@@ -143,10 +148,13 @@ static inline void extioi_update_sw_coremap(LoongArchExtIOI *s, int irq, - - for (i = 0; i < 4; i++) { - cpu = val & 0xff; -- cpu = ctz32(cpu); -- cpu = (cpu >= 4) ? 0 : cpu; - val = val >> 8; - -+ if (!(s->status & BIT(EXTIOI_ENABLE_CPU_ENCODE))) { -+ cpu = ctz32(cpu); -+ cpu = (cpu >= 4) ? 0 : cpu; -+ } -+ - if (s->sw_coremap[irq + i] == cpu) { - continue; - } -@@ -177,8 +185,12 @@ static inline void extioi_update_sw_ipmap(LoongArchExtIOI *s, int index, - val = cpu_to_le64(val); - for (i = 0; i < 4; i++) { - ipnum = val & 0xff; -- ipnum = ctz32(ipnum); -- ipnum = (ipnum >= 4) ? 0 : ipnum; -+ if (s->status & EXTIOI_ENABLE_INT_ENCODE) { -+ ipnum = (ipnum >= 8) ? 0 : ipnum; -+ } else { -+ ipnum = ctz32(ipnum); -+ ipnum = (ipnum >= 4) ? 0 : ipnum; -+ } - s->sw_ipmap[index * 4 + i] = ipnum; - val = val >> 8; - } -@@ -265,6 +277,61 @@ static const MemoryRegionOps extioi_ops = { - .endianness = DEVICE_LITTLE_ENDIAN, - }; - -+static MemTxResult extioi_virt_readw(void *opaque, hwaddr addr, uint64_t *data, -+ unsigned size, MemTxAttrs attrs) -+{ -+ LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque); -+ -+ switch (addr) { -+ case EXTIOI_VIRT_FEATURES: -+ *data = s->features; -+ break; -+ case EXTIOI_VIRT_CONFIG: -+ *data = s->status; -+ break; -+ default: -+ break; -+ } -+ -+ return MEMTX_OK; -+} -+ -+static MemTxResult extioi_virt_writew(void *opaque, hwaddr addr, -+ uint64_t val, unsigned size, -+ MemTxAttrs attrs) -+{ -+ LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque); -+ -+ switch (addr) { -+ case EXTIOI_VIRT_FEATURES: -+ return MEMTX_ACCESS_ERROR; -+ -+ case EXTIOI_VIRT_CONFIG: -+ /* -+ * extioi features can only be set at disabled status -+ */ -+ if ((s->status & BIT(EXTIOI_ENABLE)) && val) { -+ return MEMTX_ACCESS_ERROR; -+ } -+ -+ s->status = val & s->features; -+ break; -+ default: -+ break; -+ } -+ return MEMTX_OK; -+} -+ -+static const MemoryRegionOps extioi_virt_ops = { -+ .read_with_attrs = extioi_virt_readw, -+ .write_with_attrs = extioi_virt_writew, -+ .impl.min_access_size = 4, -+ .impl.max_access_size = 4, -+ .valid.min_access_size = 4, -+ .valid.max_access_size = 8, -+ .endianness = DEVICE_LITTLE_ENDIAN, -+}; -+ - static void loongarch_extioi_realize(DeviceState *dev, Error **errp) - { - LoongArchExtIOI *s = LOONGARCH_EXTIOI(dev); -@@ -284,6 +351,16 @@ static void loongarch_extioi_realize(DeviceState *dev, Error **errp) - memory_region_init_io(&s->extioi_system_mem, OBJECT(s), &extioi_ops, - s, "extioi_system_mem", 0x900); - sysbus_init_mmio(sbd, &s->extioi_system_mem); -+ -+ if (s->features & BIT(EXTIOI_HAS_VIRT_EXTENSION)) { -+ memory_region_init_io(&s->virt_extend, OBJECT(s), &extioi_virt_ops, -+ s, "extioi_virt", EXTIOI_VIRT_SIZE); -+ sysbus_init_mmio(sbd, &s->virt_extend); -+ s->features |= EXTIOI_VIRT_HAS_FEATURES; -+ } else { -+ s->status |= BIT(EXTIOI_ENABLE); -+ } -+ - s->cpu = g_new0(ExtIOICore, s->num_cpu); - if (s->cpu == NULL) { - error_setg(errp, "Memory allocation for ExtIOICore faile"); -@@ -304,6 +381,14 @@ static void loongarch_extioi_finalize(Object *obj) - g_free(s->cpu); - } - -+static void loongarch_extioi_reset(DeviceState *d) -+{ -+ LoongArchExtIOI *s = LOONGARCH_EXTIOI(d); -+ -+ /* use legacy interrupt routing method by default */ -+ s->status = 0; -+} -+ - static int vmstate_extioi_post_load(void *opaque, int version_id) - { - LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque); -@@ -347,12 +432,16 @@ static const VMStateDescription vmstate_loongarch_extioi = { - - VMSTATE_STRUCT_VARRAY_POINTER_UINT32(cpu, LoongArchExtIOI, num_cpu, - vmstate_extioi_core, ExtIOICore), -+ VMSTATE_UINT32(features, LoongArchExtIOI), -+ VMSTATE_UINT32(status, LoongArchExtIOI), - VMSTATE_END_OF_LIST() - } - }; - - static Property extioi_properties[] = { - DEFINE_PROP_UINT32("num-cpu", LoongArchExtIOI, num_cpu, 1), -+ DEFINE_PROP_BIT("has-virtualization-extension", LoongArchExtIOI, features, -+ EXTIOI_HAS_VIRT_EXTENSION, 0), - DEFINE_PROP_END_OF_LIST(), - }; - -@@ -361,6 +450,7 @@ static void loongarch_extioi_class_init(ObjectClass *klass, void *data) - DeviceClass *dc = DEVICE_CLASS(klass); - - dc->realize = loongarch_extioi_realize; -+ dc->reset = loongarch_extioi_reset; - device_class_set_props(dc, extioi_properties); - dc->vmsd = &vmstate_loongarch_extioi; - } -diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c -index 6ef40fa24a..00359643a2 100644 ---- a/hw/loongarch/virt.c -+++ b/hw/loongarch/virt.c -@@ -15,6 +15,7 @@ - #include "sysemu/runstate.h" - #include "sysemu/reset.h" - #include "sysemu/rtc.h" -+#include "sysemu/kvm.h" - #include "hw/loongarch/virt.h" - #include "exec/address-spaces.h" - #include "hw/irq.h" -@@ -618,9 +619,18 @@ static void loongarch_irq_init(LoongArchMachineState *lams) - /* Create EXTIOI device */ - extioi = qdev_new(TYPE_LOONGARCH_EXTIOI); - qdev_prop_set_uint32(extioi, "num-cpu", ms->smp.cpus); -+ if (lams->v_eiointc) { -+ qdev_prop_set_bit(extioi, "has-virtualization-extension", true); -+ } - sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi), &error_fatal); -+ - memory_region_add_subregion(&lams->system_iocsr, APIC_BASE, - sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 0)); -+ if (lams->v_eiointc) { -+ memory_region_add_subregion(&lams->system_iocsr, EXTIOI_VIRT_BASE, -+ sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 1)); -+ } -+ lams->extioi = extioi; - - /* - * connect ext irq to the cpu irq -@@ -780,32 +790,87 @@ static void loongarch_direct_kernel_boot(LoongArchMachineState *lams, - } - } - --static void loongarch_qemu_write(void *opaque, hwaddr addr, -- uint64_t val, unsigned size) -+static MemTxResult loongarch_qemu_write(void *opaque, hwaddr addr, uint64_t val, -+ unsigned size, MemTxAttrs attrs) - { -+ LoongArchMachineState *lams = LOONGARCH_MACHINE(opaque); -+ uint64_t features; -+ -+ switch (addr) { -+ case MISC_FUNC_REG: -+ if (!lams->v_eiointc) { -+ return MEMTX_OK; -+ } -+ -+ features = address_space_ldl(&lams->as_iocsr, -+ EXTIOI_VIRT_BASE + EXTIOI_VIRT_CONFIG, -+ attrs, NULL); -+ if (val & BIT_ULL(IOCSRM_EXTIOI_EN)) { -+ features |= BIT(EXTIOI_ENABLE); -+ } -+ if (val & BIT_ULL(IOCSRM_EXTIOI_INT_ENCODE)) { -+ features |= BIT(EXTIOI_ENABLE_INT_ENCODE); -+ } -+ -+ address_space_stl(&lams->as_iocsr, -+ EXTIOI_VIRT_BASE + EXTIOI_VIRT_CONFIG, -+ features, attrs, NULL); -+ } -+ -+ return MEMTX_OK; - } - --static uint64_t loongarch_qemu_read(void *opaque, hwaddr addr, unsigned size) -+static MemTxResult loongarch_qemu_read(void *opaque, hwaddr addr, -+ uint64_t *data, -+ unsigned size, MemTxAttrs attrs) - { -+ LoongArchMachineState *lams = LOONGARCH_MACHINE(opaque); -+ uint64_t ret = 0; -+ int features; -+ - switch (addr) { - case VERSION_REG: -- return 0x11ULL; -+ ret = 0x11ULL; -+ break; - case FEATURE_REG: -- return 1ULL << IOCSRF_MSI | 1ULL << IOCSRF_EXTIOI | -- 1ULL << IOCSRF_CSRIPI; -+ ret = 1ULL << IOCSRF_MSI | 1ULL << IOCSRF_EXTIOI | -+ 1ULL << IOCSRF_CSRIPI; -+ if (kvm_enabled()) { -+ ret |= 1ULL << IOCSRF_VM; -+ } -+ break; - case VENDOR_REG: -- return 0x6e6f73676e6f6f4cULL; /* "Loongson" */ -+ ret = 0x6e6f73676e6f6f4cULL; /* "Loongson" */ -+ break; - case CPUNAME_REG: -- return 0x303030354133ULL; /* "3A5000" */ -+ ret = 0x303030354133ULL; /* "3A5000" */ -+ break; - case MISC_FUNC_REG: -- return 1ULL << IOCSRM_EXTIOI_EN; -+ if (!lams->v_eiointc) { -+ ret |= BIT_ULL(IOCSRM_EXTIOI_EN); -+ break; -+ } -+ -+ features = address_space_ldl(&lams->as_iocsr, -+ EXTIOI_VIRT_BASE + EXTIOI_VIRT_CONFIG, -+ attrs, NULL); -+ if (features & BIT(EXTIOI_ENABLE)) { -+ ret |= BIT_ULL(IOCSRM_EXTIOI_EN); -+ } -+ -+ if (features & BIT(EXTIOI_ENABLE_INT_ENCODE)) { -+ ret |= BIT_ULL(IOCSRM_EXTIOI_INT_ENCODE); -+ } -+ break; - } -- return 0ULL; -+ -+ *data = ret; -+ return MEMTX_OK; - } - - static const MemoryRegionOps loongarch_qemu_ops = { -- .read = loongarch_qemu_read, -- .write = loongarch_qemu_write, -+ .read_with_attrs = loongarch_qemu_read, -+ .write_with_attrs = loongarch_qemu_write, - .endianness = DEVICE_LITTLE_ENDIAN, - .valid = { - .min_access_size = 4, -@@ -1010,6 +1075,11 @@ static void loongarch_machine_initfn(Object *obj) - { - LoongArchMachineState *lams = LOONGARCH_MACHINE(obj); - -+ if (kvm_enabled()) { -+ lams->v_eiointc = true; -+ } else { -+ lams->v_eiointc = false; -+ } - lams->acpi = ON_OFF_AUTO_AUTO; - lams->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6); - lams->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8); -@@ -1163,6 +1233,20 @@ static int64_t virt_get_default_cpu_node_id(const MachineState *ms, int idx) - return nidx; - } - -+static bool virt_get_v_eiointc(Object *obj, Error **errp) -+{ -+ LoongArchMachineState *lams = LOONGARCH_MACHINE(obj); -+ -+ return lams->v_eiointc; -+} -+ -+static void virt_set_v_eiointc(Object *obj, bool value, Error **errp) -+{ -+ LoongArchMachineState *lams = LOONGARCH_MACHINE(obj); -+ -+ lams->v_eiointc = value; -+} -+ - static void loongarch_class_init(ObjectClass *oc, void *data) - { - MachineClass *mc = MACHINE_CLASS(oc); -@@ -1201,6 +1285,12 @@ static void loongarch_class_init(ObjectClass *oc, void *data) - #ifdef CONFIG_TPM - machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS); - #endif -+ -+ object_class_property_add_bool(oc, "v-eiointc", virt_get_v_eiointc, -+ virt_set_v_eiointc); -+ object_class_property_set_description(oc, "v-eiointc", -+ "Set on/off to enable/disable The virt" -+ "LoongArch Extend I/O Interrupt Controller. "); - } - - static const TypeInfo loongarch_machine_types[] = { -diff --git a/include/hw/intc/loongarch_extioi.h b/include/hw/intc/loongarch_extioi.h -index a0a46b888c..3742fce3ee 100644 ---- a/include/hw/intc/loongarch_extioi.h -+++ b/include/hw/intc/loongarch_extioi.h -@@ -36,10 +36,27 @@ - #define EXTIOI_ISR_START (0x700 - APIC_OFFSET) - #define EXTIOI_ISR_END (0x720 - APIC_OFFSET) - #define EXTIOI_COREISR_START (0x800 - APIC_OFFSET) --#define EXTIOI_COREISR_END (0xB20 - APIC_OFFSET) -+#define EXTIOI_COREISR_END (0x820 - APIC_OFFSET) - #define EXTIOI_COREMAP_START (0xC00 - APIC_OFFSET) - #define EXTIOI_COREMAP_END (0xD00 - APIC_OFFSET) - -+#define EXTIOI_VIRT_BASE (0x40000000) -+#define EXTIOI_VIRT_SIZE (0x1000) -+#define EXTIOI_VIRT_FEATURES (0x0) -+#define EXTIOI_HAS_VIRT_EXTENSION (0) -+#define EXTIOI_HAS_ENABLE_OPTION (1) -+#define EXTIOI_HAS_INT_ENCODE (2) -+#define EXTIOI_HAS_CPU_ENCODE (3) -+#define EXTIOI_VIRT_HAS_FEATURES (BIT(EXTIOI_HAS_VIRT_EXTENSION) \ -+ | BIT(EXTIOI_HAS_INT_ENCODE) \ -+ | BIT(EXTIOI_HAS_CPU_ENCODE)) -+#define EXTIOI_VIRT_CONFIG (0x4) -+#define EXTIOI_ENABLE (1) -+#define EXTIOI_ENABLE_INT_ENCODE (2) -+#define EXTIOI_ENABLE_CPU_ENCODE (3) -+#define EXTIOI_VIRT_COREMAP_START (0x40) -+#define EXTIOI_VIRT_COREMAP_END (0x240) -+ - typedef struct ExtIOICore { - uint32_t coreisr[EXTIOI_IRQS_GROUP_COUNT]; - DECLARE_BITMAP(sw_isr[LS3A_INTC_IP], EXTIOI_IRQS); -@@ -51,6 +68,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(LoongArchExtIOI, LOONGARCH_EXTIOI) - struct LoongArchExtIOI { - SysBusDevice parent_obj; - uint32_t num_cpu; -+ uint32_t features; -+ uint32_t status; - /* hardware state */ - uint32_t nodetype[EXTIOI_IRQS_NODETYPE_COUNT / 2]; - uint32_t bounce[EXTIOI_IRQS_GROUP_COUNT]; -@@ -64,5 +83,6 @@ struct LoongArchExtIOI { - qemu_irq irq[EXTIOI_IRQS]; - ExtIOICore *cpu; - MemoryRegion extioi_system_mem; -+ MemoryRegion virt_extend; - }; - #endif /* LOONGARCH_EXTIOI_H */ -diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h -index 252f7df7f4..d48aa579b2 100644 ---- a/include/hw/loongarch/virt.h -+++ b/include/hw/loongarch/virt.h -@@ -40,6 +40,7 @@ struct LoongArchMachineState { - MemoryRegion highmem; - MemoryRegion bios; - bool bios_loaded; -+ bool v_eiointc; - /* State for other subsystems/APIs: */ - FWCfgState *fw_cfg; - Notifier machine_done; -@@ -50,11 +51,13 @@ struct LoongArchMachineState { - DeviceState *acpi_ged; - int fdt_size; - DeviceState *platform_bus_dev; -+ DeviceState *extioi; - PCIBus *pci_bus; - PFlashCFI01 *flash[2]; - MemoryRegion system_iocsr; - MemoryRegion iocsr_mem; - AddressSpace as_iocsr; -+ int features; - }; - - #define TYPE_LOONGARCH_MACHINE MACHINE_TYPE_NAME("virt") -diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h -index 4aba8aba4c..4749d41c8c 100644 ---- a/target/loongarch/cpu.h -+++ b/target/loongarch/cpu.h -@@ -36,6 +36,7 @@ - #define CPUNAME_REG 0x20 - #define MISC_FUNC_REG 0x420 - #define IOCSRM_EXTIOI_EN 48 -+#define IOCSRM_EXTIOI_INT_ENCODE 49 - - #define IOCSR_MEM_SIZE 0x428 - --- -2.33.0 - diff --git a/0031-target-loongarch-kvm-sync-kernel-header-files.patch b/0031-target-loongarch-kvm-sync-kernel-header-files.patch deleted file mode 100644 index b276524c6d7ce7a7202336b28210fd6005520255..0000000000000000000000000000000000000000 --- a/0031-target-loongarch-kvm-sync-kernel-header-files.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 1218acb3c23776861fa6b59d1eafc89aede8c246 Mon Sep 17 00:00:00 2001 -From: Bibo Mao -Date: Wed, 13 Mar 2024 10:04:33 +0800 -Subject: [PATCH] target/loongarch/kvm: sync kernel header files - -sync kernel header files. - -Signed-off-by: Bibo Mao ---- - linux-headers/asm-loongarch/kvm.h | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/linux-headers/asm-loongarch/kvm.h b/linux-headers/asm-loongarch/kvm.h -index 923d0bd382..4cec8c1601 100644 ---- a/linux-headers/asm-loongarch/kvm.h -+++ b/linux-headers/asm-loongarch/kvm.h -@@ -15,10 +15,12 @@ - */ - - #define __KVM_HAVE_READONLY_MEM -+#define __KVM_HAVE_GUEST_DEBUG - - #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 - #define KVM_DIRTY_LOG_PAGE_OFFSET 64 - -+#define KVM_GUESTDBG_USE_SW_BP 0x00010000 - /* - * for KVM_GET_REGS and KVM_SET_REGS - */ -@@ -74,6 +76,8 @@ struct kvm_fpu { - - #define KVM_REG_LOONGARCH_COUNTER (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 1) - #define KVM_REG_LOONGARCH_VCPU_RESET (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 2) -+/* Debugging: Special instruction for software breakpoint */ -+#define KVM_REG_LOONGARCH_DEBUG_INST (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 3) - - #define LOONGARCH_REG_SHIFT 3 - #define LOONGARCH_REG_64(TYPE, REG) (TYPE | KVM_REG_SIZE_U64 | (REG << LOONGARCH_REG_SHIFT)) --- -2.33.0 - diff --git a/0032-hw-intc-loongarch_extioi-Add-virt-extension-support-.patch b/0032-hw-intc-loongarch_extioi-Add-virt-extension-support-.patch deleted file mode 100644 index 8a5884f44d7c1e0e5aff56a91a813e786d894f6c..0000000000000000000000000000000000000000 --- a/0032-hw-intc-loongarch_extioi-Add-virt-extension-support-.patch +++ /dev/null @@ -1,256 +0,0 @@ -From 93ea12e1570160c9048966a2a08a35cda2a2a6af Mon Sep 17 00:00:00 2001 -From: Bibo Mao -Date: Wed, 13 Mar 2024 17:46:19 +0800 -Subject: [PATCH] hw/intc/loongarch_extioi: Add virt extension support v2 - -fix 954c513fa3846f34ecd81e4eb25457ed49362b39 -"Add virt extension support" in v2 version. - -Signed-off-by: Bibo Mao ---- - hw/intc/loongarch_extioi.c | 24 ++++------- - hw/loongarch/virt.c | 64 +++++++++++++++++------------- - include/hw/intc/loongarch_extioi.h | 3 +- - include/hw/loongarch/virt.h | 2 +- - 4 files changed, 47 insertions(+), 46 deletions(-) - -diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c -index a892edcabb..fa23e247ca 100644 ---- a/hw/intc/loongarch_extioi.c -+++ b/hw/intc/loongarch_extioi.c -@@ -55,11 +55,6 @@ static void extioi_update_irq(LoongArchExtIOI *s, int irq, int level) - static void extioi_setirq(void *opaque, int irq, int level) - { - LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque); -- -- if (s->status & BIT(EXTIOI_ENABLE)) { -- return; -- } -- - trace_loongarch_extioi_setirq(irq, level); - if (level) { - /* -@@ -148,18 +143,17 @@ static inline void extioi_update_sw_coremap(LoongArchExtIOI *s, int irq, - - for (i = 0; i < 4; i++) { - cpu = val & 0xff; -- val = val >> 8; -- -- if (!(s->status & BIT(EXTIOI_ENABLE_CPU_ENCODE))) { -+ if (!(s->status & BIT(EXTIOI_ENABLE_CPU_ENCODE))) { - cpu = ctz32(cpu); - cpu = (cpu >= 4) ? 0 : cpu; - } -+ val = val >> 8; - - if (s->sw_coremap[irq + i] == cpu) { - continue; - } - -- if (notify && test_bit(irq, (unsigned long *)s->isr)) { -+ if (notify && test_bit(irq + i, (unsigned long *)s->isr)) { - /* - * lower irq at old cpu and raise irq at new cpu - */ -@@ -185,12 +179,8 @@ static inline void extioi_update_sw_ipmap(LoongArchExtIOI *s, int index, - val = cpu_to_le64(val); - for (i = 0; i < 4; i++) { - ipnum = val & 0xff; -- if (s->status & EXTIOI_ENABLE_INT_ENCODE) { -- ipnum = (ipnum >= 8) ? 0 : ipnum; -- } else { -- ipnum = ctz32(ipnum); -- ipnum = (ipnum >= 4) ? 0 : ipnum; -- } -+ ipnum = ctz32(ipnum); -+ ipnum = (ipnum >= 4) ? 0 : ipnum; - s->sw_ipmap[index * 4 + i] = ipnum; - val = val >> 8; - } -@@ -386,7 +376,9 @@ static void loongarch_extioi_reset(DeviceState *d) - LoongArchExtIOI *s = LOONGARCH_EXTIOI(d); - - /* use legacy interrupt routing method by default */ -- s->status = 0; -+ if (s->features & BIT(EXTIOI_HAS_VIRT_EXTENSION)) { -+ s->status = 0; -+ } - } - - static int vmstate_extioi_post_load(void *opaque, int version_id) -diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c -index 00359643a2..01e59f3a95 100644 ---- a/hw/loongarch/virt.c -+++ b/hw/loongarch/virt.c -@@ -15,6 +15,7 @@ - #include "sysemu/runstate.h" - #include "sysemu/reset.h" - #include "sysemu/rtc.h" -+#include "sysemu/tcg.h" - #include "sysemu/kvm.h" - #include "hw/loongarch/virt.h" - #include "exec/address-spaces.h" -@@ -55,6 +56,31 @@ struct loaderparams { - const char *initrd_filename; - }; - -+static bool virt_is_veiointc_enabled(LoongArchMachineState *lams) -+{ -+ if (lams->veiointc == ON_OFF_AUTO_OFF) { -+ return false; -+ } -+ return true; -+} -+ -+static void virt_get_veiointc(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp) -+{ -+ LoongArchMachineState *lams = LOONGARCH_MACHINE(obj); -+ OnOffAuto veiointc = lams->veiointc; -+ -+ visit_type_OnOffAuto(v, name, &veiointc, errp); -+} -+ -+static void virt_set_veiointc(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp) -+{ -+ LoongArchMachineState *lams = LOONGARCH_MACHINE(obj); -+ -+ visit_type_OnOffAuto(v, name, &lams->veiointc, errp); -+} -+ - static PFlashCFI01 *virt_flash_create1(LoongArchMachineState *lams, - const char *name, - const char *alias_prop_name) -@@ -619,14 +645,14 @@ static void loongarch_irq_init(LoongArchMachineState *lams) - /* Create EXTIOI device */ - extioi = qdev_new(TYPE_LOONGARCH_EXTIOI); - qdev_prop_set_uint32(extioi, "num-cpu", ms->smp.cpus); -- if (lams->v_eiointc) { -+ if (virt_is_veiointc_enabled(lams)) { - qdev_prop_set_bit(extioi, "has-virtualization-extension", true); - } - sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi), &error_fatal); - - memory_region_add_subregion(&lams->system_iocsr, APIC_BASE, - sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 0)); -- if (lams->v_eiointc) { -+ if (virt_is_veiointc_enabled(lams)) { - memory_region_add_subregion(&lams->system_iocsr, EXTIOI_VIRT_BASE, - sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 1)); - } -@@ -798,7 +824,7 @@ static MemTxResult loongarch_qemu_write(void *opaque, hwaddr addr, uint64_t val, - - switch (addr) { - case MISC_FUNC_REG: -- if (!lams->v_eiointc) { -+ if (!virt_is_veiointc_enabled(lams)) { - return MEMTX_OK; - } - -@@ -846,7 +872,7 @@ static MemTxResult loongarch_qemu_read(void *opaque, hwaddr addr, - ret = 0x303030354133ULL; /* "3A5000" */ - break; - case MISC_FUNC_REG: -- if (!lams->v_eiointc) { -+ if (!virt_is_veiointc_enabled(lams)) { - ret |= BIT_ULL(IOCSRM_EXTIOI_EN); - break; - } -@@ -1075,10 +1101,8 @@ static void loongarch_machine_initfn(Object *obj) - { - LoongArchMachineState *lams = LOONGARCH_MACHINE(obj); - -- if (kvm_enabled()) { -- lams->v_eiointc = true; -- } else { -- lams->v_eiointc = false; -+ if (tcg_enabled()) { -+ lams->veiointc = ON_OFF_AUTO_OFF; - } - lams->acpi = ON_OFF_AUTO_AUTO; - lams->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6); -@@ -1233,20 +1257,6 @@ static int64_t virt_get_default_cpu_node_id(const MachineState *ms, int idx) - return nidx; - } - --static bool virt_get_v_eiointc(Object *obj, Error **errp) --{ -- LoongArchMachineState *lams = LOONGARCH_MACHINE(obj); -- -- return lams->v_eiointc; --} -- --static void virt_set_v_eiointc(Object *obj, bool value, Error **errp) --{ -- LoongArchMachineState *lams = LOONGARCH_MACHINE(obj); -- -- lams->v_eiointc = value; --} -- - static void loongarch_class_init(ObjectClass *oc, void *data) - { - MachineClass *mc = MACHINE_CLASS(oc); -@@ -1281,16 +1291,14 @@ static void loongarch_class_init(ObjectClass *oc, void *data) - NULL, NULL); - object_class_property_set_description(oc, "acpi", - "Enable ACPI"); -+ object_class_property_add(oc, "v-eiointc", "OnOffAuto", -+ virt_get_veiointc, virt_set_veiointc, NULL, NULL); -+ object_class_property_set_description(oc, "v-eiointc", -+ "Enable Virt Extend I/O Interrupt Controller"); - machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE); - #ifdef CONFIG_TPM - machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS); - #endif -- -- object_class_property_add_bool(oc, "v-eiointc", virt_get_v_eiointc, -- virt_set_v_eiointc); -- object_class_property_set_description(oc, "v-eiointc", -- "Set on/off to enable/disable The virt" -- "LoongArch Extend I/O Interrupt Controller. "); - } - - static const TypeInfo loongarch_machine_types[] = { -diff --git a/include/hw/intc/loongarch_extioi.h b/include/hw/intc/loongarch_extioi.h -index 3742fce3ee..1cf5bf9922 100644 ---- a/include/hw/intc/loongarch_extioi.h -+++ b/include/hw/intc/loongarch_extioi.h -@@ -36,7 +36,7 @@ - #define EXTIOI_ISR_START (0x700 - APIC_OFFSET) - #define EXTIOI_ISR_END (0x720 - APIC_OFFSET) - #define EXTIOI_COREISR_START (0x800 - APIC_OFFSET) --#define EXTIOI_COREISR_END (0x820 - APIC_OFFSET) -+#define EXTIOI_COREISR_END (0xB20 - APIC_OFFSET) - #define EXTIOI_COREMAP_START (0xC00 - APIC_OFFSET) - #define EXTIOI_COREMAP_END (0xD00 - APIC_OFFSET) - -@@ -48,6 +48,7 @@ - #define EXTIOI_HAS_INT_ENCODE (2) - #define EXTIOI_HAS_CPU_ENCODE (3) - #define EXTIOI_VIRT_HAS_FEATURES (BIT(EXTIOI_HAS_VIRT_EXTENSION) \ -+ | BIT(EXTIOI_HAS_ENABLE_OPTION)\ - | BIT(EXTIOI_HAS_INT_ENCODE) \ - | BIT(EXTIOI_HAS_CPU_ENCODE)) - #define EXTIOI_VIRT_CONFIG (0x4) -diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h -index d48aa579b2..99447fd1d6 100644 ---- a/include/hw/loongarch/virt.h -+++ b/include/hw/loongarch/virt.h -@@ -40,12 +40,12 @@ struct LoongArchMachineState { - MemoryRegion highmem; - MemoryRegion bios; - bool bios_loaded; -- bool v_eiointc; - /* State for other subsystems/APIs: */ - FWCfgState *fw_cfg; - Notifier machine_done; - Notifier powerdown_notifier; - OnOffAuto acpi; -+ OnOffAuto veiointc; - char *oem_id; - char *oem_table_id; - DeviceState *acpi_ged; --- -2.33.0 - diff --git a/0033-target-loongarch-kvm-Add-pmu-support.patch b/0033-target-loongarch-kvm-Add-pmu-support.patch deleted file mode 100644 index b4881f8d272f43c72d25c9c65eeaae94d98470fb..0000000000000000000000000000000000000000 --- a/0033-target-loongarch-kvm-Add-pmu-support.patch +++ /dev/null @@ -1,224 +0,0 @@ -From 9e21ba794167d715590bb05f373b09b6409da8cc Mon Sep 17 00:00:00 2001 -From: Song Gao -Date: Fri, 22 Mar 2024 19:26:35 +0800 -Subject: [PATCH] target/loongarch/kvm: Add pmu support - -This patch adds PMU support - e.g - '... -cpu max,pmu=on,pmnum=[1-16]'; - '... -cpu max,pmu=on' (default pmnum = 4); - '... -cpu max,pmu=off' (disable PMU) - -Signed-off-by: Song Gao ---- - target/loongarch/cpu.c | 64 +++++++++++++++++++++++++++ - target/loongarch/cpu.h | 2 + - target/loongarch/kvm/kvm.c | 55 ++++++++++++++++++++++- - target/loongarch/loongarch-qmp-cmds.c | 2 +- - 4 files changed, 121 insertions(+), 2 deletions(-) - -diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c -index b098b1c6f3..86d18f89a4 100644 ---- a/target/loongarch/cpu.c -+++ b/target/loongarch/cpu.c -@@ -8,6 +8,7 @@ - #include "qemu/osdep.h" - #include "qemu/log.h" - #include "qemu/qemu-print.h" -+#include "qemu/error-report.h" - #include "qapi/error.h" - #include "qemu/module.h" - #include "sysemu/qtest.h" -@@ -19,6 +20,7 @@ - #include "internals.h" - #include "fpu/softfloat-helpers.h" - #include "cpu-csr.h" -+#include "qapi/visitor.h" - #include "sysemu/reset.h" - #include "vec.h" - #ifdef CONFIG_KVM -@@ -420,6 +422,14 @@ static void loongarch_la464_initfn(Object *obj) - data = FIELD_DP32(data, CPUCFG5, CC_DIV, 1); - env->cpucfg[5] = data; - -+ if (kvm_enabled()) { -+ data = 0; -+ data = FIELD_DP32(data, CPUCFG6, PMP, 1); -+ data = FIELD_DP32(data, CPUCFG6, PMNUM, 3); -+ data = FIELD_DP32(data, CPUCFG6, PMBITS, 63); -+ env->cpucfg[6] = data; -+ } -+ - data = 0; - data = FIELD_DP32(data, CPUCFG16, L1_IUPRE, 1); - data = FIELD_DP32(data, CPUCFG16, L1_DPRE, 1); -@@ -654,6 +664,48 @@ static void loongarch_set_lasx(Object *obj, bool value, Error **errp) - } - } - -+static bool loongarch_get_pmu(Object *obj, Error **errp) -+{ -+ LoongArchCPU *cpu = LOONGARCH_CPU(obj); -+ -+ return !!(FIELD_EX32(cpu->env.cpucfg[6], CPUCFG6, PMP)); -+} -+ -+static void loongarch_set_pmu(Object *obj, bool value, Error **errp) -+{ -+ LoongArchCPU *cpu = LOONGARCH_CPU(obj); -+ -+ cpu->env.cpucfg[6] = FIELD_DP32(cpu->env.cpucfg[6], CPUCFG6, PMP, value); -+} -+ -+static void loongarch_get_pmnum(Object *obj, Visitor *v, -+ const char *name, void *opaque, -+ Error **errp) -+{ -+ LoongArchCPU *cpu = LOONGARCH_CPU(obj); -+ uint32_t value = FIELD_EX32(cpu->env.cpucfg[6], CPUCFG6, PMNUM); -+ -+ visit_type_uint32(v, name, &value, errp); -+} -+ -+static void loongarch_set_pmnum(Object *obj, Visitor *v, -+ const char *name, void *opaque, -+ Error **errp) -+{ -+ LoongArchCPU *cpu = LOONGARCH_CPU(obj); -+ uint32_t *value= opaque; -+ -+ if (!visit_type_uint32(v, name, value, errp)) { -+ return; -+ } -+ if ((*value <= PMNUM_MAX) && (*value > 0)) { -+ cpu->env.cpucfg[6] = FIELD_DP32(cpu->env.cpucfg[6], CPUCFG6, PMNUM, *value -1); -+ } else { -+ error_report("Performance counter number need be in [1- %d]\n", PMNUM_MAX); -+ exit(EXIT_FAILURE); -+ } -+} -+ - void loongarch_cpu_post_init(Object *obj) - { - LoongArchCPU *cpu = LOONGARCH_CPU(obj); -@@ -666,6 +718,18 @@ void loongarch_cpu_post_init(Object *obj) - object_property_add_bool(obj, "lasx", loongarch_get_lasx, - loongarch_set_lasx); - } -+ -+ if (kvm_enabled()) { -+ object_property_add_bool(obj, "pmu", loongarch_get_pmu, -+ loongarch_set_pmu); -+ if (FIELD_EX32(cpu->env.cpucfg[6], CPUCFG6, PMP)) { -+ uint32_t value = 4; -+ object_property_add(obj, "pmnum", "uint32", -+ loongarch_get_pmnum, -+ loongarch_set_pmnum, NULL, -+ (void *)&value); -+ } -+ } - } - - static void loongarch_cpu_init(Object *obj) -diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h -index 4749d41c8c..80cad24fa1 100644 ---- a/target/loongarch/cpu.h -+++ b/target/loongarch/cpu.h -@@ -186,6 +186,8 @@ FIELD(CPUCFG6, PMNUM, 4, 4) - FIELD(CPUCFG6, PMBITS, 8, 6) - FIELD(CPUCFG6, UPM, 14, 1) - -+#define PMNUM_MAX 16 -+ - /* cpucfg[16] bits */ - FIELD(CPUCFG16, L1_IUPRE, 0, 1) - FIELD(CPUCFG16, L1_IUUNIFY, 1, 1) -diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c -index 49d02076ad..5dda631b2b 100644 ---- a/target/loongarch/kvm/kvm.c -+++ b/target/loongarch/kvm/kvm.c -@@ -573,6 +573,53 @@ static int kvm_check_cpucfg2(CPUState *cs) - return ret; - } - -+static int kvm_check_cpucfg6(CPUState *cs) -+{ -+ int ret; -+ uint64_t val; -+ struct kvm_device_attr attr = { -+ .group = KVM_LOONGARCH_VCPU_CPUCFG, -+ .attr = 6, -+ .addr = (uint64_t)&val, -+ }; -+ LoongArchCPU *cpu = LOONGARCH_CPU(cs); -+ CPULoongArchState *env = &cpu->env; -+ -+ ret = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, &attr); -+ if (!ret) { -+ kvm_vcpu_ioctl(cs, KVM_GET_DEVICE_ATTR, &attr); -+ -+ if (FIELD_EX32(env->cpucfg[6], CPUCFG6, PMP)) { -+ /* Check PMP */ -+ if (!FIELD_EX32(val, CPUCFG6, PMP)) { -+ error_report("'pmu' feature not supported by KVM on this host" -+ " Please disable 'pmu' with " -+ "'... -cpu XXX,pmu=off ...'\n"); -+ exit(EXIT_FAILURE); -+ } -+ /* Check PMNUM */ -+ int guest_pmnum = FIELD_EX32(env->cpucfg[6], CPUCFG6, PMNUM); -+ int host_pmnum = FIELD_EX32(val, CPUCFG6, PMNUM); -+ if (guest_pmnum > host_pmnum){ -+ warn_report("The guest pmnum %d larger than KVM support %d\n", -+ guest_pmnum, host_pmnum); -+ env->cpucfg[6] = FIELD_DP32(env->cpucfg[6], CPUCFG6, -+ PMNUM, host_pmnum); -+ } -+ /* Check PMBITS */ -+ int guest_pmbits = FIELD_EX32(env->cpucfg[6], CPUCFG6, PMBITS); -+ int host_pmbits = FIELD_EX32(val, CPUCFG6, PMBITS); -+ if (guest_pmbits != host_pmbits) { -+ warn_report("The host not support PMBITS %d\n", guest_pmbits); -+ env->cpucfg[6] = FIELD_DP32(env->cpucfg[6], CPUCFG6, -+ PMBITS, host_pmbits); -+ } -+ } -+ } -+ -+ return ret; -+} -+ - static int kvm_loongarch_put_cpucfg(CPUState *cs) - { - int i, ret = 0; -@@ -586,7 +633,13 @@ static int kvm_loongarch_put_cpucfg(CPUState *cs) - if (ret) { - return ret; - } -- } -+ } -+ if (i == 6) { -+ ret = kvm_check_cpucfg6(cs); -+ if (ret) { -+ return ret; -+ } -+ } - val = env->cpucfg[i]; - ret = kvm_set_one_reg(cs, KVM_IOC_CPUCFG(i), &val); - if (ret < 0) { -diff --git a/target/loongarch/loongarch-qmp-cmds.c b/target/loongarch/loongarch-qmp-cmds.c -index 645672ff59..2612f43de9 100644 ---- a/target/loongarch/loongarch-qmp-cmds.c -+++ b/target/loongarch/loongarch-qmp-cmds.c -@@ -42,7 +42,7 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) - } - - static const char *cpu_model_advertised_features[] = { -- "lsx", "lasx", NULL -+ "lsx", "lasx", "pmu", "pmnum", NULL - }; - - CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type, --- -2.33.0 - diff --git a/0034-target-loongarch-Fix-qemu-system-loongarch64-assert-.patch b/0034-target-loongarch-Fix-qemu-system-loongarch64-assert-.patch deleted file mode 100644 index 659cfc15369d7360af748f4a254050f5798205e3..0000000000000000000000000000000000000000 --- a/0034-target-loongarch-Fix-qemu-system-loongarch64-assert-.patch +++ /dev/null @@ -1,131 +0,0 @@ -From 9e66722c617c4e01e2a5efdd7f533fd9d225033b Mon Sep 17 00:00:00 2001 -From: Song Gao -Date: Tue, 2 Apr 2024 09:39:36 +0800 -Subject: [PATCH] target/loongarch: Fix qemu-system-loongarch64 assert - failed with the option '-d int' -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -qemu-system-loongarch64 assert failed with the option '-d int', -the helper_idle() raise an exception EXCP_HLT, but the exception name is undefined. - -Signed-off-by: Song Gao -Reviewed-by: Philippe Mathieu-Daudé -Message-Id: <20240321123606.1704900-1-gaosong@loongson.cn> ---- - target/loongarch/cpu.c | 74 +++++++++++++++++++++++------------------- - 1 file changed, 40 insertions(+), 34 deletions(-) - -diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c -index 86d18f89a4..bc557f207b 100644 ---- a/target/loongarch/cpu.c -+++ b/target/loongarch/cpu.c -@@ -45,33 +45,45 @@ const char * const fregnames[32] = { - "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", - }; - --static const char * const excp_names[] = { -- [EXCCODE_INT] = "Interrupt", -- [EXCCODE_PIL] = "Page invalid exception for load", -- [EXCCODE_PIS] = "Page invalid exception for store", -- [EXCCODE_PIF] = "Page invalid exception for fetch", -- [EXCCODE_PME] = "Page modified exception", -- [EXCCODE_PNR] = "Page Not Readable exception", -- [EXCCODE_PNX] = "Page Not Executable exception", -- [EXCCODE_PPI] = "Page Privilege error", -- [EXCCODE_ADEF] = "Address error for instruction fetch", -- [EXCCODE_ADEM] = "Address error for Memory access", -- [EXCCODE_SYS] = "Syscall", -- [EXCCODE_BRK] = "Break", -- [EXCCODE_INE] = "Instruction Non-Existent", -- [EXCCODE_IPE] = "Instruction privilege error", -- [EXCCODE_FPD] = "Floating Point Disabled", -- [EXCCODE_FPE] = "Floating Point Exception", -- [EXCCODE_DBP] = "Debug breakpoint", -- [EXCCODE_BCE] = "Bound Check Exception", -- [EXCCODE_SXD] = "128 bit vector instructions Disable exception", -- [EXCCODE_ASXD] = "256 bit vector instructions Disable exception", -+struct TypeExcp { -+ int32_t exccode; -+ const char * const name; -+}; -+ -+static const struct TypeExcp excp_names[] = { -+ {EXCCODE_INT, "Interrupt"}, -+ {EXCCODE_PIL, "Page invalid exception for load"}, -+ {EXCCODE_PIS, "Page invalid exception for store"}, -+ {EXCCODE_PIF, "Page invalid exception for fetch"}, -+ {EXCCODE_PME, "Page modified exception"}, -+ {EXCCODE_PNR, "Page Not Readable exception"}, -+ {EXCCODE_PNX, "Page Not Executable exception"}, -+ {EXCCODE_PPI, "Page Privilege error"}, -+ {EXCCODE_ADEF, "Address error for instruction fetch"}, -+ {EXCCODE_ADEM, "Address error for Memory access"}, -+ {EXCCODE_SYS, "Syscall"}, -+ {EXCCODE_BRK, "Break"}, -+ {EXCCODE_INE, "Instruction Non-Existent"}, -+ {EXCCODE_IPE, "Instruction privilege error"}, -+ {EXCCODE_FPD, "Floating Point Disabled"}, -+ {EXCCODE_FPE, "Floating Point Exception"}, -+ {EXCCODE_DBP, "Debug breakpoint"}, -+ {EXCCODE_BCE, "Bound Check Exception"}, -+ {EXCCODE_SXD, "128 bit vector instructions Disable exception"}, -+ {EXCCODE_ASXD, "256 bit vector instructions Disable exception"}, -+ {EXCP_HLT, "EXCP_HLT"}, - }; - - const char *loongarch_exception_name(int32_t exception) - { -- assert(excp_names[exception]); -- return excp_names[exception]; -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(excp_names); i++) { -+ if (excp_names[i].exccode == exception) { -+ return excp_names[i].name; -+ } -+ } -+ return "Unknown"; - } - - void G_NORETURN do_raise_exception(CPULoongArchState *env, -@@ -80,7 +92,7 @@ void G_NORETURN do_raise_exception(CPULoongArchState *env, - { - CPUState *cs = env_cpu(env); - -- qemu_log_mask(CPU_LOG_INT, "%s: %d (%s)\n", -+ qemu_log_mask(CPU_LOG_INT, "%s: expection: %d (%s)\n", - __func__, - exception, - loongarch_exception_name(exception)); -@@ -161,22 +173,16 @@ static void loongarch_cpu_do_interrupt(CPUState *cs) - CPULoongArchState *env = &cpu->env; - bool update_badinstr = 1; - int cause = -1; -- const char *name; - bool tlbfill = FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR); - uint32_t vec_size = FIELD_EX64(env->CSR_ECFG, CSR_ECFG, VS); - - if (cs->exception_index != EXCCODE_INT) { -- if (cs->exception_index < 0 || -- cs->exception_index >= ARRAY_SIZE(excp_names)) { -- name = "unknown"; -- } else { -- name = excp_names[cs->exception_index]; -- } -- - qemu_log_mask(CPU_LOG_INT, - "%s enter: pc " TARGET_FMT_lx " ERA " TARGET_FMT_lx -- " TLBRERA " TARGET_FMT_lx " %s exception\n", __func__, -- env->pc, env->CSR_ERA, env->CSR_TLBRERA, name); -+ " TLBRERA " TARGET_FMT_lx " exception: %d (%s)\n", -+ __func__, env->pc, env->CSR_ERA, env->CSR_TLBRERA, -+ cs->exception_index, -+ loongarch_exception_name(cs->exception_index)); - } - - switch (cs->exception_index) { --- -2.33.0 - diff --git a/0035-newfeature-support-vpsp.patch b/0035-newfeature-support-vpsp.patch deleted file mode 100644 index 05a4bd6e1e9a0e3e78679a68df5a1b4e1714a033..0000000000000000000000000000000000000000 --- a/0035-newfeature-support-vpsp.patch +++ /dev/null @@ -1,191 +0,0 @@ -From 445b34648510cfae60fa52311199dcf9e6b3c24d Mon Sep 17 00:00:00 2001 -From: xiongmengbiao -Date: Thu, 30 Nov 2023 13:47:21 +0800 -Subject: [PATCH] [newfeature]: support vpsp - -simulate a psp misc device for support tkm's key isolation - -Change-Id: I4d9fb5a8722e90a62c52eb97069c613834ced63f -Signed-off-by: xiongmengbiao ---- - hw/misc/Kconfig | 4 ++ - hw/misc/meson.build | 1 + - hw/misc/psp.c | 141 ++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 146 insertions(+) - create mode 100644 hw/misc/psp.c - -diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig -index cc8a8c1418..2ea5c68eb5 100644 ---- a/hw/misc/Kconfig -+++ b/hw/misc/Kconfig -@@ -200,4 +200,8 @@ config IOSB - config XLNX_VERSAL_TRNG - bool - -+config PSP_DEV -+ bool -+ default y -+ - source macio/Kconfig -diff --git a/hw/misc/meson.build b/hw/misc/meson.build -index 36c20d5637..28cba0ac28 100644 ---- a/hw/misc/meson.build -+++ b/hw/misc/meson.build -@@ -9,6 +9,7 @@ system_ss.add(when: 'CONFIG_UNIMP', if_true: files('unimp.c')) - system_ss.add(when: 'CONFIG_EMPTY_SLOT', if_true: files('empty_slot.c')) - system_ss.add(when: 'CONFIG_LED', if_true: files('led.c')) - system_ss.add(when: 'CONFIG_PVPANIC_COMMON', if_true: files('pvpanic.c')) -+system_ss.add(when: 'CONFIG_PSP_DEV', if_true: files('psp.c')) - - # ARM devices - system_ss.add(when: 'CONFIG_PL310', if_true: files('arm_l2x0.c')) -diff --git a/hw/misc/psp.c b/hw/misc/psp.c -new file mode 100644 -index 0000000000..1cfbab859e ---- /dev/null -+++ b/hw/misc/psp.c -@@ -0,0 +1,141 @@ -+/* -+ * hygon psp device emulation -+ * -+ * Copyright 2024 HYGON Corp. -+ * -+ * This work is licensed under the terms of the GNU GPL, version 2 or (at -+ * your option) any later version. See the COPYING file in the top-level -+ * directory. -+ */ -+ -+#include "qemu/osdep.h" -+#include "qemu/compiler.h" -+#include "qemu/error-report.h" -+#include "qapi/error.h" -+#include "migration/vmstate.h" -+#include "hw/qdev-properties.h" -+#include "sysemu/runstate.h" -+#include -+ -+#define TYPE_PSP_DEV "psp" -+OBJECT_DECLARE_SIMPLE_TYPE(PSPDevState, PSP_DEV) -+ -+struct PSPDevState { -+ /* Private */ -+ DeviceState pdev; -+ -+ /* Public */ -+ Notifier shutdown_notifier; -+ int dev_fd; -+ uint8_t enabled; -+ -+ /** -+ * vid is used to identify a virtual machine in qemu. -+ * When a virtual machine accesses a tkm key, -+ * the TKM module uses different key spaces based on different vids. -+ */ -+ uint32_t vid; -+}; -+ -+#define PSP_DEV_PATH "/dev/hygon_psp_config" -+#define HYGON_PSP_IOC_TYPE 'H' -+#define PSP_IOC_MUTEX_ENABLE _IOWR(HYGON_PSP_IOC_TYPE, 1, NULL) -+#define PSP_IOC_MUTEX_DISABLE _IOWR(HYGON_PSP_IOC_TYPE, 2, NULL) -+#define PSP_IOC_VPSP_OPT _IOWR(HYGON_PSP_IOC_TYPE, 3, NULL) -+ -+enum VPSP_DEV_CTRL_OPCODE { -+ VPSP_OP_VID_ADD, -+ VPSP_OP_VID_DEL, -+}; -+ -+struct psp_dev_ctrl { -+ unsigned char op; -+ union { -+ unsigned int vid; -+ unsigned char reserved[128]; -+ } data; -+}; -+ -+static void psp_dev_destroy(PSPDevState *state) -+{ -+ struct psp_dev_ctrl ctrl = { 0 }; -+ if (state && state->dev_fd >= 0) { -+ if (state->enabled) { -+ ctrl.op = VPSP_OP_VID_DEL; -+ if (ioctl(state->dev_fd, PSP_IOC_VPSP_OPT, &ctrl) < 0) { -+ error_report("VPSP_OP_VID_DEL: %d", -errno); -+ } else { -+ state->enabled = false; -+ } -+ } -+ qemu_close(state->dev_fd); -+ state->dev_fd = -1; -+ } -+} -+ -+/** -+ * Guest OS performs shut down operations through 'shutdown' and 'powerdown' event. -+ * The 'powerdown' event will also trigger 'shutdown' in the end, -+ * so only attention to the 'shutdown' event. -+ * -+ * When Guest OS trigger 'reboot' or 'reset' event, to do nothing. -+*/ -+static void psp_dev_shutdown_notify(Notifier *notifier, void *data) -+{ -+ PSPDevState *state = container_of(notifier, PSPDevState, shutdown_notifier); -+ psp_dev_destroy(state); -+} -+ -+static void psp_dev_realize(DeviceState *dev, Error **errp) -+{ -+ struct psp_dev_ctrl ctrl = { 0 }; -+ PSPDevState *state = PSP_DEV(dev); -+ -+ state->dev_fd = qemu_open_old(PSP_DEV_PATH, O_RDWR); -+ if (state->dev_fd < 0) { -+ error_setg(errp, "fail to open %s, errno %d.", PSP_DEV_PATH, errno); -+ goto end; -+ } -+ -+ ctrl.op = VPSP_OP_VID_ADD; -+ ctrl.data.vid = state->vid; -+ if (ioctl(state->dev_fd, PSP_IOC_VPSP_OPT, &ctrl) < 0) { -+ error_setg(errp, "psp_dev_realize VPSP_OP_VID_ADD vid %d, return %d", ctrl.data.vid, -errno); -+ goto end; -+ } -+ -+ state->enabled = true; -+ state->shutdown_notifier.notify = psp_dev_shutdown_notify; -+ qemu_register_shutdown_notifier(&state->shutdown_notifier); -+end: -+ return; -+} -+ -+static struct Property psp_dev_properties[] = { -+ DEFINE_PROP_UINT32("vid", PSPDevState, vid, 0), -+ DEFINE_PROP_END_OF_LIST(), -+}; -+ -+static void psp_dev_class_init(ObjectClass *klass, void *data) -+{ -+ DeviceClass *dc = DEVICE_CLASS(klass); -+ -+ dc->desc = "PSP Device"; -+ dc->realize = psp_dev_realize; -+ set_bit(DEVICE_CATEGORY_MISC, dc->categories); -+ device_class_set_props(dc, psp_dev_properties); -+} -+ -+static const TypeInfo psp_dev_info = { -+ .name = TYPE_PSP_DEV, -+ .parent = TYPE_DEVICE, -+ .instance_size = sizeof(PSPDevState), -+ .class_init = psp_dev_class_init, -+}; -+ -+static void psp_dev_register_types(void) -+{ -+ type_register_static(&psp_dev_info); -+} -+ -+type_init(psp_dev_register_types) --- -2.41.0 - diff --git a/0036-target-loongarch-kvm-Fix-VM-recovery-from-disk-failu.patch b/0036-target-loongarch-kvm-Fix-VM-recovery-from-disk-failu.patch deleted file mode 100644 index 70007479a596fb4717c73715e816350fd398b8e7..0000000000000000000000000000000000000000 --- a/0036-target-loongarch-kvm-Fix-VM-recovery-from-disk-failu.patch +++ /dev/null @@ -1,42 +0,0 @@ -From d93c003720daea0d50dd6bfacce3e01dec6fd6ba Mon Sep 17 00:00:00 2001 -From: Song Gao -Date: Wed, 8 May 2024 10:47:32 +0800 -Subject: [PATCH] target/loongarch/kvm: Fix VM recovery from disk failures - -vmstate does not save kvm_state_conter, -which can cause VM recovery from disk to fail. - -Signed-off-by: Song Gao -Acked-by: Peter Xu -Message-Id: <20240508024732.3127792-1-gaosong@loongson.cn> ---- - target/loongarch/machine.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/target/loongarch/machine.c b/target/loongarch/machine.c -index 1c4e01d076..5a7df713e2 100644 ---- a/target/loongarch/machine.c -+++ b/target/loongarch/machine.c -@@ -125,8 +125,8 @@ const VMStateDescription vmstate_tlb = { - /* LoongArch CPU state */ - const VMStateDescription vmstate_loongarch_cpu = { - .name = "cpu", -- .version_id = 1, -- .minimum_version_id = 1, -+ .version_id = 2, -+ .minimum_version_id = 2, - .fields = (VMStateField[]) { - VMSTATE_UINTTL_ARRAY(env.gpr, LoongArchCPU, 32), - VMSTATE_UINTTL(env.pc, LoongArchCPU), -@@ -191,6 +191,8 @@ const VMStateDescription vmstate_loongarch_cpu = { - VMSTATE_STRUCT_ARRAY(env.tlb, LoongArchCPU, LOONGARCH_TLB_MAX, - 0, vmstate_tlb, LoongArchTLB), - -+ VMSTATE_UINT64(kvm_state_counter, LoongArchCPU), -+ - VMSTATE_END_OF_LIST() - }, - .subsections = (const VMStateDescription*[]) { --- -2.33.0 - diff --git a/0037-target-loongarch-kvm-fpu-save-the-vreg-registers-hig.patch b/0037-target-loongarch-kvm-fpu-save-the-vreg-registers-hig.patch deleted file mode 100644 index 085408481c00a05b8383ab702e4adcdeb71eb862..0000000000000000000000000000000000000000 --- a/0037-target-loongarch-kvm-fpu-save-the-vreg-registers-hig.patch +++ /dev/null @@ -1,43 +0,0 @@ -From acc4c06ed8e754f73974bddc39a877f6b5dea867 Mon Sep 17 00:00:00 2001 -From: Song Gao -Date: Tue, 14 May 2024 19:07:52 +0800 -Subject: [PATCH 2/2] target/loongarch/kvm: fpu save the vreg registers high - 192bit - -On kvm side, get_fpu/set_fpu save the vreg registers high 192bits, -but QEMU missing. - -Signed-off-by: Song Gao -Reviewed-by: Bibo Mao -Message-Id: <20240514110752.989572-1-gaosong@loongson.cn> ---- - target/loongarch/kvm/kvm.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c -index bc75552d0f..8e6e27c8bf 100644 ---- a/target/loongarch/kvm/kvm.c -+++ b/target/loongarch/kvm/kvm.c -@@ -436,6 +436,9 @@ static int kvm_loongarch_get_regs_fp(CPUState *cs) - env->fcsr0 = fpu.fcsr; - for (i = 0; i < 32; i++) { - env->fpr[i].vreg.UD[0] = fpu.fpr[i].val64[0]; -+ env->fpr[i].vreg.UD[1] = fpu.fpr[i].val64[1]; -+ env->fpr[i].vreg.UD[2] = fpu.fpr[i].val64[2]; -+ env->fpr[i].vreg.UD[3] = fpu.fpr[i].val64[3]; - } - for (i = 0; i < 8; i++) { - env->cf[i] = fpu.fcc & 0xFF; -@@ -455,6 +458,9 @@ static int kvm_loongarch_put_regs_fp(CPUState *cs) - fpu.fcc = 0; - for (i = 0; i < 32; i++) { - fpu.fpr[i].val64[0] = env->fpr[i].vreg.UD[0]; -+ fpu.fpr[i].val64[1] = env->fpr[i].vreg.UD[1]; -+ fpu.fpr[i].val64[2] = env->fpr[i].vreg.UD[2]; -+ fpu.fpr[i].val64[3] = env->fpr[i].vreg.UD[3]; - } - - for (i = 0; i < 8; i++) { --- -2.34.1 - diff --git a/1001-i386-cpu-Clear-FEAT_XSAVE_XSS_LO-HI-leafs-when-CPUID.patch b/1001-i386-cpu-Clear-FEAT_XSAVE_XSS_LO-HI-leafs-when-CPUID.patch deleted file mode 100644 index 7709d6ec139a69acc9e6e183428117da8b627e95..0000000000000000000000000000000000000000 --- a/1001-i386-cpu-Clear-FEAT_XSAVE_XSS_LO-HI-leafs-when-CPUID.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 15c883697908b38e9021277d83480d382fc76b3a Mon Sep 17 00:00:00 2001 -From: Xiaoyao Li -Date: Mon, 15 Jan 2024 04:13:24 -0500 -Subject: [PATCH] i386/cpu: Clear FEAT_XSAVE_XSS_LO/HI leafs when - CPUID_EXT_XSAVE is not available - -commit 81f5cad3858f27623b1b14467926032d229b76cc upstream. - -Leaf FEAT_XSAVE_XSS_LO and FEAT_XSAVE_XSS_HI also need to be cleared -when CPUID_EXT_XSAVE is not set. - -Intel-SIG: commit 81f5cad3858f i386/cpu: Clear FEAT_XSAVE_XSS_LO/HI leafs when CPUID_EXT_XSAVE is not available -Backport i386/cpu fixes - -Fixes: 301e90675c3f ("target/i386: Enable support for XSAVES based features") -Signed-off-by: Xiaoyao Li -Reviewed-by: Yang Weijiang -Message-ID: <20240115091325.1904229-2-xiaoyao.li@intel.com> -Cc: qemu-stable@nongnu.org -Signed-off-by: Paolo Bonzini -Signed-off-by: Jason Zeng -Signed-off-by: Aubrey Li ---- - target/i386/cpu.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index cd16cb893daf..8b9ef218d3df 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -6927,6 +6927,8 @@ static void x86_cpu_enable_xsave_components(X86CPU *cpu) - if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) { - env->features[FEAT_XSAVE_XCR0_LO] = 0; - env->features[FEAT_XSAVE_XCR0_HI] = 0; -+ env->features[FEAT_XSAVE_XSS_LO] = 0; -+ env->features[FEAT_XSAVE_XSS_HI] = 0; - return; - } - --- -2.34.1 - diff --git a/1002-i386-cpu-Mask-with-XCR0-XSS-mask-for-FEAT_XSAVE_XCR0.patch b/1002-i386-cpu-Mask-with-XCR0-XSS-mask-for-FEAT_XSAVE_XCR0.patch deleted file mode 100644 index fbefa7fdfbf87fd4844368e870cf4f75eb69d8c1..0000000000000000000000000000000000000000 --- a/1002-i386-cpu-Mask-with-XCR0-XSS-mask-for-FEAT_XSAVE_XCR0.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 626266a79b8e4826c185e94ca2fc339a304a21ca Mon Sep 17 00:00:00 2001 -From: Xiaoyao Li -Date: Mon, 15 Jan 2024 04:13:25 -0500 -Subject: [PATCH] i386/cpu: Mask with XCR0/XSS mask for FEAT_XSAVE_XCR0_HI and - FEAT_XSAVE_XSS_HI leafs - -commit a11a365159b944e05be76f3ec3b98c8b38cb70fd upstream. - -The value of FEAT_XSAVE_XCR0_HI leaf and FEAT_XSAVE_XSS_HI leaf also -need to be masked by XCR0 and XSS mask respectively, to make it -logically correct. - -Intel-SIG: commit a11a365159b9 i386/cpu: Mask with XCR0/XSS mask for FEAT_XSAVE_XCR0_HI and FEAT_XSAVE_XSS_HI leafs -Backport i386/cpu fixes - -Fixes: 301e90675c3f ("target/i386: Enable support for XSAVES based features") -Signed-off-by: Xiaoyao Li -Reviewed-by: Yang Weijiang -Message-ID: <20240115091325.1904229-3-xiaoyao.li@intel.com> -Cc: qemu-stable@nongnu.org -Signed-off-by: Paolo Bonzini -Signed-off-by: Jason Zeng -Signed-off-by: Aubrey Li ---- - target/i386/cpu.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 8b9ef218d3df..a66e5a357b19 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -6947,9 +6947,9 @@ static void x86_cpu_enable_xsave_components(X86CPU *cpu) - } - - env->features[FEAT_XSAVE_XCR0_LO] = mask & CPUID_XSTATE_XCR0_MASK; -- env->features[FEAT_XSAVE_XCR0_HI] = mask >> 32; -+ env->features[FEAT_XSAVE_XCR0_HI] = (mask & CPUID_XSTATE_XCR0_MASK) >> 32; - env->features[FEAT_XSAVE_XSS_LO] = mask & CPUID_XSTATE_XSS_MASK; -- env->features[FEAT_XSAVE_XSS_HI] = mask >> 32; -+ env->features[FEAT_XSAVE_XSS_HI] = (mask & CPUID_XSTATE_XSS_MASK) >> 32; - } - - /***** Steps involved on loading and filtering CPUID data --- -2.34.1 - diff --git a/1003-i386-cpuid-Decrease-cpuid_i-when-skipping-CPUID-leaf.patch b/1003-i386-cpuid-Decrease-cpuid_i-when-skipping-CPUID-leaf.patch deleted file mode 100644 index ba00a2d200607973be16003455ec3fa095b4f500..0000000000000000000000000000000000000000 --- a/1003-i386-cpuid-Decrease-cpuid_i-when-skipping-CPUID-leaf.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 2bb1c3d8c6d669468c574db017c96df17e797dc9 Mon Sep 17 00:00:00 2001 -From: Xiaoyao Li -Date: Wed, 24 Jan 2024 21:40:14 -0500 -Subject: [PATCH] i386/cpuid: Decrease cpuid_i when skipping CPUID leaf 1F - -commit 10f92799af8ba3c3cef2352adcd4780f13fbab31 upstream. - -Existing code misses a decrement of cpuid_i when skip leaf 0x1F. -There's a blank CPUID entry(with leaf, subleaf as 0, and all fields -stuffed 0s) left in the CPUID array. - -It conflicts with correct CPUID leaf 0. - -Intel-SIG: commit 10f92799af8b i386/cpuid: Decrease cpuid_i when skipping CPUID leaf 1F -Backport i386/cpuid fixes - -Signed-off-by: Xiaoyao Li -Reviewed-by:Yang Weijiang -Message-ID: <20240125024016.2521244-2-xiaoyao.li@intel.com> -Cc: qemu-stable@nongnu.org -Signed-off-by: Paolo Bonzini -Signed-off-by: Jason Zeng -Signed-off-by: Aubrey Li ---- - target/i386/kvm/kvm.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index 4ce80555b45c..e68eb8f5e6b0 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -1914,6 +1914,7 @@ int kvm_arch_init_vcpu(CPUState *cs) - } - case 0x1f: - if (env->nr_dies < 2) { -+ cpuid_i--; - break; - } - /* fallthrough */ --- -2.34.1 - diff --git a/1004-i386-cpuid-Move-leaf-7-to-correct-group.patch b/1004-i386-cpuid-Move-leaf-7-to-correct-group.patch deleted file mode 100644 index 659f0efbf97034fa5a2ed084b056e298aba6dd98..0000000000000000000000000000000000000000 --- a/1004-i386-cpuid-Move-leaf-7-to-correct-group.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 6449fc40100be71bdb454f542ca708026cd5ad11 Mon Sep 17 00:00:00 2001 -From: Xiaoyao Li -Date: Wed, 24 Jan 2024 21:40:16 -0500 -Subject: [PATCH] i386/cpuid: Move leaf 7 to correct group - -commit 0729857c707535847d7fe31d3d91eb8b2a118e3c upstream. - -CPUID leaf 7 was grouped together with SGX leaf 0x12 by commit -b9edbadefb9e ("i386: Propagate SGX CPUID sub-leafs to KVM") by mistake. - -SGX leaf 0x12 has its specific logic to check if subleaf (starting from 2) -is valid or not by checking the bit 0:3 of corresponding EAX is 1 or -not. - -Leaf 7 follows the logic that EAX of subleaf 0 enumerates the maximum -valid subleaf. - -Intel-SIG: commit 0729857c7075 i386/cpuid: Move leaf 7 to correct group -Backport i386/cpu fixes - -Fixes: b9edbadefb9e ("i386: Propagate SGX CPUID sub-leafs to KVM") -Signed-off-by: Xiaoyao Li -Message-ID: <20240125024016.2521244-4-xiaoyao.li@intel.com> -Cc: qemu-stable@nongnu.org -Signed-off-by: Paolo Bonzini -Signed-off-by: Jason Zeng -Signed-off-by: Aubrey Li ---- - target/i386/kvm/kvm.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index e68eb8f5e6b0..a0bc9ea7b192 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -1955,7 +1955,6 @@ int kvm_arch_init_vcpu(CPUState *cs) - c = &cpuid_data.entries[cpuid_i++]; - } - break; -- case 0x7: - case 0x12: - for (j = 0; ; j++) { - c->function = i; -@@ -1975,6 +1974,7 @@ int kvm_arch_init_vcpu(CPUState *cs) - c = &cpuid_data.entries[cpuid_i++]; - } - break; -+ case 0x7: - case 0x14: - case 0x1d: - case 0x1e: { --- -2.34.1 - diff --git a/1005-doc-update-AMD-SEV-to-include-Live-migration-flow.patch b/1005-doc-update-AMD-SEV-to-include-Live-migration-flow.patch deleted file mode 100644 index d1e845a87415cfb8c7a1eb3798e0a43e282969ee..0000000000000000000000000000000000000000 --- a/1005-doc-update-AMD-SEV-to-include-Live-migration-flow.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 7baee92cb9227cf83903bc022ce486c962201638 Mon Sep 17 00:00:00 2001 -From: Brijesh Singh -Date: Thu, 7 May 2020 22:26:17 +0000 -Subject: [PATCH 01/28] doc: update AMD SEV to include Live migration flow - -cherry-picked from https://github.com/AMDESE/qemu/commit/0e2b3d80e3. - -Reviewed-by: Dr. David Alan Gilbert -Signed-off-by: Brijesh Singh -Signed-off-by: Ashish Kalra -Signed-off-by: hanliyang ---- - docs/system/i386/amd-memory-encryption.rst | 40 +++++++++++++++++++++- - 1 file changed, 39 insertions(+), 1 deletion(-) - -diff --git a/docs/system/i386/amd-memory-encryption.rst b/docs/system/i386/amd-memory-encryption.rst -index e9bc142bc..b7e3f46ff 100644 ---- a/docs/system/i386/amd-memory-encryption.rst -+++ b/docs/system/i386/amd-memory-encryption.rst -@@ -177,7 +177,45 @@ TODO - Live Migration - --------------- - --TODO -+AMD SEV encrypts the memory of VMs and because a different key is used -+in each VM, the hypervisor will be unable to simply copy the -+ciphertext from one VM to another to migrate the VM. Instead the AMD SEV Key -+Management API provides sets of function which the hypervisor can use -+to package a guest page for migration, while maintaining the confidentiality -+provided by AMD SEV. -+ -+SEV guest VMs have the concept of private and shared memory. The private -+memory is encrypted with the guest-specific key, while shared memory may -+be encrypted with the hypervisor key. The migration APIs provided by the -+SEV API spec should be used for migrating the private pages. The -+KVM_GET_PAGE_ENC_BITMAP ioctl can be used to get the guest page encryption -+bitmap. The bitmap can be used to check if the given guest page is -+private or shared. -+ -+Before initiating the migration, we need to know the targets machine's public -+Diffie-Hellman key (PDH) and certificate chain. It can be retrieved -+with the 'query-sev-capabilities' QMP command or using the sev-tool. The -+migrate-set-parameter can be used to pass the target machine's PDH and -+certificate chain. -+ -+During the migration flow, the SEND_START is called on the source hypervisor -+to create an outgoing encryption context. The SEV guest policy dictates whether -+the certificate passed through the migrate-sev-set-info command will be -+validated. SEND_UPDATE_DATA is called to encrypt the guest private pages. -+After migration is completed, SEND_FINISH is called to destroy the encryption -+context and make the VM non-runnable to protect it against cloning. -+ -+On the target machine, RECEIVE_START is called first to create an -+incoming encryption context. The RECEIVE_UPDATE_DATA is called to copy -+the received encrypted page into guest memory. After migration has -+completed, RECEIVE_FINISH is called to make the VM runnable. -+ -+For more information about the migration see SEV API Appendix A -+Usage flow (Live migration section). -+ -+NOTE: -+To protect against the memory clone SEV APIs are designed to make the VM -+unrunnable in case of the migration failure. - - References - ---------- --- -2.31.1 - diff --git a/1006-migration.json-add-AMD-SEV-specific-migration-parame.patch b/1006-migration.json-add-AMD-SEV-specific-migration-parame.patch deleted file mode 100644 index 4963898a116bad0c2da1f3de1336e3c4a843e4f8..0000000000000000000000000000000000000000 --- a/1006-migration.json-add-AMD-SEV-specific-migration-parame.patch +++ /dev/null @@ -1,266 +0,0 @@ -From e9999946bd358b88ff4c8c66306c1cbf09fda189 Mon Sep 17 00:00:00 2001 -From: Brijesh Singh -Date: Tue, 27 Jul 2021 11:27:00 +0000 -Subject: [PATCH 02/28] migration.json: add AMD SEV specific migration - parameters - -cherry-picked from https://github.com/AMDESE/qemu/commit/d6a23bde6b6e. - -AMD SEV migration flow requires that target machine's public Diffie-Hellman -key (PDH) and certificate chain must be passed before initiating the guest -migration. User can use QMP 'migrate-set-parameters' to pass the certificate -chain. The certificate chain will be used while creating the outgoing -encryption context. - -Signed-off-by: Brijesh Singh -Signed-off-by: Ashish Kalra -[ Fix conflicts and qapi errors. ] -Signed-off-by: hanliyang ---- - migration/migration-hmp-cmds.c | 28 ++++++++++++++++ - migration/options.c | 60 ++++++++++++++++++++++++++++++++++ - qapi/migration.json | 41 +++++++++++++++++++++-- - 3 files changed, 126 insertions(+), 3 deletions(-) - -diff --git a/migration/migration-hmp-cmds.c b/migration/migration-hmp-cmds.c -index 86ae83217..7e83d908d 100644 ---- a/migration/migration-hmp-cmds.c -+++ b/migration/migration-hmp-cmds.c -@@ -392,6 +392,19 @@ void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict) - monitor_printf(mon, "%s: %s\n", - MigrationParameter_str(MIGRATION_PARAMETER_MODE), - qapi_enum_lookup(&MigMode_lookup, params->mode)); -+ -+ assert(params->sev_pdh); -+ monitor_printf(mon, "%s: %s\n", -+ MigrationParameter_str(MIGRATION_PARAMETER_SEV_PDH), -+ params->sev_pdh); -+ assert(params->sev_plat_cert); -+ monitor_printf(mon, "%s: %s\n", -+ MigrationParameter_str(MIGRATION_PARAMETER_SEV_PLAT_CERT), -+ params->sev_plat_cert); -+ assert(params->sev_amd_cert); -+ monitor_printf(mon, "%s: %s\n", -+ MigrationParameter_str(MIGRATION_PARAMETER_SEV_AMD_CERT), -+ params->sev_amd_cert); - } - - qapi_free_MigrationParameters(params); -@@ -679,6 +692,21 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict) - p->has_mode = true; - visit_type_MigMode(v, param, &p->mode, &err); - break; -+ case MIGRATION_PARAMETER_SEV_PDH: -+ p->sev_pdh = g_new0(StrOrNull, 1); -+ p->sev_pdh->type = QTYPE_QSTRING; -+ visit_type_str(v, param, &p->sev_pdh->u.s, &err); -+ break; -+ case MIGRATION_PARAMETER_SEV_PLAT_CERT: -+ p->sev_plat_cert = g_new0(StrOrNull, 1); -+ p->sev_plat_cert->type = QTYPE_QSTRING; -+ visit_type_str(v, param, &p->sev_plat_cert->u.s, &err); -+ break; -+ case MIGRATION_PARAMETER_SEV_AMD_CERT: -+ p->sev_amd_cert = g_new0(StrOrNull, 1); -+ p->sev_amd_cert->type = QTYPE_QSTRING; -+ visit_type_str(v, param, &p->sev_amd_cert->u.s, &err); -+ break; - default: - assert(0); - } -diff --git a/migration/options.c b/migration/options.c -index 8d8ec73ad..70f6beb83 100644 ---- a/migration/options.c -+++ b/migration/options.c -@@ -179,6 +179,9 @@ Property migration_properties[] = { - DEFINE_PROP_MIG_MODE("mode", MigrationState, - parameters.mode, - MIG_MODE_NORMAL), -+ DEFINE_PROP_STRING("sev-pdh", MigrationState, parameters.sev_pdh), -+ DEFINE_PROP_STRING("sev-plat-cert", MigrationState, parameters.sev_plat_cert), -+ DEFINE_PROP_STRING("sev-amd-cert", MigrationState, parameters.sev_amd_cert), - - /* Migration capabilities */ - DEFINE_PROP_MIG_CAP("x-xbzrle", MIGRATION_CAPABILITY_XBZRLE), -@@ -997,6 +1000,9 @@ MigrationParameters *qmp_query_migrate_parameters(Error **errp) - params->announce_rounds = s->parameters.announce_rounds; - params->has_announce_step = true; - params->announce_step = s->parameters.announce_step; -+ params->sev_pdh = g_strdup(s->parameters.sev_pdh); -+ params->sev_plat_cert = g_strdup(s->parameters.sev_plat_cert); -+ params->sev_amd_cert = g_strdup(s->parameters.sev_amd_cert); - - if (s->parameters.has_block_bitmap_mapping) { - params->has_block_bitmap_mapping = true; -@@ -1047,6 +1053,10 @@ void migrate_params_init(MigrationParameters *params) - params->has_x_vcpu_dirty_limit_period = true; - params->has_vcpu_dirty_limit = true; - params->has_mode = true; -+ -+ params->sev_pdh = g_strdup(""); -+ params->sev_plat_cert = g_strdup(""); -+ params->sev_amd_cert = g_strdup(""); - } - - /* -@@ -1348,6 +1358,19 @@ static void migrate_params_test_apply(MigrateSetParameters *params, - if (params->has_mode) { - dest->mode = params->mode; - } -+ -+ if (params->sev_pdh) { -+ assert(params->sev_pdh->type == QTYPE_QSTRING); -+ dest->sev_pdh = params->sev_pdh->u.s; -+ } -+ if (params->sev_plat_cert) { -+ assert(params->sev_plat_cert->type == QTYPE_QSTRING); -+ dest->sev_plat_cert = params->sev_plat_cert->u.s; -+ } -+ if (params->sev_amd_cert) { -+ assert(params->sev_amd_cert->type == QTYPE_QSTRING); -+ dest->sev_amd_cert = params->sev_amd_cert->u.s; -+ } - } - - static void migrate_params_apply(MigrateSetParameters *params, Error **errp) -@@ -1492,6 +1515,22 @@ static void migrate_params_apply(MigrateSetParameters *params, Error **errp) - if (params->has_mode) { - s->parameters.mode = params->mode; - } -+ -+ if (params->sev_pdh) { -+ g_free(s->parameters.sev_pdh); -+ assert(params->sev_pdh->type == QTYPE_QSTRING); -+ s->parameters.sev_pdh = g_strdup(params->sev_pdh->u.s); -+ } -+ if (params->sev_plat_cert) { -+ g_free(s->parameters.sev_plat_cert); -+ assert(params->sev_plat_cert->type == QTYPE_QSTRING); -+ s->parameters.sev_plat_cert = g_strdup(params->sev_plat_cert->u.s); -+ } -+ if (params->sev_amd_cert) { -+ g_free(s->parameters.sev_amd_cert); -+ assert(params->sev_amd_cert->type == QTYPE_QSTRING); -+ s->parameters.sev_amd_cert = g_strdup(params->sev_amd_cert->u.s); -+ } - } - - void qmp_migrate_set_parameters(MigrateSetParameters *params, Error **errp) -@@ -1517,6 +1556,27 @@ void qmp_migrate_set_parameters(MigrateSetParameters *params, Error **errp) - params->tls_authz->type = QTYPE_QSTRING; - params->tls_authz->u.s = strdup(""); - } -+ /* TODO Rewrite "" to null instead */ -+ if (params->sev_pdh -+ && params->sev_pdh->type == QTYPE_QNULL) { -+ qobject_unref(params->sev_pdh->u.n); -+ params->sev_pdh->type = QTYPE_QSTRING; -+ params->sev_pdh->u.s = strdup(""); -+ } -+ /* TODO Rewrite "" to null instead */ -+ if (params->sev_plat_cert -+ && params->sev_plat_cert->type == QTYPE_QNULL) { -+ qobject_unref(params->sev_plat_cert->u.n); -+ params->sev_plat_cert->type = QTYPE_QSTRING; -+ params->sev_plat_cert->u.s = strdup(""); -+ } -+ /* TODO Rewrite "" to null instead */ -+ if (params->sev_amd_cert -+ && params->sev_amd_cert->type == QTYPE_QNULL) { -+ qobject_unref(params->sev_amd_cert->u.n); -+ params->sev_amd_cert->type = QTYPE_QSTRING; -+ params->sev_amd_cert->u.s = strdup(""); -+ } - - migrate_params_test_apply(params, &tmp); - -diff --git a/qapi/migration.json b/qapi/migration.json -index eb2f88351..77051496f 100644 ---- a/qapi/migration.json -+++ b/qapi/migration.json -@@ -874,6 +874,15 @@ - # @mode: Migration mode. See description in @MigMode. Default is 'normal'. - # (Since 8.2) - # -+# @sev-pdh: The target host platform diffie-hellman key encoded in base64 -+# (Since 4.2) -+# -+# @sev-plat-cert: The target host platform certificate chain encoded in base64 -+# (Since 4.2) -+# -+# @sev-amd-cert: AMD certificate chain which include ASK and OCA encoded in -+# base64 (Since 4.2) -+# - # Features: - # - # @deprecated: Member @block-incremental is deprecated. Use -@@ -907,7 +916,8 @@ - 'block-bitmap-mapping', - { 'name': 'x-vcpu-dirty-limit-period', 'features': ['unstable'] }, - 'vcpu-dirty-limit', -- 'mode'] } -+ 'mode', -+ 'sev-pdh', 'sev-plat-cert', 'sev-amd-cert'] } - - ## - # @MigrateSetParameters: -@@ -1062,6 +1072,15 @@ - # @mode: Migration mode. See description in @MigMode. Default is 'normal'. - # (Since 8.2) - # -+# @sev-pdh: The target host platform diffie-hellman key encoded in base64 -+# (Since 4.2) -+# -+# @sev-plat-cert: The target host platform certificate chain encoded in base64 -+# (Since 4.2) -+# -+# @sev-amd-cert: AMD certificate chain which include ASK and OCA encoded in -+# base64 (Since 4.2) -+# - # Features: - # - # @deprecated: Member @block-incremental is deprecated. Use -@@ -1115,7 +1134,11 @@ - '*x-vcpu-dirty-limit-period': { 'type': 'uint64', - 'features': [ 'unstable' ] }, - '*vcpu-dirty-limit': 'uint64', -- '*mode': 'MigMode'} } -+ '*mode': 'MigMode', -+ '*sev-pdh': 'StrOrNull', -+ '*sev-plat-cert': 'StrOrNull', -+ '*sev-amd-cert' : 'StrOrNull' } } -+ - - ## - # @migrate-set-parameters: -@@ -1290,6 +1313,15 @@ - # @mode: Migration mode. See description in @MigMode. Default is 'normal'. - # (Since 8.2) - # -+# @sev-pdh: The target host platform diffie-hellman key encoded in base64 -+# (Since 4.2) -+# -+# @sev-plat-cert: The target host platform certificate chain encoded in base64 -+# (Since 4.2) -+# -+# @sev-amd-cert: AMD certificate chain which include ASK and OCA encoded in -+# base64 (Since 4.2) -+# - # Features: - # - # @deprecated: Member @block-incremental is deprecated. Use -@@ -1340,7 +1372,10 @@ - '*x-vcpu-dirty-limit-period': { 'type': 'uint64', - 'features': [ 'unstable' ] }, - '*vcpu-dirty-limit': 'uint64', -- '*mode': 'MigMode'} } -+ '*mode': 'MigMode', -+ '*sev-pdh': 'str', -+ '*sev-plat-cert': 'str', -+ '*sev-amd-cert' : 'str'} } - - ## - # @query-migrate-parameters: --- -2.31.1 - diff --git a/1007-confidential-guest-support-introduce-ConfidentialGue.patch b/1007-confidential-guest-support-introduce-ConfidentialGue.patch deleted file mode 100644 index 359e1e34de5ac04afc48f54b370155bfb1749105..0000000000000000000000000000000000000000 --- a/1007-confidential-guest-support-introduce-ConfidentialGue.patch +++ /dev/null @@ -1,67 +0,0 @@ -From f667d5c3e315ea85a2d83da2384d24fe74c2aa0b Mon Sep 17 00:00:00 2001 -From: Brijesh Singh -Date: Tue, 27 Jul 2021 11:41:37 +0000 -Subject: [PATCH 03/28] confidential guest support: introduce - ConfidentialGuestMemoryEncryptionOps for encrypted VMs - -cherry-picked from https://github.com/AMDESE/qemu/commit/74fce7be9bd. - -When memory encryption is enabled in VM, the guest RAM will be encrypted -with the guest-specific key, to protect the confidentiality of data while -in transit we need to platform specific hooks to save or migrate the -guest RAM. - -Introduce the new ConfidentialGuestMemoryEncryptionOps in this patch -which will be later used by the encrypted guest for migration. - -Signed-off-by: Brijesh Singh -Co-developed-by: Ashish Kalra -Signed-off-by: Ashish Kalra -Signed-off-by: hanliyang ---- - include/exec/confidential-guest-support.h | 27 +++++++++++++++++++++++ - 1 file changed, 27 insertions(+) - -diff --git a/include/exec/confidential-guest-support.h b/include/exec/confidential-guest-support.h -index ba2dd4b5d..343f686fc 100644 ---- a/include/exec/confidential-guest-support.h -+++ b/include/exec/confidential-guest-support.h -@@ -53,8 +53,35 @@ struct ConfidentialGuestSupport { - bool ready; - }; - -+/** -+ * The functions registers with ConfidentialGuestMemoryEncryptionOps will be -+ * used during the encrypted guest migration. -+ */ -+struct ConfidentialGuestMemoryEncryptionOps { -+ /* Initialize the platform specific state before starting the migration */ -+ int (*save_setup)(const char *pdh, const char *plat_cert, -+ const char *amd_cert); -+ -+ /* Write the encrypted page and metadata associated with it */ -+ int (*save_outgoing_page)(QEMUFile *f, uint8_t *ptr, uint32_t size, -+ uint64_t *bytes_sent); -+ -+ /* Load the incoming encrypted page into guest memory */ -+ int (*load_incoming_page)(QEMUFile *f, uint8_t *ptr); -+ -+ /* Check if gfn is in shared/unencrypted region */ -+ bool (*is_gfn_in_unshared_region)(unsigned long gfn); -+ -+ /* Write the shared regions list */ -+ int (*save_outgoing_shared_regions_list)(QEMUFile *f); -+ -+ /* Load the shared regions list */ -+ int (*load_incoming_shared_regions_list)(QEMUFile *f); -+}; -+ - typedef struct ConfidentialGuestSupportClass { - ObjectClass parent; -+ struct ConfidentialGuestMemoryEncryptionOps *memory_encryption_ops; - } ConfidentialGuestSupportClass; - - #endif /* !CONFIG_USER_ONLY */ --- -2.31.1 - diff --git a/1008-target-i386-sev-provide-callback-to-setup-outgoing-c.patch b/1008-target-i386-sev-provide-callback-to-setup-outgoing-c.patch deleted file mode 100644 index 3aab1b3b9ed6ba633c62269eda03773af27dd2df..0000000000000000000000000000000000000000 --- a/1008-target-i386-sev-provide-callback-to-setup-outgoing-c.patch +++ /dev/null @@ -1,136 +0,0 @@ -From 07d01bcf6ca2a3e5fb369f7a25b954aaebbc9b5e Mon Sep 17 00:00:00 2001 -From: Brijesh Singh -Date: Tue, 27 Jul 2021 12:10:23 +0000 -Subject: [PATCH 04/28] target/i386: sev: provide callback to setup outgoing - context - -cherry-picked from https://github.com/AMDESE/qemu/commit/7521883afc0. - -The user provides the target machine's Platform Diffie-Hellman key (PDH) -and certificate chain before starting the SEV guest migration. Cache the -certificate chain as we need them while creating the outgoing context. - -Signed-off-by: Brijesh Singh -Co-developed-by: Ashish Kalra -Signed-off-by: Ashish Kalra -[ Fix conflict. ] -Signed-off-by: hanliyang ---- - target/i386/sev.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++ - target/i386/sev.h | 2 ++ - 2 files changed, 61 insertions(+) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 9a7124668..3ab02f4c6 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -73,6 +73,12 @@ struct SevGuestState { - int sev_fd; - SevState state; - gchar *measurement; -+ guchar *remote_pdh; -+ size_t remote_pdh_len; -+ guchar *remote_plat_cert; -+ size_t remote_plat_cert_len; -+ guchar *amd_cert; -+ size_t amd_cert_len; - - uint32_t reset_cs; - uint32_t reset_ip; -@@ -157,6 +163,12 @@ static const char *const sev_fw_errlist[] = { - - #define SEV_FW_MAX_ERROR ARRAY_SIZE(sev_fw_errlist) - -+#define SEV_FW_BLOB_MAX_SIZE 0x4000 /* 16KB */ -+ -+static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { -+ .save_setup = sev_save_setup, -+}; -+ - static int - sev_ioctl(int fd, int cmd, void *data, int *error) - { -@@ -906,6 +918,48 @@ sev_vm_state_change(void *opaque, bool running, RunState state) - } - } - -+static inline bool check_blob_length(size_t value) -+{ -+ if (value > SEV_FW_BLOB_MAX_SIZE) { -+ error_report("invalid length max=%d got=%ld", -+ SEV_FW_BLOB_MAX_SIZE, value); -+ return false; -+ } -+ -+ return true; -+} -+ -+int sev_save_setup(const char *pdh, const char *plat_cert, -+ const char *amd_cert) -+{ -+ SevGuestState *s = sev_guest; -+ -+ s->remote_pdh = g_base64_decode(pdh, &s->remote_pdh_len); -+ if (!check_blob_length(s->remote_pdh_len)) { -+ goto error; -+ } -+ -+ s->remote_plat_cert = g_base64_decode(plat_cert, -+ &s->remote_plat_cert_len); -+ if (!check_blob_length(s->remote_plat_cert_len)) { -+ goto error; -+ } -+ -+ s->amd_cert = g_base64_decode(amd_cert, &s->amd_cert_len); -+ if (!check_blob_length(s->amd_cert_len)) { -+ goto error; -+ } -+ -+ return 0; -+ -+error: -+ g_free(s->remote_pdh); -+ g_free(s->remote_plat_cert); -+ g_free(s->amd_cert); -+ -+ return 1; -+} -+ - int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - { - SevGuestState *sev -@@ -920,6 +974,9 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - return 0; - } - -+ ConfidentialGuestSupportClass *cgs_class = -+ (ConfidentialGuestSupportClass *) object_get_class(OBJECT(cgs)); -+ - ret = ram_block_discard_disable(true); - if (ret) { - error_report("%s: cannot disable RAM discard", __func__); -@@ -1013,6 +1070,8 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - qemu_add_machine_init_done_notifier(&sev_machine_done_notify); - qemu_add_vm_change_state_handler(sev_vm_state_change, sev); - -+ cgs_class->memory_encryption_ops = &sev_memory_encryption_ops; -+ - cgs->ready = true; - - return 0; -diff --git a/target/i386/sev.h b/target/i386/sev.h -index e7499c95b..e96de021f 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -51,6 +51,8 @@ uint32_t sev_get_reduced_phys_bits(void); - bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp); - - int sev_encrypt_flash(uint8_t *ptr, uint64_t len, Error **errp); -+int sev_save_setup(const char *pdh, const char *plat_cert, -+ const char *amd_cert); - int sev_inject_launch_secret(const char *hdr, const char *secret, - uint64_t gpa, Error **errp); - --- -2.31.1 - diff --git a/1009-target-i386-sev-do-not-create-launch-context-for-an-.patch b/1009-target-i386-sev-do-not-create-launch-context-for-an-.patch deleted file mode 100644 index 4dcd6f3d4465fa6368ba75aab4439a82ed205034..0000000000000000000000000000000000000000 --- a/1009-target-i386-sev-do-not-create-launch-context-for-an-.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 66ccff57037c3fd1a24554111447137b6525c764 Mon Sep 17 00:00:00 2001 -From: Brijesh Singh -Date: Tue, 27 Jul 2021 12:16:09 +0000 -Subject: [PATCH 05/28] target/i386: sev: do not create launch context for an - incoming guest - -cherry-picked from https://github.com/AMDESE/qemu/commit/b85694233495. - -The LAUNCH_START is used for creating an encryption context to encrypt -newly created guest, for an incoming guest the RECEIVE_START should be -used. - -Reviewed-by: Dr. David Alan Gilbert -Signed-off-by: Brijesh Singh -Signed-off-by: Ashish Kalra -[ Fix conflict. ] -Signed-off-by: hanliyang ---- - target/i386/sev.c | 14 ++++++++++---- - 1 file changed, 10 insertions(+), 4 deletions(-) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 3ab02f4c6..b56cbdb6b 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -1060,10 +1060,16 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - goto err; - } - -- ret = sev_launch_start(sev); -- if (ret) { -- error_setg(errp, "%s: failed to create encryption context", __func__); -- goto err; -+ /* -+ * The LAUNCH context is used for new guest, if its an incoming guest -+ * then RECEIVE context will be created after the connection is established. -+ */ -+ if (!runstate_check(RUN_STATE_INMIGRATE)) { -+ ret = sev_launch_start(sev); -+ if (ret) { -+ error_setg(errp, "%s: failed to create encryption context", __func__); -+ goto err; -+ } - } - - ram_block_notifier_add(&sev_ram_notifier); --- -2.31.1 - diff --git a/1010-target-i386-sev-add-support-to-encrypt-the-outgoing-.patch b/1010-target-i386-sev-add-support-to-encrypt-the-outgoing-.patch deleted file mode 100644 index c23a01161937d9006506a4be4b0370716e7976f5..0000000000000000000000000000000000000000 --- a/1010-target-i386-sev-add-support-to-encrypt-the-outgoing-.patch +++ /dev/null @@ -1,320 +0,0 @@ -From 8d08dc0a8622eb8c512d96a1720c0e52a8ffc5ac Mon Sep 17 00:00:00 2001 -From: Brijesh Singh -Date: Tue, 27 Jul 2021 12:55:25 +0000 -Subject: [PATCH 06/28] target/i386: sev: add support to encrypt the outgoing - page - -cherry-picked from https://github.com/AMDESE/qemu/commit/5187c6f86bd. - -The sev_save_outgoing_page() provide the implementation to encrypt the -guest private pages during the transit. The routines uses the SEND_START -command to create the outgoing encryption context on the first call then -uses the SEND_UPDATE_DATA command to encrypt the data before writing it -to the socket. While encrypting the data SEND_UPDATE_DATA produces some -metadata (e.g MAC, IV). The metadata is also sent to the target machine. -After migration is completed, we issue the SEND_FINISH command to transition -the SEV guest state from sending to unrunnable state. - -Signed-off-by: Brijesh Singh -Co-developed-by: Ashish Kalra -Signed-off-by: Ashish Kalra -[ Fix conflict. ] -Signed-off-by: hanliyang ---- - target/i386/sev.c | 219 +++++++++++++++++++++++++++++++++++++++ - target/i386/sev.h | 2 + - target/i386/trace-events | 3 + - 3 files changed, 224 insertions(+) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index b56cbdb6b..617587c69 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -31,6 +31,8 @@ - #include "sysemu/runstate.h" - #include "trace.h" - #include "migration/blocker.h" -+#include "migration/qemu-file.h" -+#include "migration/misc.h" - #include "qom/object.h" - #include "monitor/monitor.h" - #include "monitor/hmp-target.h" -@@ -79,6 +81,8 @@ struct SevGuestState { - size_t remote_plat_cert_len; - guchar *amd_cert; - size_t amd_cert_len; -+ gchar *send_packet_hdr; -+ size_t send_packet_hdr_len; - - uint32_t reset_cs; - uint32_t reset_ip; -@@ -167,6 +171,7 @@ static const char *const sev_fw_errlist[] = { - - static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { - .save_setup = sev_save_setup, -+ .save_outgoing_page = sev_save_outgoing_page, - }; - - static int -@@ -960,6 +965,38 @@ error: - return 1; - } - -+static void -+sev_send_finish(void) -+{ -+ int ret, error; -+ -+ trace_kvm_sev_send_finish(); -+ ret = sev_ioctl(sev_guest->sev_fd, KVM_SEV_SEND_FINISH, 0, &error); -+ if (ret) { -+ error_report("%s: SEND_FINISH ret=%d fw_error=%d '%s'", -+ __func__, ret, error, fw_error_to_str(error)); -+ } -+ -+ g_free(sev_guest->send_packet_hdr); -+ sev_set_guest_state(sev_guest, SEV_STATE_RUNNING); -+} -+ -+static void -+sev_migration_state_notifier(Notifier *notifier, void *data) -+{ -+ MigrationState *s = data; -+ -+ if (migration_has_finished(s) || -+ migration_in_postcopy_after_devices(s) || -+ migration_has_failed(s)) { -+ if (sev_check_state(sev_guest, SEV_STATE_SEND_UPDATE)) { -+ sev_send_finish(); -+ } -+ } -+} -+ -+static Notifier sev_migration_state; -+ - int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - { - SevGuestState *sev -@@ -1075,6 +1112,7 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - ram_block_notifier_add(&sev_ram_notifier); - qemu_add_machine_init_done_notifier(&sev_machine_done_notify); - qemu_add_vm_change_state_handler(sev_vm_state_change, sev); -+ migration_add_notifier(&sev_migration_state, sev_migration_state_notifier); - - cgs_class->memory_encryption_ops = &sev_memory_encryption_ops; - -@@ -1316,6 +1354,187 @@ int sev_es_save_reset_vector(void *flash_ptr, uint64_t flash_size) - return 0; - } - -+static int -+sev_get_send_session_length(void) -+{ -+ int ret, fw_err = 0; -+ struct kvm_sev_send_start start = {}; -+ -+ ret = sev_ioctl(sev_guest->sev_fd, KVM_SEV_SEND_START, &start, &fw_err); -+ if (fw_err != SEV_RET_INVALID_LEN) { -+ ret = -1; -+ error_report("%s: failed to get session length ret=%d fw_error=%d '%s'", -+ __func__, ret, fw_err, fw_error_to_str(fw_err)); -+ goto err; -+ } -+ -+ ret = start.session_len; -+err: -+ return ret; -+} -+ -+static int -+sev_send_start(SevGuestState *s, QEMUFile *f, uint64_t *bytes_sent) -+{ -+ gsize pdh_len = 0, plat_cert_len; -+ int session_len, ret, fw_error; -+ struct kvm_sev_send_start start = { }; -+ guchar *pdh = NULL, *plat_cert = NULL, *session = NULL; -+ Error *local_err = NULL; -+ -+ if (!s->remote_pdh || !s->remote_plat_cert || !s->amd_cert_len) { -+ error_report("%s: missing remote PDH or PLAT_CERT", __func__); -+ return 1; -+ } -+ -+ start.pdh_cert_uaddr = (uintptr_t) s->remote_pdh; -+ start.pdh_cert_len = s->remote_pdh_len; -+ -+ start.plat_certs_uaddr = (uintptr_t)s->remote_plat_cert; -+ start.plat_certs_len = s->remote_plat_cert_len; -+ -+ start.amd_certs_uaddr = (uintptr_t)s->amd_cert; -+ start.amd_certs_len = s->amd_cert_len; -+ -+ /* get the session length */ -+ session_len = sev_get_send_session_length(); -+ if (session_len < 0) { -+ ret = 1; -+ goto err; -+ } -+ -+ session = g_new0(guchar, session_len); -+ start.session_uaddr = (unsigned long)session; -+ start.session_len = session_len; -+ -+ /* Get our PDH certificate */ -+ ret = sev_get_pdh_info(s->sev_fd, &pdh, &pdh_len, -+ &plat_cert, &plat_cert_len, &local_err); -+ if (ret) { -+ error_report("Failed to get our PDH cert"); -+ goto err; -+ } -+ -+ trace_kvm_sev_send_start(start.pdh_cert_uaddr, start.pdh_cert_len, -+ start.plat_certs_uaddr, start.plat_certs_len, -+ start.amd_certs_uaddr, start.amd_certs_len); -+ -+ ret = sev_ioctl(s->sev_fd, KVM_SEV_SEND_START, &start, &fw_error); -+ if (ret < 0) { -+ error_report("%s: SEND_START ret=%d fw_error=%d '%s'", -+ __func__, ret, fw_error, fw_error_to_str(fw_error)); -+ goto err; -+ } -+ -+ qemu_put_be32(f, start.policy); -+ qemu_put_be32(f, pdh_len); -+ qemu_put_buffer(f, (uint8_t *)pdh, pdh_len); -+ qemu_put_be32(f, start.session_len); -+ qemu_put_buffer(f, (uint8_t *)start.session_uaddr, start.session_len); -+ *bytes_sent = 12 + pdh_len + start.session_len; -+ -+ sev_set_guest_state(s, SEV_STATE_SEND_UPDATE); -+ -+err: -+ g_free(pdh); -+ g_free(plat_cert); -+ return ret; -+} -+ -+static int -+sev_send_get_packet_len(int *fw_err) -+{ -+ int ret; -+ struct kvm_sev_send_update_data update = { 0, }; -+ -+ ret = sev_ioctl(sev_guest->sev_fd, KVM_SEV_SEND_UPDATE_DATA, -+ &update, fw_err); -+ if (*fw_err != SEV_RET_INVALID_LEN) { -+ ret = -1; -+ error_report("%s: failed to get session length ret=%d fw_error=%d '%s'", -+ __func__, ret, *fw_err, fw_error_to_str(*fw_err)); -+ goto err; -+ } -+ -+ ret = update.hdr_len; -+ -+err: -+ return ret; -+} -+ -+static int -+sev_send_update_data(SevGuestState *s, QEMUFile *f, uint8_t *ptr, uint32_t size, -+ uint64_t *bytes_sent) -+{ -+ int ret, fw_error; -+ guchar *trans; -+ struct kvm_sev_send_update_data update = { }; -+ -+ /* -+ * If this is first call then query the packet header bytes and allocate -+ * the packet buffer. -+ */ -+ if (!s->send_packet_hdr) { -+ s->send_packet_hdr_len = sev_send_get_packet_len(&fw_error); -+ if (s->send_packet_hdr_len < 1) { -+ error_report("%s: SEND_UPDATE fw_error=%d '%s'", -+ __func__, fw_error, fw_error_to_str(fw_error)); -+ return 1; -+ } -+ -+ s->send_packet_hdr = g_new(gchar, s->send_packet_hdr_len); -+ } -+ -+ /* allocate transport buffer */ -+ trans = g_new(guchar, size); -+ -+ update.hdr_uaddr = (uintptr_t)s->send_packet_hdr; -+ update.hdr_len = s->send_packet_hdr_len; -+ update.guest_uaddr = (uintptr_t)ptr; -+ update.guest_len = size; -+ update.trans_uaddr = (uintptr_t)trans; -+ update.trans_len = size; -+ -+ trace_kvm_sev_send_update_data(ptr, trans, size); -+ -+ ret = sev_ioctl(s->sev_fd, KVM_SEV_SEND_UPDATE_DATA, &update, &fw_error); -+ if (ret) { -+ error_report("%s: SEND_UPDATE_DATA ret=%d fw_error=%d '%s'", -+ __func__, ret, fw_error, fw_error_to_str(fw_error)); -+ goto err; -+ } -+ -+ qemu_put_be32(f, update.hdr_len); -+ qemu_put_buffer(f, (uint8_t *)update.hdr_uaddr, update.hdr_len); -+ *bytes_sent = 4 + update.hdr_len; -+ -+ qemu_put_be32(f, update.trans_len); -+ qemu_put_buffer(f, (uint8_t *)update.trans_uaddr, update.trans_len); -+ *bytes_sent += (4 + update.trans_len); -+ -+err: -+ g_free(trans); -+ return ret; -+} -+ -+int sev_save_outgoing_page(QEMUFile *f, uint8_t *ptr, -+ uint32_t sz, uint64_t *bytes_sent) -+{ -+ SevGuestState *s = sev_guest; -+ -+ /* -+ * If this is a first buffer then create outgoing encryption context -+ * and write our PDH, policy and session data. -+ */ -+ if (!sev_check_state(s, SEV_STATE_SEND_UPDATE) && -+ sev_send_start(s, f, bytes_sent)) { -+ error_report("Failed to create outgoing context"); -+ return 1; -+ } -+ -+ return sev_send_update_data(s, f, ptr, sz, bytes_sent); -+} -+ - static const QemuUUID sev_hash_table_header_guid = { - .data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93, - 0xd4, 0x11, 0xfd, 0x21) -diff --git a/target/i386/sev.h b/target/i386/sev.h -index e96de021f..463e94bb8 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -53,6 +53,8 @@ bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp); - int sev_encrypt_flash(uint8_t *ptr, uint64_t len, Error **errp); - int sev_save_setup(const char *pdh, const char *plat_cert, - const char *amd_cert); -+int sev_save_outgoing_page(QEMUFile *f, uint8_t *ptr, -+ uint32_t size, uint64_t *bytes_sent); - int sev_inject_launch_secret(const char *hdr, const char *secret, - uint64_t gpa, Error **errp); - -diff --git a/target/i386/trace-events b/target/i386/trace-events -index 2cd8726ee..e8d4aec12 100644 ---- a/target/i386/trace-events -+++ b/target/i386/trace-events -@@ -11,3 +11,6 @@ kvm_sev_launch_measurement(const char *value) "data %s" - kvm_sev_launch_finish(void) "" - kvm_sev_launch_secret(uint64_t hpa, uint64_t hva, uint64_t secret, int len) "hpa 0x%" PRIx64 " hva 0x%" PRIx64 " data 0x%" PRIx64 " len %d" - kvm_sev_attestation_report(const char *mnonce, const char *data) "mnonce %s data %s" -+kvm_sev_send_start(uint64_t pdh, int l1, uint64_t plat, int l2, uint64_t amd, int l3) "pdh 0x%" PRIx64 " len %d plat 0x%" PRIx64 " len %d amd 0x%" PRIx64 " len %d" -+kvm_sev_send_update_data(void *src, void *dst, int len) "guest %p trans %p len %d" -+kvm_sev_send_finish(void) "" --- -2.31.1 - diff --git a/1011-target-i386-sev-add-support-to-load-incoming-encrypt.patch b/1011-target-i386-sev-add-support-to-load-incoming-encrypt.patch deleted file mode 100644 index 98c5e1f52faffb715359b1e1649f3df3e112dde8..0000000000000000000000000000000000000000 --- a/1011-target-i386-sev-add-support-to-load-incoming-encrypt.patch +++ /dev/null @@ -1,222 +0,0 @@ -From 0016dedce755380dc796e605f68c40d1c1b2edad Mon Sep 17 00:00:00 2001 -From: Brijesh Singh -Date: Tue, 27 Jul 2021 13:00:50 +0000 -Subject: [PATCH 07/28] target/i386: sev: add support to load incoming - encrypted page - -cherry-picked from https://github.com/AMDESE/qemu/commit/e86e5dccb045. - -The sev_load_incoming_page() provide the implementation to read the -incoming guest private pages from the socket and load it into the guest -memory. The routines uses the RECEIVE_START command to create the -incoming encryption context on the first call then uses the -RECEIEVE_UPDATE_DATA command to load the encrypted pages into the guest -memory. After migration is completed, we issue the RECEIVE_FINISH command -to transition the SEV guest to the runnable state so that it can be -executed. - -Signed-off-by: Brijesh Singh -Co-developed-by: Ashish Kalra -Signed-off-by: Ashish Kalra -[ Fix conflicts. ] -Signed-off-by: hanliyang ---- - target/i386/sev.c | 137 ++++++++++++++++++++++++++++++++++++++- - target/i386/sev.h | 1 + - target/i386/trace-events | 3 + - 3 files changed, 140 insertions(+), 1 deletion(-) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 617587c69..ee42edf4e 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -172,6 +172,7 @@ static const char *const sev_fw_errlist[] = { - static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { - .save_setup = sev_save_setup, - .save_outgoing_page = sev_save_outgoing_page, -+ .load_incoming_page = sev_load_incoming_page, - }; - - static int -@@ -911,13 +912,33 @@ sev_launch_finish(SevGuestState *sev) - migrate_add_blocker(&sev_mig_blocker, &error_fatal); - } - -+static int -+sev_receive_finish(SevGuestState *s) -+{ -+ int error, ret = 1; -+ -+ trace_kvm_sev_receive_finish(); -+ ret = sev_ioctl(s->sev_fd, KVM_SEV_RECEIVE_FINISH, 0, &error); -+ if (ret) { -+ error_report("%s: RECEIVE_FINISH ret=%d fw_error=%d '%s'", -+ __func__, ret, error, fw_error_to_str(error)); -+ goto err; -+ } -+ -+ sev_set_guest_state(s, SEV_STATE_RUNNING); -+err: -+ return ret; -+} -+ - static void - sev_vm_state_change(void *opaque, bool running, RunState state) - { - SevGuestState *sev = opaque; - - if (running) { -- if (!sev_check_state(sev, SEV_STATE_RUNNING)) { -+ if (sev_check_state(sev, SEV_STATE_RECEIVE_UPDATE)) { -+ sev_receive_finish(sev); -+ } else if (!sev_check_state(sev, SEV_STATE_RUNNING)) { - sev_launch_finish(sev); - } - } -@@ -1535,6 +1556,120 @@ int sev_save_outgoing_page(QEMUFile *f, uint8_t *ptr, - return sev_send_update_data(s, f, ptr, sz, bytes_sent); - } - -+static int -+sev_receive_start(SevGuestState *sev, QEMUFile *f) -+{ -+ int ret = 1; -+ int fw_error; -+ struct kvm_sev_receive_start start = { }; -+ gchar *session = NULL, *pdh_cert = NULL; -+ -+ /* get SEV guest handle */ -+ start.handle = object_property_get_int(OBJECT(sev), "handle", -+ &error_abort); -+ -+ /* get the source policy */ -+ start.policy = qemu_get_be32(f); -+ -+ /* get source PDH key */ -+ start.pdh_len = qemu_get_be32(f); -+ if (!check_blob_length(start.pdh_len)) { -+ return 1; -+ } -+ -+ pdh_cert = g_new(gchar, start.pdh_len); -+ qemu_get_buffer(f, (uint8_t *)pdh_cert, start.pdh_len); -+ start.pdh_uaddr = (uintptr_t)pdh_cert; -+ -+ /* get source session data */ -+ start.session_len = qemu_get_be32(f); -+ if (!check_blob_length(start.session_len)) { -+ return 1; -+ } -+ session = g_new(gchar, start.session_len); -+ qemu_get_buffer(f, (uint8_t *)session, start.session_len); -+ start.session_uaddr = (uintptr_t)session; -+ -+ trace_kvm_sev_receive_start(start.policy, session, pdh_cert); -+ -+ ret = sev_ioctl(sev_guest->sev_fd, KVM_SEV_RECEIVE_START, -+ &start, &fw_error); -+ if (ret < 0) { -+ error_report("Error RECEIVE_START ret=%d fw_error=%d '%s'", -+ ret, fw_error, fw_error_to_str(fw_error)); -+ goto err; -+ } -+ -+ object_property_set_int(OBJECT(sev), "handle", start.handle, &error_abort); -+ sev_set_guest_state(sev, SEV_STATE_RECEIVE_UPDATE); -+err: -+ g_free(session); -+ g_free(pdh_cert); -+ -+ return ret; -+} -+ -+static int sev_receive_update_data(QEMUFile *f, uint8_t *ptr) -+{ -+ int ret = 1, fw_error = 0; -+ gchar *hdr = NULL, *trans = NULL; -+ struct kvm_sev_receive_update_data update = {}; -+ -+ /* get packet header */ -+ update.hdr_len = qemu_get_be32(f); -+ if (!check_blob_length(update.hdr_len)) { -+ return 1; -+ } -+ -+ hdr = g_new(gchar, update.hdr_len); -+ qemu_get_buffer(f, (uint8_t *)hdr, update.hdr_len); -+ update.hdr_uaddr = (uintptr_t)hdr; -+ -+ /* get transport buffer */ -+ update.trans_len = qemu_get_be32(f); -+ if (!check_blob_length(update.trans_len)) { -+ goto err; -+ } -+ -+ trans = g_new(gchar, update.trans_len); -+ update.trans_uaddr = (uintptr_t)trans; -+ qemu_get_buffer(f, (uint8_t *)update.trans_uaddr, update.trans_len); -+ -+ update.guest_uaddr = (uintptr_t) ptr; -+ update.guest_len = update.trans_len; -+ -+ trace_kvm_sev_receive_update_data(trans, ptr, update.guest_len, -+ hdr, update.hdr_len); -+ -+ ret = sev_ioctl(sev_guest->sev_fd, KVM_SEV_RECEIVE_UPDATE_DATA, -+ &update, &fw_error); -+ if (ret) { -+ error_report("Error RECEIVE_UPDATE_DATA ret=%d fw_error=%d '%s'", -+ ret, fw_error, fw_error_to_str(fw_error)); -+ goto err; -+ } -+err: -+ g_free(trans); -+ g_free(hdr); -+ return ret; -+} -+ -+int sev_load_incoming_page(QEMUFile *f, uint8_t *ptr) -+{ -+ SevGuestState *s = sev_guest; -+ -+ /* -+ * If this is first buffer and SEV is not in recieiving state then -+ * use RECEIVE_START command to create a encryption context. -+ */ -+ if (!sev_check_state(s, SEV_STATE_RECEIVE_UPDATE) && -+ sev_receive_start(s, f)) { -+ return 1; -+ } -+ -+ return sev_receive_update_data(f, ptr); -+} -+ - static const QemuUUID sev_hash_table_header_guid = { - .data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93, - 0xd4, 0x11, 0xfd, 0x21) -diff --git a/target/i386/sev.h b/target/i386/sev.h -index 463e94bb8..d94da2956 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -55,6 +55,7 @@ int sev_save_setup(const char *pdh, const char *plat_cert, - const char *amd_cert); - int sev_save_outgoing_page(QEMUFile *f, uint8_t *ptr, - uint32_t size, uint64_t *bytes_sent); -+int sev_load_incoming_page(QEMUFile *f, uint8_t *ptr); - int sev_inject_launch_secret(const char *hdr, const char *secret, - uint64_t gpa, Error **errp); - -diff --git a/target/i386/trace-events b/target/i386/trace-events -index e8d4aec12..475de65ad 100644 ---- a/target/i386/trace-events -+++ b/target/i386/trace-events -@@ -14,3 +14,6 @@ kvm_sev_attestation_report(const char *mnonce, const char *data) "mnonce %s data - kvm_sev_send_start(uint64_t pdh, int l1, uint64_t plat, int l2, uint64_t amd, int l3) "pdh 0x%" PRIx64 " len %d plat 0x%" PRIx64 " len %d amd 0x%" PRIx64 " len %d" - kvm_sev_send_update_data(void *src, void *dst, int len) "guest %p trans %p len %d" - kvm_sev_send_finish(void) "" -+kvm_sev_receive_start(int policy, void *session, void *pdh) "policy 0x%x session %p pdh %p" -+kvm_sev_receive_update_data(void *src, void *dst, int len, void *hdr, int hdr_len) "guest %p trans %p len %d hdr %p hdr_len %d" -+kvm_sev_receive_finish(void) "" --- -2.31.1 - diff --git a/1012-kvm-Add-support-for-SEV-shared-regions-list-and-KVM_.patch b/1012-kvm-Add-support-for-SEV-shared-regions-list-and-KVM_.patch deleted file mode 100644 index 069445af359cd597e9061664e1b94c1671e9afcf..0000000000000000000000000000000000000000 --- a/1012-kvm-Add-support-for-SEV-shared-regions-list-and-KVM_.patch +++ /dev/null @@ -1,315 +0,0 @@ -From 08a6f74fec36c0a8af0fa4a8d32186222617d95e Mon Sep 17 00:00:00 2001 -From: Ashish Kalra -Date: Tue, 27 Jul 2021 15:05:49 +0000 -Subject: [PATCH 08/28] kvm: Add support for SEV shared regions list and - KVM_EXIT_HYPERCALL. - -cherry-picked from https://github.com/AMDESE/qemu/commit/fcbbd9b19ac. - -KVM_HC_MAP_GPA_RANGE hypercall is used by the SEV guest to notify a -change in the page encryption status to the hypervisor. The hypercall -should be invoked only when the encryption attribute is changed from -encrypted -> decrypted and vice versa. By default all guest pages are -considered encrypted. - -The hypercall exits to userspace with KVM_EXIT_HYPERCALL exit code, -currently this is used only by SEV guests for guest page encryptiion -status tracking. Add support to handle this exit and invoke SEV -shared regions list handlers. - -Add support for SEV guest shared regions and implementation of the -SEV shared regions list. - -Signed-off-by: Ashish Kalra -[ Fix conflicts. ] -Signed-off-by: hanliyang ---- - linux-headers/linux/kvm.h | 3 ++ - target/i386/kvm/kvm.c | 48 +++++++++++++++++ - target/i386/kvm/sev-stub.c | 11 ++++ - target/i386/sev.c | 106 +++++++++++++++++++++++++++++++++++++ - target/i386/sev.h | 3 ++ - 5 files changed, 171 insertions(+) - -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index 549fea3a9..9758e8fec 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -346,6 +346,7 @@ struct kvm_run { - } iocsr_io; - /* KVM_EXIT_HYPERCALL */ - struct { -+#define KVM_HC_MAP_GPA_RANGE 12 - __u64 nr; - __u64 args[6]; - __u64 ret; -@@ -1198,6 +1199,8 @@ struct kvm_ppc_resize_hpt { - #define KVM_CAP_ARM_SUPPORTED_BLOCK_SIZES 229 - #define KVM_CAP_ARM_SUPPORTED_REG_MASK_RANGES 230 - -+#define KVM_EXIT_HYPERCALL_VALID_MASK (1 << KVM_HC_MAP_GPA_RANGE) -+ - #ifdef KVM_CAP_IRQ_ROUTING - - struct kvm_irq_routing_irqchip { -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index a0bc9ea7b..82f6d3b04 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -148,6 +148,7 @@ static int has_xcrs; - static int has_sregs2; - static int has_exception_payload; - static int has_triple_fault_event; -+static int has_map_gpa_range; - - static bool has_msr_mcg_ext_ctl; - -@@ -2191,6 +2192,17 @@ int kvm_arch_init_vcpu(CPUState *cs) - c->eax = MAX(c->eax, KVM_CPUID_SIGNATURE | 0x10); - } - -+ if (sev_enabled()) { -+ c = cpuid_find_entry(&cpuid_data.cpuid, -+ KVM_CPUID_FEATURES | kvm_base, 0); -+ if (c) { -+ c->eax |= (1 << KVM_FEATURE_MIGRATION_CONTROL); -+ if (has_map_gpa_range) { -+ c->eax |= (1 << KVM_FEATURE_HC_MAP_GPA_RANGE); -+ } -+ } -+ } -+ - cpuid_data.cpuid.nent = cpuid_i; - - cpuid_data.cpuid.padding = 0; -@@ -2584,6 +2596,17 @@ int kvm_arch_init(MachineState *ms, KVMState *s) - #endif - } - -+ has_map_gpa_range = kvm_check_extension(s, KVM_CAP_EXIT_HYPERCALL); -+ if (has_map_gpa_range) { -+ ret = kvm_vm_enable_cap(s, KVM_CAP_EXIT_HYPERCALL, 0, -+ KVM_EXIT_HYPERCALL_VALID_MASK); -+ if (ret < 0) { -+ error_report("kvm: Failed to enable MAP_GPA_RANGE cap: %s", -+ strerror(-ret)); -+ return ret; -+ } -+ } -+ - ret = kvm_get_supported_msrs(s); - if (ret < 0) { - return ret; -@@ -4936,6 +4959,28 @@ static int kvm_handle_tpr_access(X86CPU *cpu) - return 1; - } - -+static int kvm_handle_exit_hypercall(X86CPU *cpu, struct kvm_run *run) -+{ -+ /* -+ * Currently this exit is only used by SEV guests for -+ * guest page encryption status tracking. -+ */ -+ if (run->hypercall.nr == KVM_HC_MAP_GPA_RANGE) { -+ unsigned long enc = run->hypercall.args[2]; -+ unsigned long gpa = run->hypercall.args[0]; -+ unsigned long npages = run->hypercall.args[1]; -+ unsigned long gfn_start = gpa >> TARGET_PAGE_BITS; -+ unsigned long gfn_end = gfn_start + npages; -+ -+ if (enc) { -+ sev_remove_shared_regions_list(gfn_start, gfn_end); -+ } else { -+ sev_add_shared_regions_list(gfn_start, gfn_end); -+ } -+ } -+ return 0; -+} -+ - int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) - { - static const uint8_t int3 = 0xcc; -@@ -5359,6 +5404,9 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) - ret = kvm_xen_handle_exit(cpu, &run->xen); - break; - #endif -+ case KVM_EXIT_HYPERCALL: -+ ret = kvm_handle_exit_hypercall(cpu, run); -+ break; - default: - fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason); - ret = -1; -diff --git a/target/i386/kvm/sev-stub.c b/target/i386/kvm/sev-stub.c -index 1be5341e8..1282d242a 100644 ---- a/target/i386/kvm/sev-stub.c -+++ b/target/i386/kvm/sev-stub.c -@@ -19,3 +19,14 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - /* If we get here, cgs must be some non-SEV thing */ - return 0; - } -+ -+int sev_remove_shared_regions_list(unsigned long gfn_start, -+ unsigned long gfn_end) -+{ -+ return 0; -+} -+ -+int sev_add_shared_regions_list(unsigned long gfn_start, unsigned long gfn_end) -+{ -+ return 0; -+} -diff --git a/target/i386/sev.c b/target/i386/sev.c -index ee42edf4e..bd00a28e9 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -44,6 +44,11 @@ - #define TYPE_SEV_GUEST "sev-guest" - OBJECT_DECLARE_SIMPLE_TYPE(SevGuestState, SEV_GUEST) - -+struct shared_region { -+ unsigned long gfn_start, gfn_end; -+ QTAILQ_ENTRY(shared_region) list; -+}; -+ - - /** - * SevGuestState: -@@ -87,6 +92,8 @@ struct SevGuestState { - uint32_t reset_cs; - uint32_t reset_ip; - bool reset_data_valid; -+ -+ QTAILQ_HEAD(, shared_region) shared_regions_list; - }; - - #define DEFAULT_GUEST_POLICY 0x1 /* disable debug */ -@@ -1136,6 +1143,7 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - migration_add_notifier(&sev_migration_state, sev_migration_state_notifier); - - cgs_class->memory_encryption_ops = &sev_memory_encryption_ops; -+ QTAILQ_INIT(&sev->shared_regions_list); - - cgs->ready = true; - -@@ -1670,6 +1678,104 @@ int sev_load_incoming_page(QEMUFile *f, uint8_t *ptr) - return sev_receive_update_data(f, ptr); - } - -+int sev_remove_shared_regions_list(unsigned long start, unsigned long end) -+{ -+ SevGuestState *s = sev_guest; -+ struct shared_region *pos; -+ -+ QTAILQ_FOREACH(pos, &s->shared_regions_list, list) { -+ unsigned long l, r; -+ unsigned long curr_gfn_end = pos->gfn_end; -+ -+ /* -+ * Find if any intersection exists ? -+ * left bound for intersecting segment -+ */ -+ l = MAX(start, pos->gfn_start); -+ /* right bound for intersecting segment */ -+ r = MIN(end, pos->gfn_end); -+ if (l <= r) { -+ if (pos->gfn_start == l && pos->gfn_end == r) { -+ QTAILQ_REMOVE(&s->shared_regions_list, pos, list); -+ } else if (l == pos->gfn_start) { -+ pos->gfn_start = r; -+ } else if (r == pos->gfn_end) { -+ pos->gfn_end = l; -+ } else { -+ /* Do a de-merge -- split linked list nodes */ -+ struct shared_region *shrd_region; -+ -+ pos->gfn_end = l; -+ shrd_region = g_malloc0(sizeof(*shrd_region)); -+ if (!shrd_region) { -+ return 0; -+ } -+ shrd_region->gfn_start = r; -+ shrd_region->gfn_end = curr_gfn_end; -+ QTAILQ_INSERT_AFTER(&s->shared_regions_list, pos, -+ shrd_region, list); -+ } -+ } -+ if (end <= curr_gfn_end) { -+ break; -+ } -+ } -+ return 0; -+} -+ -+int sev_add_shared_regions_list(unsigned long start, unsigned long end) -+{ -+ struct shared_region *shrd_region; -+ struct shared_region *pos; -+ SevGuestState *s = sev_guest; -+ -+ if (QTAILQ_EMPTY(&s->shared_regions_list)) { -+ shrd_region = g_malloc0(sizeof(*shrd_region)); -+ if (!shrd_region) { -+ return -1; -+ } -+ shrd_region->gfn_start = start; -+ shrd_region->gfn_end = end; -+ QTAILQ_INSERT_TAIL(&s->shared_regions_list, shrd_region, list); -+ return 0; -+ } -+ -+ /* -+ * shared regions list is a sorted list in ascending order -+ * of guest PA's and also merges consecutive range of guest PA's -+ */ -+ QTAILQ_FOREACH(pos, &s->shared_regions_list, list) { -+ /* handle duplicate overlapping regions */ -+ if (start >= pos->gfn_start && end <= pos->gfn_end) { -+ return 0; -+ } -+ if (pos->gfn_end < start) { -+ continue; -+ } -+ /* merge consecutive guest PA(s) -- forward merge */ -+ if (pos->gfn_start <= start && pos->gfn_end >= start) { -+ pos->gfn_end = end; -+ return 0; -+ } -+ break; -+ } -+ /* -+ * Add a new node -+ */ -+ shrd_region = g_malloc0(sizeof(*shrd_region)); -+ if (!shrd_region) { -+ return -1; -+ } -+ shrd_region->gfn_start = start; -+ shrd_region->gfn_end = end; -+ if (pos) { -+ QTAILQ_INSERT_BEFORE(pos, shrd_region, list); -+ } else { -+ QTAILQ_INSERT_TAIL(&s->shared_regions_list, shrd_region, list); -+ } -+ return 1; -+} -+ - static const QemuUUID sev_hash_table_header_guid = { - .data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93, - 0xd4, 0x11, 0xfd, 0x21) -diff --git a/target/i386/sev.h b/target/i386/sev.h -index d94da2956..acf69d4e6 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -61,6 +61,9 @@ int sev_inject_launch_secret(const char *hdr, const char *secret, - - int sev_es_save_reset_vector(void *flash_ptr, uint64_t flash_size); - void sev_es_set_reset_vector(CPUState *cpu); -+int sev_remove_shared_regions_list(unsigned long gfn_start, -+ unsigned long gfn_end); -+int sev_add_shared_regions_list(unsigned long gfn_start, unsigned long gfn_end); - - int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp); - --- -2.31.1 - diff --git a/1013-migration-add-support-to-migrate-shared-regions-list.patch b/1013-migration-add-support-to-migrate-shared-regions-list.patch deleted file mode 100644 index e0633d752648eaa2cd190aaa26e5e79815e36590..0000000000000000000000000000000000000000 --- a/1013-migration-add-support-to-migrate-shared-regions-list.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 458a857abe8ba6dd8e581957dba850c36277f92f Mon Sep 17 00:00:00 2001 -From: Brijesh Singh -Date: Tue, 27 Jul 2021 16:31:36 +0000 -Subject: [PATCH 09/28] migration: add support to migrate shared regions list - -cherry-picked from https://github.com/AMDESE/qemu/commit/9236f522e48b6. - -When memory encryption is enabled, the hypervisor maintains a shared -regions list which is referred by hypervisor during migration to check -if page is private or shared. This list is built during the VM bootup and -must be migrated to the target host so that hypervisor on target host can -use it for future migration. - -Signed-off-by: Brijesh Singh -Co-developed-by: Ashish Kalra -Signed-off-by: Ashish Kalra -[ Fix conflicts. ] -Signed-off-by: hanliyang ---- - include/exec/confidential-guest-support.h | 2 +- - target/i386/sev.c | 45 +++++++++++++++++++++++ - target/i386/sev.h | 2 + - 3 files changed, 48 insertions(+), 1 deletion(-) - -diff --git a/include/exec/confidential-guest-support.h b/include/exec/confidential-guest-support.h -index 343f686fc..dd4887f65 100644 ---- a/include/exec/confidential-guest-support.h -+++ b/include/exec/confidential-guest-support.h -@@ -73,7 +73,7 @@ struct ConfidentialGuestMemoryEncryptionOps { - bool (*is_gfn_in_unshared_region)(unsigned long gfn); - - /* Write the shared regions list */ -- int (*save_outgoing_shared_regions_list)(QEMUFile *f); -+ int (*save_outgoing_shared_regions_list)(QEMUFile *f, uint64_t *bytes_sent); - - /* Load the shared regions list */ - int (*load_incoming_shared_regions_list)(QEMUFile *f); -diff --git a/target/i386/sev.c b/target/i386/sev.c -index bd00a28e9..aeb3e323d 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -176,10 +176,15 @@ static const char *const sev_fw_errlist[] = { - - #define SEV_FW_BLOB_MAX_SIZE 0x4000 /* 16KB */ - -+#define SHARED_REGION_LIST_CONT 0x1 -+#define SHARED_REGION_LIST_END 0x2 -+ - static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { - .save_setup = sev_save_setup, - .save_outgoing_page = sev_save_outgoing_page, - .load_incoming_page = sev_load_incoming_page, -+ .save_outgoing_shared_regions_list = sev_save_outgoing_shared_regions_list, -+ .load_incoming_shared_regions_list = sev_load_incoming_shared_regions_list, - }; - - static int -@@ -1776,6 +1781,46 @@ int sev_add_shared_regions_list(unsigned long start, unsigned long end) - return 1; - } - -+int sev_save_outgoing_shared_regions_list(QEMUFile *f, uint64_t *bytes_sent) -+{ -+ SevGuestState *s = sev_guest; -+ struct shared_region *pos; -+ -+ QTAILQ_FOREACH(pos, &s->shared_regions_list, list) { -+ qemu_put_be32(f, SHARED_REGION_LIST_CONT); -+ qemu_put_be32(f, pos->gfn_start); -+ qemu_put_be32(f, pos->gfn_end); -+ *bytes_sent += 12; -+ } -+ -+ qemu_put_be32(f, SHARED_REGION_LIST_END); -+ *bytes_sent += 4; -+ return 0; -+} -+ -+int sev_load_incoming_shared_regions_list(QEMUFile *f) -+{ -+ SevGuestState *s = sev_guest; -+ struct shared_region *shrd_region; -+ int status; -+ -+ status = qemu_get_be32(f); -+ while (status == SHARED_REGION_LIST_CONT) { -+ -+ shrd_region = g_malloc0(sizeof(*shrd_region)); -+ if (!shrd_region) { -+ return 0; -+ } -+ shrd_region->gfn_start = qemu_get_be32(f); -+ shrd_region->gfn_end = qemu_get_be32(f); -+ -+ QTAILQ_INSERT_TAIL(&s->shared_regions_list, shrd_region, list); -+ -+ status = qemu_get_be32(f); -+ } -+ return 0; -+} -+ - static const QemuUUID sev_hash_table_header_guid = { - .data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93, - 0xd4, 0x11, 0xfd, 0x21) -diff --git a/target/i386/sev.h b/target/i386/sev.h -index acf69d4e6..5b4231c85 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -64,6 +64,8 @@ void sev_es_set_reset_vector(CPUState *cpu); - int sev_remove_shared_regions_list(unsigned long gfn_start, - unsigned long gfn_end); - int sev_add_shared_regions_list(unsigned long gfn_start, unsigned long gfn_end); -+int sev_save_outgoing_shared_regions_list(QEMUFile *f, uint64_t *bytes_sent); -+int sev_load_incoming_shared_regions_list(QEMUFile *f); - - int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp); - --- -2.31.1 - diff --git a/1014-migration-ram-add-support-to-send-encrypted-pages.patch b/1014-migration-ram-add-support-to-send-encrypted-pages.patch deleted file mode 100644 index fbc7295be7fc6add7d37294fce3f23823fe29a45..0000000000000000000000000000000000000000 --- a/1014-migration-ram-add-support-to-send-encrypted-pages.patch +++ /dev/null @@ -1,343 +0,0 @@ -From 639f32076d0a6596ebd0fbc7aa6465786c57e5e8 Mon Sep 17 00:00:00 2001 -From: Brijesh Singh -Date: Tue, 27 Jul 2021 16:53:19 +0000 -Subject: [PATCH 10/28] migration/ram: add support to send encrypted pages - -cherry-picked from https://github.com/AMDESE/qemu/commit/2d6bda0d4cf. - -When memory encryption is enabled, the guest memory will be encrypted with -the guest specific key. The patch introduces RAM_SAVE_FLAG_ENCRYPTED_PAGE -flag to distinguish the encrypted data from plaintext. Encrypted pages -may need special handling. The sev_save_outgoing_page() is used -by the sender to write the encrypted pages onto the socket, similarly the -sev_load_incoming_page() is used by the target to read the -encrypted pages from the socket and load into the guest memory. - -Signed-off-by: Brijesh Singh -Co-developed-by: Ashish Kalra -Signed-off-by: Ashish Kalra -[ Fix conflicts. ] -Signed-off-by: hanliyang ---- - migration/migration.h | 2 + - migration/ram.c | 174 +++++++++++++++++++++++++++++++++++++++++- - target/i386/sev.c | 14 ++++ - target/i386/sev.h | 4 + - 4 files changed, 192 insertions(+), 2 deletions(-) - -diff --git a/migration/migration.h b/migration/migration.h -index cf2c9c88e..65f5599f4 100644 ---- a/migration/migration.h -+++ b/migration/migration.h -@@ -550,4 +550,6 @@ void migration_rp_kick(MigrationState *s); - - int migration_stop_vm(RunState state); - -+bool memcrypt_enabled(void); -+ - #endif -diff --git a/migration/ram.c b/migration/ram.c -index 8c7886ab7..317aea563 100644 ---- a/migration/ram.c -+++ b/migration/ram.c -@@ -63,6 +63,10 @@ - #include "options.h" - #include "sysemu/dirtylimit.h" - #include "sysemu/kvm.h" -+#include "exec/confidential-guest-support.h" -+ -+/* Defines RAM_SAVE_ENCRYPTED_PAGE and RAM_SAVE_SHARED_REGION_LIST */ -+#include "target/i386/sev.h" - - #include "hw/boards.h" /* for machine_dump_guest_core() */ - -@@ -92,7 +96,16 @@ - /* 0x80 is reserved in rdma.h for RAM_SAVE_FLAG_HOOK */ - #define RAM_SAVE_FLAG_COMPRESS_PAGE 0x100 - #define RAM_SAVE_FLAG_MULTIFD_FLUSH 0x200 --/* We can't use any flag that is bigger than 0x200 */ -+#define RAM_SAVE_FLAG_ENCRYPTED_DATA 0x400 -+ -+bool memcrypt_enabled(void) -+{ -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ if(ms->cgs) -+ return ms->cgs->ready; -+ else -+ return false; -+} - - XBZRLECacheStats xbzrle_counters; - -@@ -1204,6 +1217,88 @@ static int save_normal_page(PageSearchStatus *pss, RAMBlock *block, - return 1; - } - -+/** -+ * ram_save_encrypted_page - send the given encrypted page to the stream -+ */ -+static int ram_save_encrypted_page(RAMState *rs, PageSearchStatus *pss) -+{ -+ QEMUFile *file = pss->pss_channel; -+ int ret; -+ uint8_t *p; -+ RAMBlock *block = pss->block; -+ ram_addr_t offset = ((ram_addr_t)pss->page) << TARGET_PAGE_BITS; -+ uint64_t bytes_xmit = 0; -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ ConfidentialGuestSupportClass *cgs_class = -+ (ConfidentialGuestSupportClass *) object_get_class(OBJECT(ms->cgs)); -+ struct ConfidentialGuestMemoryEncryptionOps *ops = -+ cgs_class->memory_encryption_ops; -+ -+ p = block->host + offset; -+ trace_ram_save_page(block->idstr, (uint64_t)offset, p); -+ -+ ram_transferred_add(save_page_header(pss, file, block, -+ offset | RAM_SAVE_FLAG_ENCRYPTED_DATA)); -+ qemu_put_be32(file, RAM_SAVE_ENCRYPTED_PAGE); -+ ret = ops->save_outgoing_page(file, p, TARGET_PAGE_SIZE, &bytes_xmit); -+ if (ret) { -+ return -1; -+ } -+ ram_transferred_add(4 + bytes_xmit); -+ stat64_add(&mig_stats.normal_pages, 1); -+ -+ return 1; -+} -+ -+/** -+ * ram_save_shared_region_list: send the shared region list -+ */ -+static int ram_save_shared_region_list(RAMState *rs, QEMUFile *f) -+{ -+ int ret; -+ uint64_t bytes_xmit = 0; -+ PageSearchStatus *pss = &rs->pss[RAM_CHANNEL_PRECOPY]; -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ ConfidentialGuestSupportClass *cgs_class = -+ (ConfidentialGuestSupportClass *) object_get_class(OBJECT(ms->cgs)); -+ struct ConfidentialGuestMemoryEncryptionOps *ops = -+ cgs_class->memory_encryption_ops; -+ -+ ram_transferred_add(save_page_header(pss, f, -+ pss->last_sent_block, -+ RAM_SAVE_FLAG_ENCRYPTED_DATA)); -+ qemu_put_be32(f, RAM_SAVE_SHARED_REGIONS_LIST); -+ ret = ops->save_outgoing_shared_regions_list(f, &bytes_xmit); -+ if (ret < 0) { -+ return ret; -+ } -+ ram_transferred_add(4 + bytes_xmit); -+ -+ return 0; -+} -+ -+static int load_encrypted_data(QEMUFile *f, uint8_t *ptr) -+{ -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ ConfidentialGuestSupportClass *cgs_class = -+ (ConfidentialGuestSupportClass *) object_get_class(OBJECT(ms->cgs)); -+ struct ConfidentialGuestMemoryEncryptionOps *ops = -+ cgs_class->memory_encryption_ops; -+ -+ int flag; -+ -+ flag = qemu_get_be32(f); -+ -+ if (flag == RAM_SAVE_ENCRYPTED_PAGE) { -+ return ops->load_incoming_page(f, ptr); -+ } else if (flag == RAM_SAVE_SHARED_REGIONS_LIST) { -+ return ops->load_incoming_shared_regions_list(f); -+ } else { -+ error_report("unknown encrypted flag %x", flag); -+ return 1; -+ } -+} -+ - /** - * ram_save_page: send the given page to the stream - * -@@ -2034,6 +2129,35 @@ static bool save_compress_page(RAMState *rs, PageSearchStatus *pss, - compress_send_queued_data); - } - -+/** -+ * encrypted_test_list: check if the page is encrypted -+ * -+ * Returns a bool indicating whether the page is encrypted. -+ */ -+static bool encrypted_test_list(RAMState *rs, RAMBlock *block, -+ unsigned long page) -+{ -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ ConfidentialGuestSupportClass *cgs_class = -+ (ConfidentialGuestSupportClass *) object_get_class(OBJECT(ms->cgs)); -+ struct ConfidentialGuestMemoryEncryptionOps *ops = -+ cgs_class->memory_encryption_ops; -+ unsigned long gfn; -+ -+ /* ROM devices contains the unencrypted data */ -+ if (memory_region_is_rom(block->mr)) { -+ return false; -+ } -+ -+ /* -+ * Translate page in ram_addr_t address space to GPA address -+ * space using memory region. -+ */ -+ gfn = page + (block->mr->addr >> TARGET_PAGE_BITS); -+ -+ return ops->is_gfn_in_unshared_region(gfn); -+} -+ - /** - * ram_save_target_page_legacy: save one target page - * -@@ -2052,6 +2176,17 @@ static int ram_save_target_page_legacy(RAMState *rs, PageSearchStatus *pss) - return res; - } - -+ /* -+ * If memory encryption is enabled then use memory encryption APIs -+ * to write the outgoing buffer to the wire. The encryption APIs -+ * will take care of accessing the guest memory and re-encrypt it -+ * for the transport purposes. -+ */ -+ if (memcrypt_enabled() && -+ encrypted_test_list(rs, pss->block, pss->page)) { -+ return ram_save_encrypted_page(rs, pss); -+ } -+ - if (save_compress_page(rs, pss, offset)) { - return 1; - } -@@ -2917,6 +3052,18 @@ void qemu_guest_free_page_hint(void *addr, size_t len) - } - } - -+static int ram_encrypted_save_setup(void) -+{ -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ ConfidentialGuestSupportClass *cgs_class = -+ (ConfidentialGuestSupportClass *) object_get_class(OBJECT(ms->cgs)); -+ struct ConfidentialGuestMemoryEncryptionOps *ops = -+ cgs_class->memory_encryption_ops; -+ MigrationParameters *p = &migrate_get_current()->parameters; -+ -+ return ops->save_setup(p->sev_pdh, p->sev_plat_cert, p->sev_amd_cert); -+} -+ - /* - * Each of ram_save_setup, ram_save_iterate and ram_save_complete has - * long-running RCU critical section. When rcu-reclaims in the code -@@ -2952,6 +3099,13 @@ static int ram_save_setup(QEMUFile *f, void *opaque) - (*rsp)->pss[RAM_CHANNEL_PRECOPY].pss_channel = f; - - WITH_RCU_READ_LOCK_GUARD() { -+ -+ if (memcrypt_enabled()) { -+ if (ram_encrypted_save_setup()) { -+ return -1; -+ } -+ } -+ - qemu_put_be64(f, ram_bytes_total_with_ignored() - | RAM_SAVE_FLAG_MEM_SIZE); - -@@ -3181,6 +3335,15 @@ static int ram_save_complete(QEMUFile *f, void *opaque) - qemu_file_set_error(f, ret); - return ret; - } -+ -+ /* send the shared regions list */ -+ if (memcrypt_enabled()) { -+ ret = ram_save_shared_region_list(rs, f); -+ if (ret < 0) { -+ qemu_file_set_error(f, ret); -+ return ret; -+ } -+ } - } - - ret = multifd_send_sync_main(rs->pss[RAM_CHANNEL_PRECOPY].pss_channel); -@@ -3918,7 +4081,8 @@ static int ram_load_precopy(QEMUFile *f) - } - - if (flags & (RAM_SAVE_FLAG_ZERO | RAM_SAVE_FLAG_PAGE | -- RAM_SAVE_FLAG_COMPRESS_PAGE | RAM_SAVE_FLAG_XBZRLE)) { -+ RAM_SAVE_FLAG_COMPRESS_PAGE | RAM_SAVE_FLAG_XBZRLE | -+ RAM_SAVE_FLAG_ENCRYPTED_DATA)) { - RAMBlock *block = ram_block_from_stream(mis, f, flags, - RAM_CHANNEL_PRECOPY); - -@@ -4011,6 +4175,12 @@ static int ram_load_precopy(QEMUFile *f) - qemu_file_set_error(f, ret); - } - break; -+ case RAM_SAVE_FLAG_ENCRYPTED_DATA: -+ if (load_encrypted_data(f, host)) { -+ error_report("Failed to load encrypted data"); -+ ret = -EINVAL; -+ } -+ break; - default: - error_report("Unknown combination of migration flags: 0x%x", flags); - ret = -EINVAL; -diff --git a/target/i386/sev.c b/target/i386/sev.c -index aeb3e323d..851175631 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -183,6 +183,7 @@ static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { - .save_setup = sev_save_setup, - .save_outgoing_page = sev_save_outgoing_page, - .load_incoming_page = sev_load_incoming_page, -+ .is_gfn_in_unshared_region = sev_is_gfn_in_unshared_region, - .save_outgoing_shared_regions_list = sev_save_outgoing_shared_regions_list, - .load_incoming_shared_regions_list = sev_load_incoming_shared_regions_list, - }; -@@ -1821,6 +1822,19 @@ int sev_load_incoming_shared_regions_list(QEMUFile *f) - return 0; - } - -+bool sev_is_gfn_in_unshared_region(unsigned long gfn) -+{ -+ SevGuestState *s = sev_guest; -+ struct shared_region *pos; -+ -+ QTAILQ_FOREACH(pos, &s->shared_regions_list, list) { -+ if (gfn >= pos->gfn_start && gfn < pos->gfn_end) { -+ return false; -+ } -+ } -+ return true; -+} -+ - static const QemuUUID sev_hash_table_header_guid = { - .data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93, - 0xd4, 0x11, 0xfd, 0x21) -diff --git a/target/i386/sev.h b/target/i386/sev.h -index 5b4231c85..b9c2afb79 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -38,6 +38,9 @@ typedef struct SevKernelLoaderContext { - size_t cmdline_size; - } SevKernelLoaderContext; - -+#define RAM_SAVE_ENCRYPTED_PAGE 0x1 -+#define RAM_SAVE_SHARED_REGIONS_LIST 0x2 -+ - #ifdef CONFIG_SEV - bool sev_enabled(void); - bool sev_es_enabled(void); -@@ -66,6 +69,7 @@ int sev_remove_shared_regions_list(unsigned long gfn_start, - int sev_add_shared_regions_list(unsigned long gfn_start, unsigned long gfn_end); - int sev_save_outgoing_shared_regions_list(QEMUFile *f, uint64_t *bytes_sent); - int sev_load_incoming_shared_regions_list(QEMUFile *f); -+bool sev_is_gfn_in_unshared_region(unsigned long gfn); - - int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp); - --- -2.31.1 - diff --git a/1015-migration-ram-Force-encrypted-status-for-flash0-flas.patch b/1015-migration-ram-Force-encrypted-status-for-flash0-flas.patch deleted file mode 100644 index 22cb91cb0648dec9c2535c0a225e411ec31c6d1e..0000000000000000000000000000000000000000 --- a/1015-migration-ram-Force-encrypted-status-for-flash0-flas.patch +++ /dev/null @@ -1,44 +0,0 @@ -From d92cc48c799a42a8aaccc4e21ce95213981bef00 Mon Sep 17 00:00:00 2001 -From: Ashish Kalra -Date: Tue, 27 Jul 2021 18:05:25 +0000 -Subject: [PATCH 11/28] migration/ram: Force encrypted status for flash0 & - flash1 devices. - -cherry-picked from https://github.com/AMDESE/qemu/commit/803d6a4c8d. - -Currently OVMF clears the C-bit and marks NonExistent memory space -as decrypted in the page encryption bitmap. By marking the -NonExistent memory space as decrypted it gurantees any future MMIO adds -will work correctly, but this marks flash0 device space as decrypted. -At reset the SEV core will be in forced encrypted state, so this -decrypted marking of flash0 device space will cause VCPU reset to fail -as flash0 device pages will be migrated incorrectly. - -Signed-off-by: Ashish Kalra -Signed-off-by: hanliyang ---- - migration/ram.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/migration/ram.c b/migration/ram.c -index 317aea563..09faa8572 100644 ---- a/migration/ram.c -+++ b/migration/ram.c -@@ -2149,6 +2149,14 @@ static bool encrypted_test_list(RAMState *rs, RAMBlock *block, - return false; - } - -+ if (!strcmp(memory_region_name(block->mr), "system.flash0")) { -+ return true; -+ } -+ -+ if (!strcmp(memory_region_name(block->mr), "system.flash1")) { -+ return false; -+ } -+ - /* - * Translate page in ram_addr_t address space to GPA address - * space using memory region. --- -2.31.1 - diff --git a/1016-kvm-Add-support-for-userspace-MSR-filtering-and-hand.patch b/1016-kvm-Add-support-for-userspace-MSR-filtering-and-hand.patch deleted file mode 100644 index 455ad292a96b3a6f05dbc608769538f562896782..0000000000000000000000000000000000000000 --- a/1016-kvm-Add-support-for-userspace-MSR-filtering-and-hand.patch +++ /dev/null @@ -1,123 +0,0 @@ -From fadc1e0f1a90a7e81da7eca4604ef2733070d022 Mon Sep 17 00:00:00 2001 -From: Ashish Kalra -Date: Tue, 27 Jul 2021 17:59:33 +0000 -Subject: [PATCH 12/28] kvm: Add support for userspace MSR filtering and - handling of MSR_KVM_MIGRATION_CONTROL. - -cherry-picked from https://github.com/AMDESE/qemu/commit/67935c3fd5f. - -Add support for userspace MSR filtering using KVM_X86_SET_MSR_FILTER -ioctl and handling of MSRs in userspace. Currently this is only used -for SEV guests which use MSR_KVM_MIGRATION_CONTROL to indicate if the -guest is enabled and ready for migration. - -KVM arch code calls into SEV guest specific code to delete the -SEV migrate blocker which has been setup at SEV_LAUNCH_FINISH. - -Signed-off-by: Ashish Kalra -[ Fix conflicts. ] -Signed-off-by: hanliyang ---- - target/i386/kvm/kvm.c | 35 +++++++++++++++++++++++++++++++++++ - target/i386/kvm/sev-stub.c | 4 ++++ - target/i386/sev.c | 6 ++++++ - target/i386/sev.h | 1 + - 4 files changed, 46 insertions(+) - -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index 82f6d3b04..a5a755db0 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -2488,6 +2488,32 @@ static bool kvm_rdmsr_core_thread_count(X86CPU *cpu, uint32_t msr, - return true; - } - -+/* -+ * Currently this exit is only used by SEV guests for -+ * MSR_KVM_MIGRATION_CONTROL to indicate if the guest -+ * is ready for migration. -+ */ -+static uint64_t msr_kvm_migration_control; -+ -+static bool kvm_rdmsr_kvm_migration_control(X86CPU *cpu, uint32_t msr, -+ uint64_t *val) -+{ -+ *val = msr_kvm_migration_control; -+ -+ return true; -+} -+ -+static bool kvm_wrmsr_kvm_migration_control(X86CPU *cpu, uint32_t msr, -+ uint64_t val) -+{ -+ msr_kvm_migration_control = val; -+ -+ if (val == KVM_MIGRATION_READY) -+ sev_del_migrate_blocker(); -+ -+ return true; -+} -+ - static Notifier smram_machine_done; - static KVMMemoryListener smram_listener; - static AddressSpace smram_address_space; -@@ -2735,6 +2761,15 @@ int kvm_arch_init(MachineState *ms, KVMState *s) - strerror(-ret)); - exit(1); - } -+ -+ r = kvm_filter_msr(s, MSR_KVM_MIGRATION_CONTROL, -+ kvm_rdmsr_kvm_migration_control, -+ kvm_wrmsr_kvm_migration_control); -+ if (!r) { -+ error_report("Could not install MSR_KVM_MIGRATION_CONTROL handler: %s", -+ strerror(-ret)); -+ exit(1); -+ } - } - - return 0; -diff --git a/target/i386/kvm/sev-stub.c b/target/i386/kvm/sev-stub.c -index 1282d242a..99899688e 100644 ---- a/target/i386/kvm/sev-stub.c -+++ b/target/i386/kvm/sev-stub.c -@@ -30,3 +30,7 @@ int sev_add_shared_regions_list(unsigned long gfn_start, unsigned long gfn_end) - { - return 0; - } -+ -+void sev_del_migrate_blocker(void) -+{ -+} -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 851175631..aeeb479b5 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -925,6 +925,12 @@ sev_launch_finish(SevGuestState *sev) - migrate_add_blocker(&sev_mig_blocker, &error_fatal); - } - -+void -+sev_del_migrate_blocker(void) -+{ -+ migrate_del_blocker(&sev_mig_blocker); -+} -+ - static int - sev_receive_finish(SevGuestState *s) - { -diff --git a/target/i386/sev.h b/target/i386/sev.h -index b9c2afb79..84e3bdf2d 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -70,6 +70,7 @@ int sev_add_shared_regions_list(unsigned long gfn_start, unsigned long gfn_end); - int sev_save_outgoing_shared_regions_list(QEMUFile *f, uint64_t *bytes_sent); - int sev_load_incoming_shared_regions_list(QEMUFile *f); - bool sev_is_gfn_in_unshared_region(unsigned long gfn); -+void sev_del_migrate_blocker(void); - - int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp); - --- -2.31.1 - diff --git a/1017-target-i386-sev-Return-0-if-sev_send_get_packet_len-.patch b/1017-target-i386-sev-Return-0-if-sev_send_get_packet_len-.patch deleted file mode 100644 index 675caa3cb160f84bb6e50b8b00b7580fb5462650..0000000000000000000000000000000000000000 --- a/1017-target-i386-sev-Return-0-if-sev_send_get_packet_len-.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 73ea7fc6bb73f32c95328c540361d2ea1671fdc2 Mon Sep 17 00:00:00 2001 -From: hanliyang -Date: Wed, 31 Jan 2024 07:26:57 +0800 -Subject: [PATCH 13/28] target/i386: sev: Return 0 if sev_send_get_packet_len() - fails - -The send_packet_hdr_len of struct SEVState is of type size_t -which is an unsigned class type. If the send_packet_hdr_len -is assigned as -1, then it will be a huge number and the QEMU -process will crash when allocating packet buffer with the -huge size. - -For example, the following code could cause crash described -above. - - ``` - static int - sev_send_update_data(SEVState *s, QEMUFile *f, uint8_t *ptr, uint32_t size, - uint64_t *bytes_sent) - { - - ...... - - if (!s->send_packet_hdr) { - s->send_packet_hdr_len = sev_send_get_packet_len(&fw_error); - if (s->send_packet_hdr_len < 1) { - error_report("%s: SEND_UPDATE fw_error=%d '%s'", - __func__, fw_error, fw_error_to_str(fw_error)); - return 1; - } - - s->send_packet_hdr = g_new(gchar, s->send_packet_hdr_len); - } - - ...... - - } - ``` - -Signed-off-by: hanliyang ---- - target/i386/sev.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index aeeb479b5..b1b26b8a2 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -1491,7 +1491,7 @@ sev_send_get_packet_len(int *fw_err) - ret = sev_ioctl(sev_guest->sev_fd, KVM_SEV_SEND_UPDATE_DATA, - &update, fw_err); - if (*fw_err != SEV_RET_INVALID_LEN) { -- ret = -1; -+ ret = 0; - error_report("%s: failed to get session length ret=%d fw_error=%d '%s'", - __func__, ret, *fw_err, fw_error_to_str(*fw_err)); - goto err; --- -2.31.1 - diff --git a/1018-migration-ram-Force-encrypted-status-for-VGA-vram.patch b/1018-migration-ram-Force-encrypted-status-for-VGA-vram.patch deleted file mode 100644 index c986ca2b73b86957ba991757cb26ebe678fb9e3b..0000000000000000000000000000000000000000 --- a/1018-migration-ram-Force-encrypted-status-for-VGA-vram.patch +++ /dev/null @@ -1,32 +0,0 @@ -From e0cf323893b47b5184f6a87354c6eec3f1e0a1c2 Mon Sep 17 00:00:00 2001 -From: hanliyang -Date: Tue, 8 Dec 2020 22:57:46 -0500 -Subject: [PATCH 14/28] migration/ram: Force encrypted status for VGA vram - -The VGA vram memory region act as frame buffer of VM. This memory -is decrypted in the QEMU process. For CSV VM live migration, we -should avoid memory encryption status check on VGA vram. - -Signed-off-by: hanliyang ---- - migration/ram.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/migration/ram.c b/migration/ram.c -index 09faa8572..f71173855 100644 ---- a/migration/ram.c -+++ b/migration/ram.c -@@ -2157,6 +2157,10 @@ static bool encrypted_test_list(RAMState *rs, RAMBlock *block, - return false; - } - -+ if (!strcmp(memory_region_name(block->mr), "vga.vram")) { -+ return false; -+ } -+ - /* - * Translate page in ram_addr_t address space to GPA address - * space using memory region. --- -2.31.1 - diff --git a/1019-target-i386-sev-Clear-shared_regions_list-when-reboo.patch b/1019-target-i386-sev-Clear-shared_regions_list-when-reboo.patch deleted file mode 100644 index 26140d3783010b99869bb2c848a80473962ebd9e..0000000000000000000000000000000000000000 --- a/1019-target-i386-sev-Clear-shared_regions_list-when-reboo.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 64925eb013b2b0c85f2dd2a791019eebfb1e195f Mon Sep 17 00:00:00 2001 -From: hanliyang -Date: Sun, 16 Jan 2022 19:57:58 -0500 -Subject: [PATCH 15/28] target/i386: sev: Clear shared_regions_list when reboot - CSV Guest - -Also fix memory leak in sev_remove_shared_regions_list(). - -Signed-off-by: hanliyang ---- - target/i386/kvm/kvm.c | 5 +++++ - target/i386/sev.c | 5 +++-- - 2 files changed, 8 insertions(+), 2 deletions(-) - -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index a5a755db0..5730d0e0c 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -2270,6 +2270,11 @@ void kvm_arch_reset_vcpu(X86CPU *cpu) - env->mp_state = KVM_MP_STATE_RUNNABLE; - } - -+ if (cpu_is_bsp(cpu) && -+ sev_enabled() && has_map_gpa_range) { -+ sev_remove_shared_regions_list(0, -1); -+ } -+ - /* enabled by default */ - env->poll_control_msr = 1; - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index b1b26b8a2..594f034e8 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -1693,9 +1693,9 @@ int sev_load_incoming_page(QEMUFile *f, uint8_t *ptr) - int sev_remove_shared_regions_list(unsigned long start, unsigned long end) - { - SevGuestState *s = sev_guest; -- struct shared_region *pos; -+ struct shared_region *pos, *next_pos; - -- QTAILQ_FOREACH(pos, &s->shared_regions_list, list) { -+ QTAILQ_FOREACH_SAFE(pos, &s->shared_regions_list, list, next_pos) { - unsigned long l, r; - unsigned long curr_gfn_end = pos->gfn_end; - -@@ -1709,6 +1709,7 @@ int sev_remove_shared_regions_list(unsigned long start, unsigned long end) - if (l <= r) { - if (pos->gfn_start == l && pos->gfn_end == r) { - QTAILQ_REMOVE(&s->shared_regions_list, pos, list); -+ g_free(pos); - } else if (l == pos->gfn_start) { - pos->gfn_start = r; - } else if (r == pos->gfn_end) { --- -2.31.1 - diff --git a/1020-migration-ram-Fix-calculation-of-gfn-correpond-to-a-.patch b/1020-migration-ram-Fix-calculation-of-gfn-correpond-to-a-.patch deleted file mode 100644 index bd35406a3f49a8a6a17f75a2073fbf83d7911878..0000000000000000000000000000000000000000 --- a/1020-migration-ram-Fix-calculation-of-gfn-correpond-to-a-.patch +++ /dev/null @@ -1,57 +0,0 @@ -From e5107cd74257898fd2a1bf83883e4142c652980e Mon Sep 17 00:00:00 2001 -From: hanliyang -Date: Sun, 16 Jan 2022 20:05:02 -0500 -Subject: [PATCH 16/28] migration/ram: Fix calculation of gfn correpond to a - page in ramblock - -A RAMBlock contains a host memory region which may consist of many -discontiguous MemoryRegion in AddressSpace of a Guest, so we cannot -get gpa by MemoryRegion.addr. Since KVM memslot records the relationship -between gpa and hva, so we can pass the hva of page in RAMBlock to -kvm_phisical_memory_addr_from_host() to get the expected gpa. - -Signed-off-by: hanliyang ---- - migration/ram.c | 12 +++++++++++- - 1 file changed, 11 insertions(+), 1 deletion(-) - -diff --git a/migration/ram.c b/migration/ram.c -index f71173855..22f07a064 100644 ---- a/migration/ram.c -+++ b/migration/ram.c -@@ -67,6 +67,7 @@ - - /* Defines RAM_SAVE_ENCRYPTED_PAGE and RAM_SAVE_SHARED_REGION_LIST */ - #include "target/i386/sev.h" -+#include "sysemu/kvm.h" - - #include "hw/boards.h" /* for machine_dump_guest_core() */ - -@@ -2143,6 +2144,8 @@ static bool encrypted_test_list(RAMState *rs, RAMBlock *block, - struct ConfidentialGuestMemoryEncryptionOps *ops = - cgs_class->memory_encryption_ops; - unsigned long gfn; -+ hwaddr paddr = 0; -+ int ret; - - /* ROM devices contains the unencrypted data */ - if (memory_region_is_rom(block->mr)) { -@@ -2165,7 +2168,14 @@ static bool encrypted_test_list(RAMState *rs, RAMBlock *block, - * Translate page in ram_addr_t address space to GPA address - * space using memory region. - */ -- gfn = page + (block->mr->addr >> TARGET_PAGE_BITS); -+ if (kvm_enabled()) { -+ ret = kvm_physical_memory_addr_from_host(kvm_state, -+ block->host + (page << TARGET_PAGE_BITS), &paddr); -+ if (ret == 0) { -+ return false; -+ } -+ } -+ gfn = paddr >> TARGET_PAGE_BITS; - - return ops->is_gfn_in_unshared_region(gfn); - } --- -2.31.1 - diff --git a/1021-target-i386-Introduce-header-file-csv.h.patch b/1021-target-i386-Introduce-header-file-csv.h.patch deleted file mode 100644 index 7bd9203a856654bf4c71d82032b0d5c4b8ea2f00..0000000000000000000000000000000000000000 --- a/1021-target-i386-Introduce-header-file-csv.h.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 1a911e312fc82eedd8200ef28a7f8fed1ffe4aec Mon Sep 17 00:00:00 2001 -From: hanliyang -Date: Thu, 14 Mar 2024 19:21:11 +0800 -Subject: [PATCH 17/28] target/i386: Introduce header file csv.h - -This header file is used to provide common helper functions -and data structures for Hygon CSV. - -Signed-off-by: hanliyang ---- - configs/devices/i386-softmmu/default.mak | 1 + - hw/i386/Kconfig | 5 +++ - target/i386/csv.h | 47 ++++++++++++++++++++++++ - 3 files changed, 53 insertions(+) - create mode 100644 target/i386/csv.h - -diff --git a/configs/devices/i386-softmmu/default.mak b/configs/devices/i386-softmmu/default.mak -index 598c6646d..db83ffcab 100644 ---- a/configs/devices/i386-softmmu/default.mak -+++ b/configs/devices/i386-softmmu/default.mak -@@ -23,6 +23,7 @@ - #CONFIG_TPM_TIS_ISA=n - #CONFIG_VTD=n - #CONFIG_SGX=n -+#CONFIG_CSV=n - - # Boards: - # -diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig -index 55850791d..08f3ae43f 100644 ---- a/hw/i386/Kconfig -+++ b/hw/i386/Kconfig -@@ -10,6 +10,10 @@ config SGX - bool - depends on KVM - -+config CSV -+ bool -+ depends on SEV -+ - config PC - bool - imply APPLESMC -@@ -26,6 +30,7 @@ config PC - imply QXL - imply SEV - imply SGX -+ imply CSV - imply TEST_DEVICES - imply TPM_CRB - imply TPM_TIS_ISA -diff --git a/target/i386/csv.h b/target/i386/csv.h -new file mode 100644 -index 000000000..f935babe9 ---- /dev/null -+++ b/target/i386/csv.h -@@ -0,0 +1,47 @@ -+/* -+ * QEMU CSV support -+ * -+ * Copyright: Hygon Info Technologies Ltd. 2022 -+ * -+ * Author: -+ * Jiang Xin -+ * -+ * This work is licensed under the terms of the GNU GPL, version 2 or later. -+ * See the COPYING file in the top-level directory. -+ * -+ */ -+ -+#ifndef I386_CSV_H -+#define I386_CSV_H -+ -+#ifdef CONFIG_CSV -+ -+#include "cpu.h" -+ -+#define CPUID_VENDOR_HYGON_EBX 0x6f677948 /* "Hygo" */ -+#define CPUID_VENDOR_HYGON_ECX 0x656e6975 /* "uine" */ -+#define CPUID_VENDOR_HYGON_EDX 0x6e65476e /* "nGen" */ -+ -+static bool __attribute__((unused)) is_hygon_cpu(void) -+{ -+ uint32_t ebx = 0; -+ uint32_t ecx = 0; -+ uint32_t edx = 0; -+ -+ host_cpuid(0, 0, NULL, &ebx, &ecx, &edx); -+ -+ if (ebx == CPUID_VENDOR_HYGON_EBX && -+ ecx == CPUID_VENDOR_HYGON_ECX && -+ edx == CPUID_VENDOR_HYGON_EDX) -+ return true; -+ else -+ return false; -+} -+ -+#else -+ -+#define is_hygon_cpu() (false) -+ -+#endif -+ -+#endif --- -2.31.1 - diff --git a/1022-target-i386-csv-Read-cert-chain-from-file-when-prepa.patch b/1022-target-i386-csv-Read-cert-chain-from-file-when-prepa.patch deleted file mode 100644 index bac67afcb3805870135c043bdf000c3843bb9ced..0000000000000000000000000000000000000000 --- a/1022-target-i386-csv-Read-cert-chain-from-file-when-prepa.patch +++ /dev/null @@ -1,140 +0,0 @@ -From 771f30ba4ab5be48a2d88499fb7a3b5072536587 Mon Sep 17 00:00:00 2001 -From: hanliyang -Date: Mon, 13 Nov 2023 21:55:33 +0000 -Subject: [PATCH 18/28] target/i386: csv: Read cert chain from file when - prepared for CSV live migration - -The cert chain is too long when encoded with base64, use the filename -of cert chain instead of the encoded string when prepared for CSV live -migration. - -[ Fix conflicts. ] -Signed-off-by: hanliyang ---- - qapi/migration.json | 24 +++++++++++++++--------- - target/i386/sev.c | 30 ++++++++++++++++++++++++++---- - 2 files changed, 41 insertions(+), 13 deletions(-) - -diff --git a/qapi/migration.json b/qapi/migration.json -index 77051496f..14e70a5b7 100644 ---- a/qapi/migration.json -+++ b/qapi/migration.json -@@ -874,14 +874,16 @@ - # @mode: Migration mode. See description in @MigMode. Default is 'normal'. - # (Since 8.2) - # --# @sev-pdh: The target host platform diffie-hellman key encoded in base64 -+# @sev-pdh: The target host platform diffie-hellman key encoded in base64, or -+# pdh filename for hygon - # (Since 4.2) - # --# @sev-plat-cert: The target host platform certificate chain encoded in base64 -+# @sev-plat-cert: The target host platform certificate chain encoded in base64, -+# or plat cert filename for hygon - # (Since 4.2) - # - # @sev-amd-cert: AMD certificate chain which include ASK and OCA encoded in --# base64 (Since 4.2) -+# base64, or vendor cert filename for hygon (Since 4.2) - # - # Features: - # -@@ -1072,14 +1074,16 @@ - # @mode: Migration mode. See description in @MigMode. Default is 'normal'. - # (Since 8.2) - # --# @sev-pdh: The target host platform diffie-hellman key encoded in base64 -+# @sev-pdh: The target host platform diffie-hellman key encoded in base64, or -+# pdh filename for hygon - # (Since 4.2) - # --# @sev-plat-cert: The target host platform certificate chain encoded in base64 -+# @sev-plat-cert: The target host platform certificate chain encoded in base64, -+# or plat cert filename for hygon - # (Since 4.2) - # - # @sev-amd-cert: AMD certificate chain which include ASK and OCA encoded in --# base64 (Since 4.2) -+# base64, or vendor cert filename for hygon (Since 4.2) - # - # Features: - # -@@ -1313,14 +1317,16 @@ - # @mode: Migration mode. See description in @MigMode. Default is 'normal'. - # (Since 8.2) - # --# @sev-pdh: The target host platform diffie-hellman key encoded in base64 -+# @sev-pdh: The target host platform diffie-hellman key encoded in base64, or -+# pdh filename for hygon - # (Since 4.2) - # --# @sev-plat-cert: The target host platform certificate chain encoded in base64 -+# @sev-plat-cert: The target host platform certificate chain encoded in base64, -+# or plat cert filename for hygon - # (Since 4.2) - # - # @sev-amd-cert: AMD certificate chain which include ASK and OCA encoded in --# base64 (Since 4.2) -+# base64, or vendor cert filename for hygon (Since 4.2) - # - # Features: - # -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 594f034e8..ab7893fca 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -27,6 +27,7 @@ - #include "crypto/hash.h" - #include "sysemu/kvm.h" - #include "sev.h" -+#include "csv.h" - #include "sysemu/sysemu.h" - #include "sysemu/runstate.h" - #include "trace.h" -@@ -979,18 +980,39 @@ int sev_save_setup(const char *pdh, const char *plat_cert, - { - SevGuestState *s = sev_guest; - -- s->remote_pdh = g_base64_decode(pdh, &s->remote_pdh_len); -+ if (is_hygon_cpu()) { -+ if (sev_read_file_base64(pdh, &s->remote_pdh, -+ &s->remote_pdh_len) < 0) { -+ goto error; -+ } -+ } else { -+ s->remote_pdh = g_base64_decode(pdh, &s->remote_pdh_len); -+ } - if (!check_blob_length(s->remote_pdh_len)) { - goto error; - } - -- s->remote_plat_cert = g_base64_decode(plat_cert, -- &s->remote_plat_cert_len); -+ if (is_hygon_cpu()) { -+ if (sev_read_file_base64(plat_cert, &s->remote_plat_cert, -+ &s->remote_plat_cert_len) < 0) { -+ goto error; -+ } -+ } else { -+ s->remote_plat_cert = g_base64_decode(plat_cert, -+ &s->remote_plat_cert_len); -+ } - if (!check_blob_length(s->remote_plat_cert_len)) { - goto error; - } - -- s->amd_cert = g_base64_decode(amd_cert, &s->amd_cert_len); -+ if (is_hygon_cpu()) { -+ if (sev_read_file_base64(amd_cert, &s->amd_cert, -+ &s->amd_cert_len) < 0) { -+ goto error; -+ } -+ } else { -+ s->amd_cert = g_base64_decode(amd_cert, &s->amd_cert_len); -+ } - if (!check_blob_length(s->amd_cert_len)) { - goto error; - } --- -2.31.1 - diff --git a/1023-target-i386-csv-add-support-to-queue-the-outgoing-pa.patch b/1023-target-i386-csv-add-support-to-queue-the-outgoing-pa.patch deleted file mode 100644 index 8737896cbc941e7a9b5784b8ce68485f05b06f15..0000000000000000000000000000000000000000 --- a/1023-target-i386-csv-add-support-to-queue-the-outgoing-pa.patch +++ /dev/null @@ -1,259 +0,0 @@ -From 80508ddb448151afabbab70d34178d07fb1a2bdf Mon Sep 17 00:00:00 2001 -From: fangbaoshun -Date: Mon, 2 Aug 2021 11:00:07 +0800 -Subject: [PATCH 19/28] target/i386: csv: add support to queue the outgoing - page into a list - -The csv_queue_outgoing_page() provide the implementation to queue the -guest private pages during transmission. The routines queues the outgoing -pages into a listi, and then issues the KVM_CSV_COMMAND_BATCH command to -encrypt the pages togather before writing them to the socket. - -Signed-off-by: hanliyang ---- - include/exec/confidential-guest-support.h | 3 + - linux-headers/linux/kvm.h | 6 + - target/i386/csv.h | 11 ++ - target/i386/sev.c | 161 ++++++++++++++++++++++ - 4 files changed, 181 insertions(+) - -diff --git a/include/exec/confidential-guest-support.h b/include/exec/confidential-guest-support.h -index dd4887f65..8949568ac 100644 ---- a/include/exec/confidential-guest-support.h -+++ b/include/exec/confidential-guest-support.h -@@ -77,6 +77,9 @@ struct ConfidentialGuestMemoryEncryptionOps { - - /* Load the shared regions list */ - int (*load_incoming_shared_regions_list)(QEMUFile *f); -+ -+ /* Queue the encrypted page and metadata associated with it into a list */ -+ int (*queue_outgoing_page)(uint8_t *ptr, uint32_t size, uint64_t addr); - }; - - typedef struct ConfidentialGuestSupportClass { -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index 9758e8fec..a61be972c 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -2024,6 +2024,12 @@ struct kvm_sev_receive_update_data { - __u32 trans_len; - }; - -+struct kvm_csv_batch_list_node { -+ __u64 cmd_data_addr; -+ __u64 addr; -+ __u64 next_cmd_addr; -+}; -+ - #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) - #define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1) - #define KVM_DEV_ASSIGN_MASK_INTX (1 << 2) -diff --git a/target/i386/csv.h b/target/i386/csv.h -index f935babe9..4c1ef2002 100644 ---- a/target/i386/csv.h -+++ b/target/i386/csv.h -@@ -44,4 +44,15 @@ static bool __attribute__((unused)) is_hygon_cpu(void) - - #endif - -+typedef struct CsvBatchCmdList CsvBatchCmdList; -+typedef void (*CsvDestroyCmdNodeFn) (void *data); -+ -+struct CsvBatchCmdList { -+ struct kvm_csv_batch_list_node *head; -+ struct kvm_csv_batch_list_node *tail; -+ CsvDestroyCmdNodeFn destroy_fn; -+}; -+ -+int csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr); -+ - #endif -diff --git a/target/i386/sev.c b/target/i386/sev.c -index ab7893fca..027249e44 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -95,6 +95,9 @@ struct SevGuestState { - bool reset_data_valid; - - QTAILQ_HEAD(, shared_region) shared_regions_list; -+ -+ /* link list used for HYGON CSV */ -+ CsvBatchCmdList *csv_batch_cmd_list; - }; - - #define DEFAULT_GUEST_POLICY 0x1 /* disable debug */ -@@ -187,6 +190,7 @@ static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { - .is_gfn_in_unshared_region = sev_is_gfn_in_unshared_region, - .save_outgoing_shared_regions_list = sev_save_outgoing_shared_regions_list, - .load_incoming_shared_regions_list = sev_load_incoming_shared_regions_list, -+ .queue_outgoing_page = csv_queue_outgoing_page, - }; - - static int -@@ -1864,6 +1868,163 @@ bool sev_is_gfn_in_unshared_region(unsigned long gfn) - return true; - } - -+static CsvBatchCmdList * -+csv_batch_cmd_list_create(struct kvm_csv_batch_list_node *head, -+ CsvDestroyCmdNodeFn func) -+{ -+ CsvBatchCmdList *csv_batch_cmd_list = -+ g_malloc0(sizeof(*csv_batch_cmd_list)); -+ -+ if (!csv_batch_cmd_list) { -+ return NULL; -+ } -+ -+ csv_batch_cmd_list->head = head; -+ csv_batch_cmd_list->tail = head; -+ csv_batch_cmd_list->destroy_fn = func; -+ -+ return csv_batch_cmd_list; -+} -+ -+static int -+csv_batch_cmd_list_add_after(CsvBatchCmdList *list, -+ struct kvm_csv_batch_list_node *new_node) -+{ -+ list->tail->next_cmd_addr = (__u64)new_node; -+ list->tail = new_node; -+ -+ return 0; -+} -+ -+static struct kvm_csv_batch_list_node * -+csv_batch_cmd_list_node_create(uint64_t cmd_data_addr, uint64_t addr) -+{ -+ struct kvm_csv_batch_list_node *new_node = -+ g_malloc0(sizeof(struct kvm_csv_batch_list_node)); -+ -+ if (!new_node) { -+ return NULL; -+ } -+ -+ new_node->cmd_data_addr = cmd_data_addr; -+ new_node->addr = addr; -+ new_node->next_cmd_addr = 0; -+ -+ return new_node; -+} -+ -+static int csv_batch_cmd_list_destroy(CsvBatchCmdList *list) -+{ -+ struct kvm_csv_batch_list_node *node = list->head; -+ -+ while (node != NULL) { -+ if (list->destroy_fn != NULL) -+ list->destroy_fn((void *)node->cmd_data_addr); -+ -+ list->head = (struct kvm_csv_batch_list_node *)node->next_cmd_addr; -+ g_free(node); -+ node = list->head; -+ } -+ -+ g_free(list); -+ return 0; -+} -+ -+static void send_update_data_free(void *data) -+{ -+ struct kvm_sev_send_update_data *update = -+ (struct kvm_sev_send_update_data *)data; -+ g_free((guchar *)update->hdr_uaddr); -+ g_free((guchar *)update->trans_uaddr); -+ g_free(update); -+} -+ -+static int -+csv_send_queue_data(SevGuestState *s, uint8_t *ptr, -+ uint32_t size, uint64_t addr) -+{ -+ int ret = 0; -+ int fw_error; -+ guchar *trans; -+ guchar *packet_hdr; -+ struct kvm_sev_send_update_data *update; -+ struct kvm_csv_batch_list_node *new_node = NULL; -+ -+ /* If this is first call then query the packet header bytes and allocate -+ * the packet buffer. -+ */ -+ if (s->send_packet_hdr_len < 1) { -+ s->send_packet_hdr_len = sev_send_get_packet_len(&fw_error); -+ if (s->send_packet_hdr_len < 1) { -+ error_report("%s: SEND_UPDATE fw_error=%d '%s'", -+ __func__, fw_error, fw_error_to_str(fw_error)); -+ return 1; -+ } -+ } -+ -+ packet_hdr = g_new(guchar, s->send_packet_hdr_len); -+ memset(packet_hdr, 0, s->send_packet_hdr_len); -+ -+ update = g_new0(struct kvm_sev_send_update_data, 1); -+ -+ /* allocate transport buffer */ -+ trans = g_new(guchar, size); -+ -+ update->hdr_uaddr = (unsigned long)packet_hdr; -+ update->hdr_len = s->send_packet_hdr_len; -+ update->guest_uaddr = (unsigned long)ptr; -+ update->guest_len = size; -+ update->trans_uaddr = (unsigned long)trans; -+ update->trans_len = size; -+ -+ new_node = csv_batch_cmd_list_node_create((uint64_t)update, addr); -+ if (!new_node) { -+ ret = -ENOMEM; -+ goto err; -+ } -+ -+ if (s->csv_batch_cmd_list == NULL) { -+ s->csv_batch_cmd_list = csv_batch_cmd_list_create(new_node, -+ send_update_data_free); -+ if (s->csv_batch_cmd_list == NULL) { -+ ret = -ENOMEM; -+ goto err; -+ } -+ } else { -+ /* Add new_node's command address to the last_node */ -+ csv_batch_cmd_list_add_after(s->csv_batch_cmd_list, new_node); -+ } -+ -+ trace_kvm_sev_send_update_data(ptr, trans, size); -+ -+ return ret; -+ -+err: -+ g_free(trans); -+ g_free(update); -+ g_free(packet_hdr); -+ g_free(new_node); -+ if (s->csv_batch_cmd_list) { -+ csv_batch_cmd_list_destroy(s->csv_batch_cmd_list); -+ s->csv_batch_cmd_list = NULL; -+ } -+ return ret; -+} -+ -+int -+csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr) -+{ -+ SevGuestState *s = sev_guest; -+ -+ /* Only support for HYGON CSV */ -+ if (!is_hygon_cpu()) { -+ error_report("Only support enqueue pages for HYGON CSV"); -+ return -EINVAL; -+ } -+ -+ return csv_send_queue_data(s, ptr, sz, addr); -+} -+ - static const QemuUUID sev_hash_table_header_guid = { - .data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93, - 0xd4, 0x11, 0xfd, 0x21) --- -2.31.1 - diff --git a/1024-target-i386-csv-add-support-to-encrypt-the-outgoing-.patch b/1024-target-i386-csv-add-support-to-encrypt-the-outgoing-.patch deleted file mode 100644 index 8e53350fcacb33cd6b5c3dc2e645456cd4f93bd1..0000000000000000000000000000000000000000 --- a/1024-target-i386-csv-add-support-to-encrypt-the-outgoing-.patch +++ /dev/null @@ -1,207 +0,0 @@ -From 95ec49aa8a1a291f2fbb34daf9b054307161ab3f Mon Sep 17 00:00:00 2001 -From: fangbaoshun -Date: Mon, 2 Aug 2021 11:41:58 +0800 -Subject: [PATCH 20/28] target/i386: csv: add support to encrypt the outgoing - pages in the list queued before. - -The csv_save_queued_outgoing_pages() provide the implementation to encrypt -the guest private pages during transmission. The routines uses SEND_START -command to create the outgoing encryption context on the first call then -uses COMMAND_BATCH command to send the SEND_UPDATE_DATA commands queued -in the list to encrypt the data before writing it to the socket. While -encrypting the data SEND_UPDATE_DATA produces some metadata (e.g MAC, IV). -The metadata is also sent to the target machine. After migration is completed, -we issue the SEND_FINISH command to transition the SEV guest state from sending -to unrunnable state. - -Signed-off-by: hanliyang ---- - include/exec/confidential-guest-support.h | 4 ++ - linux-headers/linux/kvm.h | 8 +++ - target/i386/csv.h | 1 + - target/i386/sev.c | 88 +++++++++++++++++++++++ - target/i386/sev.h | 3 + - 5 files changed, 104 insertions(+) - -diff --git a/include/exec/confidential-guest-support.h b/include/exec/confidential-guest-support.h -index 8949568ac..c84f8c1ef 100644 ---- a/include/exec/confidential-guest-support.h -+++ b/include/exec/confidential-guest-support.h -@@ -80,6 +80,10 @@ struct ConfidentialGuestMemoryEncryptionOps { - - /* Queue the encrypted page and metadata associated with it into a list */ - int (*queue_outgoing_page)(uint8_t *ptr, uint32_t size, uint64_t addr); -+ -+ /* Write the list queued with encrypted pages and metadata associated -+ * with them */ -+ int (*save_queued_outgoing_pages)(QEMUFile *f, uint64_t *bytes_sent); - }; - - typedef struct ConfidentialGuestSupportClass { -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index a61be972c..8595dd5ca 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -1928,6 +1928,9 @@ enum sev_cmd_id { - /* Guest Migration Extension */ - KVM_SEV_SEND_CANCEL, - -+ /* Hygon CSV batch command */ -+ KVM_CSV_COMMAND_BATCH = 0x18, -+ - KVM_SEV_NR_MAX, - }; - -@@ -2030,6 +2033,11 @@ struct kvm_csv_batch_list_node { - __u64 next_cmd_addr; - }; - -+struct kvm_csv_command_batch { -+ __u32 command_id; -+ __u64 csv_batch_list_uaddr; -+}; -+ - #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) - #define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1) - #define KVM_DEV_ASSIGN_MASK_INTX (1 << 2) -diff --git a/target/i386/csv.h b/target/i386/csv.h -index 4c1ef2002..2a3a3119d 100644 ---- a/target/i386/csv.h -+++ b/target/i386/csv.h -@@ -54,5 +54,6 @@ struct CsvBatchCmdList { - }; - - int csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr); -+int csv_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent); - - #endif -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 027249e44..cfbc9fb59 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -191,6 +191,7 @@ static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { - .save_outgoing_shared_regions_list = sev_save_outgoing_shared_regions_list, - .load_incoming_shared_regions_list = sev_load_incoming_shared_regions_list, - .queue_outgoing_page = csv_queue_outgoing_page, -+ .save_queued_outgoing_pages = csv_save_queued_outgoing_pages, - }; - - static int -@@ -2011,6 +2012,69 @@ err: - return ret; - } - -+static int -+csv_command_batch(uint32_t cmd_id, uint64_t head_uaddr, int *fw_err) -+{ -+ int ret; -+ struct kvm_csv_command_batch command_batch = { }; -+ -+ command_batch.command_id = cmd_id; -+ command_batch.csv_batch_list_uaddr = head_uaddr; -+ -+ ret = sev_ioctl(sev_guest->sev_fd, KVM_CSV_COMMAND_BATCH, -+ &command_batch, fw_err); -+ if (ret) { -+ error_report("%s: COMMAND_BATCH ret=%d fw_err=%d '%s'", -+ __func__, ret, *fw_err, fw_error_to_str(*fw_err)); -+ } -+ -+ return ret; -+} -+ -+static int -+csv_send_update_data_batch(SevGuestState *s, QEMUFile *f, uint64_t *bytes_sent) -+{ -+ int ret, fw_error = 0; -+ struct kvm_sev_send_update_data *update; -+ struct kvm_csv_batch_list_node *node; -+ -+ ret = csv_command_batch(KVM_SEV_SEND_UPDATE_DATA, -+ (uint64_t)s->csv_batch_cmd_list->head, &fw_error); -+ if (ret) { -+ error_report("%s: csv_command_batch ret=%d fw_error=%d '%s'", -+ __func__, ret, fw_error, fw_error_to_str(fw_error)); -+ goto err; -+ } -+ -+ for (node = s->csv_batch_cmd_list->head; -+ node != NULL; -+ node = (struct kvm_csv_batch_list_node *)node->next_cmd_addr) { -+ if (node != s->csv_batch_cmd_list->head) { -+ /* head's page header is saved before send_update_data */ -+ qemu_put_be64(f, node->addr); -+ *bytes_sent += 8; -+ if (node->next_cmd_addr != 0) -+ qemu_put_be32(f, RAM_SAVE_ENCRYPTED_PAGE_BATCH); -+ else -+ qemu_put_be32(f, RAM_SAVE_ENCRYPTED_PAGE_BATCH_END); -+ *bytes_sent += 4; -+ } -+ update = (struct kvm_sev_send_update_data *)node->cmd_data_addr; -+ qemu_put_be32(f, update->hdr_len); -+ qemu_put_buffer(f, (uint8_t *)update->hdr_uaddr, update->hdr_len); -+ *bytes_sent += (4 + update->hdr_len); -+ -+ qemu_put_be32(f, update->trans_len); -+ qemu_put_buffer(f, (uint8_t *)update->trans_uaddr, update->trans_len); -+ *bytes_sent += (4 + update->trans_len); -+ } -+ -+err: -+ csv_batch_cmd_list_destroy(s->csv_batch_cmd_list); -+ s->csv_batch_cmd_list = NULL; -+ return ret; -+} -+ - int - csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr) - { -@@ -2025,6 +2089,30 @@ csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr) - return csv_send_queue_data(s, ptr, sz, addr); - } - -+int -+csv_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent) -+{ -+ SevGuestState *s = sev_guest; -+ -+ /* Only support for HYGON CSV */ -+ if (!is_hygon_cpu()) { -+ error_report("Only support transfer queued pages for HYGON CSV"); -+ return -EINVAL; -+ } -+ -+ /* -+ * If this is a first buffer then create outgoing encryption context -+ * and write our PDH, policy and session data. -+ */ -+ if (!sev_check_state(s, SEV_STATE_SEND_UPDATE) && -+ sev_send_start(s, f, bytes_sent)) { -+ error_report("Failed to create outgoing context"); -+ return 1; -+ } -+ -+ return csv_send_update_data_batch(s, f, bytes_sent); -+} -+ - static const QemuUUID sev_hash_table_header_guid = { - .data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93, - 0xd4, 0x11, 0xfd, 0x21) -diff --git a/target/i386/sev.h b/target/i386/sev.h -index 84e3bdf2d..f7886116e 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -41,6 +41,9 @@ typedef struct SevKernelLoaderContext { - #define RAM_SAVE_ENCRYPTED_PAGE 0x1 - #define RAM_SAVE_SHARED_REGIONS_LIST 0x2 - -+#define RAM_SAVE_ENCRYPTED_PAGE_BATCH 0x4 -+#define RAM_SAVE_ENCRYPTED_PAGE_BATCH_END 0x5 -+ - #ifdef CONFIG_SEV - bool sev_enabled(void); - bool sev_es_enabled(void); --- -2.31.1 - diff --git a/1025-target-i386-csv-add-support-to-queue-the-incoming-pa.patch b/1025-target-i386-csv-add-support-to-queue-the-incoming-pa.patch deleted file mode 100644 index 97c5325a9ea1d3c61e38df3c892eca143ab56e7c..0000000000000000000000000000000000000000 --- a/1025-target-i386-csv-add-support-to-queue-the-incoming-pa.patch +++ /dev/null @@ -1,170 +0,0 @@ -From df598a3d495b5351f6c15a27ba4d3ab1139c852b Mon Sep 17 00:00:00 2001 -From: fangbaoshun -Date: Mon, 2 Aug 2021 13:49:48 +0800 -Subject: [PATCH 21/28] target/i386: csv: add support to queue the incoming - page into a list - -The csv_queue_incoming_page() provide the implementation to queue the -guest private pages during transmission. The routines queues the incoming -socket which contains the guest private pages into a list then uses the -COMMAND_BATCH command to load the encrypted pages into the guest memory. - -Signed-off-by: hanliyang ---- - include/exec/confidential-guest-support.h | 3 + - target/i386/csv.h | 1 + - target/i386/sev.c | 92 +++++++++++++++++++++++ - 3 files changed, 96 insertions(+) - -diff --git a/include/exec/confidential-guest-support.h b/include/exec/confidential-guest-support.h -index c84f8c1ef..101cc5220 100644 ---- a/include/exec/confidential-guest-support.h -+++ b/include/exec/confidential-guest-support.h -@@ -84,6 +84,9 @@ struct ConfidentialGuestMemoryEncryptionOps { - /* Write the list queued with encrypted pages and metadata associated - * with them */ - int (*save_queued_outgoing_pages)(QEMUFile *f, uint64_t *bytes_sent); -+ -+ /* Queue the incoming encrypted page into a list */ -+ int (*queue_incoming_page)(QEMUFile *f, uint8_t *ptr); - }; - - typedef struct ConfidentialGuestSupportClass { -diff --git a/target/i386/csv.h b/target/i386/csv.h -index 2a3a3119d..d1bcc8bc1 100644 ---- a/target/i386/csv.h -+++ b/target/i386/csv.h -@@ -55,5 +55,6 @@ struct CsvBatchCmdList { - - int csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr); - int csv_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent); -+int csv_queue_incoming_page(QEMUFile *f, uint8_t *ptr); - - #endif -diff --git a/target/i386/sev.c b/target/i386/sev.c -index cfbc9fb59..97e2e7153 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -192,6 +192,7 @@ static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { - .load_incoming_shared_regions_list = sev_load_incoming_shared_regions_list, - .queue_outgoing_page = csv_queue_outgoing_page, - .save_queued_outgoing_pages = csv_save_queued_outgoing_pages, -+ .queue_incoming_page = csv_queue_incoming_page, - }; - - static int -@@ -1940,6 +1941,15 @@ static void send_update_data_free(void *data) - g_free(update); - } - -+static void receive_update_data_free(void *data) -+{ -+ struct kvm_sev_receive_update_data *update = -+ (struct kvm_sev_receive_update_data *)data; -+ g_free((guchar *)update->hdr_uaddr); -+ g_free((guchar *)update->trans_uaddr); -+ g_free(update); -+} -+ - static int - csv_send_queue_data(SevGuestState *s, uint8_t *ptr, - uint32_t size, uint64_t addr) -@@ -2012,6 +2022,66 @@ err: - return ret; - } - -+static int -+csv_receive_queue_data(SevGuestState *s, QEMUFile *f, uint8_t *ptr) -+{ -+ int ret = 0; -+ gchar *hdr = NULL, *trans = NULL; -+ struct kvm_sev_receive_update_data *update; -+ struct kvm_csv_batch_list_node *new_node = NULL; -+ -+ update = g_new0(struct kvm_sev_receive_update_data, 1); -+ /* get packet header */ -+ update->hdr_len = qemu_get_be32(f); -+ hdr = g_new(gchar, update->hdr_len); -+ qemu_get_buffer(f, (uint8_t *)hdr, update->hdr_len); -+ update->hdr_uaddr = (unsigned long)hdr; -+ -+ /* get transport buffer */ -+ update->trans_len = qemu_get_be32(f); -+ trans = g_new(gchar, update->trans_len); -+ update->trans_uaddr = (unsigned long)trans; -+ qemu_get_buffer(f, (uint8_t *)update->trans_uaddr, update->trans_len); -+ -+ /* set guest address,guest len is page_size */ -+ update->guest_uaddr = (uint64_t)ptr; -+ update->guest_len = TARGET_PAGE_SIZE; -+ -+ new_node = csv_batch_cmd_list_node_create((uint64_t)update, 0); -+ if (!new_node) { -+ ret = -ENOMEM; -+ goto err; -+ } -+ -+ if (s->csv_batch_cmd_list == NULL) { -+ s->csv_batch_cmd_list = csv_batch_cmd_list_create(new_node, -+ receive_update_data_free); -+ if (s->csv_batch_cmd_list == NULL) { -+ ret = -ENOMEM; -+ goto err; -+ } -+ } else { -+ /* Add new_node's command address to the last_node */ -+ csv_batch_cmd_list_add_after(s->csv_batch_cmd_list, new_node); -+ } -+ -+ trace_kvm_sev_receive_update_data(trans, (void *)ptr, update->guest_len, -+ (void *)hdr, update->hdr_len); -+ -+ return ret; -+ -+err: -+ g_free(trans); -+ g_free(update); -+ g_free(hdr); -+ g_free(new_node); -+ if (s->csv_batch_cmd_list) { -+ csv_batch_cmd_list_destroy(s->csv_batch_cmd_list); -+ s->csv_batch_cmd_list = NULL; -+ } -+ return ret; -+} -+ - static int - csv_command_batch(uint32_t cmd_id, uint64_t head_uaddr, int *fw_err) - { -@@ -2089,6 +2159,28 @@ csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr) - return csv_send_queue_data(s, ptr, sz, addr); - } - -+int csv_queue_incoming_page(QEMUFile *f, uint8_t *ptr) -+{ -+ SevGuestState *s = sev_guest; -+ -+ /* Only support for HYGON CSV */ -+ if (!is_hygon_cpu()) { -+ error_report("Only support enqueue received pages for HYGON CSV"); -+ return -EINVAL; -+ } -+ -+ /* -+ * If this is first buffer and SEV is not in recieiving state then -+ * use RECEIVE_START command to create a encryption context. -+ */ -+ if (!sev_check_state(s, SEV_STATE_RECEIVE_UPDATE) && -+ sev_receive_start(s, f)) { -+ return 1; -+ } -+ -+ return csv_receive_queue_data(s, f, ptr); -+} -+ - int - csv_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent) - { --- -2.31.1 - diff --git a/1026-target-i386-csv-add-support-to-load-incoming-encrypt.patch b/1026-target-i386-csv-add-support-to-load-incoming-encrypt.patch deleted file mode 100644 index fea18de439710745ddf6c8e5582b302e0218f2a6..0000000000000000000000000000000000000000 --- a/1026-target-i386-csv-add-support-to-load-incoming-encrypt.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 6248758d909135ec632ecd952007161f99a6f376 Mon Sep 17 00:00:00 2001 -From: fangbaoshun -Date: Mon, 2 Aug 2021 14:11:43 +0800 -Subject: [PATCH 22/28] target/i386: csv: add support to load incoming - encrypted pages queued in the CMD list - -The csv_load_queued_incoming_pages() provide the implementation to read the -incoming guest private pages from the socket queued in the CMD list and load -them into the guest memory. The routines uses the RECEIVE_START command to -create the incoming encryption context on the first call then uses the -COMMAND_BATCH carried with RECEIEVE_UPDATE_DATA commands to load the encrypted -pages into the guest memory. After migration is completed, we issue the -RECEIVE_FINISH command to transition the SEV guest to the runnable state -so that it can be executed. - -Signed-off-by: hanliyang ---- - include/exec/confidential-guest-support.h | 3 +++ - target/i386/csv.h | 1 + - target/i386/sev.c | 32 +++++++++++++++++++++++ - 3 files changed, 36 insertions(+) - -diff --git a/include/exec/confidential-guest-support.h b/include/exec/confidential-guest-support.h -index 101cc5220..cb14b815c 100644 ---- a/include/exec/confidential-guest-support.h -+++ b/include/exec/confidential-guest-support.h -@@ -87,6 +87,9 @@ struct ConfidentialGuestMemoryEncryptionOps { - - /* Queue the incoming encrypted page into a list */ - int (*queue_incoming_page)(QEMUFile *f, uint8_t *ptr); -+ -+ /* Load the incoming encrypted pages queued in list into guest memory */ -+ int (*load_queued_incoming_pages)(QEMUFile *f); - }; - - typedef struct ConfidentialGuestSupportClass { -diff --git a/target/i386/csv.h b/target/i386/csv.h -index d1bcc8bc1..977f08b98 100644 ---- a/target/i386/csv.h -+++ b/target/i386/csv.h -@@ -56,5 +56,6 @@ struct CsvBatchCmdList { - int csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr); - int csv_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent); - int csv_queue_incoming_page(QEMUFile *f, uint8_t *ptr); -+int csv_load_queued_incoming_pages(QEMUFile *f); - - #endif -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 97e2e7153..8e5da510d 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -193,6 +193,7 @@ static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { - .queue_outgoing_page = csv_queue_outgoing_page, - .save_queued_outgoing_pages = csv_save_queued_outgoing_pages, - .queue_incoming_page = csv_queue_incoming_page, -+ .load_queued_incoming_pages = csv_load_queued_incoming_pages, - }; - - static int -@@ -2145,6 +2146,24 @@ err: - return ret; - } - -+static int -+csv_receive_update_data_batch(SevGuestState *s) -+{ -+ int ret; -+ int fw_error; -+ -+ ret = csv_command_batch(KVM_SEV_RECEIVE_UPDATE_DATA, -+ (uint64_t)s->csv_batch_cmd_list->head, &fw_error); -+ if (ret) { -+ error_report("%s: csv_command_batch ret=%d fw_error=%d '%s'", -+ __func__, ret, fw_error, fw_error_to_str(fw_error)); -+ } -+ -+ csv_batch_cmd_list_destroy(s->csv_batch_cmd_list); -+ s->csv_batch_cmd_list = NULL; -+ return ret; -+} -+ - int - csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr) - { -@@ -2205,6 +2224,19 @@ csv_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent) - return csv_send_update_data_batch(s, f, bytes_sent); - } - -+int csv_load_queued_incoming_pages(QEMUFile *f) -+{ -+ SevGuestState *s = sev_guest; -+ -+ /* Only support for HYGON CSV */ -+ if (!is_hygon_cpu()) { -+ error_report("Only support load queued pages for HYGON CSV"); -+ return -EINVAL; -+ } -+ -+ return csv_receive_update_data_batch(s); -+} -+ - static const QemuUUID sev_hash_table_header_guid = { - .data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93, - 0xd4, 0x11, 0xfd, 0x21) --- -2.31.1 - diff --git a/1027-migration-ram-Accelerate-the-transmission-of-CSV-gue.patch b/1027-migration-ram-Accelerate-the-transmission-of-CSV-gue.patch deleted file mode 100644 index 3c29f2e2999d825c5d89b35b6f9fed8ac21d69b3..0000000000000000000000000000000000000000 --- a/1027-migration-ram-Accelerate-the-transmission-of-CSV-gue.patch +++ /dev/null @@ -1,208 +0,0 @@ -From c48d56c99370549e32a9fc79c9d14e1336b6b843 Mon Sep 17 00:00:00 2001 -From: fangbaoshun -Date: Mon, 2 Aug 2021 14:35:51 +0800 -Subject: [PATCH 23/28] migration/ram: Accelerate the transmission of CSV - guest's encrypted pages - -When memory encryption is enabled, the guest memory will be encrypted with -the guest specific key. The patch introduces an accelerate solution which -queued the pages into list and send them togather by COMMAND_BATCH. - -Signed-off-by: hanliyang ---- - configs/devices/i386-softmmu/default.mak | 1 + - hw/i386/Kconfig | 5 + - migration/ram.c | 119 +++++++++++++++++++++++ - target/i386/csv.h | 2 + - 4 files changed, 127 insertions(+) - -diff --git a/configs/devices/i386-softmmu/default.mak b/configs/devices/i386-softmmu/default.mak -index db83ffcab..e948e54e4 100644 ---- a/configs/devices/i386-softmmu/default.mak -+++ b/configs/devices/i386-softmmu/default.mak -@@ -24,6 +24,7 @@ - #CONFIG_VTD=n - #CONFIG_SGX=n - #CONFIG_CSV=n -+#CONFIG_HYGON_CSV_MIG_ACCEL=n - - # Boards: - # -diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig -index 08f3ae43f..682e324f1 100644 ---- a/hw/i386/Kconfig -+++ b/hw/i386/Kconfig -@@ -12,8 +12,13 @@ config SGX - - config CSV - bool -+ select HYGON_CSV_MIG_ACCEL - depends on SEV - -+config HYGON_CSV_MIG_ACCEL -+ bool -+ depends on CSV -+ - config PC - bool - imply APPLESMC -diff --git a/migration/ram.c b/migration/ram.c -index 22f07a064..be8dca326 100644 ---- a/migration/ram.c -+++ b/migration/ram.c -@@ -67,6 +67,7 @@ - - /* Defines RAM_SAVE_ENCRYPTED_PAGE and RAM_SAVE_SHARED_REGION_LIST */ - #include "target/i386/sev.h" -+#include "target/i386/csv.h" - #include "sysemu/kvm.h" - - #include "hw/boards.h" /* for machine_dump_guest_core() */ -@@ -2334,6 +2335,112 @@ out: - return ret; - } - -+#ifdef CONFIG_HYGON_CSV_MIG_ACCEL -+/** -+ * ram_save_encrypted_pages_in_batch: send the given encrypted pages to -+ * the stream. -+ * -+ * Sending pages of 4K size in batch. The saving stops at the end of -+ * the block. -+ * -+ * The caller must be with ram_state.bitmap_mutex held to call this -+ * function. -+ * -+ * Returns the number of pages written or negative on error -+ * -+ * @rs: current RAM state -+ * @pss: data about the page we want to send -+ */ -+static int -+ram_save_encrypted_pages_in_batch(RAMState *rs, PageSearchStatus *pss) -+{ -+ bool page_dirty; -+ int ret; -+ int tmppages, pages = 0; -+ uint8_t *p; -+ uint32_t host_len = 0; -+ uint64_t bytes_xmit = 0; -+ ram_addr_t offset, start_offset = 0; -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ ConfidentialGuestSupportClass *cgs_class = -+ (ConfidentialGuestSupportClass *)object_get_class(OBJECT(ms->cgs)); -+ struct ConfidentialGuestMemoryEncryptionOps *ops = -+ cgs_class->memory_encryption_ops; -+ -+ do { -+ page_dirty = migration_bitmap_clear_dirty(rs, pss->block, pss->page); -+ -+ /* Check the pages is dirty and if it is send it */ -+ if (page_dirty) { -+ /* Process the unencrypted page */ -+ if (!encrypted_test_list(rs, pss->block, pss->page)) { -+ tmppages = migration_ops->ram_save_target_page(rs, pss); -+ } else { -+ /* Caculate the offset and host virtual address of the page */ -+ offset = ((ram_addr_t)pss->page) << TARGET_PAGE_BITS; -+ p = pss->block->host + offset; -+ -+ /* Record the offset and host virtual address of the first -+ * page in this loop which will be used below. -+ */ -+ if (host_len == 0) { -+ start_offset = offset | RAM_SAVE_FLAG_ENCRYPTED_DATA; -+ } else { -+ offset |= (RAM_SAVE_FLAG_ENCRYPTED_DATA | RAM_SAVE_FLAG_CONTINUE); -+ } -+ -+ /* Queue the outgoing page if the page is not zero page. -+ * If the queued pages are up to the outgoing page window size, -+ * process them below. -+ */ -+ if (ops->queue_outgoing_page(p, TARGET_PAGE_SIZE, offset)) -+ return -1; -+ -+ tmppages = 1; -+ host_len += TARGET_PAGE_SIZE; -+ -+ stat64_add(&mig_stats.normal_pages, 1); -+ } -+ } else { -+ tmppages = 0; -+ } -+ -+ if (tmppages >= 0) { -+ pages += tmppages; -+ } else { -+ return tmppages; -+ } -+ -+ pss_find_next_dirty(pss); -+ } while (offset_in_ramblock(pss->block, -+ ((ram_addr_t)pss->page) << TARGET_PAGE_BITS) && -+ host_len < CSV_OUTGOING_PAGE_WINDOW_SIZE); -+ -+ /* Check if there are any queued pages */ -+ if (host_len != 0) { -+ ram_transferred_add(save_page_header(pss, pss->pss_channel, -+ pss->block, start_offset)); -+ /* if only one page queued, flag is BATCH_END, else flag is BATCH */ -+ if (host_len > TARGET_PAGE_SIZE) -+ qemu_put_be32(pss->pss_channel, RAM_SAVE_ENCRYPTED_PAGE_BATCH); -+ else -+ qemu_put_be32(pss->pss_channel, RAM_SAVE_ENCRYPTED_PAGE_BATCH_END); -+ ram_transferred_add(4); -+ /* Process the queued pages in batch */ -+ ret = ops->save_queued_outgoing_pages(pss->pss_channel, &bytes_xmit); -+ if (ret) { -+ return -1; -+ } -+ ram_transferred_add(bytes_xmit); -+ } -+ -+ /* The offset we leave with is the last one we looked at */ -+ pss->page--; -+ -+ return pages; -+} -+#endif -+ - /** - * ram_save_host_page: save a whole host page - * -@@ -2369,6 +2476,18 @@ static int ram_save_host_page(RAMState *rs, PageSearchStatus *pss) - return 0; - } - -+#ifdef CONFIG_HYGON_CSV_MIG_ACCEL -+ /* -+ * If command_batch function is enabled and memory encryption is enabled -+ * then use command batch APIs to accelerate the sending process -+ * to write the outgoing buffer to the wire. The encryption APIs -+ * will re-encrypt the data with transport key so that data is prototect -+ * on the wire. -+ */ -+ if (memcrypt_enabled() && is_hygon_cpu() && !migration_in_postcopy()) -+ return ram_save_encrypted_pages_in_batch(rs, pss); -+#endif -+ - /* Update host page boundary information */ - pss_host_page_prepare(pss); - -diff --git a/target/i386/csv.h b/target/i386/csv.h -index 977f08b98..74a54f9b9 100644 ---- a/target/i386/csv.h -+++ b/target/i386/csv.h -@@ -44,6 +44,8 @@ static bool __attribute__((unused)) is_hygon_cpu(void) - - #endif - -+#define CSV_OUTGOING_PAGE_WINDOW_SIZE (4094 * TARGET_PAGE_SIZE) -+ - typedef struct CsvBatchCmdList CsvBatchCmdList; - typedef void (*CsvDestroyCmdNodeFn) (void *data); - --- -2.31.1 - diff --git a/1028-migration-ram-Accelerate-the-loading-of-CSV-guest-s-.patch b/1028-migration-ram-Accelerate-the-loading-of-CSV-guest-s-.patch deleted file mode 100644 index b8498f357be9e5769e31197c075706de48b6bb24..0000000000000000000000000000000000000000 --- a/1028-migration-ram-Accelerate-the-loading-of-CSV-guest-s-.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 62434ee38c7097aec5e5f67b56ae96d6b6ab2162 Mon Sep 17 00:00:00 2001 -From: fangbaoshun -Date: Mon, 2 Aug 2021 14:49:45 +0800 -Subject: [PATCH 24/28] migration/ram: Accelerate the loading of CSV guest's - encrypted pages - -When memory encryption is enabled, the guest memory will be encrypted with -the guest specific key. The patch introduces an accelerate solution which -queued the pages into list and load them togather by COMMAND_BATCH. - -Signed-off-by: hanliyang ---- - migration/ram.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/migration/ram.c b/migration/ram.c -index be8dca326..c7245aa4d 100644 ---- a/migration/ram.c -+++ b/migration/ram.c -@@ -1295,6 +1295,14 @@ static int load_encrypted_data(QEMUFile *f, uint8_t *ptr) - return ops->load_incoming_page(f, ptr); - } else if (flag == RAM_SAVE_SHARED_REGIONS_LIST) { - return ops->load_incoming_shared_regions_list(f); -+ } else if (flag == RAM_SAVE_ENCRYPTED_PAGE_BATCH) { -+ return ops->queue_incoming_page(f, ptr); -+ } else if (flag == RAM_SAVE_ENCRYPTED_PAGE_BATCH_END) { -+ if (ops->queue_incoming_page(f, ptr)) { -+ error_report("Failed to queue incoming data"); -+ return -EINVAL; -+ } -+ return ops->load_queued_incoming_pages(f); - } else { - error_report("unknown encrypted flag %x", flag); - return 1; --- -2.31.1 - diff --git a/1029-target-i386-csv-Add-support-for-migrate-VMSA-for-CSV.patch b/1029-target-i386-csv-Add-support-for-migrate-VMSA-for-CSV.patch deleted file mode 100644 index 9bcd217fe7371eda200be049df363c652765d3eb..0000000000000000000000000000000000000000 --- a/1029-target-i386-csv-Add-support-for-migrate-VMSA-for-CSV.patch +++ /dev/null @@ -1,434 +0,0 @@ -From 86144110e4cd8f2cba918c22127659e5046b623d Mon Sep 17 00:00:00 2001 -From: hanliyang -Date: Tue, 7 Jun 2022 15:19:32 +0800 -Subject: [PATCH 25/28] target/i386: csv: Add support for migrate VMSA for CSV2 - guest - -CSV2 can protect guest's cpu state through memory encryption. Each -vcpu has its corresponding memory, which is also called VMSA, and -is encrypted by guest's specific encrytion key. - -When CSV2 guest exit to host, the vcpu's state will be encrypted -and saved to VMSA, and the VMSA will be decrypted and loaded to cpu -when the guest's vcpu running at next time. - -If user wants to migrate one CSV2 guest to target machine, the VMSA -of the vcpus also should be migrated to target. CSV firmware provides -SEND_UPDATE_VMSA/RECEIVE_UPDATE_VMSA API through which VMSA can be -converted into secure data and transmitted to the remote end (for -example, network transmission). - -The migration of cpu state is identified by CPUState.cpu_index which -may not equals to vcpu id from KVM's perspective. - -When migrate the VMSA, the source QEMU will invoke SEND_UPDATE_VMSA to -generate data correspond to VMSA, after target QEMU received the data, -it will calc target vcpu id in the KVM by CPUState.cpu_index, and then -invoke RECEIVE_UPDATE_VMSA to restore VMSA correspond to vcpu. - -Signed-off-by: hanliyang ---- - include/exec/confidential-guest-support.h | 6 + - linux-headers/linux/kvm.h | 16 ++ - migration/ram.c | 42 +++++ - target/i386/csv.h | 2 + - target/i386/sev.c | 201 ++++++++++++++++++++++ - target/i386/sev.h | 1 + - target/i386/trace-events | 2 + - 7 files changed, 270 insertions(+) - -diff --git a/include/exec/confidential-guest-support.h b/include/exec/confidential-guest-support.h -index cb14b815c..2cba27642 100644 ---- a/include/exec/confidential-guest-support.h -+++ b/include/exec/confidential-guest-support.h -@@ -90,6 +90,12 @@ struct ConfidentialGuestMemoryEncryptionOps { - - /* Load the incoming encrypted pages queued in list into guest memory */ - int (*load_queued_incoming_pages)(QEMUFile *f); -+ -+ /* Write the encrypted cpu state */ -+ int (*save_outgoing_cpu_state)(QEMUFile *f, uint64_t *bytes_sent); -+ -+ /* Load the encrypted cpu state */ -+ int (*load_incoming_cpu_state)(QEMUFile *f); - }; - - typedef struct ConfidentialGuestSupportClass { -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index 8595dd5ca..2ed7ae472 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -2009,6 +2009,14 @@ struct kvm_sev_send_update_data { - __u32 trans_len; - }; - -+struct kvm_sev_send_update_vmsa { -+ __u32 vcpu_id; -+ __u64 hdr_uaddr; -+ __u32 hdr_len; -+ __u64 trans_uaddr; -+ __u32 trans_len; -+}; -+ - struct kvm_sev_receive_start { - __u32 handle; - __u32 policy; -@@ -2027,6 +2035,14 @@ struct kvm_sev_receive_update_data { - __u32 trans_len; - }; - -+struct kvm_sev_receive_update_vmsa { -+ __u32 vcpu_id; -+ __u64 hdr_uaddr; -+ __u32 hdr_len; -+ __u64 trans_uaddr; -+ __u32 trans_len; -+}; -+ - struct kvm_csv_batch_list_node { - __u64 cmd_data_addr; - __u64 addr; -diff --git a/migration/ram.c b/migration/ram.c -index c7245aa4d..198b06000 100644 ---- a/migration/ram.c -+++ b/migration/ram.c -@@ -1279,6 +1279,33 @@ static int ram_save_shared_region_list(RAMState *rs, QEMUFile *f) - return 0; - } - -+/** -+ * ram_save_encrypted_cpu_state: send the encrypted cpu state -+ */ -+static int ram_save_encrypted_cpu_state(RAMState *rs, QEMUFile *f) -+{ -+ int ret; -+ uint64_t bytes_xmit = 0; -+ PageSearchStatus *pss = &rs->pss[RAM_CHANNEL_PRECOPY]; -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ ConfidentialGuestSupportClass *cgs_class = -+ (ConfidentialGuestSupportClass *) object_get_class(OBJECT(ms->cgs)); -+ struct ConfidentialGuestMemoryEncryptionOps *ops = -+ cgs_class->memory_encryption_ops; -+ -+ ram_transferred_add(save_page_header(pss, f, -+ pss->last_sent_block, -+ RAM_SAVE_FLAG_ENCRYPTED_DATA)); -+ qemu_put_be32(f, RAM_SAVE_ENCRYPTED_CPU_STATE); -+ ret = ops->save_outgoing_cpu_state(f, &bytes_xmit); -+ if (ret < 0) { -+ return ret; -+ } -+ ram_transferred_add(4 + bytes_xmit); -+ -+ return 0; -+} -+ - static int load_encrypted_data(QEMUFile *f, uint8_t *ptr) - { - MachineState *ms = MACHINE(qdev_get_machine()); -@@ -1303,6 +1330,8 @@ static int load_encrypted_data(QEMUFile *f, uint8_t *ptr) - return -EINVAL; - } - return ops->load_queued_incoming_pages(f); -+ } else if (flag == RAM_SAVE_ENCRYPTED_CPU_STATE) { -+ return ops->load_incoming_cpu_state(f); - } else { - error_report("unknown encrypted flag %x", flag); - return 1; -@@ -3492,6 +3521,19 @@ static int ram_save_complete(QEMUFile *f, void *opaque) - qemu_file_set_error(f, ret); - return ret; - } -+ -+ /* -+ * send the encrypted cpu state, for example, CSV2 guest's -+ * vmsa for each vcpu. -+ */ -+ if (is_hygon_cpu()) { -+ ret = ram_save_encrypted_cpu_state(rs, f); -+ if (ret < 0) { -+ error_report("Failed to save encrypted cpu state"); -+ qemu_file_set_error(f, ret); -+ return ret; -+ } -+ } - } - } - -diff --git a/target/i386/csv.h b/target/i386/csv.h -index 74a54f9b9..47741a0a4 100644 ---- a/target/i386/csv.h -+++ b/target/i386/csv.h -@@ -59,5 +59,7 @@ int csv_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr); - int csv_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent); - int csv_queue_incoming_page(QEMUFile *f, uint8_t *ptr); - int csv_load_queued_incoming_pages(QEMUFile *f); -+int csv_save_outgoing_cpu_state(QEMUFile *f, uint64_t *bytes_sent); -+int csv_load_incoming_cpu_state(QEMUFile *f); - - #endif -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 8e5da510d..52693ae8b 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -90,6 +90,10 @@ struct SevGuestState { - gchar *send_packet_hdr; - size_t send_packet_hdr_len; - -+ /* needed by live migration of HYGON CSV2 guest */ -+ gchar *send_vmsa_packet_hdr; -+ size_t send_vmsa_packet_hdr_len; -+ - uint32_t reset_cs; - uint32_t reset_ip; - bool reset_data_valid; -@@ -183,6 +187,9 @@ static const char *const sev_fw_errlist[] = { - #define SHARED_REGION_LIST_CONT 0x1 - #define SHARED_REGION_LIST_END 0x2 - -+#define ENCRYPTED_CPU_STATE_CONT 0x1 -+#define ENCRYPTED_CPU_STATE_END 0x2 -+ - static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { - .save_setup = sev_save_setup, - .save_outgoing_page = sev_save_outgoing_page, -@@ -194,6 +201,8 @@ static struct ConfidentialGuestMemoryEncryptionOps sev_memory_encryption_ops = { - .save_queued_outgoing_pages = csv_save_queued_outgoing_pages, - .queue_incoming_page = csv_queue_incoming_page, - .load_queued_incoming_pages = csv_load_queued_incoming_pages, -+ .save_outgoing_cpu_state = csv_save_outgoing_cpu_state, -+ .load_incoming_cpu_state = csv_load_incoming_cpu_state, - }; - - static int -@@ -1047,6 +1056,9 @@ sev_send_finish(void) - } - - g_free(sev_guest->send_packet_hdr); -+ if (sev_es_enabled() && is_hygon_cpu()) { -+ g_free(sev_guest->send_vmsa_packet_hdr); -+ } - sev_set_guest_state(sev_guest, SEV_STATE_RUNNING); - } - -@@ -2237,6 +2249,195 @@ int csv_load_queued_incoming_pages(QEMUFile *f) - return csv_receive_update_data_batch(s); - } - -+static int -+sev_send_vmsa_get_packet_len(int *fw_err) -+{ -+ int ret; -+ struct kvm_sev_send_update_vmsa update = { 0, }; -+ -+ ret = sev_ioctl(sev_guest->sev_fd, KVM_SEV_SEND_UPDATE_VMSA, -+ &update, fw_err); -+ if (*fw_err != SEV_RET_INVALID_LEN) { -+ ret = 0; -+ error_report("%s: failed to get session length ret=%d fw_error=%d '%s'", -+ __func__, ret, *fw_err, fw_error_to_str(*fw_err)); -+ goto err; -+ } -+ -+ ret = update.hdr_len; -+ -+err: -+ return ret; -+} -+ -+static int -+sev_send_update_vmsa(SevGuestState *s, QEMUFile *f, uint32_t cpu_id, -+ uint32_t cpu_index, uint32_t size, uint64_t *bytes_sent) -+{ -+ int ret, fw_error; -+ guchar *trans = NULL; -+ struct kvm_sev_send_update_vmsa update = {}; -+ -+ /* -+ * If this is first call then query the packet header bytes and allocate -+ * the packet buffer. -+ */ -+ if (!s->send_vmsa_packet_hdr) { -+ s->send_vmsa_packet_hdr_len = sev_send_vmsa_get_packet_len(&fw_error); -+ if (s->send_vmsa_packet_hdr_len < 1) { -+ error_report("%s: SEND_UPDATE_VMSA fw_error=%d '%s'", -+ __func__, fw_error, fw_error_to_str(fw_error)); -+ return 1; -+ } -+ -+ s->send_vmsa_packet_hdr = g_new(gchar, s->send_vmsa_packet_hdr_len); -+ } -+ -+ /* allocate transport buffer */ -+ trans = g_new(guchar, size); -+ -+ update.vcpu_id = cpu_id; -+ update.hdr_uaddr = (uintptr_t)s->send_vmsa_packet_hdr; -+ update.hdr_len = s->send_vmsa_packet_hdr_len; -+ update.trans_uaddr = (uintptr_t)trans; -+ update.trans_len = size; -+ -+ trace_kvm_sev_send_update_vmsa(cpu_id, cpu_index, trans, size); -+ -+ ret = sev_ioctl(s->sev_fd, KVM_SEV_SEND_UPDATE_VMSA, &update, &fw_error); -+ if (ret) { -+ error_report("%s: SEND_UPDATE_VMSA ret=%d fw_error=%d '%s'", -+ __func__, ret, fw_error, fw_error_to_str(fw_error)); -+ goto err; -+ } -+ -+ /* -+ * Migration of vCPU's VMState according to the instance_id -+ * (i.e. CPUState.cpu_index) -+ */ -+ qemu_put_be32(f, sizeof(uint32_t)); -+ qemu_put_buffer(f, (uint8_t *)&cpu_index, sizeof(uint32_t)); -+ *bytes_sent += 4 + sizeof(uint32_t); -+ -+ qemu_put_be32(f, update.hdr_len); -+ qemu_put_buffer(f, (uint8_t *)update.hdr_uaddr, update.hdr_len); -+ *bytes_sent += 4 + update.hdr_len; -+ -+ qemu_put_be32(f, update.trans_len); -+ qemu_put_buffer(f, (uint8_t *)update.trans_uaddr, update.trans_len); -+ *bytes_sent += 4 + update.trans_len; -+ -+err: -+ g_free(trans); -+ return ret; -+} -+ -+int csv_save_outgoing_cpu_state(QEMUFile *f, uint64_t *bytes_sent) -+{ -+ SevGuestState *s = sev_guest; -+ CPUState *cpu; -+ int ret = 0; -+ -+ /* Only support migrate VMSAs for HYGON CSV2 guest */ -+ if (!sev_es_enabled() || !is_hygon_cpu()) { -+ return 0; -+ } -+ -+ CPU_FOREACH(cpu) { -+ qemu_put_be32(f, ENCRYPTED_CPU_STATE_CONT); -+ *bytes_sent += 4; -+ ret = sev_send_update_vmsa(s, f, kvm_arch_vcpu_id(cpu), -+ cpu->cpu_index, TARGET_PAGE_SIZE, bytes_sent); -+ if (ret) { -+ goto err; -+ } -+ } -+ -+ qemu_put_be32(f, ENCRYPTED_CPU_STATE_END); -+ *bytes_sent += 4; -+ -+err: -+ return ret; -+} -+ -+static int sev_receive_update_vmsa(QEMUFile *f) -+{ -+ int ret = 1, fw_error = 0; -+ CPUState *cpu; -+ uint32_t cpu_index, cpu_id = 0; -+ gchar *hdr = NULL, *trans = NULL; -+ struct kvm_sev_receive_update_vmsa update = {}; -+ -+ /* get cpu index buffer */ -+ assert(qemu_get_be32(f) == sizeof(uint32_t)); -+ qemu_get_buffer(f, (uint8_t *)&cpu_index, sizeof(uint32_t)); -+ -+ CPU_FOREACH(cpu) { -+ if (cpu->cpu_index == cpu_index) { -+ cpu_id = kvm_arch_vcpu_id(cpu); -+ break; -+ } -+ } -+ update.vcpu_id = cpu_id; -+ -+ /* get packet header */ -+ update.hdr_len = qemu_get_be32(f); -+ if (!check_blob_length(update.hdr_len)) { -+ return 1; -+ } -+ -+ hdr = g_new(gchar, update.hdr_len); -+ qemu_get_buffer(f, (uint8_t *)hdr, update.hdr_len); -+ update.hdr_uaddr = (uintptr_t)hdr; -+ -+ /* get transport buffer */ -+ update.trans_len = qemu_get_be32(f); -+ if (!check_blob_length(update.trans_len)) { -+ goto err; -+ } -+ -+ trans = g_new(gchar, update.trans_len); -+ update.trans_uaddr = (uintptr_t)trans; -+ qemu_get_buffer(f, (uint8_t *)update.trans_uaddr, update.trans_len); -+ -+ trace_kvm_sev_receive_update_vmsa(cpu_id, cpu_index, -+ trans, update.trans_len, hdr, update.hdr_len); -+ -+ ret = sev_ioctl(sev_guest->sev_fd, KVM_SEV_RECEIVE_UPDATE_VMSA, -+ &update, &fw_error); -+ if (ret) { -+ error_report("Error RECEIVE_UPDATE_VMSA ret=%d fw_error=%d '%s'", -+ ret, fw_error, fw_error_to_str(fw_error)); -+ } -+ -+err: -+ g_free(trans); -+ g_free(hdr); -+ return ret; -+} -+ -+int csv_load_incoming_cpu_state(QEMUFile *f) -+{ -+ int status, ret = 0; -+ -+ /* Only support migrate VMSAs for HYGON CSV2 guest */ -+ if (!sev_es_enabled() || !is_hygon_cpu()) { -+ return 0; -+ } -+ -+ status = qemu_get_be32(f); -+ while (status == ENCRYPTED_CPU_STATE_CONT) { -+ ret = sev_receive_update_vmsa(f); -+ if (ret) { -+ break; -+ } -+ -+ status = qemu_get_be32(f); -+ } -+ -+ return ret; -+} -+ - static const QemuUUID sev_hash_table_header_guid = { - .data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93, - 0xd4, 0x11, 0xfd, 0x21) -diff --git a/target/i386/sev.h b/target/i386/sev.h -index f7886116e..209c92fd6 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -43,6 +43,7 @@ typedef struct SevKernelLoaderContext { - - #define RAM_SAVE_ENCRYPTED_PAGE_BATCH 0x4 - #define RAM_SAVE_ENCRYPTED_PAGE_BATCH_END 0x5 -+#define RAM_SAVE_ENCRYPTED_CPU_STATE 0x6 - - #ifdef CONFIG_SEV - bool sev_enabled(void); -diff --git a/target/i386/trace-events b/target/i386/trace-events -index 475de65ad..87b765c73 100644 ---- a/target/i386/trace-events -+++ b/target/i386/trace-events -@@ -17,3 +17,5 @@ kvm_sev_send_finish(void) "" - kvm_sev_receive_start(int policy, void *session, void *pdh) "policy 0x%x session %p pdh %p" - kvm_sev_receive_update_data(void *src, void *dst, int len, void *hdr, int hdr_len) "guest %p trans %p len %d hdr %p hdr_len %d" - kvm_sev_receive_finish(void) "" -+kvm_sev_send_update_vmsa(uint32_t cpu_id, uint32_t cpu_index, void *dst, int len) "cpu_id %d cpu_index %d trans %p len %d" -+kvm_sev_receive_update_vmsa(uint32_t cpu_id, uint32_t cpu_index, void *src, int len, void *hdr, int hdr_len) "cpu_id %d cpu_index %d trans %p len %d hdr %p hdr_len %d" --- -2.31.1 - diff --git a/1030-target-i386-get-set-migrate-GHCB-state.patch b/1030-target-i386-get-set-migrate-GHCB-state.patch deleted file mode 100644 index 5ec9dd798ecd6b810aef394420f1846696cfe517..0000000000000000000000000000000000000000 --- a/1030-target-i386-get-set-migrate-GHCB-state.patch +++ /dev/null @@ -1,190 +0,0 @@ -From b1e7543269ba3a0d562d22a07a295abb576aa598 Mon Sep 17 00:00:00 2001 -From: panpingsheng -Date: Sat, 12 Jun 2021 15:15:29 +0800 -Subject: [PATCH 26/28] target/i386: get/set/migrate GHCB state - -GHCB state is necessary to CSV2 guest when migrating to target. - -Add GHCB related definition, it also adds corresponding part -to kvm_get/put, and vmstate. - -Signed-off-by: hanliyang ---- - linux-headers/linux/kvm.h | 2 ++ - target/i386/cpu.h | 5 +++++ - target/i386/kvm/kvm.c | 11 +++++++++++ - target/i386/kvm/sev-stub.c | 2 ++ - target/i386/machine.c | 24 ++++++++++++++++++++++++ - target/i386/sev.c | 10 ++++++++++ - target/i386/sev.h | 2 ++ - 7 files changed, 56 insertions(+) - -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index 2ed7ae472..bdcd7a014 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -1199,6 +1199,8 @@ struct kvm_ppc_resize_hpt { - #define KVM_CAP_ARM_SUPPORTED_BLOCK_SIZES 229 - #define KVM_CAP_ARM_SUPPORTED_REG_MASK_RANGES 230 - -+#define KVM_CAP_SEV_ES_GHCB 500 -+ - #define KVM_EXIT_HYPERCALL_VALID_MASK (1 << KVM_HC_MAP_GPA_RANGE) - - #ifdef KVM_CAP_IRQ_ROUTING -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index ef987f344..09041a5f5 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -519,6 +519,8 @@ typedef enum X86Seg { - - #define MSR_VM_HSAVE_PA 0xc0010117 - -+#define MSR_AMD64_SEV_ES_GHCB 0xc0010130 -+ - #define MSR_IA32_XFD 0x000001c4 - #define MSR_IA32_XFD_ERR 0x000001c5 - -@@ -1884,6 +1886,9 @@ typedef struct CPUArchState { - - /* Number of dies within this CPU package. */ - unsigned nr_dies; -+ -+ /* GHCB guest physical address info */ -+ uint64_t ghcb_gpa; - } CPUX86State; - - struct kvm_msrs; -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index 5730d0e0c..9e6524273 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -3625,6 +3625,10 @@ static int kvm_put_msrs(X86CPU *cpu, int level) - } - } - -+ if (sev_kvm_has_msr_ghcb) { -+ kvm_msr_entry_add(cpu, MSR_AMD64_SEV_ES_GHCB, env->ghcb_gpa); -+ } -+ - return kvm_buf_set_msrs(cpu); - } - -@@ -3999,6 +4003,10 @@ static int kvm_get_msrs(X86CPU *cpu) - } - } - -+ if (sev_kvm_has_msr_ghcb) { -+ kvm_msr_entry_add(cpu, MSR_AMD64_SEV_ES_GHCB, 0); -+ } -+ - ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_MSRS, cpu->kvm_msr_buf); - if (ret < 0) { - return ret; -@@ -4319,6 +4327,9 @@ static int kvm_get_msrs(X86CPU *cpu) - case MSR_ARCH_LBR_INFO_0 ... MSR_ARCH_LBR_INFO_0 + 31: - env->lbr_records[index - MSR_ARCH_LBR_INFO_0].info = msrs[i].data; - break; -+ case MSR_AMD64_SEV_ES_GHCB: -+ env->ghcb_gpa = msrs[i].data; -+ break; - } - } - -diff --git a/target/i386/kvm/sev-stub.c b/target/i386/kvm/sev-stub.c -index 99899688e..a0aac1117 100644 ---- a/target/i386/kvm/sev-stub.c -+++ b/target/i386/kvm/sev-stub.c -@@ -14,6 +14,8 @@ - #include "qemu/osdep.h" - #include "sev.h" - -+bool sev_kvm_has_msr_ghcb; -+ - int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - { - /* If we get here, cgs must be some non-SEV thing */ -diff --git a/target/i386/machine.c b/target/i386/machine.c -index a1041ef82..9a1cb8f3b 100644 ---- a/target/i386/machine.c -+++ b/target/i386/machine.c -@@ -1605,6 +1605,27 @@ static const VMStateDescription vmstate_triple_fault = { - } - }; - -+#if defined(CONFIG_KVM) && defined(TARGET_X86_64) -+static bool msr_ghcb_gpa_needed(void *opaque) -+{ -+ X86CPU *cpu = opaque; -+ CPUX86State *env = &cpu->env; -+ -+ return env->ghcb_gpa != 0; -+} -+ -+static const VMStateDescription vmstate_msr_ghcb_gpa = { -+ .name = "cpu/svm_msr_ghcb_gpa", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .needed = msr_ghcb_gpa_needed, -+ .fields = (VMStateField[]) { -+ VMSTATE_UINT64(env.ghcb_gpa, X86CPU), -+ VMSTATE_END_OF_LIST() -+ } -+}; -+#endif -+ - const VMStateDescription vmstate_x86_cpu = { - .name = "cpu", - .version_id = 12, -@@ -1751,6 +1772,9 @@ const VMStateDescription vmstate_x86_cpu = { - #endif - &vmstate_arch_lbr, - &vmstate_triple_fault, -+#if defined(CONFIG_KVM) && defined(TARGET_X86_64) -+ &vmstate_msr_ghcb_gpa, -+#endif - NULL - } - }; -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 52693ae8b..71d317e86 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -152,6 +152,8 @@ QEMU_BUILD_BUG_ON(sizeof(PaddedSevHashTable) % 16 != 0); - static SevGuestState *sev_guest; - static Error *sev_mig_blocker; - -+bool sev_kvm_has_msr_ghcb; -+ - static const char *const sev_fw_errlist[] = { - [SEV_RET_SUCCESS] = "", - [SEV_RET_INVALID_PLATFORM_STATE] = "Platform state is invalid", -@@ -1198,6 +1200,14 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - cgs_class->memory_encryption_ops = &sev_memory_encryption_ops; - QTAILQ_INIT(&sev->shared_regions_list); - -+ /* Determine whether support MSR_AMD64_SEV_ES_GHCB */ -+ if (sev_es_enabled()) { -+ sev_kvm_has_msr_ghcb = -+ kvm_vm_check_extension(kvm_state, KVM_CAP_SEV_ES_GHCB); -+ } else { -+ sev_kvm_has_msr_ghcb = false; -+ } -+ - cgs->ready = true; - - return 0; -diff --git a/target/i386/sev.h b/target/i386/sev.h -index 209c92fd6..0bfe3879e 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -78,4 +78,6 @@ void sev_del_migrate_blocker(void); - - int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp); - -+extern bool sev_kvm_has_msr_ghcb; -+ - #endif --- -2.31.1 - diff --git a/1031-target-i386-kvm-Fix-the-resettable-info-when-emulate.patch b/1031-target-i386-kvm-Fix-the-resettable-info-when-emulate.patch deleted file mode 100644 index 7bb0155cec58ac457186282e0456c4d12ff0e6bd..0000000000000000000000000000000000000000 --- a/1031-target-i386-kvm-Fix-the-resettable-info-when-emulate.patch +++ /dev/null @@ -1,179 +0,0 @@ -From 35872adf8405bcbaf37bbd5a79b7cb1d1f28ace0 Mon Sep 17 00:00:00 2001 -From: hanliyang -Date: Sun, 19 Jun 2022 16:49:45 +0800 -Subject: [PATCH 27/28] target/i386/kvm: Fix the resettable info when emulate - Hygon CSV2 guest - -SEV-ES guest will be terminated by QEMU when receive reboot request. -In order to support reboot for CSV2 guest, report resettable in -kvm_arch_cpu_check_are_resettable(). But the CSV2 guest is still not -resettable if it was migrated to target machine. - -Signed-off-by: hanliyang ---- - target/i386/csv-sysemu-stub.c | 16 ++++++++++++++++ - target/i386/csv.c | 20 ++++++++++++++++++++ - target/i386/csv.h | 2 ++ - target/i386/kvm/csv-stub.c | 17 +++++++++++++++++ - target/i386/kvm/kvm.c | 4 ++++ - target/i386/kvm/meson.build | 1 + - target/i386/meson.build | 1 + - target/i386/sev.c | 9 +++++++++ - 8 files changed, 70 insertions(+) - create mode 100644 target/i386/csv-sysemu-stub.c - create mode 100644 target/i386/csv.c - create mode 100644 target/i386/kvm/csv-stub.c - -diff --git a/target/i386/csv-sysemu-stub.c b/target/i386/csv-sysemu-stub.c -new file mode 100644 -index 000000000..5874e4cc1 ---- /dev/null -+++ b/target/i386/csv-sysemu-stub.c -@@ -0,0 +1,16 @@ -+/* -+ * QEMU CSV system stub -+ * -+ * Copyright: Hygon Info Technologies Ltd. 2022 -+ * -+ * Author: -+ * Jiang Xin -+ * -+ * This work is licensed under the terms of the GNU GPL, version 2 or later. -+ * See the COPYING file in the top-level directory. -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include "sev.h" -+#include "csv.h" -diff --git a/target/i386/csv.c b/target/i386/csv.c -new file mode 100644 -index 000000000..88fb05ac3 ---- /dev/null -+++ b/target/i386/csv.c -@@ -0,0 +1,20 @@ -+/* -+ * QEMU CSV support -+ * -+ * Copyright: Hygon Info Technologies Ltd. 2022 -+ * -+ * Author: -+ * Jiang Xin -+ * -+ * This work is licensed under the terms of the GNU GPL, version 2 or later. -+ * See the COPYING file in the top-level directory. -+ * -+ */ -+ -+#include "qemu/osdep.h" -+ -+#include "cpu.h" -+#include "sev.h" -+#include "csv.h" -+ -+bool csv_kvm_cpu_reset_inhibit; -diff --git a/target/i386/csv.h b/target/i386/csv.h -index 47741a0a4..ac4bb5bee 100644 ---- a/target/i386/csv.h -+++ b/target/i386/csv.h -@@ -46,6 +46,8 @@ static bool __attribute__((unused)) is_hygon_cpu(void) - - #define CSV_OUTGOING_PAGE_WINDOW_SIZE (4094 * TARGET_PAGE_SIZE) - -+extern bool csv_kvm_cpu_reset_inhibit; -+ - typedef struct CsvBatchCmdList CsvBatchCmdList; - typedef void (*CsvDestroyCmdNodeFn) (void *data); - -diff --git a/target/i386/kvm/csv-stub.c b/target/i386/kvm/csv-stub.c -new file mode 100644 -index 000000000..4d1376f26 ---- /dev/null -+++ b/target/i386/kvm/csv-stub.c -@@ -0,0 +1,17 @@ -+/* -+ * QEMU CSV stub -+ * -+ * Copyright Hygon Info Technologies Ltd. 2024 -+ * -+ * Authors: -+ * Han Liyang -+ * -+ * This work is licensed under the terms of the GNU GPL, version 2 or later. -+ * See the COPYING file in the top-level directory. -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include "csv.h" -+ -+bool csv_kvm_cpu_reset_inhibit; -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index 9e6524273..2866a6d0e 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -32,6 +32,7 @@ - #include "sysemu/runstate.h" - #include "kvm_i386.h" - #include "sev.h" -+#include "csv.h" - #include "xen-emu.h" - #include "hyperv.h" - #include "hyperv-proto.h" -@@ -5710,6 +5711,9 @@ bool kvm_has_waitpkg(void) - - bool kvm_arch_cpu_check_are_resettable(void) - { -+ if (is_hygon_cpu()) -+ return !csv_kvm_cpu_reset_inhibit; -+ - return !sev_es_enabled(); - } - -diff --git a/target/i386/kvm/meson.build b/target/i386/kvm/meson.build -index 84d9143e6..3c3f8cf93 100644 ---- a/target/i386/kvm/meson.build -+++ b/target/i386/kvm/meson.build -@@ -8,6 +8,7 @@ i386_kvm_ss.add(files( - i386_kvm_ss.add(when: 'CONFIG_XEN_EMU', if_true: files('xen-emu.c')) - - i386_kvm_ss.add(when: 'CONFIG_SEV', if_false: files('sev-stub.c')) -+i386_kvm_ss.add(when: 'CONFIG_CSV', if_false: files('csv-stub.c')) - - i386_system_ss.add(when: 'CONFIG_HYPERV', if_true: files('hyperv.c'), if_false: files('hyperv-stub.c')) - -diff --git a/target/i386/meson.build b/target/i386/meson.build -index 7c74bfa85..594a0a6ab 100644 ---- a/target/i386/meson.build -+++ b/target/i386/meson.build -@@ -21,6 +21,7 @@ i386_system_ss.add(files( - 'cpu-sysemu.c', - )) - i386_system_ss.add(when: 'CONFIG_SEV', if_true: files('sev.c'), if_false: files('sev-sysemu-stub.c')) -+i386_system_ss.add(when: 'CONFIG_CSV', if_true: files('csv.c'), if_false: files('csv-sysemu-stub.c')) - - i386_user_ss = ss.source_set() - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 71d317e86..3406861f6 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -1190,6 +1190,15 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - error_setg(errp, "%s: failed to create encryption context", __func__); - goto err; - } -+ } else { -+ /* -+ * The CSV2 guest is not resettable after migrated to target machine, -+ * set csv_kvm_cpu_reset_inhibit to true to indicate the CSV2 guest is -+ * not resettable. -+ */ -+ if (is_hygon_cpu() && sev_es_enabled()) { -+ csv_kvm_cpu_reset_inhibit = true; -+ } - } - - ram_block_notifier_add(&sev_ram_notifier); --- -2.31.1 - diff --git a/1032-kvm-Add-support-for-CSV2-reboot.patch b/1032-kvm-Add-support-for-CSV2-reboot.patch deleted file mode 100644 index c08a105eb89e56e8faa13e439c5e73d5461edf32..0000000000000000000000000000000000000000 --- a/1032-kvm-Add-support-for-CSV2-reboot.patch +++ /dev/null @@ -1,170 +0,0 @@ -From 04158d0c919c406aafa5f5a366c48484dfe92c14 Mon Sep 17 00:00:00 2001 -From: hanliyang -Date: Thu, 15 Apr 2021 08:32:24 -0400 -Subject: [PATCH 28/28] kvm: Add support for CSV2 reboot - -Linux will set vcpu.arch.guest_state_protected to true after execute -LAUNCH_UPDATE_VMSA successfully, and then KVM will prevent any changes -to VMCB State Save Area. - -In order to support CSV2 guest reboot, calls cpus_control_pre_system_reset() -to set vcpu.arch.guest_state_protected to false, and calls -cpus_control_post_system_reset() to restore VMSA of guest's vcpu with -data generated by LAUNCH_UPDATE_VMSA. - -In addition, for memory encrypted guest, additional works may be -required during system reset, such as flushing the cache. The function -cpus_control_post_system_reset() hints linux to flush caches of guest -memory. - -Signed-off-by: hanliyang ---- - accel/kvm/kvm-accel-ops.c | 3 +++ - accel/kvm/kvm-all.c | 10 ++++++++++ - accel/kvm/kvm-cpus.h | 3 +++ - include/sysemu/accel-ops.h | 3 +++ - include/sysemu/cpus.h | 2 ++ - linux-headers/linux/kvm.h | 4 ++++ - system/cpus.c | 14 ++++++++++++++ - system/runstate.c | 4 ++++ - 8 files changed, 43 insertions(+) - -diff --git a/accel/kvm/kvm-accel-ops.c b/accel/kvm/kvm-accel-ops.c -index 6195150a0..54f19028b 100644 ---- a/accel/kvm/kvm-accel-ops.c -+++ b/accel/kvm/kvm-accel-ops.c -@@ -112,6 +112,9 @@ static void kvm_accel_ops_class_init(ObjectClass *oc, void *data) - ops->remove_breakpoint = kvm_remove_breakpoint; - ops->remove_all_breakpoints = kvm_remove_all_breakpoints; - #endif -+ -+ ops->control_pre_system_reset = kvm_cpus_control_pre_system_reset; -+ ops->control_post_system_reset = kvm_cpus_control_post_system_reset; - } - - static const TypeInfo kvm_accel_ops_type = { -diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index e39a810a4..e5ed69c33 100644 ---- a/accel/kvm/kvm-all.c -+++ b/accel/kvm/kvm-all.c -@@ -2761,6 +2761,16 @@ void kvm_cpu_synchronize_pre_loadvm(CPUState *cpu) - run_on_cpu(cpu, do_kvm_cpu_synchronize_pre_loadvm, RUN_ON_CPU_NULL); - } - -+void kvm_cpus_control_pre_system_reset(void) -+{ -+ kvm_vm_ioctl(kvm_state, KVM_CONTROL_VCPU_PRE_SYSTEM_RESET, NULL); -+} -+ -+void kvm_cpus_control_post_system_reset(void) -+{ -+ kvm_vm_ioctl(kvm_state, KVM_CONTROL_VCPU_POST_SYSTEM_RESET, NULL); -+} -+ - #ifdef KVM_HAVE_MCE_INJECTION - static __thread void *pending_sigbus_addr; - static __thread int pending_sigbus_code; -diff --git a/accel/kvm/kvm-cpus.h b/accel/kvm/kvm-cpus.h -index ca40add32..27b9d0d9d 100644 ---- a/accel/kvm/kvm-cpus.h -+++ b/accel/kvm/kvm-cpus.h -@@ -23,4 +23,7 @@ int kvm_insert_breakpoint(CPUState *cpu, int type, vaddr addr, vaddr len); - int kvm_remove_breakpoint(CPUState *cpu, int type, vaddr addr, vaddr len); - void kvm_remove_all_breakpoints(CPUState *cpu); - -+void kvm_cpus_control_pre_system_reset(void); -+void kvm_cpus_control_post_system_reset(void); -+ - #endif /* KVM_CPUS_H */ -diff --git a/include/sysemu/accel-ops.h b/include/sysemu/accel-ops.h -index ef91fc28b..7a32e7f82 100644 ---- a/include/sysemu/accel-ops.h -+++ b/include/sysemu/accel-ops.h -@@ -53,6 +53,9 @@ struct AccelOpsClass { - int (*insert_breakpoint)(CPUState *cpu, int type, vaddr addr, vaddr len); - int (*remove_breakpoint)(CPUState *cpu, int type, vaddr addr, vaddr len); - void (*remove_all_breakpoints)(CPUState *cpu); -+ -+ void (*control_pre_system_reset)(void); -+ void (*control_post_system_reset)(void); - }; - - #endif /* ACCEL_OPS_H */ -diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h -index b4a566cfe..f24d27daf 100644 ---- a/include/sysemu/cpus.h -+++ b/include/sysemu/cpus.h -@@ -44,6 +44,8 @@ extern int icount_align_option; - void qemu_cpu_kick_self(void); - - bool cpus_are_resettable(void); -+void cpus_control_pre_system_reset(void); -+void cpus_control_post_system_reset(void); - - void cpu_synchronize_all_states(void); - void cpu_synchronize_all_post_reset(void); -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index bdcd7a014..372d0bd14 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -1583,6 +1583,10 @@ struct kvm_s390_ucas_mapping { - #define KVM_GET_DEVICE_ATTR _IOW(KVMIO, 0xe2, struct kvm_device_attr) - #define KVM_HAS_DEVICE_ATTR _IOW(KVMIO, 0xe3, struct kvm_device_attr) - -+/* ioctls for control vcpu setup during system reset */ -+#define KVM_CONTROL_VCPU_PRE_SYSTEM_RESET _IO(KVMIO, 0xe8) -+#define KVM_CONTROL_VCPU_POST_SYSTEM_RESET _IO(KVMIO, 0xe9) -+ - /* - * ioctls for vcpu fds - */ -diff --git a/system/cpus.c b/system/cpus.c -index a444a747f..cbeec13f3 100644 ---- a/system/cpus.c -+++ b/system/cpus.c -@@ -193,6 +193,20 @@ void cpu_synchronize_pre_loadvm(CPUState *cpu) - } - } - -+void cpus_control_pre_system_reset(void) -+{ -+ if (cpus_accel->control_pre_system_reset) { -+ cpus_accel->control_pre_system_reset(); -+ } -+} -+ -+void cpus_control_post_system_reset(void) -+{ -+ if (cpus_accel->control_post_system_reset) { -+ cpus_accel->control_post_system_reset(); -+ } -+} -+ - bool cpus_are_resettable(void) - { - if (cpus_accel->cpus_are_resettable) { -diff --git a/system/runstate.c b/system/runstate.c -index ea9d6c2a3..365f2f44b 100644 ---- a/system/runstate.c -+++ b/system/runstate.c -@@ -486,6 +486,8 @@ void qemu_system_reset(ShutdownCause reason) - - mc = current_machine ? MACHINE_GET_CLASS(current_machine) : NULL; - -+ cpus_control_pre_system_reset(); -+ - cpu_synchronize_all_states(); - - if (mc && mc->reset) { -@@ -502,6 +504,8 @@ void qemu_system_reset(ShutdownCause reason) - qapi_event_send_reset(shutdown_caused_by_guest(reason), reason); - } - cpu_synchronize_all_post_reset(); -+ -+ cpus_control_post_system_reset(); - } - - /* --- -2.31.1 - diff --git a/1033-target-i386-csv-Add-CSV3-context.patch b/1033-target-i386-csv-Add-CSV3-context.patch deleted file mode 100644 index 880f4c2ae67e91fd79f489d0395fcb22cb098d94..0000000000000000000000000000000000000000 --- a/1033-target-i386-csv-Add-CSV3-context.patch +++ /dev/null @@ -1,86 +0,0 @@ -From d9da5a2694de340197ff8e51080f112af8bfff5c Mon Sep 17 00:00:00 2001 -From: jiangxin -Date: Tue, 24 Aug 2021 14:57:28 +0800 -Subject: [PATCH 01/14] target/i386: csv: Add CSV3 context - -CSV/CSV2/CSV3 are the secure virtualization features on Hygon CPUs. -The CSV and CSV2 are compatible with the AMD SEV and SEV-ES, -respectively. From CSV3, we introduced more secure features to -protect the guest, users can bit 6 of the guest policy to run a -CSV3 guest. - -Add the context and the build option. - -Signed-off-by: Xin Jiang -Signed-off-by: hanliyang ---- - target/i386/csv.c | 11 +++++++++++ - target/i386/csv.h | 18 ++++++++++++++++++ - 2 files changed, 29 insertions(+) - -diff --git a/target/i386/csv.c b/target/i386/csv.c -index 88fb05ac3..9a1de04db 100644 ---- a/target/i386/csv.c -+++ b/target/i386/csv.c -@@ -18,3 +18,14 @@ - #include "csv.h" - - bool csv_kvm_cpu_reset_inhibit; -+ -+Csv3GuestState csv3_guest = { 0 }; -+ -+bool -+csv3_enabled(void) -+{ -+ if (!is_hygon_cpu()) -+ return false; -+ -+ return sev_es_enabled() && (csv3_guest.policy & GUEST_POLICY_CSV3_BIT); -+} -diff --git a/target/i386/csv.h b/target/i386/csv.h -index ac4bb5bee..7852fb8dc 100644 ---- a/target/i386/csv.h -+++ b/target/i386/csv.h -@@ -14,6 +14,8 @@ - #ifndef I386_CSV_H - #define I386_CSV_H - -+#include "qapi/qapi-commands-misc-target.h" -+ - #ifdef CONFIG_CSV - - #include "cpu.h" -@@ -38,9 +40,12 @@ static bool __attribute__((unused)) is_hygon_cpu(void) - return false; - } - -+bool csv3_enabled(void); -+ - #else - - #define is_hygon_cpu() (false) -+#define csv3_enabled() (false) - - #endif - -@@ -64,4 +69,17 @@ int csv_load_queued_incoming_pages(QEMUFile *f); - int csv_save_outgoing_cpu_state(QEMUFile *f, uint64_t *bytes_sent); - int csv_load_incoming_cpu_state(QEMUFile *f); - -+/* CSV3 */ -+#define GUEST_POLICY_CSV3_BIT (1 << 6) -+ -+struct Csv3GuestState { -+ uint32_t policy; -+ int sev_fd; -+ void *state; -+}; -+ -+typedef struct Csv3GuestState Csv3GuestState; -+ -+extern struct Csv3GuestState csv3_guest; -+ - #endif --- -2.31.1 - diff --git a/1034-target-i386-csv-Add-command-to-initialize-CSV3-conte.patch b/1034-target-i386-csv-Add-command-to-initialize-CSV3-conte.patch deleted file mode 100644 index 7e8bf484b787141d2bef77700214dca9bf158ec5..0000000000000000000000000000000000000000 --- a/1034-target-i386-csv-Add-command-to-initialize-CSV3-conte.patch +++ /dev/null @@ -1,202 +0,0 @@ -From ab6316e662eac3bd66085d50d33153d8205b2334 Mon Sep 17 00:00:00 2001 -From: jiangxin -Date: Wed, 25 Aug 2021 11:07:41 +0800 -Subject: [PATCH 02/14] target/i386: csv: Add command to initialize CSV3 - context - -When CSV3 is enabled, KVM_CSV3_INIT command is used to initialize -the platform, which is implemented by reusing the SEV API framework -and extending the functionality. - -The KVM_CSV3_INIT command should be performed earlier than -any other command. - -Signed-off-by: Xin Jiang -Signed-off-by: hanliyang ---- - linux-headers/linux/kvm.h | 11 +++++++++ - target/i386/csv-sysemu-stub.c | 5 ++++ - target/i386/csv.c | 45 +++++++++++++++++++++++++++++++++++ - target/i386/csv.h | 4 ++++ - target/i386/sev.c | 17 +++++++++++++ - target/i386/sev.h | 7 ++++++ - 6 files changed, 89 insertions(+) - -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index 372d0bd14..d976908bc 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -2060,6 +2060,17 @@ struct kvm_csv_command_batch { - __u64 csv_batch_list_uaddr; - }; - -+/* CSV3 command */ -+enum csv3_cmd_id { -+ KVM_CSV3_NR_MIN = 0xc0, -+ -+ KVM_CSV3_INIT = KVM_CSV3_NR_MIN, -+}; -+ -+struct kvm_csv3_init_data { -+ __u64 nodemask; -+}; -+ - #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) - #define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1) - #define KVM_DEV_ASSIGN_MASK_INTX (1 << 2) -diff --git a/target/i386/csv-sysemu-stub.c b/target/i386/csv-sysemu-stub.c -index 5874e4cc1..72f0f5c77 100644 ---- a/target/i386/csv-sysemu-stub.c -+++ b/target/i386/csv-sysemu-stub.c -@@ -14,3 +14,8 @@ - #include "qemu/osdep.h" - #include "sev.h" - #include "csv.h" -+ -+int csv3_init(uint32_t policy, int fd, void *state, struct sev_ops *ops) -+{ -+ return 0; -+} -diff --git a/target/i386/csv.c b/target/i386/csv.c -index 9a1de04db..f02aadb54 100644 ---- a/target/i386/csv.c -+++ b/target/i386/csv.c -@@ -12,6 +12,13 @@ - */ - - #include "qemu/osdep.h" -+#include "qemu/error-report.h" -+ -+#include -+ -+#ifdef CONFIG_NUMA -+#include -+#endif - - #include "cpu.h" - #include "sev.h" -@@ -21,6 +28,44 @@ bool csv_kvm_cpu_reset_inhibit; - - Csv3GuestState csv3_guest = { 0 }; - -+int -+csv3_init(uint32_t policy, int fd, void *state, struct sev_ops *ops) -+{ -+ int fw_error; -+ int ret; -+ struct kvm_csv3_init_data data = { 0 }; -+ -+#ifdef CONFIG_NUMA -+ int mode; -+ unsigned long nodemask; -+ -+ /* Set flags as 0 to retrieve the default NUMA policy. */ -+ ret = get_mempolicy(&mode, &nodemask, sizeof(nodemask) * 8, NULL, 0); -+ if (ret == 0 && (mode == MPOL_BIND)) -+ data.nodemask = nodemask; -+#endif -+ -+ if (!ops || !ops->sev_ioctl || !ops->fw_error_to_str) -+ return -1; -+ -+ csv3_guest.policy = policy; -+ if (csv3_enabled()) { -+ ret = ops->sev_ioctl(fd, KVM_CSV3_INIT, &data, &fw_error); -+ if (ret) { -+ csv3_guest.policy = 0; -+ error_report("%s: Fail to initialize ret=%d fw_error=%d '%s'", -+ __func__, ret, fw_error, ops->fw_error_to_str(fw_error)); -+ return -1; -+ } -+ -+ csv3_guest.sev_fd = fd; -+ csv3_guest.state = state; -+ csv3_guest.sev_ioctl = ops->sev_ioctl; -+ csv3_guest.fw_error_to_str = ops->fw_error_to_str; -+ } -+ return 0; -+} -+ - bool - csv3_enabled(void) - { -diff --git a/target/i386/csv.h b/target/i386/csv.h -index 7852fb8dc..cf125fe0f 100644 ---- a/target/i386/csv.h -+++ b/target/i386/csv.h -@@ -15,6 +15,7 @@ - #define I386_CSV_H - - #include "qapi/qapi-commands-misc-target.h" -+#include "sev.h" - - #ifdef CONFIG_CSV - -@@ -76,10 +77,13 @@ struct Csv3GuestState { - uint32_t policy; - int sev_fd; - void *state; -+ int (*sev_ioctl)(int fd, int cmd, void *data, int *error); -+ const char *(*fw_error_to_str)(int code); - }; - - typedef struct Csv3GuestState Csv3GuestState; - - extern struct Csv3GuestState csv3_guest; -+extern int csv3_init(uint32_t policy, int fd, void *state, struct sev_ops *ops); - - #endif -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 3406861f6..50f3429a4 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -1180,6 +1180,18 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - goto err; - } - -+ /* Support CSV3 */ -+ if (!ret && cmd == KVM_SEV_ES_INIT) { -+ ret = csv3_init(sev_guest->policy, sev->sev_fd, (void *)&sev->state, &sev_ops); -+ if (ret) { -+ error_setg(errp, "%s: failed to init csv3 context", __func__); -+ goto err; -+ } -+ /* The CSV3 guest is not resettable */ -+ if (csv3_enabled()) -+ csv_kvm_cpu_reset_inhibit = true; -+ } -+ - /* - * The LAUNCH context is used for new guest, if its an incoming guest - * then RECEIVE context will be created after the connection is established. -@@ -2589,6 +2601,11 @@ bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp) - return ret; - } - -+struct sev_ops sev_ops = { -+ .sev_ioctl = sev_ioctl, -+ .fw_error_to_str = fw_error_to_str, -+}; -+ - static void - sev_register_types(void) - { -diff --git a/target/i386/sev.h b/target/i386/sev.h -index 0bfe3879e..e91431e0f 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -80,4 +80,11 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp); - - extern bool sev_kvm_has_msr_ghcb; - -+struct sev_ops { -+ int (*sev_ioctl)(int fd, int cmd, void *data, int *error); -+ const char *(*fw_error_to_str)(int code); -+}; -+ -+extern struct sev_ops sev_ops; -+ - #endif --- -2.31.1 - diff --git a/1035-target-i386-csv-Add-command-to-load-data-to-CSV3-gue.patch b/1035-target-i386-csv-Add-command-to-load-data-to-CSV3-gue.patch deleted file mode 100644 index ca4a3aeb051b4b6fe237c11937bdf201f02a1c45..0000000000000000000000000000000000000000 --- a/1035-target-i386-csv-Add-command-to-load-data-to-CSV3-gue.patch +++ /dev/null @@ -1,166 +0,0 @@ -From 39ab65c4235b733a1a4e0147be3f81881fb1c551 Mon Sep 17 00:00:00 2001 -From: jiangxin -Date: Wed, 25 Aug 2021 09:59:16 +0800 -Subject: [PATCH 03/14] target/i386: csv: Add command to load data to CSV3 - guest memory - -The KVM_CSV3_LAUNCH_ENCRYPT_DATA command is used to load data to an -encrypted guest memory in an isolated memory region that guest owns. - -Signed-off-by: Xin Jiang -Signed-off-by: hanliyang ---- - linux-headers/linux/kvm.h | 7 ++++ - target/i386/csv-sysemu-stub.c | 5 +++ - target/i386/csv.c | 69 +++++++++++++++++++++++++++++++++++ - target/i386/csv.h | 2 + - target/i386/trace-events | 3 ++ - 5 files changed, 86 insertions(+) - -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index d976908bc..fa7b41581 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -2065,6 +2065,13 @@ enum csv3_cmd_id { - KVM_CSV3_NR_MIN = 0xc0, - - KVM_CSV3_INIT = KVM_CSV3_NR_MIN, -+ KVM_CSV3_LAUNCH_ENCRYPT_DATA, -+}; -+ -+struct kvm_csv3_launch_encrypt_data { -+ __u64 gpa; -+ __u64 uaddr; -+ __u32 len; - }; - - struct kvm_csv3_init_data { -diff --git a/target/i386/csv-sysemu-stub.c b/target/i386/csv-sysemu-stub.c -index 72f0f5c77..b0ccbd2f1 100644 ---- a/target/i386/csv-sysemu-stub.c -+++ b/target/i386/csv-sysemu-stub.c -@@ -19,3 +19,8 @@ int csv3_init(uint32_t policy, int fd, void *state, struct sev_ops *ops) - { - return 0; - } -+ -+int csv3_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp) -+{ -+ g_assert_not_reached(); -+} -diff --git a/target/i386/csv.c b/target/i386/csv.c -index f02aadb54..0e3f4478a 100644 ---- a/target/i386/csv.c -+++ b/target/i386/csv.c -@@ -13,6 +13,7 @@ - - #include "qemu/osdep.h" - #include "qemu/error-report.h" -+#include "qapi/error.h" - - #include - -@@ -20,6 +21,7 @@ - #include - #endif - -+#include "trace.h" - #include "cpu.h" - #include "sev.h" - #include "csv.h" -@@ -74,3 +76,70 @@ csv3_enabled(void) - - return sev_es_enabled() && (csv3_guest.policy & GUEST_POLICY_CSV3_BIT); - } -+ -+static bool -+csv3_check_state(SevState state) -+{ -+ return *((SevState *)csv3_guest.state) == state ? true : false; -+} -+ -+static int -+csv3_ioctl(int cmd, void *data, int *error) -+{ -+ if (csv3_guest.sev_ioctl) -+ return csv3_guest.sev_ioctl(csv3_guest.sev_fd, cmd, data, error); -+ else -+ return -1; -+} -+ -+static const char * -+fw_error_to_str(int code) -+{ -+ if (csv3_guest.fw_error_to_str) -+ return csv3_guest.fw_error_to_str(code); -+ else -+ return NULL; -+} -+ -+static int -+csv3_launch_encrypt_data(uint64_t gpa, uint8_t *addr, uint64_t len) -+{ -+ int ret, fw_error; -+ struct kvm_csv3_launch_encrypt_data update; -+ -+ if (!addr || !len) { -+ return 1; -+ } -+ -+ update.gpa = (__u64)gpa; -+ update.uaddr = (__u64)(unsigned long)addr; -+ update.len = len; -+ trace_kvm_csv3_launch_encrypt_data(gpa, addr, len); -+ ret = csv3_ioctl(KVM_CSV3_LAUNCH_ENCRYPT_DATA, &update, &fw_error); -+ if (ret) { -+ error_report("%s: CSV3 LAUNCH_ENCRYPT_DATA ret=%d fw_error=%d '%s'", -+ __func__, ret, fw_error, fw_error_to_str(fw_error)); -+ } -+ -+ return ret; -+} -+ -+int -+csv3_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp) -+{ -+ int ret = 0; -+ -+ if (!csv3_enabled()) { -+ error_setg(errp, "%s: CSV3 is not enabled", __func__); -+ return -1; -+ } -+ -+ /* if CSV3 is in update state then load the data to secure memory */ -+ if (csv3_check_state(SEV_STATE_LAUNCH_UPDATE)) { -+ ret = csv3_launch_encrypt_data(gpa, ptr, len); -+ if (ret) -+ error_setg(errp, "%s: CSV3 fail to encrypt data", __func__); -+ } -+ -+ return ret; -+} -diff --git a/target/i386/csv.h b/target/i386/csv.h -index cf125fe0f..928774f59 100644 ---- a/target/i386/csv.h -+++ b/target/i386/csv.h -@@ -86,4 +86,6 @@ typedef struct Csv3GuestState Csv3GuestState; - extern struct Csv3GuestState csv3_guest; - extern int csv3_init(uint32_t policy, int fd, void *state, struct sev_ops *ops); - -+int csv3_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp); -+ - #endif -diff --git a/target/i386/trace-events b/target/i386/trace-events -index 87b765c73..e07061bf3 100644 ---- a/target/i386/trace-events -+++ b/target/i386/trace-events -@@ -19,3 +19,6 @@ kvm_sev_receive_update_data(void *src, void *dst, int len, void *hdr, int hdr_le - kvm_sev_receive_finish(void) "" - kvm_sev_send_update_vmsa(uint32_t cpu_id, uint32_t cpu_index, void *dst, int len) "cpu_id %d cpu_index %d trans %p len %d" - kvm_sev_receive_update_vmsa(uint32_t cpu_id, uint32_t cpu_index, void *src, int len, void *hdr, int hdr_len) "cpu_id %d cpu_index %d trans %p len %d hdr %p hdr_len %d" -+ -+# csv.c -+kvm_csv3_launch_encrypt_data(uint64_t gpa, void *addr, uint64_t len) "gpa 0x%" PRIx64 "addr %p len 0x%" PRIu64 --- -2.31.1 - diff --git a/1036-target-i386-csv-Add-command-to-load-vmcb-to-CSV3-gue.patch b/1036-target-i386-csv-Add-command-to-load-vmcb-to-CSV3-gue.patch deleted file mode 100644 index febed2638d656f38345b4065cd187e20464167c3..0000000000000000000000000000000000000000 --- a/1036-target-i386-csv-Add-command-to-load-vmcb-to-CSV3-gue.patch +++ /dev/null @@ -1,108 +0,0 @@ -From dad06ad8bf5f8ba7842f92f0a92346697740557a Mon Sep 17 00:00:00 2001 -From: jiangxin -Date: Wed, 25 Aug 2021 12:25:05 +0800 -Subject: [PATCH 04/14] target/i386: csv: Add command to load vmcb to CSV3 - guest memory - -The KVM_CSV3_LAUNCH_ENCRYPT_VMCB command is used to load and encrypt -the initial VMCB data to secure memory in an isolated region that -guest owns. - -Signed-off-by: Xin Jiang -Signed-off-by: hanliyang ---- - linux-headers/linux/kvm.h | 1 + - target/i386/csv-sysemu-stub.c | 5 +++++ - target/i386/csv.c | 21 +++++++++++++++++++++ - target/i386/csv.h | 1 + - target/i386/sev.c | 8 ++++++-- - 5 files changed, 34 insertions(+), 2 deletions(-) - -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index fa7b41581..061b2e7f0 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -2066,6 +2066,7 @@ enum csv3_cmd_id { - - KVM_CSV3_INIT = KVM_CSV3_NR_MIN, - KVM_CSV3_LAUNCH_ENCRYPT_DATA, -+ KVM_CSV3_LAUNCH_ENCRYPT_VMCB, - }; - - struct kvm_csv3_launch_encrypt_data { -diff --git a/target/i386/csv-sysemu-stub.c b/target/i386/csv-sysemu-stub.c -index b0ccbd2f1..23d885f0f 100644 ---- a/target/i386/csv-sysemu-stub.c -+++ b/target/i386/csv-sysemu-stub.c -@@ -24,3 +24,8 @@ int csv3_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp) - { - g_assert_not_reached(); - } -+ -+int csv3_launch_encrypt_vmcb(void) -+{ -+ g_assert_not_reached(); -+} -diff --git a/target/i386/csv.c b/target/i386/csv.c -index 0e3f4478a..f423b898f 100644 ---- a/target/i386/csv.c -+++ b/target/i386/csv.c -@@ -143,3 +143,24 @@ csv3_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp) - - return ret; - } -+ -+int -+csv3_launch_encrypt_vmcb(void) -+{ -+ int ret, fw_error; -+ -+ if (!csv3_enabled()) { -+ error_report("%s: CSV3 is not enabled",__func__); -+ return -1; -+ } -+ -+ ret = csv3_ioctl(KVM_CSV3_LAUNCH_ENCRYPT_VMCB, NULL, &fw_error); -+ if (ret) { -+ error_report("%s: CSV3 LAUNCH_ENCRYPT_VMCB ret=%d fw_error=%d '%s'", -+ __func__, ret, fw_error, fw_error_to_str(fw_error)); -+ goto err; -+ } -+ -+err: -+ return ret; -+} -diff --git a/target/i386/csv.h b/target/i386/csv.h -index 928774f59..6444d54ef 100644 ---- a/target/i386/csv.h -+++ b/target/i386/csv.h -@@ -85,6 +85,7 @@ typedef struct Csv3GuestState Csv3GuestState; - - extern struct Csv3GuestState csv3_guest; - extern int csv3_init(uint32_t policy, int fd, void *state, struct sev_ops *ops); -+extern int csv3_launch_encrypt_vmcb(void); - - int csv3_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp); - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 50f3429a4..b77572f0b 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -857,8 +857,12 @@ sev_launch_get_measure(Notifier *notifier, void *unused) - } - - if (sev_es_enabled()) { -- /* measure all the VM save areas before getting launch_measure */ -- ret = sev_launch_update_vmsa(sev); -+ if (csv3_enabled()) { -+ ret = csv3_launch_encrypt_vmcb(); -+ } else { -+ /* measure all the VM save areas before getting launch_measure */ -+ ret = sev_launch_update_vmsa(sev); -+ } - if (ret) { - exit(1); - } --- -2.31.1 - diff --git a/1037-target-i386-cpu-Populate-CPUID-0x8000_001F-when-CSV3.patch b/1037-target-i386-cpu-Populate-CPUID-0x8000_001F-when-CSV3.patch deleted file mode 100644 index 56c39136d3c4176f76d679c94c6bb8dc322c90f5..0000000000000000000000000000000000000000 --- a/1037-target-i386-cpu-Populate-CPUID-0x8000_001F-when-CSV3.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 94786f0f3fb14205852f0c7ad8c3b4b8fb0ff4fa Mon Sep 17 00:00:00 2001 -From: jiangxin -Date: Tue, 24 Aug 2021 17:31:28 +0800 -Subject: [PATCH 05/14] target/i386: cpu: Populate CPUID 0x8000_001F when CSV3 - is active - -On Hygon platform, bit 30 of EAX indicates whether -this feature is supported in hardware. - -When CSV3 is active, CPUID 0x8000_001F provides -information for it. - -Signed-off-by: Xin Jiang -Signed-off-by: hanliyang ---- - target/i386/cpu.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index a66e5a357..c01943ee6 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -29,6 +29,7 @@ - #include "hvf/hvf-i386.h" - #include "kvm/kvm_i386.h" - #include "sev.h" -+#include "csv.h" - #include "qapi/error.h" - #include "qemu/error-report.h" - #include "qapi/qapi-visit-machine.h" -@@ -6660,6 +6661,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, - if (sev_enabled()) { - *eax = 0x2; - *eax |= sev_es_enabled() ? 0x8 : 0; -+ *eax |= csv3_enabled() ? 0x40000000 : 0; /* bit 30 for CSV3 */ - *ebx = sev_get_cbit_position() & 0x3f; /* EBX[5:0] */ - *ebx |= (sev_get_reduced_phys_bits() & 0x3f) << 6; /* EBX[11:6] */ - } --- -2.31.1 - diff --git a/1038-target-i386-csv-Do-not-register-unregister-guest-sec.patch b/1038-target-i386-csv-Do-not-register-unregister-guest-sec.patch deleted file mode 100644 index 3a1939c91b1acd7d049d1d9840538033612145ea..0000000000000000000000000000000000000000 --- a/1038-target-i386-csv-Do-not-register-unregister-guest-sec.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 1ac5b6d0bef3090fea6fbcc0435cb4215bdf0129 Mon Sep 17 00:00:00 2001 -From: jiangxin -Date: Wed, 25 Aug 2021 12:36:00 +0800 -Subject: [PATCH 06/14] target/i386: csv: Do not register/unregister guest - secure memory for CSV3 guest - -CSV3's guest memory is allocated by firmware in secure processor -from dedicated memory reserved upon system boot up, consequently -it is not necessary to add notifier to pin/unpin memory. - -Signed-off-by: Xin Jiang -Signed-off-by: hanliyang ---- - target/i386/sev.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index b77572f0b..eb1026b57 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -1217,7 +1217,10 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - } - } - -- ram_block_notifier_add(&sev_ram_notifier); -+ /* CSV3 guest do not need notifier to reg/unreg memory */ -+ if (!csv3_enabled()) { -+ ram_block_notifier_add(&sev_ram_notifier); -+ } - qemu_add_machine_init_done_notifier(&sev_machine_done_notify); - qemu_add_vm_change_state_handler(sev_vm_state_change, sev); - migration_add_notifier(&sev_migration_state, sev_migration_state_notifier); --- -2.31.1 - diff --git a/1039-target-i386-csv-Load-initial-image-to-private-memory.patch b/1039-target-i386-csv-Load-initial-image-to-private-memory.patch deleted file mode 100644 index 8a22f5dda7204c6cc28b36d4eb6cb529d39eb371..0000000000000000000000000000000000000000 --- a/1039-target-i386-csv-Load-initial-image-to-private-memory.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 1234dd2391d79ba6a2db3fe82a22822ef7ad9e02 Mon Sep 17 00:00:00 2001 -From: jiangxin -Date: Wed, 25 Aug 2021 14:29:40 +0800 -Subject: [PATCH 07/14] target/i386: csv: Load initial image to private memory - for CSV3 guest - -The initial image of CSV3 guest should be loaded into private memory -before boot the guest. - -Add APIs to implement the image load. - -Signed-off-by: Xin Jiang -Signed-off-by: hanliyang ---- - hw/i386/pc_sysfw.c | 14 +++++++++++++- - 1 file changed, 13 insertions(+), 1 deletion(-) - -diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c -index c8d9e71b8..2bbcbb8d3 100644 ---- a/hw/i386/pc_sysfw.c -+++ b/hw/i386/pc_sysfw.c -@@ -37,6 +37,7 @@ - #include "hw/block/flash.h" - #include "sysemu/kvm.h" - #include "sev.h" -+#include "csv.h" - - #define FLASH_SECTOR_SIZE 4096 - -@@ -263,7 +264,18 @@ void x86_firmware_configure(void *ptr, int size) - error_report("failed to locate and/or save reset vector"); - exit(1); - } -+ if (csv3_enabled()) { -+ ram_addr_t offset = 0; -+ MemoryRegion *mr; - -- sev_encrypt_flash(ptr, size, &error_fatal); -+ mr = memory_region_from_host(ptr, &offset); -+ if (!mr) { -+ error_report("failed to get memory region of flash"); -+ exit(1); -+ } -+ csv3_load_data(mr->addr + offset, ptr, size, &error_fatal); -+ } else { -+ sev_encrypt_flash(ptr, size, &error_fatal); -+ } - } - } --- -2.31.1 - diff --git a/1040-vga-Force-full-update-for-CSV3-guest.patch b/1040-vga-Force-full-update-for-CSV3-guest.patch deleted file mode 100644 index 49c2b26480652c46dcdbc41ed463a9ffebcbb729..0000000000000000000000000000000000000000 --- a/1040-vga-Force-full-update-for-CSV3-guest.patch +++ /dev/null @@ -1,128 +0,0 @@ -From ef998e2666f941ca94f8b5383d574bb886dcf81a Mon Sep 17 00:00:00 2001 -From: Xin Jiang -Date: Thu, 13 Jul 2023 09:35:10 +0800 -Subject: [PATCH 08/14] vga: Force full update for CSV3 guest - -As CSV3's NPT(nested page table) is managed by firmware, VMM is hard -to track the dirty pages of vga buffer. Although VMM could perform -a command to firmware to update read/write attribute of vga buffer -in NPT, it costs more time due to communication between VMM and -firmware. So the simplest method is to fully update vga buffer -always. - -Signed-off-by: Xin Jiang -Signed-off-by: hanliyang ---- - accel/kvm/kvm-all.c | 1 + - accel/stubs/kvm-stub.c | 1 + - hw/display/vga.c | 7 +++++++ - include/sysemu/kvm.h | 8 ++++++++ - target/i386/csv.c | 3 +++ - 5 files changed, 20 insertions(+) - -diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index e5ed69c33..25d23bba2 100644 ---- a/accel/kvm/kvm-all.c -+++ b/accel/kvm/kvm-all.c -@@ -98,6 +98,7 @@ bool kvm_allowed; - bool kvm_readonly_mem_allowed; - bool kvm_vm_attributes_allowed; - bool kvm_msi_use_devid; -+bool kvm_csv3_allowed; - bool kvm_has_guest_debug; - static int kvm_sstep_flags; - static bool kvm_immediate_exit; -diff --git a/accel/stubs/kvm-stub.c b/accel/stubs/kvm-stub.c -index 1b37d9a30..45b23f61c 100644 ---- a/accel/stubs/kvm-stub.c -+++ b/accel/stubs/kvm-stub.c -@@ -24,6 +24,7 @@ bool kvm_gsi_direct_mapping; - bool kvm_allowed; - bool kvm_readonly_mem_allowed; - bool kvm_msi_use_devid; -+bool kvm_csv3_allowed; - - void kvm_flush_coalesced_mmio_buffer(void) - { -diff --git a/hw/display/vga.c b/hw/display/vga.c -index 37557c344..d70226a89 100644 ---- a/hw/display/vga.c -+++ b/hw/display/vga.c -@@ -39,6 +39,8 @@ - #include "migration/vmstate.h" - #include "trace.h" - -+#include "sysemu/kvm.h" -+ - //#define DEBUG_VGA_MEM - //#define DEBUG_VGA_REG - -@@ -1783,6 +1785,11 @@ static void vga_update_display(void *opaque) - s->cursor_blink_time = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL); - full_update = 1; - } -+ -+ /* Force to full update in CSV guest. */ -+ if (kvm_csv3_enabled()) -+ full_update = 1; -+ - switch(graphic_mode) { - case GMODE_TEXT: - vga_draw_text(s, full_update); -diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h -index d61487816..1e15cfe9d 100644 ---- a/include/sysemu/kvm.h -+++ b/include/sysemu/kvm.h -@@ -42,6 +42,7 @@ extern bool kvm_gsi_routing_allowed; - extern bool kvm_gsi_direct_mapping; - extern bool kvm_readonly_mem_allowed; - extern bool kvm_msi_use_devid; -+extern bool kvm_csv3_allowed; - - #define kvm_enabled() (kvm_allowed) - /** -@@ -143,6 +144,12 @@ extern bool kvm_msi_use_devid; - */ - #define kvm_msi_devid_required() (kvm_msi_use_devid) - -+/** -+ * kvm_csv3_enabled: -+ * Returns: true if CSV3 feature is used for the VM. -+ */ -+#define kvm_csv3_enabled() (kvm_csv3_allowed) -+ - #else - - #define kvm_enabled() (0) -@@ -157,6 +164,7 @@ extern bool kvm_msi_use_devid; - #define kvm_gsi_direct_mapping() (false) - #define kvm_readonly_mem_enabled() (false) - #define kvm_msi_devid_required() (false) -+#define kvm_csv3_enabled() (false) - - #endif /* CONFIG_KVM_IS_POSSIBLE */ - -diff --git a/target/i386/csv.c b/target/i386/csv.c -index f423b898f..70900be86 100644 ---- a/target/i386/csv.c -+++ b/target/i386/csv.c -@@ -14,6 +14,7 @@ - #include "qemu/osdep.h" - #include "qemu/error-report.h" - #include "qapi/error.h" -+#include "sysemu/kvm.h" - - #include - -@@ -60,6 +61,8 @@ csv3_init(uint32_t policy, int fd, void *state, struct sev_ops *ops) - return -1; - } - -+ kvm_csv3_allowed = true; -+ - csv3_guest.sev_fd = fd; - csv3_guest.state = state; - csv3_guest.sev_ioctl = ops->sev_ioctl; --- -2.31.1 - diff --git a/1041-vfio-Only-map-shared-region-for-CSV3-virtual-machine.patch b/1041-vfio-Only-map-shared-region-for-CSV3-virtual-machine.patch deleted file mode 100644 index ef0d64cc1e007491b82af65e2b74ad28f91d7f39..0000000000000000000000000000000000000000 --- a/1041-vfio-Only-map-shared-region-for-CSV3-virtual-machine.patch +++ /dev/null @@ -1,397 +0,0 @@ -From 0d2dbd4d687ce23342fc072c1d5a64c28f3580c7 Mon Sep 17 00:00:00 2001 -From: liuyafei -Date: Mon, 22 May 2023 20:37:40 +0800 -Subject: [PATCH 09/14] vfio: Only map shared region for CSV3 virtual machine - -qemu vfio listener map/unmap all of the virtual machine's memory. -It does not work for CSV3 virtual machine, as only shared memory -should be accessed by device. - -Signed-off-by: liuyafei -Signed-off-by: hanliyang ---- - hw/vfio/container.c | 46 +++++++++++- - include/exec/memory.h | 11 +++ - system/memory.c | 18 +++++ - target/i386/csv-sysemu-stub.c | 10 +++ - target/i386/csv.c | 134 ++++++++++++++++++++++++++++++++++ - target/i386/csv.h | 12 +++ - target/i386/kvm/kvm.c | 2 + - 7 files changed, 230 insertions(+), 3 deletions(-) - -diff --git a/hw/vfio/container.c b/hw/vfio/container.c -index 242010036..ce075f37d 100644 ---- a/hw/vfio/container.c -+++ b/hw/vfio/container.c -@@ -30,6 +30,7 @@ - #include "qemu/error-report.h" - #include "qemu/range.h" - #include "sysemu/reset.h" -+#include "sysemu/kvm.h" - #include "trace.h" - #include "qapi/error.h" - #include "migration/migration.h" -@@ -468,6 +469,32 @@ static void vfio_free_container(VFIOContainer *container) - g_free(container); - } - -+static SharedRegionListener *g_shl; -+ -+static void shared_memory_listener_register(MemoryListener *listener, -+ AddressSpace *as) -+{ -+ SharedRegionListener *shl; -+ -+ shl = g_new0(SharedRegionListener, 1); -+ -+ shl->listener = listener; -+ shl->as = as; -+ -+ shared_region_register_listener(shl); -+ g_shl = shl; -+} -+ -+static void shared_memory_listener_unregister(void) -+{ -+ SharedRegionListener *shl = g_shl; -+ -+ shared_region_unregister_listener(shl); -+ -+ g_free(shl); -+ g_shl = NULL; -+} -+ - static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - Error **errp) - { -@@ -613,7 +640,12 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - - container->listener = vfio_memory_listener; - -- memory_listener_register(&container->listener, container->space->as); -+ if (kvm_csv3_enabled()) { -+ shared_memory_listener_register(&container->listener, -+ container->space->as); -+ } else { -+ memory_listener_register(&container->listener, container->space->as); -+ } - - if (container->error) { - ret = -1; -@@ -629,7 +661,11 @@ listener_release_exit: - QLIST_REMOVE(group, container_next); - QLIST_REMOVE(container, next); - vfio_kvm_device_del_group(group); -- memory_listener_unregister(&container->listener); -+ if (kvm_csv3_enabled()) { -+ shared_memory_listener_unregister(); -+ } else { -+ memory_listener_unregister(&container->listener); -+ } - if (container->iommu_type == VFIO_SPAPR_TCE_v2_IOMMU || - container->iommu_type == VFIO_SPAPR_TCE_IOMMU) { - vfio_spapr_container_deinit(container); -@@ -663,7 +699,11 @@ static void vfio_disconnect_container(VFIOGroup *group) - * group. - */ - if (QLIST_EMPTY(&container->group_list)) { -- memory_listener_unregister(&container->listener); -+ if (kvm_csv3_enabled()) { -+ shared_memory_listener_unregister(); -+ } else { -+ memory_listener_unregister(&container->listener); -+ } - if (container->iommu_type == VFIO_SPAPR_TCE_v2_IOMMU || - container->iommu_type == VFIO_SPAPR_TCE_IOMMU) { - vfio_spapr_container_deinit(container); -diff --git a/include/exec/memory.h b/include/exec/memory.h -index 831f7c996..3e65d8d9f 100644 ---- a/include/exec/memory.h -+++ b/include/exec/memory.h -@@ -775,6 +775,17 @@ bool memory_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr, - ram_addr_t *ram_addr, bool *read_only, - bool *mr_has_discard_manager); - -+typedef struct SharedRegionListener SharedRegionListener; -+struct SharedRegionListener { -+ MemoryListener *listener; -+ AddressSpace *as; -+ QTAILQ_ENTRY(SharedRegionListener) next; -+}; -+ -+void shared_region_register_listener(SharedRegionListener *shl); -+void shared_region_unregister_listener(SharedRegionListener *shl); -+void *shared_region_listeners_get(void); -+ - typedef struct CoalescedMemoryRange CoalescedMemoryRange; - typedef struct MemoryRegionIoeventfd MemoryRegionIoeventfd; - -diff --git a/system/memory.c b/system/memory.c -index 798b6c0a1..2ffb878eb 100644 ---- a/system/memory.c -+++ b/system/memory.c -@@ -48,6 +48,9 @@ static QTAILQ_HEAD(, MemoryListener) memory_listeners - static QTAILQ_HEAD(, AddressSpace) address_spaces - = QTAILQ_HEAD_INITIALIZER(address_spaces); - -+static QTAILQ_HEAD(, SharedRegionListener) shared_region_listeners -+ = QTAILQ_HEAD_INITIALIZER(shared_region_listeners); -+ - static GHashTable *flat_views; - - typedef struct AddrRange AddrRange; -@@ -2226,6 +2229,21 @@ bool memory_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr, - return true; - } - -+void shared_region_register_listener(SharedRegionListener *shl) -+{ -+ QTAILQ_INSERT_TAIL(&shared_region_listeners, shl, next); -+} -+ -+void shared_region_unregister_listener(SharedRegionListener *shl) -+{ -+ QTAILQ_REMOVE(&shared_region_listeners, shl, next); -+} -+ -+void *shared_region_listeners_get(void) -+{ -+ return &shared_region_listeners; -+} -+ - void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client) - { - uint8_t mask = 1 << client; -diff --git a/target/i386/csv-sysemu-stub.c b/target/i386/csv-sysemu-stub.c -index 23d885f0f..db22c299a 100644 ---- a/target/i386/csv-sysemu-stub.c -+++ b/target/i386/csv-sysemu-stub.c -@@ -29,3 +29,13 @@ int csv3_launch_encrypt_vmcb(void) - { - g_assert_not_reached(); - } -+ -+int csv3_shared_region_dma_map(uint64_t start, uint64_t end) -+{ -+ return 0; -+} -+ -+void csv3_shared_region_dma_unmap(uint64_t start, uint64_t end) -+{ -+ -+} -diff --git a/target/i386/csv.c b/target/i386/csv.c -index 70900be86..5823c8994 100644 ---- a/target/i386/csv.c -+++ b/target/i386/csv.c -@@ -15,6 +15,7 @@ - #include "qemu/error-report.h" - #include "qapi/error.h" - #include "sysemu/kvm.h" -+#include "exec/address-spaces.h" - - #include - -@@ -67,6 +68,8 @@ csv3_init(uint32_t policy, int fd, void *state, struct sev_ops *ops) - csv3_guest.state = state; - csv3_guest.sev_ioctl = ops->sev_ioctl; - csv3_guest.fw_error_to_str = ops->fw_error_to_str; -+ QTAILQ_INIT(&csv3_guest.dma_map_regions_list); -+ qemu_mutex_init(&csv3_guest.dma_map_regions_list_mutex); - } - return 0; - } -@@ -167,3 +170,134 @@ csv3_launch_encrypt_vmcb(void) - err: - return ret; - } -+ -+int csv3_shared_region_dma_map(uint64_t start, uint64_t end) -+{ -+ MemoryRegionSection section; -+ AddressSpace *as; -+ QTAILQ_HEAD(, SharedRegionListener) *shared_region_listeners; -+ SharedRegionListener *shl; -+ MemoryListener *listener; -+ uint64_t size; -+ Csv3GuestState *s = &csv3_guest; -+ struct dma_map_region *region, *pos; -+ int ret = 0; -+ -+ if (!csv3_enabled()) -+ return 0; -+ -+ if (end <= start) -+ return 0; -+ -+ shared_region_listeners = shared_region_listeners_get(); -+ if (QTAILQ_EMPTY(shared_region_listeners)) -+ return 0; -+ -+ size = end - start; -+ -+ qemu_mutex_lock(&s->dma_map_regions_list_mutex); -+ QTAILQ_FOREACH(pos, &s->dma_map_regions_list, list) { -+ if (start >= (pos->start + pos->size)) { -+ continue; -+ } else if ((start + size) <= pos->start) { -+ break; -+ } else { -+ goto end; -+ } -+ } -+ QTAILQ_FOREACH(shl, shared_region_listeners, next) { -+ listener = shl->listener; -+ as = shl->as; -+ section = memory_region_find(as->root, start, size); -+ if (!section.mr) { -+ goto end; -+ } -+ -+ if (!memory_region_is_ram(section.mr)) { -+ memory_region_unref(section.mr); -+ goto end; -+ } -+ -+ if (listener->region_add) { -+ listener->region_add(listener, §ion); -+ } -+ memory_region_unref(section.mr); -+ } -+ -+ region = g_malloc0(sizeof(*region)); -+ if (!region) { -+ ret = -1; -+ goto end; -+ } -+ region->start = start; -+ region->size = size; -+ -+ if (pos) { -+ QTAILQ_INSERT_BEFORE(pos, region, list); -+ } else { -+ QTAILQ_INSERT_TAIL(&s->dma_map_regions_list, region, list); -+ } -+ -+end: -+ qemu_mutex_unlock(&s->dma_map_regions_list_mutex); -+ return ret; -+} -+ -+void csv3_shared_region_dma_unmap(uint64_t start, uint64_t end) -+{ -+ MemoryRegionSection section; -+ AddressSpace *as; -+ QTAILQ_HEAD(, SharedRegionListener) *shared_region_listeners; -+ SharedRegionListener *shl; -+ MemoryListener *listener; -+ uint64_t size; -+ Csv3GuestState *s = &csv3_guest; -+ struct dma_map_region *pos, *next_pos; -+ -+ if (!csv3_enabled()) -+ return; -+ -+ if (end <= start) -+ return; -+ -+ shared_region_listeners = shared_region_listeners_get(); -+ if (QTAILQ_EMPTY(shared_region_listeners)) -+ return; -+ -+ size = end - start; -+ -+ qemu_mutex_lock(&s->dma_map_regions_list_mutex); -+ QTAILQ_FOREACH_SAFE(pos, &s->dma_map_regions_list, list, next_pos) { -+ uint64_t l, r; -+ uint64_t curr_end = pos->start + pos->size; -+ -+ l = MAX(start, pos->start); -+ r = MIN(start + size, pos->start + pos->size); -+ if (l < r) { -+ if ((start <= pos->start) && (start + size >= pos->start + pos->size)) { -+ QTAILQ_FOREACH(shl, shared_region_listeners, next) { -+ listener = shl->listener; -+ as = shl->as; -+ section = memory_region_find(as->root, pos->start, pos->size); -+ if (!section.mr) { -+ goto end; -+ } -+ if (listener->region_del) { -+ listener->region_del(listener, §ion); -+ } -+ memory_region_unref(section.mr); -+ } -+ -+ QTAILQ_REMOVE(&s->dma_map_regions_list, pos, list); -+ g_free(pos); -+ } -+ break; -+ } -+ if ((start + size) <= curr_end) { -+ break; -+ } -+ } -+end: -+ qemu_mutex_unlock(&s->dma_map_regions_list_mutex); -+ return; -+} -diff --git a/target/i386/csv.h b/target/i386/csv.h -index 6444d54ef..0c402cefd 100644 ---- a/target/i386/csv.h -+++ b/target/i386/csv.h -@@ -15,6 +15,8 @@ - #define I386_CSV_H - - #include "qapi/qapi-commands-misc-target.h" -+#include "qemu/thread.h" -+#include "qemu/queue.h" - #include "sev.h" - - #ifdef CONFIG_CSV -@@ -73,12 +75,19 @@ int csv_load_incoming_cpu_state(QEMUFile *f); - /* CSV3 */ - #define GUEST_POLICY_CSV3_BIT (1 << 6) - -+struct dma_map_region { -+ uint64_t start, size; -+ QTAILQ_ENTRY(dma_map_region) list; -+}; -+ - struct Csv3GuestState { - uint32_t policy; - int sev_fd; - void *state; - int (*sev_ioctl)(int fd, int cmd, void *data, int *error); - const char *(*fw_error_to_str)(int code); -+ QTAILQ_HEAD(, dma_map_region) dma_map_regions_list; -+ QemuMutex dma_map_regions_list_mutex; - }; - - typedef struct Csv3GuestState Csv3GuestState; -@@ -89,4 +98,7 @@ extern int csv3_launch_encrypt_vmcb(void); - - int csv3_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp); - -+int csv3_shared_region_dma_map(uint64_t start, uint64_t end); -+void csv3_shared_region_dma_unmap(uint64_t start, uint64_t end); -+ - #endif -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index 2866a6d0e..925f4f804 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -5026,8 +5026,10 @@ static int kvm_handle_exit_hypercall(X86CPU *cpu, struct kvm_run *run) - - if (enc) { - sev_remove_shared_regions_list(gfn_start, gfn_end); -+ csv3_shared_region_dma_unmap(gpa, gfn_end << TARGET_PAGE_BITS); - } else { - sev_add_shared_regions_list(gfn_start, gfn_end); -+ csv3_shared_region_dma_map(gpa, gfn_end << TARGET_PAGE_BITS); - } - } - return 0; --- -2.31.1 - diff --git a/1042-linux-headers-update-kernel-headers-to-include-CSV3-.patch b/1042-linux-headers-update-kernel-headers-to-include-CSV3-.patch deleted file mode 100644 index ee137076f3888a9332d71ba8536b322bcf05a4a0..0000000000000000000000000000000000000000 --- a/1042-linux-headers-update-kernel-headers-to-include-CSV3-.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 9a1d0fdf779053eba4ba380adeef54d126b87b7b Mon Sep 17 00:00:00 2001 -From: jiangxin -Date: Fri, 17 Jun 2022 09:25:19 +0800 -Subject: [PATCH 10/14] linux-headers: update kernel headers to include CSV3 - migration cmds - -Four new migration commands are added to support CSV3 migration. - -KVM_CSV3_SEND_ENCRYPT_DATA/KVM_CSV3_RECEIVE_ENCRYPT_DATA cmds are -used to migrate guest's pages. - -KVM_CSV3_SEND_ENCRYPT_CONTEXT/KVM_CSV3_RECEIVE_ENCRYPT_CONTEXT cmds -are used to migration guest's runtime context. - -Signed-off-by: Xin Jiang -Signed-off-by: hanliyang ---- - linux-headers/linux/kvm.h | 38 ++++++++++++++++++++++++++++++++++++++ - 1 file changed, 38 insertions(+) - -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index 061b2e7f0..6edf0b33a 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -2067,6 +2067,12 @@ enum csv3_cmd_id { - KVM_CSV3_INIT = KVM_CSV3_NR_MIN, - KVM_CSV3_LAUNCH_ENCRYPT_DATA, - KVM_CSV3_LAUNCH_ENCRYPT_VMCB, -+ KVM_CSV3_SEND_ENCRYPT_DATA, -+ KVM_CSV3_SEND_ENCRYPT_CONTEXT, -+ KVM_CSV3_RECEIVE_ENCRYPT_DATA, -+ KVM_CSV3_RECEIVE_ENCRYPT_CONTEXT, -+ -+ KVM_CSV3_NR_MAX, - }; - - struct kvm_csv3_launch_encrypt_data { -@@ -2079,6 +2085,38 @@ struct kvm_csv3_init_data { - __u64 nodemask; - }; - -+struct kvm_csv3_send_encrypt_data { -+ __u64 hdr_uaddr; -+ __u32 hdr_len; -+ __u64 guest_addr_data; -+ __u32 guest_addr_len; -+ __u64 trans_uaddr; -+ __u32 trans_len; -+}; -+ -+struct kvm_csv3_send_encrypt_context { -+ __u64 hdr_uaddr; -+ __u32 hdr_len; -+ __u64 trans_uaddr; -+ __u32 trans_len; -+}; -+ -+struct kvm_csv3_receive_encrypt_data { -+ __u64 hdr_uaddr; -+ __u32 hdr_len; -+ __u64 guest_addr_data; -+ __u32 guest_addr_len; -+ __u64 trans_uaddr; -+ __u32 trans_len; -+}; -+ -+struct kvm_csv3_receive_encrypt_context { -+ __u64 hdr_uaddr; -+ __u32 hdr_len; -+ __u64 trans_uaddr; -+ __u32 trans_len; -+}; -+ - #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) - #define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1) - #define KVM_DEV_ASSIGN_MASK_INTX (1 << 2) --- -2.31.1 - diff --git a/1043-target-i386-csv-Add-support-to-migrate-the-outgoing-.patch b/1043-target-i386-csv-Add-support-to-migrate-the-outgoing-.patch deleted file mode 100644 index 079568af057072be1c64ac30714e732fc18394df..0000000000000000000000000000000000000000 --- a/1043-target-i386-csv-Add-support-to-migrate-the-outgoing-.patch +++ /dev/null @@ -1,454 +0,0 @@ -From 161f1fdbd8cc76f8859a0f1d92dd3a179cd426e5 Mon Sep 17 00:00:00 2001 -From: jiangxin -Date: Fri, 17 Jun 2022 09:37:56 +0800 -Subject: [PATCH 11/14] target/i386: csv: Add support to migrate the outgoing - page for CSV3 guest - -The csv3_send_encrypt_data() provides the method to encrypt the -guest's private pages during migration. The routine is similar to -CSV2's. Usually, it starts with a SEND_START command to create the -migration context. Then SEND_ENCRYPT_DATA command is performed to -encrypt guest pages. After migration is completed, a SEND_FINISH -command is performed to the firmware. - -Signed-off-by: Jiang Xin -Signed-off-by: hanliyang ---- - migration/ram.c | 87 ++++++++++++++++++ - target/i386/csv.c | 184 +++++++++++++++++++++++++++++++++++++++ - target/i386/csv.h | 22 +++++ - target/i386/sev.c | 14 ++- - target/i386/sev.h | 1 + - target/i386/trace-events | 1 + - 6 files changed, 308 insertions(+), 1 deletion(-) - -diff --git a/migration/ram.c b/migration/ram.c -index 198b06000..71353bc90 100644 ---- a/migration/ram.c -+++ b/migration/ram.c -@@ -2478,6 +2478,90 @@ ram_save_encrypted_pages_in_batch(RAMState *rs, PageSearchStatus *pss) - } - #endif - -+/** -+ * ram_save_csv3_pages - send the given csv3 VM pages to the stream -+ */ -+static int ram_save_csv3_pages(RAMState *rs, PageSearchStatus *pss) -+{ -+ bool page_dirty; -+ int ret; -+ int tmppages, pages = 0; -+ uint8_t *p; -+ uint32_t host_len = 0; -+ uint64_t bytes_xmit = 0; -+ RAMBlock *block = pss->block; -+ ram_addr_t offset = 0; -+ hwaddr paddr = RAM_ADDR_INVALID; -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ ConfidentialGuestSupportClass *cgs_class = -+ (ConfidentialGuestSupportClass *) object_get_class(OBJECT(ms->cgs)); -+ struct ConfidentialGuestMemoryEncryptionOps *ops = -+ cgs_class->memory_encryption_ops; -+ -+ if (!kvm_csv3_enabled()) -+ return 0; -+ -+ do { -+ page_dirty = migration_bitmap_clear_dirty(rs, block, pss->page); -+ -+ /* Check the pages is dirty and if it is send it */ -+ if (page_dirty) { -+ ret = kvm_physical_memory_addr_from_host(kvm_state, -+ block->host + (pss->page << TARGET_PAGE_BITS), &paddr); -+ /* Process ROM or MMIO */ -+ if (paddr == RAM_ADDR_INVALID || -+ memory_region_is_rom(block->mr)) { -+ tmppages = migration_ops->ram_save_target_page(rs, pss); -+ } else { -+ /* Caculate the offset and host virtual address of the page */ -+ offset = pss->page << TARGET_PAGE_BITS; -+ p = block->host + offset; -+ -+ if (ops->queue_outgoing_page(p, TARGET_PAGE_SIZE, offset)) -+ return -1; -+ -+ tmppages = 1; -+ host_len += TARGET_PAGE_SIZE; -+ -+ stat64_add(&mig_stats.normal_pages, 1); -+ } -+ } else { -+ tmppages = 0; -+ } -+ -+ if (tmppages >= 0) { -+ pages += tmppages; -+ } else { -+ return tmppages; -+ } -+ -+ pss_find_next_dirty(pss); -+ } while (offset_in_ramblock(block, -+ ((ram_addr_t)pss->page) << TARGET_PAGE_BITS) && -+ host_len < CSV3_OUTGOING_PAGE_WINDOW_SIZE); -+ -+ /* Check if there are any queued pages */ -+ if (host_len != 0) { -+ /* Always set offset as 0 for csv3. */ -+ ram_transferred_add(save_page_header(pss, pss->pss_channel, -+ block, 0 | RAM_SAVE_FLAG_ENCRYPTED_DATA)); -+ -+ qemu_put_be32(pss->pss_channel, RAM_SAVE_ENCRYPTED_PAGE); -+ ram_transferred_add(4); -+ /* Process the queued pages in batch */ -+ ret = ops->save_queued_outgoing_pages(pss->pss_channel, &bytes_xmit); -+ if (ret) { -+ return -1; -+ } -+ ram_transferred_add(bytes_xmit); -+ } -+ -+ /* The offset we leave with is the last one we looked at */ -+ pss->page--; -+ -+ return pages; -+} -+ - /** - * ram_save_host_page: save a whole host page - * -@@ -2513,6 +2597,9 @@ static int ram_save_host_page(RAMState *rs, PageSearchStatus *pss) - return 0; - } - -+ if (kvm_csv3_enabled()) -+ return ram_save_csv3_pages(rs, pss); -+ - #ifdef CONFIG_HYGON_CSV_MIG_ACCEL - /* - * If command_batch function is enabled and memory encryption is enabled -diff --git a/target/i386/csv.c b/target/i386/csv.c -index 5823c8994..ffa5a73a7 100644 ---- a/target/i386/csv.c -+++ b/target/i386/csv.c -@@ -16,8 +16,13 @@ - #include "qapi/error.h" - #include "sysemu/kvm.h" - #include "exec/address-spaces.h" -+#include "migration/blocker.h" -+#include "migration/qemu-file.h" -+#include "migration/misc.h" -+#include "monitor/monitor.h" - - #include -+#include - - #ifdef CONFIG_NUMA - #include -@@ -30,6 +35,19 @@ - - bool csv_kvm_cpu_reset_inhibit; - -+struct ConfidentialGuestMemoryEncryptionOps csv3_memory_encryption_ops = { -+ .save_setup = sev_save_setup, -+ .save_outgoing_page = NULL, -+ .is_gfn_in_unshared_region = NULL, -+ .save_outgoing_shared_regions_list = sev_save_outgoing_shared_regions_list, -+ .load_incoming_shared_regions_list = sev_load_incoming_shared_regions_list, -+ .queue_outgoing_page = csv3_queue_outgoing_page, -+ .save_queued_outgoing_pages = csv3_save_queued_outgoing_pages, -+}; -+ -+#define CSV3_OUTGOING_PAGE_NUM \ -+ (CSV3_OUTGOING_PAGE_WINDOW_SIZE / TARGET_PAGE_SIZE) -+ - Csv3GuestState csv3_guest = { 0 }; - - int -@@ -70,6 +88,7 @@ csv3_init(uint32_t policy, int fd, void *state, struct sev_ops *ops) - csv3_guest.fw_error_to_str = ops->fw_error_to_str; - QTAILQ_INIT(&csv3_guest.dma_map_regions_list); - qemu_mutex_init(&csv3_guest.dma_map_regions_list_mutex); -+ csv3_guest.sev_send_start = ops->sev_send_start; - } - return 0; - } -@@ -301,3 +320,168 @@ end: - qemu_mutex_unlock(&s->dma_map_regions_list_mutex); - return; - } -+ -+static inline hwaddr csv3_hva_to_gfn(uint8_t *ptr) -+{ -+ ram_addr_t offset = RAM_ADDR_INVALID; -+ -+ kvm_physical_memory_addr_from_host(kvm_state, ptr, &offset); -+ -+ return offset >> TARGET_PAGE_BITS; -+} -+ -+static int -+csv3_send_start(QEMUFile *f, uint64_t *bytes_sent) -+{ -+ if (csv3_guest.sev_send_start) -+ return csv3_guest.sev_send_start(f, bytes_sent); -+ else -+ return -1; -+} -+ -+static int -+csv3_send_get_packet_len(int *fw_err) -+{ -+ int ret; -+ struct kvm_csv3_send_encrypt_data update = {0}; -+ -+ update.hdr_len = 0; -+ update.trans_len = 0; -+ ret = csv3_ioctl(KVM_CSV3_SEND_ENCRYPT_DATA, &update, fw_err); -+ if (*fw_err != SEV_RET_INVALID_LEN) { -+ error_report("%s: failed to get session length ret=%d fw_error=%d '%s'", -+ __func__, ret, *fw_err, fw_error_to_str(*fw_err)); -+ ret = 0; -+ goto err; -+ } -+ -+ if (update.hdr_len <= INT_MAX) -+ ret = update.hdr_len; -+ else -+ ret = 0; -+ -+err: -+ return ret; -+} -+ -+static int -+csv3_send_encrypt_data(Csv3GuestState *s, QEMUFile *f, -+ uint8_t *ptr, uint32_t size, uint64_t *bytes_sent) -+{ -+ int ret, fw_error = 0; -+ guchar *trans; -+ uint32_t guest_addr_entry_num; -+ uint32_t i; -+ struct kvm_csv3_send_encrypt_data update = { }; -+ -+ /* -+ * If this is first call then query the packet header bytes and allocate -+ * the packet buffer. -+ */ -+ if (!s->send_packet_hdr) { -+ s->send_packet_hdr_len = csv3_send_get_packet_len(&fw_error); -+ if (s->send_packet_hdr_len < 1) { -+ error_report("%s: SEND_UPDATE fw_error=%d '%s'", -+ __func__, fw_error, fw_error_to_str(fw_error)); -+ return 1; -+ } -+ -+ s->send_packet_hdr = g_new(gchar, s->send_packet_hdr_len); -+ } -+ -+ if (!s->guest_addr_len || !s->guest_addr_data) { -+ error_report("%s: invalid host address or size", __func__); -+ return 1; -+ } else { -+ guest_addr_entry_num = s->guest_addr_len / sizeof(struct guest_addr_entry); -+ } -+ -+ /* allocate transport buffer */ -+ trans = g_new(guchar, guest_addr_entry_num * TARGET_PAGE_SIZE); -+ -+ update.hdr_uaddr = (uintptr_t)s->send_packet_hdr; -+ update.hdr_len = s->send_packet_hdr_len; -+ update.guest_addr_data = (uintptr_t)s->guest_addr_data; -+ update.guest_addr_len = s->guest_addr_len; -+ update.trans_uaddr = (uintptr_t)trans; -+ update.trans_len = guest_addr_entry_num * TARGET_PAGE_SIZE; -+ -+ trace_kvm_csv3_send_encrypt_data(trans, update.trans_len); -+ -+ ret = csv3_ioctl(KVM_CSV3_SEND_ENCRYPT_DATA, &update, &fw_error); -+ if (ret) { -+ error_report("%s: SEND_ENCRYPT_DATA ret=%d fw_error=%d '%s'", -+ __func__, ret, fw_error, fw_error_to_str(fw_error)); -+ goto err; -+ } -+ -+ for (i = 0; i < guest_addr_entry_num; i++) { -+ if (s->guest_addr_data[i].share) -+ memcpy(trans + i * TARGET_PAGE_SIZE, (guchar *)s->guest_hva_data[i].hva, -+ TARGET_PAGE_SIZE); -+ } -+ -+ qemu_put_be32(f, update.hdr_len); -+ qemu_put_buffer(f, (uint8_t *)update.hdr_uaddr, update.hdr_len); -+ *bytes_sent += 4 + update.hdr_len; -+ -+ qemu_put_be32(f, update.guest_addr_len); -+ qemu_put_buffer(f, (uint8_t *)update.guest_addr_data, update.guest_addr_len); -+ *bytes_sent += 4 + update.guest_addr_len; -+ -+ qemu_put_be32(f, update.trans_len); -+ qemu_put_buffer(f, (uint8_t *)update.trans_uaddr, update.trans_len); -+ *bytes_sent += (4 + update.trans_len); -+ -+err: -+ s->guest_addr_len = 0; -+ g_free(trans); -+ return ret; -+} -+ -+int -+csv3_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr) -+{ -+ Csv3GuestState *s = &csv3_guest; -+ uint32_t i = 0; -+ -+ (void) addr; -+ -+ if (!s->guest_addr_data) { -+ s->guest_hva_data = g_new0(struct guest_hva_entry, CSV3_OUTGOING_PAGE_NUM); -+ s->guest_addr_data = g_new0(struct guest_addr_entry, CSV3_OUTGOING_PAGE_NUM); -+ s->guest_addr_len = 0; -+ } -+ -+ if (s->guest_addr_len >= sizeof(struct guest_addr_entry) * CSV3_OUTGOING_PAGE_NUM) { -+ error_report("Failed to queue outgoing page"); -+ return 1; -+ } -+ -+ i = s->guest_addr_len / sizeof(struct guest_addr_entry); -+ s->guest_hva_data[i].hva = (uintptr_t)ptr; -+ s->guest_addr_data[i].share = 0; -+ s->guest_addr_data[i].reserved = 0; -+ s->guest_addr_data[i].gfn = csv3_hva_to_gfn(ptr); -+ s->guest_addr_len += sizeof(struct guest_addr_entry); -+ -+ return 0; -+} -+ -+int -+csv3_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent) -+{ -+ Csv3GuestState *s = &csv3_guest; -+ -+ /* -+ * If this is a first buffer then create outgoing encryption context -+ * and write our PDH, policy and session data. -+ */ -+ if (!csv3_check_state(SEV_STATE_SEND_UPDATE) && -+ csv3_send_start(f, bytes_sent)) { -+ error_report("Failed to create outgoing context"); -+ return 1; -+ } -+ -+ return csv3_send_encrypt_data(s, f, NULL, 0, bytes_sent); -+} -diff --git a/target/i386/csv.h b/target/i386/csv.h -index 0c402cefd..e808bea61 100644 ---- a/target/i386/csv.h -+++ b/target/i386/csv.h -@@ -80,6 +80,18 @@ struct dma_map_region { - QTAILQ_ENTRY(dma_map_region) list; - }; - -+#define CSV3_OUTGOING_PAGE_WINDOW_SIZE (512 * TARGET_PAGE_SIZE) -+ -+struct guest_addr_entry { -+ uint64_t share: 1; -+ uint64_t reserved: 11; -+ uint64_t gfn: 52; -+}; -+ -+struct guest_hva_entry { -+ uint64_t hva; -+}; -+ - struct Csv3GuestState { - uint32_t policy; - int sev_fd; -@@ -88,11 +100,19 @@ struct Csv3GuestState { - const char *(*fw_error_to_str)(int code); - QTAILQ_HEAD(, dma_map_region) dma_map_regions_list; - QemuMutex dma_map_regions_list_mutex; -+ gchar *send_packet_hdr; -+ size_t send_packet_hdr_len; -+ struct guest_hva_entry *guest_hva_data; -+ struct guest_addr_entry *guest_addr_data; -+ size_t guest_addr_len; -+ -+ int (*sev_send_start)(QEMUFile *f, uint64_t *bytes_sent); - }; - - typedef struct Csv3GuestState Csv3GuestState; - - extern struct Csv3GuestState csv3_guest; -+extern struct ConfidentialGuestMemoryEncryptionOps csv3_memory_encryption_ops; - extern int csv3_init(uint32_t policy, int fd, void *state, struct sev_ops *ops); - extern int csv3_launch_encrypt_vmcb(void); - -@@ -100,5 +120,7 @@ int csv3_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp); - - int csv3_shared_region_dma_map(uint64_t start, uint64_t end); - void csv3_shared_region_dma_unmap(uint64_t start, uint64_t end); -+int csv3_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr); -+int csv3_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent); - - #endif -diff --git a/target/i386/sev.c b/target/i386/sev.c -index eb1026b57..465b62cb7 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -1225,7 +1225,11 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - qemu_add_vm_change_state_handler(sev_vm_state_change, sev); - migration_add_notifier(&sev_migration_state, sev_migration_state_notifier); - -- cgs_class->memory_encryption_ops = &sev_memory_encryption_ops; -+ if (csv3_enabled()) { -+ cgs_class->memory_encryption_ops = &csv3_memory_encryption_ops; -+ } else { -+ cgs_class->memory_encryption_ops = &sev_memory_encryption_ops; -+ } - QTAILQ_INIT(&sev->shared_regions_list); - - /* Determine whether support MSR_AMD64_SEV_ES_GHCB */ -@@ -2608,9 +2612,17 @@ bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp) - return ret; - } - -+static int _sev_send_start(QEMUFile *f, uint64_t *bytes_sent) -+{ -+ SevGuestState *s = sev_guest; -+ -+ return sev_send_start(s, f, bytes_sent); -+} -+ - struct sev_ops sev_ops = { - .sev_ioctl = sev_ioctl, - .fw_error_to_str = fw_error_to_str, -+ .sev_send_start = _sev_send_start, - }; - - static void -diff --git a/target/i386/sev.h b/target/i386/sev.h -index e91431e0f..8ccef22a9 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -83,6 +83,7 @@ extern bool sev_kvm_has_msr_ghcb; - struct sev_ops { - int (*sev_ioctl)(int fd, int cmd, void *data, int *error); - const char *(*fw_error_to_str)(int code); -+ int (*sev_send_start)(QEMUFile *f, uint64_t *bytes_sent); - }; - - extern struct sev_ops sev_ops; -diff --git a/target/i386/trace-events b/target/i386/trace-events -index e07061bf3..6ebb644cb 100644 ---- a/target/i386/trace-events -+++ b/target/i386/trace-events -@@ -22,3 +22,4 @@ kvm_sev_receive_update_vmsa(uint32_t cpu_id, uint32_t cpu_index, void *src, int - - # csv.c - kvm_csv3_launch_encrypt_data(uint64_t gpa, void *addr, uint64_t len) "gpa 0x%" PRIx64 "addr %p len 0x%" PRIu64 -+kvm_csv3_send_encrypt_data(void *dst, int len) "trans %p len %d" --- -2.31.1 - diff --git a/1044-target-i386-csv-Add-support-to-migrate-the-incoming-.patch b/1044-target-i386-csv-Add-support-to-migrate-the-incoming-.patch deleted file mode 100644 index 306d8e2f46f9b2b16910ef92340333ee98ef108d..0000000000000000000000000000000000000000 --- a/1044-target-i386-csv-Add-support-to-migrate-the-incoming-.patch +++ /dev/null @@ -1,205 +0,0 @@ -From e1ed25546ed0c9b1ae43c99131ef7910db6d03eb Mon Sep 17 00:00:00 2001 -From: jiangxin -Date: Fri, 17 Jun 2022 09:45:45 +0800 -Subject: [PATCH 12/14] target/i386: csv: Add support to migrate the incoming - page for CSV3 guest - -The csv3_receive_encrypt_data() provides the method to read incoming -guest private pages from socket and load them into guest memory. -The routine is similar to CSV2's. Usually, it starts with a RECEIVE -START command to create the migration context. Then RECEIVE ENCRYPT -DATA command is performed to let the firmware load incoming pages -into guest memory. After migration is completed, a RECEIVE FINISH -command is performed to the firmware. - -Signed-off-by: Jiang Xin -Signed-off-by: hanliyang ---- - target/i386/csv.c | 87 ++++++++++++++++++++++++++++++++++++++++ - target/i386/csv.h | 2 + - target/i386/sev.c | 8 ++++ - target/i386/sev.h | 1 + - target/i386/trace-events | 1 + - 5 files changed, 99 insertions(+) - -diff --git a/target/i386/csv.c b/target/i386/csv.c -index ffa5a73a7..81407e3c2 100644 ---- a/target/i386/csv.c -+++ b/target/i386/csv.c -@@ -38,11 +38,14 @@ bool csv_kvm_cpu_reset_inhibit; - struct ConfidentialGuestMemoryEncryptionOps csv3_memory_encryption_ops = { - .save_setup = sev_save_setup, - .save_outgoing_page = NULL, -+ .load_incoming_page = csv3_load_incoming_page, - .is_gfn_in_unshared_region = NULL, - .save_outgoing_shared_regions_list = sev_save_outgoing_shared_regions_list, - .load_incoming_shared_regions_list = sev_load_incoming_shared_regions_list, - .queue_outgoing_page = csv3_queue_outgoing_page, - .save_queued_outgoing_pages = csv3_save_queued_outgoing_pages, -+ .queue_incoming_page = NULL, -+ .load_queued_incoming_pages = NULL, - }; - - #define CSV3_OUTGOING_PAGE_NUM \ -@@ -89,6 +92,7 @@ csv3_init(uint32_t policy, int fd, void *state, struct sev_ops *ops) - QTAILQ_INIT(&csv3_guest.dma_map_regions_list); - qemu_mutex_init(&csv3_guest.dma_map_regions_list_mutex); - csv3_guest.sev_send_start = ops->sev_send_start; -+ csv3_guest.sev_receive_start = ops->sev_receive_start; - } - return 0; - } -@@ -485,3 +489,86 @@ csv3_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent) - - return csv3_send_encrypt_data(s, f, NULL, 0, bytes_sent); - } -+ -+static int -+csv3_receive_start(QEMUFile *f) -+{ -+ if (csv3_guest.sev_receive_start) -+ return csv3_guest.sev_receive_start(f); -+ else -+ return -1; -+} -+ -+static int csv3_receive_encrypt_data(QEMUFile *f, uint8_t *ptr) -+{ -+ int ret = 1, fw_error = 0; -+ uint32_t i, guest_addr_entry_num; -+ gchar *hdr = NULL, *trans = NULL; -+ struct guest_addr_entry *guest_addr_data; -+ struct kvm_csv3_receive_encrypt_data update = {}; -+ void *hva = NULL; -+ MemoryRegion *mr = NULL; -+ -+ /* get packet header */ -+ update.hdr_len = qemu_get_be32(f); -+ -+ hdr = g_new(gchar, update.hdr_len); -+ qemu_get_buffer(f, (uint8_t *)hdr, update.hdr_len); -+ update.hdr_uaddr = (uintptr_t)hdr; -+ -+ /* get guest addr data */ -+ update.guest_addr_len = qemu_get_be32(f); -+ -+ guest_addr_data = (struct guest_addr_entry *)g_new(gchar, update.guest_addr_len); -+ qemu_get_buffer(f, (uint8_t *)guest_addr_data, update.guest_addr_len); -+ update.guest_addr_data = (uintptr_t)guest_addr_data; -+ -+ /* get transport buffer */ -+ update.trans_len = qemu_get_be32(f); -+ -+ trans = g_new(gchar, update.trans_len); -+ update.trans_uaddr = (uintptr_t)trans; -+ qemu_get_buffer(f, (uint8_t *)update.trans_uaddr, update.trans_len); -+ -+ /* update share memory. */ -+ guest_addr_entry_num = update.guest_addr_len / sizeof(struct guest_addr_entry); -+ for (i = 0; i < guest_addr_entry_num; i++) { -+ if (guest_addr_data[i].share) { -+ hva = gpa2hva(&mr, -+ ((uint64_t)guest_addr_data[i].gfn << TARGET_PAGE_BITS), -+ TARGET_PAGE_SIZE, -+ NULL); -+ if (hva) -+ memcpy(hva, trans + i * TARGET_PAGE_SIZE, TARGET_PAGE_SIZE); -+ } -+ } -+ -+ trace_kvm_csv3_receive_encrypt_data(trans, update.trans_len, hdr, update.hdr_len); -+ -+ ret = csv3_ioctl(KVM_CSV3_RECEIVE_ENCRYPT_DATA, &update, &fw_error); -+ if (ret) { -+ error_report("Error RECEIVE_ENCRYPT_DATA ret=%d fw_error=%d '%s'", -+ ret, fw_error, fw_error_to_str(fw_error)); -+ goto err; -+ } -+ -+err: -+ g_free(trans); -+ g_free(guest_addr_data); -+ g_free(hdr); -+ return ret; -+} -+ -+int csv3_load_incoming_page(QEMUFile *f, uint8_t *ptr) -+{ -+ /* -+ * If this is first buffer and SEV is not in recieiving state then -+ * use RECEIVE_START command to create a encryption context. -+ */ -+ if (!csv3_check_state(SEV_STATE_RECEIVE_UPDATE) && -+ csv3_receive_start(f)) { -+ return 1; -+ } -+ -+ return csv3_receive_encrypt_data(f, ptr); -+} -diff --git a/target/i386/csv.h b/target/i386/csv.h -index e808bea61..b0adae0a8 100644 ---- a/target/i386/csv.h -+++ b/target/i386/csv.h -@@ -107,6 +107,7 @@ struct Csv3GuestState { - size_t guest_addr_len; - - int (*sev_send_start)(QEMUFile *f, uint64_t *bytes_sent); -+ int (*sev_receive_start)(QEMUFile *f); - }; - - typedef struct Csv3GuestState Csv3GuestState; -@@ -120,6 +121,7 @@ int csv3_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp); - - int csv3_shared_region_dma_map(uint64_t start, uint64_t end); - void csv3_shared_region_dma_unmap(uint64_t start, uint64_t end); -+int csv3_load_incoming_page(QEMUFile *f, uint8_t *ptr); - int csv3_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr); - int csv3_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent); - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 465b62cb7..337f54415 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -2619,10 +2619,18 @@ static int _sev_send_start(QEMUFile *f, uint64_t *bytes_sent) - return sev_send_start(s, f, bytes_sent); - } - -+static int _sev_receive_start(QEMUFile *f) -+{ -+ SevGuestState *s = sev_guest; -+ -+ return sev_receive_start(s, f); -+} -+ - struct sev_ops sev_ops = { - .sev_ioctl = sev_ioctl, - .fw_error_to_str = fw_error_to_str, - .sev_send_start = _sev_send_start, -+ .sev_receive_start = _sev_receive_start, - }; - - static void -diff --git a/target/i386/sev.h b/target/i386/sev.h -index 8ccef22a9..647b426b1 100644 ---- a/target/i386/sev.h -+++ b/target/i386/sev.h -@@ -84,6 +84,7 @@ struct sev_ops { - int (*sev_ioctl)(int fd, int cmd, void *data, int *error); - const char *(*fw_error_to_str)(int code); - int (*sev_send_start)(QEMUFile *f, uint64_t *bytes_sent); -+ int (*sev_receive_start)(QEMUFile *f); - }; - - extern struct sev_ops sev_ops; -diff --git a/target/i386/trace-events b/target/i386/trace-events -index 6ebb644cb..9609fe3d5 100644 ---- a/target/i386/trace-events -+++ b/target/i386/trace-events -@@ -23,3 +23,4 @@ kvm_sev_receive_update_vmsa(uint32_t cpu_id, uint32_t cpu_index, void *src, int - # csv.c - kvm_csv3_launch_encrypt_data(uint64_t gpa, void *addr, uint64_t len) "gpa 0x%" PRIx64 "addr %p len 0x%" PRIu64 - kvm_csv3_send_encrypt_data(void *dst, int len) "trans %p len %d" -+kvm_csv3_receive_encrypt_data(void *dst, int len, void *hdr, int hdr_len) "trans %p len %d hdr %p hdr_len %d" --- -2.31.1 - diff --git a/1045-target-i386-csv-Add-support-to-migrate-the-outgoing-.patch b/1045-target-i386-csv-Add-support-to-migrate-the-outgoing-.patch deleted file mode 100644 index 3bfdb71f8568c772cf2ae359833a750abb1b9d5b..0000000000000000000000000000000000000000 --- a/1045-target-i386-csv-Add-support-to-migrate-the-outgoing-.patch +++ /dev/null @@ -1,139 +0,0 @@ -From 434ad630110cd376ea184a11572ec72961e679a4 Mon Sep 17 00:00:00 2001 -From: jiangxin -Date: Fri, 17 Jun 2022 09:52:31 +0800 -Subject: [PATCH 13/14] target/i386: csv: Add support to migrate the outgoing - context for CSV3 guest - -CSV3 needs to migrate guest cpu's context pages. Prior to migration -of the context, it should query transfer buffer length and header -data length by SEND ENCRYPT CONTEXT command. New migration flag -RAM_SAVE_ENCRYPTED_CSV3_CONTEXT is defined for CSV3. - -Signed-off-by: Jiang Xin -Signed-off-by: hanliyang ---- - target/i386/csv.c | 81 ++++++++++++++++++++++++++++++++++++++++ - target/i386/csv.h | 1 + - target/i386/trace-events | 1 + - 3 files changed, 83 insertions(+) - -diff --git a/target/i386/csv.c b/target/i386/csv.c -index 81407e3c2..1560db680 100644 ---- a/target/i386/csv.c -+++ b/target/i386/csv.c -@@ -46,6 +46,7 @@ struct ConfidentialGuestMemoryEncryptionOps csv3_memory_encryption_ops = { - .save_queued_outgoing_pages = csv3_save_queued_outgoing_pages, - .queue_incoming_page = NULL, - .load_queued_incoming_pages = NULL, -+ .save_outgoing_cpu_state = csv3_save_outgoing_context, - }; - - #define CSV3_OUTGOING_PAGE_NUM \ -@@ -572,3 +573,83 @@ int csv3_load_incoming_page(QEMUFile *f, uint8_t *ptr) - - return csv3_receive_encrypt_data(f, ptr); - } -+ -+static int -+csv3_send_get_context_len(int *fw_err, int *context_len, int *hdr_len) -+{ -+ int ret = 0; -+ struct kvm_csv3_send_encrypt_context update = { 0 }; -+ -+ ret = csv3_ioctl(KVM_CSV3_SEND_ENCRYPT_CONTEXT, &update, fw_err); -+ if (*fw_err != SEV_RET_INVALID_LEN) { -+ error_report("%s: failed to get context length ret=%d fw_error=%d '%s'", -+ __func__, ret, *fw_err, fw_error_to_str(*fw_err)); -+ ret = -1; -+ goto err; -+ } -+ -+ if (update.trans_len <= INT_MAX && update.hdr_len <= INT_MAX) { -+ *context_len = update.trans_len; -+ *hdr_len = update.hdr_len; -+ } -+ ret = 0; -+err: -+ return ret; -+} -+ -+static int -+csv3_send_encrypt_context(Csv3GuestState *s, QEMUFile *f, uint64_t *bytes_sent) -+{ -+ int ret, fw_error = 0; -+ int context_len = 0; -+ int hdr_len = 0; -+ guchar *trans; -+ guchar *hdr; -+ struct kvm_csv3_send_encrypt_context update = { }; -+ -+ ret = csv3_send_get_context_len(&fw_error, &context_len, &hdr_len); -+ if (context_len < 1 || hdr_len < 1) { -+ error_report("%s: fail to get context length fw_error=%d '%s'", -+ __func__, fw_error, fw_error_to_str(fw_error)); -+ return 1; -+ } -+ -+ /* allocate transport buffer */ -+ trans = g_new(guchar, context_len); -+ hdr = g_new(guchar, hdr_len); -+ -+ update.hdr_uaddr = (uintptr_t)hdr; -+ update.hdr_len = hdr_len; -+ update.trans_uaddr = (uintptr_t)trans; -+ update.trans_len = context_len; -+ -+ trace_kvm_csv3_send_encrypt_context(trans, update.trans_len); -+ -+ ret = csv3_ioctl(KVM_CSV3_SEND_ENCRYPT_CONTEXT, &update, &fw_error); -+ if (ret) { -+ error_report("%s: SEND_ENCRYPT_CONTEXT ret=%d fw_error=%d '%s'", -+ __func__, ret, fw_error, fw_error_to_str(fw_error)); -+ goto err; -+ } -+ -+ qemu_put_be32(f, update.hdr_len); -+ qemu_put_buffer(f, (uint8_t *)update.hdr_uaddr, update.hdr_len); -+ *bytes_sent += 4 + update.hdr_len; -+ -+ qemu_put_be32(f, update.trans_len); -+ qemu_put_buffer(f, (uint8_t *)update.trans_uaddr, update.trans_len); -+ *bytes_sent += 4 + update.trans_len; -+ -+err: -+ g_free(trans); -+ g_free(hdr); -+ return ret; -+} -+ -+int csv3_save_outgoing_context(QEMUFile *f, uint64_t *bytes_sent) -+{ -+ Csv3GuestState *s = &csv3_guest; -+ -+ /* send csv3 context. */ -+ return csv3_send_encrypt_context(s, f, bytes_sent); -+} -diff --git a/target/i386/csv.h b/target/i386/csv.h -index b0adae0a8..e9b8e00c9 100644 ---- a/target/i386/csv.h -+++ b/target/i386/csv.h -@@ -124,5 +124,6 @@ void csv3_shared_region_dma_unmap(uint64_t start, uint64_t end); - int csv3_load_incoming_page(QEMUFile *f, uint8_t *ptr); - int csv3_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr); - int csv3_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent); -+int csv3_save_outgoing_context(QEMUFile *f, uint64_t *bytes_sent); - - #endif -diff --git a/target/i386/trace-events b/target/i386/trace-events -index 9609fe3d5..31a2418bb 100644 ---- a/target/i386/trace-events -+++ b/target/i386/trace-events -@@ -23,4 +23,5 @@ kvm_sev_receive_update_vmsa(uint32_t cpu_id, uint32_t cpu_index, void *src, int - # csv.c - kvm_csv3_launch_encrypt_data(uint64_t gpa, void *addr, uint64_t len) "gpa 0x%" PRIx64 "addr %p len 0x%" PRIu64 - kvm_csv3_send_encrypt_data(void *dst, int len) "trans %p len %d" -+kvm_csv3_send_encrypt_context(void *dst, int len) "trans %p len %d" - kvm_csv3_receive_encrypt_data(void *dst, int len, void *hdr, int hdr_len) "trans %p len %d hdr %p hdr_len %d" --- -2.31.1 - diff --git a/1046-target-i386-csv-Add-support-to-migrate-the-incoming-.patch b/1046-target-i386-csv-Add-support-to-migrate-the-incoming-.patch deleted file mode 100644 index f23e7401b31d99cbca69df0fd0df989fda0ce554..0000000000000000000000000000000000000000 --- a/1046-target-i386-csv-Add-support-to-migrate-the-incoming-.patch +++ /dev/null @@ -1,110 +0,0 @@ -From e944da634c51c78e5fad793096c9ceba04ba3f19 Mon Sep 17 00:00:00 2001 -From: jiangxin -Date: Fri, 17 Jun 2022 10:00:46 +0800 -Subject: [PATCH 14/14] target/i386: csv: Add support to migrate the incoming - context for CSV3 guest - -The csv3_load_incoming_context() provides the method to read incoming -guest's context from socket. It loads them into guest private memory. -This is the last step during migration and RECEIVE FINISH command is -performed by then to complete the whole migration. - -Signed-off-by: Jiang Xin -Signed-off-by: hanliyang ---- - target/i386/csv.c | 45 ++++++++++++++++++++++++++++++++++++++++ - target/i386/csv.h | 1 + - target/i386/trace-events | 1 + - 3 files changed, 47 insertions(+) - -diff --git a/target/i386/csv.c b/target/i386/csv.c -index 1560db680..0593f9b19 100644 ---- a/target/i386/csv.c -+++ b/target/i386/csv.c -@@ -47,6 +47,7 @@ struct ConfidentialGuestMemoryEncryptionOps csv3_memory_encryption_ops = { - .queue_incoming_page = NULL, - .load_queued_incoming_pages = NULL, - .save_outgoing_cpu_state = csv3_save_outgoing_context, -+ .load_incoming_cpu_state = csv3_load_incoming_context, - }; - - #define CSV3_OUTGOING_PAGE_NUM \ -@@ -646,6 +647,42 @@ err: - return ret; - } - -+static int -+csv3_receive_encrypt_context(Csv3GuestState *s, QEMUFile *f) -+{ -+ int ret = 1, fw_error = 0; -+ gchar *hdr = NULL, *trans = NULL; -+ struct kvm_csv3_receive_encrypt_context update = {}; -+ -+ /* get packet header */ -+ update.hdr_len = qemu_get_be32(f); -+ -+ hdr = g_new(gchar, update.hdr_len); -+ qemu_get_buffer(f, (uint8_t *)hdr, update.hdr_len); -+ update.hdr_uaddr = (uintptr_t)hdr; -+ -+ /* get transport buffer */ -+ update.trans_len = qemu_get_be32(f); -+ -+ trans = g_new(gchar, update.trans_len); -+ update.trans_uaddr = (uintptr_t)trans; -+ qemu_get_buffer(f, (uint8_t *)update.trans_uaddr, update.trans_len); -+ -+ trace_kvm_csv3_receive_encrypt_context(trans, update.trans_len, hdr, update.hdr_len); -+ -+ ret = csv3_ioctl(KVM_CSV3_RECEIVE_ENCRYPT_CONTEXT, &update, &fw_error); -+ if (ret) { -+ error_report("Error RECEIVE_ENCRYPT_CONTEXT ret=%d fw_error=%d '%s'", -+ ret, fw_error, fw_error_to_str(fw_error)); -+ goto err; -+ } -+ -+err: -+ g_free(trans); -+ g_free(hdr); -+ return ret; -+} -+ - int csv3_save_outgoing_context(QEMUFile *f, uint64_t *bytes_sent) - { - Csv3GuestState *s = &csv3_guest; -@@ -653,3 +690,11 @@ int csv3_save_outgoing_context(QEMUFile *f, uint64_t *bytes_sent) - /* send csv3 context. */ - return csv3_send_encrypt_context(s, f, bytes_sent); - } -+ -+int csv3_load_incoming_context(QEMUFile *f) -+{ -+ Csv3GuestState *s = &csv3_guest; -+ -+ /* receive csv3 context. */ -+ return csv3_receive_encrypt_context(s, f); -+} -diff --git a/target/i386/csv.h b/target/i386/csv.h -index e9b8e00c9..bbe372498 100644 ---- a/target/i386/csv.h -+++ b/target/i386/csv.h -@@ -122,6 +122,7 @@ int csv3_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp); - int csv3_shared_region_dma_map(uint64_t start, uint64_t end); - void csv3_shared_region_dma_unmap(uint64_t start, uint64_t end); - int csv3_load_incoming_page(QEMUFile *f, uint8_t *ptr); -+int csv3_load_incoming_context(QEMUFile *f); - int csv3_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr); - int csv3_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent); - int csv3_save_outgoing_context(QEMUFile *f, uint64_t *bytes_sent); -diff --git a/target/i386/trace-events b/target/i386/trace-events -index 31a2418bb..515441c4f 100644 ---- a/target/i386/trace-events -+++ b/target/i386/trace-events -@@ -25,3 +25,4 @@ kvm_csv3_launch_encrypt_data(uint64_t gpa, void *addr, uint64_t len) "gpa 0x%" P - kvm_csv3_send_encrypt_data(void *dst, int len) "trans %p len %d" - kvm_csv3_send_encrypt_context(void *dst, int len) "trans %p len %d" - kvm_csv3_receive_encrypt_data(void *dst, int len, void *hdr, int hdr_len) "trans %p len %d hdr %p hdr_len %d" -+kvm_csv3_receive_encrypt_context(void *dst, int len, void *hdr, int hdr_len) "trans %p len %d hdr %p hdr_len %d" --- -2.31.1 - diff --git a/1047-target-i386-sev-Fix-incompatibility-between-SEV-and-.patch b/1047-target-i386-sev-Fix-incompatibility-between-SEV-and-.patch deleted file mode 100644 index 111042e113d7f6b4da8b00563a599e3f1fb3cdd3..0000000000000000000000000000000000000000 --- a/1047-target-i386-sev-Fix-incompatibility-between-SEV-and-.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 07177f6d3928d81a0c604df28efe4ac99ff96572 Mon Sep 17 00:00:00 2001 -From: hanliyang -Date: Fri, 1 Mar 2024 14:12:44 +0800 -Subject: [PATCH 1/2] target/i386: sev: Fix incompatibility between SEV and CSV - on the GET_ID API - -If the length of GET_ID request is too small, Hygon CSV will return -SEV_RET_INVALID_PARAM. This return code doesn't comply with SEV API -Spec. - -Hygon will consider to fix the compitibility issue of return value -of the GET_ID API, so also check whether the return value is -SEV_RET_INVALID_LEN on Hygon CPUs. - -Signed-off-by: hanliyang -Change-Id: I204e69817fbb97c6c81bea086af53d4c312895b4 ---- - target/i386/sev.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/target/i386/sev.c b/target/i386/sev.c -index 337f54415..95b16cc63 100644 ---- a/target/i386/sev.c -+++ b/target/i386/sev.c -@@ -589,7 +589,8 @@ static int sev_get_cpu0_id(int fd, guchar **id, size_t *id_len, Error **errp) - - /* query the ID length */ - r = sev_platform_ioctl(fd, SEV_GET_ID2, &get_id2, &err); -- if (r < 0 && err != SEV_RET_INVALID_LEN) { -+ if (r < 0 && err != SEV_RET_INVALID_LEN && -+ !(is_hygon_cpu() && err == SEV_RET_INVALID_PARAM)) { - error_setg(errp, "SEV: Failed to get ID ret=%d fw_err=%d (%s)", - r, err, fw_error_to_str(err)); - return 1; --- -2.31.1 - diff --git a/1048-target-i386-sev-Add-support-for-reuse-ASID-for-diffe.patch b/1048-target-i386-sev-Add-support-for-reuse-ASID-for-diffe.patch deleted file mode 100644 index 8ff070eea07f9376911bac6a8c3f7c61f51aeef9..0000000000000000000000000000000000000000 --- a/1048-target-i386-sev-Add-support-for-reuse-ASID-for-diffe.patch +++ /dev/null @@ -1,188 +0,0 @@ -From 61c644ba560b8dd7fef2180633b0aa0cb1998fcd Mon Sep 17 00:00:00 2001 -From: appleLin -Date: Wed, 3 Aug 2022 21:02:41 +0800 -Subject: [PATCH 2/2] target/i386: sev: Add support for reuse ASID for - different CSV guests - -In you want to reuse one ASID for many CSV guests, you should provide a -label (i.e. userid) and the length of the label when launch CSV guest. -The CSV guests which were provided the same userid will share the same -ASID. - -Signed-off-by: hanliyang -Change-Id: I929a7489b310f08535df67c231ee7b3cd9cee51e ---- - linux-headers/linux/kvm.h | 5 +++++ - qapi/qom.json | 5 ++++- - qemu-options.hx | 5 ++++- - target/i386/csv.h | 5 +++-- - target/i386/sev.c | 47 ++++++++++++++++++++++++++++++++++++++- - 5 files changed, 62 insertions(+), 5 deletions(-) - -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index 6edf0b33a..f67a7dde1 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -2060,6 +2060,11 @@ struct kvm_csv_command_batch { - __u64 csv_batch_list_uaddr; - }; - -+struct kvm_csv_init { -+ __u64 userid_addr; -+ __u32 len; -+}; -+ - /* CSV3 command */ - enum csv3_cmd_id { - KVM_CSV3_NR_MIN = 0xc0, -diff --git a/qapi/qom.json b/qapi/qom.json -index c53ef978f..89a2516b4 100644 ---- a/qapi/qom.json -+++ b/qapi/qom.json -@@ -866,6 +866,8 @@ - # designated guest firmware page for measured boot with -kernel - # (default: false) (since 6.2) - # -+# @user-id: the user id of the guest owner, only support on Hygon CPUs -+# - # Since: 2.12 - ## - { 'struct': 'SevGuestProperties', -@@ -876,7 +878,8 @@ - '*handle': 'uint32', - '*cbitpos': 'uint32', - 'reduced-phys-bits': 'uint32', -- '*kernel-hashes': 'bool' } } -+ '*kernel-hashes': 'bool', -+ '*user-id': 'str' } } - - ## - # @ThreadContextProperties: -diff --git a/qemu-options.hx b/qemu-options.hx -index 42fd09e4d..0bc184cd0 100644 ---- a/qemu-options.hx -+++ b/qemu-options.hx -@@ -5637,7 +5637,7 @@ SRST - -object secret,id=sec0,keyid=secmaster0,format=base64,\\ - data=$SECRET,iv=$(dh_cert_file = g_strdup(value); - } - -+static char * -+sev_guest_get_user_id(Object *obj, Error **errp) -+{ -+ SevGuestState *s = SEV_GUEST(obj); -+ -+ return g_strdup(s->user_id); -+} -+ -+static void -+sev_guest_set_user_id(Object *obj, const char *value, Error **errp) -+{ -+ SevGuestState *s = SEV_GUEST(obj); -+ -+ s->user_id = g_strdup(value); -+} -+ - static char * - sev_guest_get_sev_device(Object *obj, Error **errp) - { -@@ -426,6 +443,11 @@ sev_guest_class_init(ObjectClass *oc, void *data) - sev_guest_set_kernel_hashes); - object_class_property_set_description(oc, "kernel-hashes", - "add kernel hashes to guest firmware for measured Linux boot"); -+ object_class_property_add_str(oc, "user-id", -+ sev_guest_get_user_id, -+ sev_guest_set_user_id); -+ object_class_property_set_description(oc, "user-id", -+ "user id of the guest owner"); - } - - static void -@@ -1178,7 +1200,30 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) - } - - trace_kvm_sev_init(); -- ret = sev_ioctl(sev->sev_fd, cmd, NULL, &fw_error); -+ -+ /* Only support reuse asid for CSV/CSV2 guest */ -+ if (is_hygon_cpu() && -+ (sev_guest->policy & GUEST_POLICY_REUSE_ASID) && -+ !(sev_guest->policy & GUEST_POLICY_CSV3_BIT)) { -+ char *user_id = NULL; -+ struct kvm_csv_init *init_cmd_buf = NULL; -+ -+ user_id = object_property_get_str(OBJECT(sev), "user-id", NULL); -+ if (user_id && strlen(user_id)) { -+ init_cmd_buf = g_new0(struct kvm_csv_init, 1); -+ init_cmd_buf->len = strlen(user_id); -+ init_cmd_buf->userid_addr = (__u64)user_id; -+ } -+ ret = sev_ioctl(sev->sev_fd, cmd, init_cmd_buf, &fw_error); -+ -+ if (user_id) { -+ g_free(user_id); -+ g_free(init_cmd_buf); -+ } -+ } else { -+ ret = sev_ioctl(sev->sev_fd, cmd, NULL, &fw_error); -+ } -+ - if (ret) { - error_setg(errp, "%s: failed to initialize ret=%d fw_error=%d '%s'", - __func__, ret, fw_error, fw_error_to_str(fw_error)); --- -2.31.1 - diff --git a/1049-target-i386-Add-Hygon-Dhyana-v3-CPU-model.patch b/1049-target-i386-Add-Hygon-Dhyana-v3-CPU-model.patch deleted file mode 100644 index 1152322c62704603a7a926d85cd392606d55270b..0000000000000000000000000000000000000000 --- a/1049-target-i386-Add-Hygon-Dhyana-v3-CPU-model.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 3c8add582393a03c9e85fdececc0e4cea229be54 Mon Sep 17 00:00:00 2001 -From: Yanjing Zhou -Date: Tue, 16 Apr 2024 15:27:33 +0800 -Subject: [PATCH 1/2] target/i386: Add Hygon Dhyana-v3 CPU model - -Add the following feature bits for Dhyana CPU model: -perfctr-core, clzero, xsaveerptr, aes, pclmulqdq, sha-ni - -Disable xsaves feature bit for Erratum 1386 - -Signed-off-by: Yanjing Zhou ---- - target/i386/cpu.c | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index c01943ee6..1da8732c3 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -4658,6 +4658,20 @@ static const X86CPUDefinition builtin_x86_defs[] = { - { /* end of list */ } - }, - }, -+ { .version = 3, -+ .props = (PropValue[]) { -+ { "xsaves", "off" }, -+ { "perfctr-core", "on" }, -+ { "clzero", "on" }, -+ { "xsaveerptr", "on" }, -+ { "aes", "on" }, -+ { "pclmulqdq", "on" }, -+ { "sha-ni", "on" }, -+ { "model-id", -+ "Hygon Dhyana-v3 processor" }, -+ { /* end of list */ } -+ }, -+ }, - { /* end of list */ } - } - }, --- -2.41.0 - diff --git a/1050-target-i386-Add-new-Hygon-Dharma-CPU-model.patch b/1050-target-i386-Add-new-Hygon-Dharma-CPU-model.patch deleted file mode 100644 index 2ed71535c8b19893980499c60db413f471adbf38..0000000000000000000000000000000000000000 --- a/1050-target-i386-Add-new-Hygon-Dharma-CPU-model.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 6e3d78f1f63f9a2c2dd3c50dc81af222822da99d Mon Sep 17 00:00:00 2001 -From: Yanjing Zhou -Date: Tue, 16 Apr 2024 16:05:00 +0800 -Subject: [PATCH 2/2] target/i386: Add new Hygon 'Dharma' CPU model - -Add the following feature bits compare to Dhyana CPU model: -stibp, ibrs, umip, ssbd - -Signed-off-by: Yanjing Zhou ---- - target/i386/cpu.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 99 insertions(+) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 1da8732c3..ce0c0bd49 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -2163,6 +2163,56 @@ static const CPUCaches epyc_genoa_cache_info = { - }, - }; - -+static const CPUCaches dharma_cache_info = { -+ .l1d_cache = &(CPUCacheInfo) { -+ .type = DATA_CACHE, -+ .level = 1, -+ .size = 32 * KiB, -+ .line_size = 64, -+ .associativity = 8, -+ .partitions = 1, -+ .sets = 64, -+ .lines_per_tag = 1, -+ .self_init = 1, -+ .no_invd_sharing = true, -+ }, -+ .l1i_cache = &(CPUCacheInfo) { -+ .type = INSTRUCTION_CACHE, -+ .level = 1, -+ .size = 32 * KiB, -+ .line_size = 64, -+ .associativity = 8, -+ .partitions = 1, -+ .sets = 64, -+ .lines_per_tag = 1, -+ .self_init = 1, -+ .no_invd_sharing = true, -+ }, -+ .l2_cache = &(CPUCacheInfo) { -+ .type = UNIFIED_CACHE, -+ .level = 2, -+ .size = 512 * KiB, -+ .line_size = 64, -+ .associativity = 8, -+ .partitions = 1, -+ .sets = 1024, -+ .lines_per_tag = 1, -+ }, -+ .l3_cache = &(CPUCacheInfo) { -+ .type = UNIFIED_CACHE, -+ .level = 3, -+ .size = 16 * MiB, -+ .line_size = 64, -+ .associativity = 16, -+ .partitions = 1, -+ .sets = 16384, -+ .lines_per_tag = 1, -+ .self_init = true, -+ .inclusive = true, -+ .complex_indexing = true, -+ }, -+}; -+ - /* The following VMX features are not supported by KVM and are left out in the - * CPU definitions: - * -@@ -4903,6 +4953,55 @@ static const X86CPUDefinition builtin_x86_defs[] = { - .model_id = "AMD EPYC-Genoa Processor", - .cache_info = &epyc_genoa_cache_info, - }, -+ { -+ .name = "Dharma", -+ .level = 0xd, -+ .vendor = CPUID_VENDOR_HYGON, -+ .family = 24, -+ .model = 4, -+ .stepping = 0, -+ .features[FEAT_1_EDX] = -+ CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | CPUID_CLFLUSH | -+ CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | CPUID_PGE | -+ CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | CPUID_MCE | -+ CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | CPUID_DE | -+ CPUID_VME | CPUID_FP87, -+ .features[FEAT_1_ECX] = -+ CPUID_EXT_RDRAND | CPUID_EXT_F16C | CPUID_EXT_AVX | -+ CPUID_EXT_XSAVE | CPUID_EXT_AES | CPUID_EXT_POPCNT | -+ CPUID_EXT_MOVBE | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 | -+ CPUID_EXT_CX16 | CPUID_EXT_FMA | CPUID_EXT_SSSE3 | -+ CPUID_EXT_MONITOR | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3, -+ .features[FEAT_8000_0001_EDX] = -+ CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_PDPE1GB | -+ CPUID_EXT2_FFXSR | CPUID_EXT2_MMXEXT | CPUID_EXT2_NX | -+ CPUID_EXT2_SYSCALL, -+ .features[FEAT_8000_0001_ECX] = -+ CPUID_EXT3_OSVW | CPUID_EXT3_3DNOWPREFETCH | -+ CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | -+ CPUID_EXT3_CR8LEG | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM | -+ CPUID_EXT3_TOPOEXT | CPUID_EXT3_PERFCORE, -+ .features[FEAT_8000_0008_EBX] = -+ CPUID_8000_0008_EBX_CLZERO | CPUID_8000_0008_EBX_XSAVEERPTR | -+ CPUID_8000_0008_EBX_IBPB | CPUID_8000_0008_EBX_IBRS | -+ CPUID_8000_0008_EBX_STIBP | CPUID_8000_0008_EBX_AMD_SSBD, -+ .features[FEAT_7_0_EBX] = -+ CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_AVX2 | -+ CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_RDSEED | -+ CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLFLUSHOPT | -+ CPUID_7_0_EBX_SHA_NI, -+ .features[FEAT_7_0_ECX] = CPUID_7_0_ECX_UMIP, -+ .features[FEAT_XSAVE] = -+ CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC | -+ CPUID_XSAVE_XGETBV1, -+ .features[FEAT_6_EAX] = -+ CPUID_6_EAX_ARAT, -+ .features[FEAT_SVM] = -+ CPUID_SVM_NPT | CPUID_SVM_NRIPSAVE, -+ .xlevel = 0x8000001E, -+ .model_id = "Hygon Dharma Processor", -+ .cache_info = &dharma_cache_info, -+ }, - }; - - /* --- -2.41.0 - diff --git a/1051-vfio-Add-vfio-based-mediated-hct-support.patch b/1051-vfio-Add-vfio-based-mediated-hct-support.patch deleted file mode 100644 index 6e03e4a2e10652863f151b5b4a56bc6dfe8c1cb1..0000000000000000000000000000000000000000 --- a/1051-vfio-Add-vfio-based-mediated-hct-support.patch +++ /dev/null @@ -1,591 +0,0 @@ -From 6f57bd71c92c0f3aff091c9fcc18cbc152978e71 Mon Sep 17 00:00:00 2001 -From: Yabin Li -Date: Fri, 4 Aug 2023 21:09:08 +0800 -Subject: [PATCH] vfio: Add vfio based mediated hct support. - -add device hct used for simulate hygon ccp - -Signed-off-by: liyabin -Signed-off-by: yangdepei -Change-Id: I8606ad46b4fa3671233597e89c14589b96a9081b ---- - hw/vfio/Kconfig | 6 + - hw/vfio/hct.c | 540 ++++++++++++++++++++++++++++++++++++++++++++ - hw/vfio/meson.build | 1 + - 3 files changed, 547 insertions(+) - create mode 100644 hw/vfio/hct.c - -diff --git a/hw/vfio/Kconfig b/hw/vfio/Kconfig -index 7cdba0560a..5f0d3c2d2b 100644 ---- a/hw/vfio/Kconfig -+++ b/hw/vfio/Kconfig -@@ -41,3 +41,9 @@ config VFIO_IGD - bool - default y if PC_PCI - depends on VFIO_PCI -+ -+config VFIO_HCT -+ bool -+ default y -+ select VFIO -+ depends on LINUX && PCI -diff --git a/hw/vfio/hct.c b/hw/vfio/hct.c -new file mode 100644 -index 0000000000..fb429271bb ---- /dev/null -+++ b/hw/vfio/hct.c -@@ -0,0 +1,540 @@ -+/* -+ * vfio based mediated ccp(hct) assignment support -+ * -+ * Copyright 2023 HYGON Corp. -+ * -+ * This work is licensed under the terms of the GNU GPL, version 2 or (at -+ * your option) any later version. See the COPYING file in the top-level -+ * directory. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "qemu/osdep.h" -+#include "qemu/queue.h" -+#include "qemu/main-loop.h" -+#include "qemu/log.h" -+#include "trace.h" -+#include "hw/pci/pci.h" -+#include "hw/vfio/pci.h" -+#include "qemu/range.h" -+#include "sysemu/kvm.h" -+#include "hw/pci/msi.h" -+#include "qemu/error-report.h" -+#include "qapi/error.h" -+#include "hw/qdev-properties.h" -+ -+#define MAX_CCP_CNT 48 -+#define PAGE_SIZE 4096 -+#define HCT_SHARED_MEMORY_SIZE (PAGE_SIZE * MAX_CCP_CNT) -+#define CCP_INDEX_BYTES 4 -+#define PATH_MAX 4096 -+#define TYPE_HCT_DEV "hct" -+#define PCI_HCT_DEV(obj) OBJECT_CHECK(HCTDevState, (obj), TYPE_HCT_DEV) -+#define HCT_MMIO_SIZE (1 << 20) -+#define HCT_MAX_PASID (1 << 8) -+ -+#define PCI_VENDOR_ID_HYGON_CCP 0x1d94 -+#define PCI_DEVICE_ID_HYGON_CCP 0x1468 -+ -+#define HCT_SHARE_DEV "/dev/hct_share" -+ -+#define HCT_VERSION_STRING "0.5" -+#define DEF_VERSION_STRING "0.1" -+#define VERSION_SIZE 16 -+ -+#define HCT_SHARE_IOC_TYPE 'C' -+#define HCT_SHARE_OP_TYPE 0x01 -+#define HCT_SHARE_OP _IOWR(HCT_SHARE_IOC_TYPE, \ -+ HCT_SHARE_OP_TYPE, \ -+ struct hct_dev_ctrl) -+#define HCT_SHARE_OP_DMA_MAP 0x01 -+#define HCT_SHARE_OP_GET_ID 0x03 -+#define HCT_SHARE_OP_GET_PASID 0x04 -+#define HCT_SHARE_OP_DMA_UNMAP 0x05 -+#define HCT_SHARE_OP_GET_VERSION 0x06 -+ -+/* BARS */ -+#define HCT_REG_BAR_IDX 2 -+#define HCT_SHARED_BAR_IDX 3 -+#define HCT_PASID_BAR_IDX 4 -+ -+#define PASID_OFFSET 40 -+ -+static volatile struct hct_data { -+ int init; -+ int hct_fd; -+ unsigned long pasid; -+ uint8_t *pasid_memory; -+ uint8_t *hct_shared_memory; -+ uint8_t ccp_index[MAX_CCP_CNT]; -+ uint8_t ccp_cnt; -+} hct_data; -+ -+typedef struct SharedDevice { -+ PCIDevice dev; -+ int shared_memory_offset; -+} SharedDevice; -+ -+typedef struct HctDevState { -+ SharedDevice sdev; -+ VFIODevice vdev; -+ MemoryRegion mmio; -+ MemoryRegion shared; -+ MemoryRegion pasid; -+ void *maps[PCI_NUM_REGIONS]; -+} HCTDevState; -+ -+struct hct_dev_ctrl { -+ unsigned char op; -+ unsigned char rsvd[3]; -+ union { -+ unsigned char version[VERSION_SIZE]; -+ struct { -+ unsigned long vaddr; -+ unsigned long iova; -+ unsigned long size; -+ }; -+ unsigned int id; -+ }; -+}; -+ -+static int pasid_get_and_init(HCTDevState *state) -+{ -+ struct hct_dev_ctrl ctrl; -+ int ret; -+ -+ ctrl.op = HCT_SHARE_OP_GET_PASID; -+ ctrl.id = -1; -+ ret = ioctl(hct_data.hct_fd, HCT_SHARE_OP, &ctrl); -+ if (ret < 0) { -+ ret = -errno; -+ error_report("GET_PASID fail: %d", -errno); -+ goto out; -+ } -+ -+ *hct_data.pasid_memory = ctrl.id; -+ hct_data.pasid = ctrl.id; -+ -+out: -+ return ret; -+} -+ -+static const MemoryRegionOps hct_mmio_ops = { -+ .endianness = DEVICE_NATIVE_ENDIAN, -+ .valid = -+ { -+ .min_access_size = 4, -+ .max_access_size = 4, -+ }, -+}; -+ -+static void vfio_hct_detach_device(HCTDevState *state) -+{ -+ vfio_detach_device(&state->vdev); -+ g_free(state->vdev.name); -+} -+ -+static void vfio_hct_exit(PCIDevice *dev) -+{ -+ HCTDevState *state = PCI_HCT_DEV(dev); -+ -+ vfio_hct_detach_device(state); -+ -+ if (hct_data.hct_fd) { -+ qemu_close(hct_data.hct_fd); -+ hct_data.hct_fd = 0; -+ } -+} -+ -+static Property vfio_hct_properties[] = { -+ DEFINE_PROP_STRING("sysfsdev", HCTDevState, vdev.sysfsdev), -+ DEFINE_PROP_END_OF_LIST(), -+}; -+ -+static void vfio_ccp_compute_needs_reset(VFIODevice *vdev) -+{ -+ vdev->needs_reset = false; -+} -+ -+struct VFIODeviceOps vfio_ccp_ops = { -+ .vfio_compute_needs_reset = vfio_ccp_compute_needs_reset, -+}; -+ -+/* create BAR2, BAR3 and BAR4 space for the virtual machine. */ -+static int vfio_hct_region_mmap(HCTDevState *state) -+{ -+ int ret; -+ int i; -+ struct vfio_region_info *info; -+ -+ for (i = 0; i < PCI_ROM_SLOT; i++) { -+ ret = vfio_get_region_info(&state->vdev, i, &info); -+ if (ret) -+ goto out; -+ -+ if (info->size) { -+ state->maps[i] = mmap(NULL, info->size, PROT_READ | PROT_WRITE, -+ MAP_SHARED, state->vdev.fd, info->offset); -+ if (state->maps[i] == MAP_FAILED) { -+ ret = -errno; -+ g_free(info); -+ error_report("vfio mmap fail\n"); -+ goto out; -+ } -+ } -+ g_free(info); -+ } -+ -+ memory_region_init_io(&state->mmio, OBJECT(state), &hct_mmio_ops, state, -+ "hct mmio", HCT_MMIO_SIZE); -+ memory_region_init_ram_device_ptr(&state->mmio, OBJECT(state), "hct mmio", -+ HCT_MMIO_SIZE, -+ state->maps[HCT_REG_BAR_IDX]); -+ -+ memory_region_init_io(&state->shared, OBJECT(state), &hct_mmio_ops, state, -+ "hct shared memory", PAGE_SIZE); -+ memory_region_init_ram_device_ptr( -+ &state->shared, OBJECT(state), "hct shared memory", PAGE_SIZE, -+ (void *)hct_data.hct_shared_memory + -+ state->sdev.shared_memory_offset * PAGE_SIZE); -+ -+ memory_region_init_io(&state->pasid, OBJECT(state), &hct_mmio_ops, state, -+ "hct pasid", PAGE_SIZE); -+ memory_region_init_ram_device_ptr(&state->pasid, OBJECT(state), "hct pasid", -+ PAGE_SIZE, hct_data.pasid_memory); -+ -+ pci_register_bar(&state->sdev.dev, HCT_REG_BAR_IDX, -+ PCI_BASE_ADDRESS_SPACE_MEMORY, &state->mmio); -+ pci_register_bar(&state->sdev.dev, HCT_SHARED_BAR_IDX, -+ PCI_BASE_ADDRESS_SPACE_MEMORY, &state->shared); -+ pci_register_bar(&state->sdev.dev, HCT_PASID_BAR_IDX, -+ PCI_BASE_ADDRESS_SPACE_MEMORY, &state->pasid); -+out: -+ return ret; -+} -+ -+static int hct_check_duplicated_index(int index) -+{ -+ int cnt; -+ for (cnt = 0; cnt < hct_data.ccp_cnt; cnt++) { -+ if (hct_data.ccp_index[cnt] == index) { -+ error_report("many mdev shouldn't be mapped to one ccp in a " -+ "virtual machine!\n"); -+ return -1; -+ } -+ } -+ -+ hct_data.ccp_index[hct_data.ccp_cnt++] = index; -+ return 0; -+} -+ -+static int hct_get_ccp_index(HCTDevState *state) -+{ -+ char path[PATH_MAX]; -+ char buf[CCP_INDEX_BYTES]; -+ int fd; -+ int ret; -+ int ccp_index; -+ -+ snprintf(path, PATH_MAX, "%s/vendor/id", state->vdev.sysfsdev); -+ fd = qemu_open_old(path, O_RDONLY); -+ if (fd < 0) { -+ error_report("open %s fail\n", path); -+ return -errno; -+ } -+ -+ ret = read(fd, buf, sizeof(buf)); -+ if (ret < 0) { -+ ret = -errno; -+ error_report("read %s fail\n", path); -+ goto out; -+ } -+ -+ if (1 != sscanf(buf, "%d", &ccp_index)) { -+ ret = -errno; -+ error_report("format addr %s fail\n", buf); -+ goto out; -+ } -+ -+ if (!hct_check_duplicated_index(ccp_index)) { -+ state->sdev.shared_memory_offset = ccp_index; -+ } else { -+ ret = -1; -+ } -+ -+out: -+ qemu_close(fd); -+ return ret; -+} -+ -+static int hct_api_version_check(void) -+{ -+ struct hct_dev_ctrl ctrl; -+ int ret; -+ -+ ctrl.op = HCT_SHARE_OP_GET_VERSION; -+ memcpy(ctrl.version, DEF_VERSION_STRING, sizeof(DEF_VERSION_STRING)); -+ ret = ioctl(hct_data.hct_fd, HCT_SHARE_OP, &ctrl); -+ if (ret < 0) { -+ error_report("ret %d, errno %d: fail to get hct.ko version.\n", ret, -+ errno); -+ return -1; -+ } else if (memcmp(ctrl.version, HCT_VERSION_STRING, -+ sizeof(HCT_VERSION_STRING)) < 0) { -+ error_report("The hct.ko version is %s, please upgrade to version %s " -+ "or higher.\n", -+ ctrl.version, HCT_VERSION_STRING); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static int hct_shared_memory_init(void) -+{ -+ int ret = 0; -+ -+ hct_data.hct_shared_memory = -+ mmap(NULL, HCT_SHARED_MEMORY_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, -+ hct_data.hct_fd, 0); -+ if (hct_data.hct_shared_memory == MAP_FAILED) { -+ ret = -errno; -+ error_report("map hct shared memory fail\n"); -+ goto out; -+ } -+ -+out: -+ return ret; -+} -+ -+static void hct_listener_region_add(MemoryListener *listener, -+ MemoryRegionSection *section) -+{ -+ struct hct_dev_ctrl ctrl; -+ hwaddr iova; -+ Int128 llend, llsize; -+ void *vaddr; -+ int ret; -+ -+ iova = REAL_HOST_PAGE_ALIGN(section->offset_within_address_space); -+ llend = int128_make64(section->offset_within_address_space); -+ llend = int128_add(llend, section->size); -+ llend = int128_add(llend, int128_exts64(qemu_real_host_page_mask())); -+ -+ if (int128_ge(int128_make64(iova), llend)) { -+ return; -+ } -+ -+ if (!section->mr->ram) { -+ return; -+ } -+ -+ vaddr = memory_region_get_ram_ptr(section->mr) + -+ section->offset_within_region + -+ (iova - section->offset_within_address_space); -+ llsize = int128_sub(llend, int128_make64(iova)); -+ -+ ctrl.op = HCT_SHARE_OP_DMA_MAP; -+ ctrl.iova = iova | (hct_data.pasid << PASID_OFFSET); -+ ctrl.vaddr = (uint64_t)vaddr; -+ ctrl.size = llsize; -+ ret = ioctl(hct_data.hct_fd, HCT_SHARE_OP, &ctrl); -+ if (ret < 0) -+ error_report("VFIO_MAP_DMA: %d, iova=%lx", -errno, iova); -+} -+ -+static void hct_listener_region_del(MemoryListener *listener, -+ MemoryRegionSection *section) -+{ -+ struct hct_dev_ctrl ctrl; -+ hwaddr iova; -+ Int128 llend, llsize; -+ int ret; -+ -+ iova = REAL_HOST_PAGE_ALIGN(section->offset_within_address_space); -+ llend = int128_make64(section->offset_within_address_space); -+ llend = int128_add(llend, section->size); -+ llend = int128_add(llend, int128_exts64(qemu_real_host_page_mask())); -+ -+ if (int128_ge(int128_make64(iova), llend)) { -+ return; -+ } -+ -+ if (!section->mr->ram) { -+ return; -+ } -+ -+ llsize = int128_sub(llend, int128_make64(iova)); -+ -+ ctrl.op = HCT_SHARE_OP_DMA_UNMAP; -+ ctrl.iova = iova | (hct_data.pasid << PASID_OFFSET); -+ ctrl.size = llsize; -+ ret = ioctl(hct_data.hct_fd, HCT_SHARE_OP, &ctrl); -+ if (ret < 0) -+ error_report("VFIO_UNMAP_DMA: %d", -errno); -+} -+ -+static MemoryListener hct_memory_listener = { -+ .region_add = hct_listener_region_add, -+ .region_del = hct_listener_region_del, -+}; -+ -+static void hct_data_uninit(HCTDevState *state) -+{ -+ if (hct_data.hct_fd) { -+ qemu_close(hct_data.hct_fd); -+ hct_data.hct_fd = 0; -+ } -+ -+ if (hct_data.pasid) { -+ hct_data.pasid = 0; -+ } -+ -+ if (hct_data.pasid_memory) { -+ munmap(hct_data.pasid_memory, PAGE_SIZE); -+ hct_data.pasid_memory = NULL; -+ } -+ -+ if (hct_data.hct_shared_memory) { -+ munmap((void *)hct_data.hct_shared_memory, HCT_SHARED_MEMORY_SIZE); -+ hct_data.hct_shared_memory = NULL; -+ } -+ -+ memory_listener_unregister(&hct_memory_listener); -+} -+ -+static int hct_data_init(HCTDevState *state) -+{ -+ int ret; -+ -+ if (hct_data.init == 0) { -+ -+ hct_data.hct_fd = qemu_open_old(HCT_SHARE_DEV, O_RDWR); -+ if (hct_data.hct_fd < 0) { -+ error_report("fail to open %s, errno %d.", HCT_SHARE_DEV, errno); -+ ret = -errno; -+ goto out; -+ } -+ -+ /* The hct.ko version number needs not to be less than 0.2. */ -+ ret = hct_api_version_check(); -+ if (ret) -+ goto out; -+ -+ /* assign a page to the virtual BAR3 of each CCP. */ -+ ret = hct_shared_memory_init(); -+ if (ret) -+ goto out; -+ -+ hct_data.pasid_memory = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, -+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); -+ if (hct_data.pasid_memory < 0) -+ goto unmap_shared_memory_exit; -+ -+ /* assign a unique pasid to each virtual machine. */ -+ ret = pasid_get_and_init(state); -+ if (ret < 0) -+ goto unmap_pasid_memory_exit; -+ -+ /* perform DMA_MAP and DMA_UNMAP operations on all memories of the -+ * virtual machine. */ -+ memory_listener_register(&hct_memory_listener, &address_space_memory); -+ -+ hct_data.init = 1; -+ } -+ -+ return hct_get_ccp_index(state); -+ -+unmap_pasid_memory_exit: -+ munmap(hct_data.pasid_memory, PAGE_SIZE); -+ -+unmap_shared_memory_exit: -+ munmap((void *)hct_data.hct_shared_memory, HCT_SHARED_MEMORY_SIZE); -+ -+out: -+ return ret; -+} -+ -+/* When device is loaded */ -+static void vfio_hct_realize(PCIDevice *pci_dev, Error **errp) -+{ -+ int ret; -+ char *mdevid; -+ Error *err = NULL; -+ HCTDevState *state = PCI_HCT_DEV(pci_dev); -+ -+ /* parsing mdev device name from startup scripts */ -+ mdevid = g_path_get_basename(state->vdev.sysfsdev); -+ state->vdev.name = g_strdup_printf("%s", mdevid); -+ -+ ret = hct_data_init(state); -+ if (ret < 0) { -+ g_free(state->vdev.name); -+ goto out; -+ } -+ -+ ret = vfio_attach_device(state->vdev.name, &state->vdev, -+ pci_device_iommu_address_space(pci_dev), &err); -+ -+ if (ret) { -+ error_report("attach device failed, name = %s", state->vdev.name); -+ goto data_uninit_out; -+ } -+ -+ state->vdev.ops = &vfio_ccp_ops; -+ state->vdev.dev = &state->sdev.dev.qdev; -+ -+ ret = vfio_hct_region_mmap(state); -+ if (ret < 0) -+ goto detach_device_out; -+ -+ return; -+ -+detach_device_out: -+ vfio_hct_detach_device(state); -+ -+data_uninit_out: -+ hct_data_uninit(state); -+ -+out: -+ return; -+} -+ -+static void hct_dev_class_init(ObjectClass *klass, void *data) -+{ -+ DeviceClass *dc = DEVICE_CLASS(klass); -+ PCIDeviceClass *pdc = PCI_DEVICE_CLASS(klass); -+ -+ dc->desc = "HCT Device"; -+ device_class_set_props(dc, vfio_hct_properties); -+ -+ pdc->realize = vfio_hct_realize; -+ pdc->exit = vfio_hct_exit; -+ pdc->vendor_id = PCI_VENDOR_ID_HYGON_CCP; -+ pdc->device_id = PCI_DEVICE_ID_HYGON_CCP; -+ pdc->class_id = PCI_CLASS_CRYPT_OTHER; -+ set_bit(DEVICE_CATEGORY_MISC, dc->categories); -+ -+ return; -+} -+ -+static const TypeInfo pci_hct_info = { -+ .name = TYPE_HCT_DEV, -+ .parent = TYPE_PCI_DEVICE, -+ .instance_size = sizeof(HCTDevState), -+ .class_init = hct_dev_class_init, -+ .interfaces = -+ (InterfaceInfo[]){ -+ {INTERFACE_CONVENTIONAL_PCI_DEVICE}, -+ {}, -+ }, -+}; -+ -+static void hct_register_types(void) { type_register_static(&pci_hct_info); } -+ -+type_init(hct_register_types); -diff --git a/hw/vfio/meson.build b/hw/vfio/meson.build -index 2a6912c940..b1db4c8605 100644 ---- a/hw/vfio/meson.build -+++ b/hw/vfio/meson.build -@@ -17,5 +17,6 @@ vfio_ss.add(when: 'CONFIG_VFIO_XGMAC', if_true: files('calxeda-xgmac.c')) - vfio_ss.add(when: 'CONFIG_VFIO_AMD_XGBE', if_true: files('amd-xgbe.c')) - vfio_ss.add(when: 'CONFIG_VFIO_AP', if_true: files('ap.c')) - vfio_ss.add(when: 'CONFIG_VFIO_IGD', if_true: files('igd.c')) -+vfio_ss.add(when: 'CONFIG_VFIO_HCT', if_true: files('hct.c')) - - specific_ss.add_all(when: 'CONFIG_VFIO', if_true: vfio_ss) --- -2.17.1 - diff --git a/1052-hw-net-virtio-net-Update-event-idx-if-guest-has-made.patch b/1052-hw-net-virtio-net-Update-event-idx-if-guest-has-made.patch deleted file mode 100644 index b0d6294475d04363b59ebcda2e8224316c656037..0000000000000000000000000000000000000000 --- a/1052-hw-net-virtio-net-Update-event-idx-if-guest-has-made.patch +++ /dev/null @@ -1,31 +0,0 @@ -From b93fbd340ded30b49af77ad5e348b93419e69cc0 Mon Sep 17 00:00:00 2001 -From: eastmoutain <14304864+eastmoutain@user.noreply.gitee.com> -Date: Mon, 17 Jun 2024 10:00:46 +0800 -Subject: [PATCH] hw/net: virtio-net: Update event idx if guest has made extra - buffers during double check - -If guest has made some buffers available during double check, -but the total buffer size available is lower than @bufsize, -notify the guest with the latest available idx(event idx) -seen by the host. - -Signed-off-by: yangwencheng ---- - hw/net/virtio-net.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c -index 80c56f0cf..dc0b65501 100644 ---- a/hw/net/virtio-net.c -+++ b/hw/net/virtio-net.c -@@ -1648,6 +1648,7 @@ static int virtio_net_has_buffers(VirtIONetQueue *q, int bufsize) - if (virtio_queue_empty(q->rx_vq) || - (n->mergeable_rx_bufs && - !virtqueue_avail_bytes(q->rx_vq, bufsize, 0))) { -+ virtio_queue_set_notification(q->rx_vq, 1); - return 0; - } - } --- -2.39.3 - diff --git a/1053-target-i386-csv-Release-CSV3-shared-pages-after-unma.patch b/1053-target-i386-csv-Release-CSV3-shared-pages-after-unma.patch deleted file mode 100644 index c5370a3892698a7b5886da698ca8b3f8357de981..0000000000000000000000000000000000000000 --- a/1053-target-i386-csv-Release-CSV3-shared-pages-after-unma.patch +++ /dev/null @@ -1,130 +0,0 @@ -From c112d0e1711e11f20bbde37c8af806f9cee8e336 Mon Sep 17 00:00:00 2001 -From: eastmoutain <14304864+eastmoutain@user.noreply.gitee.com> -Date: Mon, 20 May 2024 21:12:23 +0800 -Subject: [PATCH] target/i386: csv: Release CSV3 shared pages after unmapping - DMA - -The shared pages are created for Device DMA access, release them -once DMA mapping is removed. - -Signed-off-by: yangwencheng ---- - linux-headers/linux/kvm.h | 9 +++++++++ - target/i386/csv-sysemu-stub.c | 5 +++++ - target/i386/csv.c | 34 ++++++++++++++++++++++++++++++++++ - target/i386/csv.h | 1 + - target/i386/kvm/kvm.c | 1 + - 5 files changed, 50 insertions(+) - -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index f67a7dde1..36da75b92 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -2076,6 +2076,7 @@ enum csv3_cmd_id { - KVM_CSV3_SEND_ENCRYPT_CONTEXT, - KVM_CSV3_RECEIVE_ENCRYPT_DATA, - KVM_CSV3_RECEIVE_ENCRYPT_CONTEXT, -+ KVM_CSV3_HANDLE_MEMORY, - - KVM_CSV3_NR_MAX, - }; -@@ -2122,6 +2123,14 @@ struct kvm_csv3_receive_encrypt_context { - __u32 trans_len; - }; - -+#define KVM_CSV3_RELEASE_SHARED_MEMORY (0x0001) -+ -+struct kvm_csv3_handle_memory { -+ __u64 gpa; -+ __u32 num_pages; -+ __u32 opcode; -+}; -+ - #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) - #define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1) - #define KVM_DEV_ASSIGN_MASK_INTX (1 << 2) -diff --git a/target/i386/csv-sysemu-stub.c b/target/i386/csv-sysemu-stub.c -index db22c299a..f3224a015 100644 ---- a/target/i386/csv-sysemu-stub.c -+++ b/target/i386/csv-sysemu-stub.c -@@ -39,3 +39,8 @@ void csv3_shared_region_dma_unmap(uint64_t start, uint64_t end) - { - - } -+ -+void csv3_shared_region_relese(uint64_t gpa, uint32_t num_pages) -+{ -+ -+} -diff --git a/target/i386/csv.c b/target/i386/csv.c -index 0593f9b19..a869cc2a7 100644 ---- a/target/i386/csv.c -+++ b/target/i386/csv.c -@@ -268,6 +268,40 @@ end: - return ret; - } - -+void csv3_shared_region_release(uint64_t gpa, uint32_t num_pages) -+{ -+ struct kvm_csv3_handle_memory mem = { 0 }; -+ MemoryRegion *mr = NULL; -+ void *hva; -+ int ret; -+ -+ if (!csv3_enabled()) -+ return; -+ -+ if (!gpa || !num_pages) -+ return; -+ -+ mem.gpa = (__u64)gpa; -+ mem.num_pages = (__u32)num_pages; -+ mem.opcode = (__u32)KVM_CSV3_RELEASE_SHARED_MEMORY; -+ -+ /* unpin the pages */ -+ ret = csv3_ioctl(KVM_CSV3_HANDLE_MEMORY, &mem, NULL); -+ if (ret <= 0) { -+ if (ret < 0) -+ error_report("%s: CSV3 unpin failed ret %d", __func__, ret); -+ return; -+ } -+ -+ /* drop the pages */ -+ hva = gpa2hva(&mr, gpa, num_pages << TARGET_PAGE_BITS, NULL); -+ if (hva) { -+ ret = madvise(hva, num_pages << TARGET_PAGE_BITS, MADV_DONTNEED); -+ if (ret) -+ error_report("%s: madvise failed %d", __func__, ret); -+ } -+} -+ - void csv3_shared_region_dma_unmap(uint64_t start, uint64_t end) - { - MemoryRegionSection section; -diff --git a/target/i386/csv.h b/target/i386/csv.h -index e5e05d006..a32588ab9 100644 ---- a/target/i386/csv.h -+++ b/target/i386/csv.h -@@ -122,6 +122,7 @@ int csv3_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp); - - int csv3_shared_region_dma_map(uint64_t start, uint64_t end); - void csv3_shared_region_dma_unmap(uint64_t start, uint64_t end); -+void csv3_shared_region_release(uint64_t gpa, uint32_t num_pages); - int csv3_load_incoming_page(QEMUFile *f, uint8_t *ptr); - int csv3_load_incoming_context(QEMUFile *f); - int csv3_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr); -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index 925f4f804..fdceecc84 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -5027,6 +5027,7 @@ static int kvm_handle_exit_hypercall(X86CPU *cpu, struct kvm_run *run) - if (enc) { - sev_remove_shared_regions_list(gfn_start, gfn_end); - csv3_shared_region_dma_unmap(gpa, gfn_end << TARGET_PAGE_BITS); -+ csv3_shared_region_release(gpa, npages); - } else { - sev_add_shared_regions_list(gfn_start, gfn_end); - csv3_shared_region_dma_map(gpa, gfn_end << TARGET_PAGE_BITS); --- -2.39.3 - diff --git a/1054-virtio-net-Fix-network-stall-at-the-host-side-waitin.patch b/1054-virtio-net-Fix-network-stall-at-the-host-side-waitin.patch deleted file mode 100644 index eb97e05f80795a6ca6d77ad60872fd35d7818267..0000000000000000000000000000000000000000 --- a/1054-virtio-net-Fix-network-stall-at-the-host-side-waitin.patch +++ /dev/null @@ -1,339 +0,0 @@ -From f8854b36713ca37b4f8dd62d59ac9f83623c47fe Mon Sep 17 00:00:00 2001 -From: thomas -Date: Fri, 12 Jul 2024 11:10:53 +0800 -Subject: [PATCH] virtio-net: Fix network stall at the host side waiting for - kick - -Patch 06b12970174 ("virtio-net: fix network stall under load") -added double-check to test whether the available buffer size -can satisfy the request or not, in case the guest has added -some buffers to the avail ring simultaneously after the first -check. It will be lucky if the available buffer size becomes -okay after the double-check, then the host can send the packet -to the guest. If the buffer size still can't satisfy the request, -even if the guest has added some buffers, viritio-net would -stall at the host side forever. - -The patch enables notification and checks whether the guest has -added some buffers since last check of available buffers when -the available buffers are insufficient. If no buffer is added, -return false, else recheck the available buffers in the loop. -If the available buffers are sufficient, disable notification -and return true. - -Changes: -1. Change the return type of virtqueue_get_avail_bytes() from void - to int, it returns an opaque that represents the shadow_avail_idx - of the virtqueue on success, else -1 on error. -2. Add a new API: virtio_queue_enable_notification_and_check(), - it takes an opaque as input arg which is returned from - virtqueue_get_avail_bytes(). It enables notification firstly, - then checks whether the guest has added some buffers since - last check of available buffers or not by virtio_queue_poll(), - return ture if yes. - -The patch also reverts patch "06b12970174". -The patch also reverts patch -1052-hw-net-virtio-net-Update-event-idx-if-guest-has-made.patch. - -The case below can reproduce the stall. - - Guest 0 - +--------+ - | iperf | - ---------------> | server | - Host | +--------+ - +--------+ | ... - | iperf |---- - | client |---- Guest n - +--------+ | +--------+ - | | iperf | - ---------------> | server | - +--------+ - -Boot many guests from qemu with virtio network: - qemu ... -netdev tap,id=net_x \ - -device virtio-net-pci-non-transitional,\ - iommu_platform=on,mac=xx:xx:xx:xx:xx:xx,netdev=net_x - -Each guest acts as iperf server with commands below: - iperf3 -s -D -i 10 -p 8001 - iperf3 -s -D -i 10 -p 8002 - -The host as iperf client: - iperf3 -c guest_IP -p 8001 -i 30 -w 256k -P 20 -t 40000 - iperf3 -c guest_IP -p 8002 -i 30 -w 256k -P 20 -t 40000 - -After some time, the host loses connection to the guest, -the guest can send packet to the host, but can't receive -packet from the host. - -It's more likely to happen if SWIOTLB is enabled in the guest, -allocating and freeing bounce buffer takes some CPU ticks, -copying from/to bounce buffer takes more CPU ticks, compared -with that there is no bounce buffer in the guest. -Once the rate of producing packets from the host approximates -the rate of receiveing packets in the guest, the guest would -loop in NAPI. - - receive packets --- - | | - v | - free buf virtnet_poll - | | - v | - add buf to avail ring --- - | - | need kick the host? - | NAPI continues - v - receive packets --- - | | - v | - free buf virtnet_poll - | | - v | - add buf to avail ring --- - | - v - ... ... - -On the other hand, the host fetches free buf from avail -ring, if the buf in the avail ring is not enough, the -host notifies the guest the event by writing the avail -idx read from avail ring to the event idx of used ring, -then the host goes to sleep, waiting for the kick signal -from the guest. - -Once the guest finds the host is waiting for kick singal -(in virtqueue_kick_prepare_split()), it kicks the host. - -The host may stall forever at the sequences below: - - Host Guest - ------------ ----------- - fetch buf, send packet receive packet --- - ... ... | - fetch buf, send packet add buf | - ... add buf virtnet_poll - buf not enough avail idx-> add buf | - read avail idx add buf | - add buf --- - receive packet --- - write event idx ... | - wait for kick add buf virtnet_poll - ... | - --- - no more packet, exit NAPI - -In the first loop of NAPI above, indicated in the range of -virtnet_poll above, the host is sending packets while the -guest is receiving packets and adding buffers. - step 1: The buf is not enough, for example, a big packet - needs 5 buf, but the available buf count is 3. - The host read current avail idx. - step 2: The guest adds some buf, then checks whether the - host is waiting for kick signal, not at this time. - The used ring is not empty, the guest continues - the second loop of NAPI. - step 3: The host writes the avail idx read from avail - ring to used ring as event idx via - virtio_queue_set_notification(q->rx_vq, 1). - step 4: At the end of the second loop of NAPI, recheck - whether kick is needed, as the event idx in the - used ring written by the host is beyound the - range of kick condition, the guest will not - send kick signal to the host. - -Fixes: 06b12970174 ("virtio-net: fix network stall under load") -Cc: qemu-stable@nongnu.org -Signed-off-by: Wencheng Yang -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Jason Wang ---- - hw/net/virtio-net.c | 29 +++++++++-------- - hw/virtio/virtio.c | 64 +++++++++++++++++++++++++++++++++++--- - include/hw/virtio/virtio.h | 18 +++++++++-- - 3 files changed, 91 insertions(+), 20 deletions(-) - -diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c -index dc0b65501e..3f589e618a 100644 ---- a/hw/net/virtio-net.c -+++ b/hw/net/virtio-net.c -@@ -1635,25 +1635,28 @@ static bool virtio_net_can_receive(NetClientState *nc) - - static int virtio_net_has_buffers(VirtIONetQueue *q, int bufsize) - { -+ int opaque; -+ unsigned int in_bytes; - VirtIONet *n = q->n; -- if (virtio_queue_empty(q->rx_vq) || -- (n->mergeable_rx_bufs && -- !virtqueue_avail_bytes(q->rx_vq, bufsize, 0))) { -- virtio_queue_set_notification(q->rx_vq, 1); -- -- /* To avoid a race condition where the guest has made some buffers -- * available after the above check but before notification was -- * enabled, check for available buffers again. -- */ -- if (virtio_queue_empty(q->rx_vq) || -- (n->mergeable_rx_bufs && -- !virtqueue_avail_bytes(q->rx_vq, bufsize, 0))) { -- virtio_queue_set_notification(q->rx_vq, 1); -+ -+ while (virtio_queue_empty(q->rx_vq) || n->mergeable_rx_bufs) { -+ opaque = virtqueue_get_avail_bytes(q->rx_vq, &in_bytes, NULL, -+ bufsize, 0); -+ /* Buffer is enough, disable notifiaction */ -+ if (bufsize <= in_bytes) { -+ break; -+ } -+ -+ if (virtio_queue_enable_notification_and_check(q->rx_vq, opaque)) { -+ /* Guest has added some buffers, try again */ -+ continue; -+ } else { - return 0; - } - } - - virtio_queue_set_notification(q->rx_vq, 0); -+ - return 1; - } - -diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c -index 3a160f86ed..4e8e131915 100644 ---- a/hw/virtio/virtio.c -+++ b/hw/virtio/virtio.c -@@ -744,6 +744,60 @@ int virtio_queue_empty(VirtQueue *vq) - } - } - -+static bool virtio_queue_split_poll(VirtQueue *vq, unsigned shadow_idx) -+{ -+ if (unlikely(!vq->vring.avail)) { -+ return false; -+ } -+ -+ return (uint16_t)shadow_idx != vring_avail_idx(vq); -+} -+ -+static bool virtio_queue_packed_poll(VirtQueue *vq, unsigned shadow_idx) -+{ -+ VRingPackedDesc desc; -+ VRingMemoryRegionCaches *caches; -+ -+ if (unlikely(!vq->vring.desc)) { -+ return false; -+ } -+ -+ caches = vring_get_region_caches(vq); -+ if (!caches) { -+ return false; -+ } -+ -+ vring_packed_desc_read(vq->vdev, &desc, &caches->desc, -+ shadow_idx, true); -+ -+ return is_desc_avail(desc.flags, vq->shadow_avail_wrap_counter); -+} -+ -+static bool virtio_queue_poll(VirtQueue *vq, unsigned shadow_idx) -+{ -+ if (virtio_device_disabled(vq->vdev)) { -+ return false; -+ } -+ -+ if (virtio_vdev_has_feature(vq->vdev, VIRTIO_F_RING_PACKED)) { -+ return virtio_queue_packed_poll(vq, shadow_idx); -+ } else { -+ return virtio_queue_split_poll(vq, shadow_idx); -+ } -+} -+ -+bool virtio_queue_enable_notification_and_check(VirtQueue *vq, -+ int opaque) -+{ -+ virtio_queue_set_notification(vq, 1); -+ -+ if (opaque >= 0) { -+ return virtio_queue_poll(vq, (unsigned)opaque); -+ } else { -+ return false; -+ } -+} -+ - static void virtqueue_unmap_sg(VirtQueue *vq, const VirtQueueElement *elem, - unsigned int len) - { -@@ -1323,9 +1377,9 @@ err: - goto done; - } - --void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes, -- unsigned int *out_bytes, -- unsigned max_in_bytes, unsigned max_out_bytes) -+int virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes, -+ unsigned int *out_bytes, unsigned max_in_bytes, -+ unsigned max_out_bytes) - { - uint16_t desc_size; - VRingMemoryRegionCaches *caches; -@@ -1358,7 +1412,7 @@ void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes, - caches); - } - -- return; -+ return (int)vq->shadow_avail_idx; - err: - if (in_bytes) { - *in_bytes = 0; -@@ -1366,6 +1420,8 @@ err: - if (out_bytes) { - *out_bytes = 0; - } -+ -+ return -1; - } - - int virtqueue_avail_bytes(VirtQueue *vq, unsigned int in_bytes, -diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h -index c8f72850bc..d2f4ed160d 100644 ---- a/include/hw/virtio/virtio.h -+++ b/include/hw/virtio/virtio.h -@@ -270,9 +270,13 @@ void qemu_put_virtqueue_element(VirtIODevice *vdev, QEMUFile *f, - VirtQueueElement *elem); - int virtqueue_avail_bytes(VirtQueue *vq, unsigned int in_bytes, - unsigned int out_bytes); --void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes, -- unsigned int *out_bytes, -- unsigned max_in_bytes, unsigned max_out_bytes); -+/** -+ * Return <0 on error or an opaque >=0 to pass to -+ * virtio_queue_enable_notification_and_check on success. -+ */ -+int virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes, -+ unsigned int *out_bytes, unsigned max_in_bytes, -+ unsigned max_out_bytes); - - void virtio_notify_irqfd(VirtIODevice *vdev, VirtQueue *vq); - void virtio_notify(VirtIODevice *vdev, VirtQueue *vq); -@@ -306,6 +310,14 @@ int virtio_queue_ready(VirtQueue *vq); - - int virtio_queue_empty(VirtQueue *vq); - -+/** -+ * Enable notification and check whether guest has added some -+ * buffers since last call to virtqueue_get_avail_bytes. -+ * -+ * @opaque: value returned from virtqueue_get_avail_bytes -+ */ -+bool virtio_queue_enable_notification_and_check(VirtQueue *vq, -+ int opaque); - /* Host binding interface. */ - - uint32_t virtio_config_readb(VirtIODevice *vdev, uint32_t addr); --- -2.43.5 - diff --git a/download b/download new file mode 100644 index 0000000000000000000000000000000000000000..76df5f9f598a2236ba58a4f681e0c0bd81c9b12a --- /dev/null +++ b/download @@ -0,0 +1 @@ +e59aac156eaf0028f142accd3d1692e7 qemu-8.2.0.tar.xz diff --git a/qemu-8.2.0.tar.xz b/qemu-8.2.0.tar.xz deleted file mode 100644 index 6d13b5dd8d4d58c99a8d664ca6f207c9ae5c59b7..0000000000000000000000000000000000000000 Binary files a/qemu-8.2.0.tar.xz and /dev/null differ diff --git a/qemu.spec b/qemu.spec index af5d49d48cdbf18ac3205dd3b9d2c96baa8b4a0b..6d48b8fba44ccd13a8bbe91c96ab4ff3338ae581 100644 --- a/qemu.spec +++ b/qemu.spec @@ -1,4 +1,4 @@ -%define anolis_release 19 +%define anolis_release 20 %bcond_with check @@ -253,7 +253,7 @@ Epoch: 2 License: GPLv2 and BSD and MIT and CC-BY URL: http://www.qemu.org/ -Source0: https://download.qemu.org/%{name}-%{version}.tar.xz +Source0: https://gitee.com/anolis/qemu-kvm/archive/refs/tags/%{name}-%{version}.tar.xz Source10: qemu-guest-agent.service Source11: 99-qemu-guest-agent.rules @@ -266,103 +266,6 @@ Source27: kvm.conf Source31: kvm-x86.conf Source36: README.tests -Patch0001: 0001-sgx-stub-fix.patch -Patch0002: 0002-Fix-crash-when-loading-snapshot-on-inactive-node.patch - -Patch0003: 0003-hw-loongarch-virt-Align-high-memory-base-address-wit.patch -Patch0004: 0004-target-loongarch-Add-timer-information-dump-support.patch -Patch0005: 0005-target-loongarch-meson-move-gdbstub.c-to-loongarch.s.patch -Patch0006: 0006-target-loongarch-move-translate-modules-to-tcg.patch -Patch0007: 0007-linux-headers-Update-to-Linux-v6.7-rc5.patch -Patch0008: 0008-linux-headers-Synchronize-linux-headers-from-linux-v.patch -Patch0009: 0009-target-loongarch-Define-some-kvm_arch-interfaces.patch -Patch0010: 0010-target-loongarch-Supplement-vcpu-env-initial-when-vc.patch -Patch0011: 0011-target-loongarch-Implement-kvm-get-set-registers.patch -Patch0012: 0012-target-loongarch-Implement-kvm_arch_init-function.patch -Patch0013: 0013-target-loongarch-Implement-kvm_arch_init_vcpu.patch -Patch0014: 0014-target-loongarch-Implement-kvm_arch_handle_exit.patch -Patch0015: 0015-target-loongarch-Restrict-TCG-specific-code.patch -Patch0016: 0016-target-loongarch-Implement-set-vcpu-intr-for-kvm.patch -Patch0017: 0017-target-loongarch-Add-loongarch-kvm-into-meson-build.patch -Patch0018: 0018-hw-intc-loongarch_ipi-Use-MemTxAttrs-interface-for-i.patch -Patch0019: 0019-hw-loongarch-virt-Set-iocsr-address-space-per-board-.patch -Patch0020: 0020-hw-intc-loongarch_extioi-Add-dynamic-cpu-number-supp.patch -Patch0021: 0021-hw-intc-loongarch_extioi-Add-vmstate-post_load-suppo.patch -Patch0022: 0022-configure-Add-linux-header-compile-support-for-Loong.patch -Patch0023: 0023-target-loongarch-Set-cpuid-CSR-register-only-once-wi.patch -Patch0024: 0024-target-loongarch-kvm-Enable-LSX-LASX-extension.patch -Patch0025: 0025-target-loongarch-Fix-qtest-test-hmp-error-when-KVM-o.patch -Patch0026: 0026-loongarch-Change-the-UEFI-loading-mode-to-loongarch.patch -Patch0027: 0027-target-loongarch-Fix-tlb-huge-page-loading-issue.patch -Patch0028: 0028-target-loongarch-Fix-qemu-loongarch64-hang-when-exec.patch -Patch0029: 0029-target-loongarch-kvm-Add-software-breakpoint-support.patch -Patch0030: 0030-hw-intc-loongarch_extioi-Add-virt-extension-support.patch -Patch0031: 0031-target-loongarch-kvm-sync-kernel-header-files.patch -Patch0032: 0032-hw-intc-loongarch_extioi-Add-virt-extension-support-.patch -Patch0033: 0033-target-loongarch-kvm-Add-pmu-support.patch -Patch0034: 0034-target-loongarch-Fix-qemu-system-loongarch64-assert-.patch - -Patch0035: 0035-newfeature-support-vpsp.patch - -Patch0036: 0036-target-loongarch-kvm-Fix-VM-recovery-from-disk-failu.patch -Patch0037: 0037-target-loongarch-kvm-fpu-save-the-vreg-registers-hig.patch - -Patch1001: 1001-i386-cpu-Clear-FEAT_XSAVE_XSS_LO-HI-leafs-when-CPUID.patch -Patch1002: 1002-i386-cpu-Mask-with-XCR0-XSS-mask-for-FEAT_XSAVE_XCR0.patch -Patch1003: 1003-i386-cpuid-Decrease-cpuid_i-when-skipping-CPUID-leaf.patch -Patch1004: 1004-i386-cpuid-Move-leaf-7-to-correct-group.patch - -Patch1005: 1005-doc-update-AMD-SEV-to-include-Live-migration-flow.patch -Patch1006: 1006-migration.json-add-AMD-SEV-specific-migration-parame.patch -Patch1007: 1007-confidential-guest-support-introduce-ConfidentialGue.patch -Patch1008: 1008-target-i386-sev-provide-callback-to-setup-outgoing-c.patch -Patch1009: 1009-target-i386-sev-do-not-create-launch-context-for-an-.patch -Patch1010: 1010-target-i386-sev-add-support-to-encrypt-the-outgoing-.patch -Patch1011: 1011-target-i386-sev-add-support-to-load-incoming-encrypt.patch -Patch1012: 1012-kvm-Add-support-for-SEV-shared-regions-list-and-KVM_.patch -Patch1013: 1013-migration-add-support-to-migrate-shared-regions-list.patch -Patch1014: 1014-migration-ram-add-support-to-send-encrypted-pages.patch -Patch1015: 1015-migration-ram-Force-encrypted-status-for-flash0-flas.patch -Patch1016: 1016-kvm-Add-support-for-userspace-MSR-filtering-and-hand.patch -Patch1017: 1017-target-i386-sev-Return-0-if-sev_send_get_packet_len-.patch -Patch1018: 1018-migration-ram-Force-encrypted-status-for-VGA-vram.patch -Patch1019: 1019-target-i386-sev-Clear-shared_regions_list-when-reboo.patch -Patch1020: 1020-migration-ram-Fix-calculation-of-gfn-correpond-to-a-.patch -Patch1021: 1021-target-i386-Introduce-header-file-csv.h.patch -Patch1022: 1022-target-i386-csv-Read-cert-chain-from-file-when-prepa.patch -Patch1023: 1023-target-i386-csv-add-support-to-queue-the-outgoing-pa.patch -Patch1024: 1024-target-i386-csv-add-support-to-encrypt-the-outgoing-.patch -Patch1025: 1025-target-i386-csv-add-support-to-queue-the-incoming-pa.patch -Patch1026: 1026-target-i386-csv-add-support-to-load-incoming-encrypt.patch -Patch1027: 1027-migration-ram-Accelerate-the-transmission-of-CSV-gue.patch -Patch1028: 1028-migration-ram-Accelerate-the-loading-of-CSV-guest-s-.patch -Patch1029: 1029-target-i386-csv-Add-support-for-migrate-VMSA-for-CSV.patch -Patch1030: 1030-target-i386-get-set-migrate-GHCB-state.patch -Patch1031: 1031-target-i386-kvm-Fix-the-resettable-info-when-emulate.patch -Patch1032: 1032-kvm-Add-support-for-CSV2-reboot.patch -Patch1033: 1033-target-i386-csv-Add-CSV3-context.patch -Patch1034: 1034-target-i386-csv-Add-command-to-initialize-CSV3-conte.patch -Patch1035: 1035-target-i386-csv-Add-command-to-load-data-to-CSV3-gue.patch -Patch1036: 1036-target-i386-csv-Add-command-to-load-vmcb-to-CSV3-gue.patch -Patch1037: 1037-target-i386-cpu-Populate-CPUID-0x8000_001F-when-CSV3.patch -Patch1038: 1038-target-i386-csv-Do-not-register-unregister-guest-sec.patch -Patch1039: 1039-target-i386-csv-Load-initial-image-to-private-memory.patch -Patch1040: 1040-vga-Force-full-update-for-CSV3-guest.patch -Patch1041: 1041-vfio-Only-map-shared-region-for-CSV3-virtual-machine.patch -Patch1042: 1042-linux-headers-update-kernel-headers-to-include-CSV3-.patch -Patch1043: 1043-target-i386-csv-Add-support-to-migrate-the-outgoing-.patch -Patch1044: 1044-target-i386-csv-Add-support-to-migrate-the-incoming-.patch -Patch1045: 1045-target-i386-csv-Add-support-to-migrate-the-outgoing-.patch -Patch1046: 1046-target-i386-csv-Add-support-to-migrate-the-incoming-.patch -Patch1047: 1047-target-i386-sev-Fix-incompatibility-between-SEV-and-.patch -Patch1048: 1048-target-i386-sev-Add-support-for-reuse-ASID-for-diffe.patch -Patch1049: 1049-target-i386-Add-Hygon-Dhyana-v3-CPU-model.patch -Patch1050: 1050-target-i386-Add-new-Hygon-Dharma-CPU-model.patch -Patch1051: 1051-vfio-Add-vfio-based-mediated-hct-support.patch -Patch1052: 1052-hw-net-virtio-net-Update-event-idx-if-guest-has-made.patch -Patch1053: 1053-target-i386-csv-Release-CSV3-shared-pages-after-unma.patch -Patch1054: 1054-virtio-net-Fix-network-stall-at-the-host-side-waitin.patch - ExclusiveArch: x86_64 aarch64 loongarch64 BuildRequires: meson >= %{meson_version} @@ -1925,6 +1828,9 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %endif %changelog +* Tue Oct 29 2024 Xuchun Shang - 2:8.2.0-20 +- Update the src package and release for version 20 + * Thu Sep 26 2024 Wenlong Zhang - 2:8.2.0-19 - enable block_rbd for loongarch64