!1055 [sync] PR-1053: QEMU update to version 8.2.0-26:
From: @openeuler-sync-bot Reviewed-by: @imxcc Signed-off-by: @imxcc
This commit is contained in:
commit
4f20e01d35
64
9pfs-fix-crash-on-Treaddir-request.patch
Normal file
64
9pfs-fix-crash-on-Treaddir-request.patch
Normal file
@ -0,0 +1,64 @@
|
||||
From 93e7987cb5a7b33c2d2e0a02b7f310955ca11851 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Schoenebeck <qemu_oss@crudebyte.com>
|
||||
Date: Tue, 5 Nov 2024 11:25:26 +0100
|
||||
Subject: [PATCH] 9pfs: fix crash on 'Treaddir' request
|
||||
|
||||
A bad (broken or malicious) 9p client (guest) could cause QEMU host to
|
||||
crash by sending a 9p 'Treaddir' request with a numeric file ID (FID) that
|
||||
was previously opened for a file instead of an expected directory:
|
||||
|
||||
#0 0x0000762aff8f4919 in __GI___rewinddir (dirp=0xf) at
|
||||
../sysdeps/unix/sysv/linux/rewinddir.c:29
|
||||
#1 0x0000557b7625fb40 in do_readdir_many (pdu=0x557bb67d2eb0,
|
||||
fidp=0x557bb67955b0, entries=0x762afe9fff58, offset=0, maxsize=131072,
|
||||
dostat=<optimized out>) at ../hw/9pfs/codir.c:101
|
||||
#2 v9fs_co_readdir_many (pdu=pdu@entry=0x557bb67d2eb0,
|
||||
fidp=fidp@entry=0x557bb67955b0, entries=entries@entry=0x762afe9fff58,
|
||||
offset=0, maxsize=131072, dostat=false) at ../hw/9pfs/codir.c:226
|
||||
#3 0x0000557b7625c1f9 in v9fs_do_readdir (pdu=0x557bb67d2eb0,
|
||||
fidp=0x557bb67955b0, offset=<optimized out>,
|
||||
max_count=<optimized out>) at ../hw/9pfs/9p.c:2488
|
||||
#4 v9fs_readdir (opaque=0x557bb67d2eb0) at ../hw/9pfs/9p.c:2602
|
||||
|
||||
That's because V9fsFidOpenState was declared as union type. So the
|
||||
same memory region is used for either an open POSIX file handle (int),
|
||||
or a POSIX DIR* pointer, etc., so 9p server incorrectly used the
|
||||
previously opened (valid) POSIX file handle (0xf) as DIR* pointer,
|
||||
eventually causing a crash in glibc's rewinddir() function.
|
||||
|
||||
Root cause was therefore a missing check in 9p server's 'Treaddir'
|
||||
request handler, which must ensure that the client supplied FID was
|
||||
really opened as directory stream before trying to access the
|
||||
aforementioned union and its DIR* member.
|
||||
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Fixes: d62dbb51f7 ("virtio-9p: Add fidtype so that we can do type ...")
|
||||
Reported-by: Akihiro Suda <suda.kyoto@gmail.com>
|
||||
Tested-by: Akihiro Suda <suda.kyoto@gmail.com>
|
||||
Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
|
||||
Reviewed-by: Greg Kurz <groug@kaod.org>
|
||||
Message-Id: <E1t8GnN-002RS8-E2@kylie.crudebyte.com>
|
||||
Signed-off-by: Zhongrui Tang <tangzhongrui_yewu@cmss.chinamobile.com>
|
||||
---
|
||||
hw/9pfs/9p.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
|
||||
index af636cfb2d..9a291d1b51 100644
|
||||
--- a/hw/9pfs/9p.c
|
||||
+++ b/hw/9pfs/9p.c
|
||||
@@ -2587,6 +2587,11 @@ static void coroutine_fn v9fs_readdir(void *opaque)
|
||||
retval = -EINVAL;
|
||||
goto out_nofid;
|
||||
}
|
||||
+ if (fidp->fid_type != P9_FID_DIR) {
|
||||
+ warn_report_once("9p: bad client: T_readdir on non-directory stream");
|
||||
+ retval = -ENOTDIR;
|
||||
+ goto out;
|
||||
+ }
|
||||
if (!fidp->fs.dir.stream) {
|
||||
retval = -EINVAL;
|
||||
goto out;
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
52
accel-tcg-Fix-typo-causing-tb-page_addr-1-to-not-be-.patch
Normal file
52
accel-tcg-Fix-typo-causing-tb-page_addr-1-to-not-be-.patch
Normal file
@ -0,0 +1,52 @@
|
||||
From 378d79fa6b9410af702776ffa93865219f273380 Mon Sep 17 00:00:00 2001
|
||||
From: Anton Johansson <anjo@rev.ng>
|
||||
Date: Wed, 12 Jun 2024 15:30:31 +0200
|
||||
Subject: [PATCH] accel/tcg: Fix typo causing tb->page_addr[1] to not be
|
||||
recorded
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
For TBs crossing page boundaries, the 2nd page will never be
|
||||
recorded/removed, as the index of the 2nd page is computed from the
|
||||
address of the 1st page. This is due to a typo, fix it.
|
||||
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Fixes: deba78709a ("accel/tcg: Always lock pages before translation")
|
||||
Signed-off-by: Anton Johansson <anjo@rev.ng>
|
||||
Reviewed-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
|
||||
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
|
||||
Message-Id: <20240612133031.15298-1-anjo@rev.ng>
|
||||
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
(cherry picked from commit 3b279f73fa37bec8d3ba04a15f5153d6491cffaf)
|
||||
Signed-off-by: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
|
||||
---
|
||||
accel/tcg/tb-maint.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c
|
||||
index 3d2a896220..eb37f9e8a8 100644
|
||||
--- a/accel/tcg/tb-maint.c
|
||||
+++ b/accel/tcg/tb-maint.c
|
||||
@@ -712,7 +712,7 @@ static void tb_record(TranslationBlock *tb)
|
||||
tb_page_addr_t paddr0 = tb_page_addr0(tb);
|
||||
tb_page_addr_t paddr1 = tb_page_addr1(tb);
|
||||
tb_page_addr_t pindex0 = paddr0 >> TARGET_PAGE_BITS;
|
||||
- tb_page_addr_t pindex1 = paddr0 >> TARGET_PAGE_BITS;
|
||||
+ tb_page_addr_t pindex1 = paddr1 >> TARGET_PAGE_BITS;
|
||||
|
||||
assert(paddr0 != -1);
|
||||
if (unlikely(paddr1 != -1) && pindex0 != pindex1) {
|
||||
@@ -744,7 +744,7 @@ static void tb_remove(TranslationBlock *tb)
|
||||
tb_page_addr_t paddr0 = tb_page_addr0(tb);
|
||||
tb_page_addr_t paddr1 = tb_page_addr1(tb);
|
||||
tb_page_addr_t pindex0 = paddr0 >> TARGET_PAGE_BITS;
|
||||
- tb_page_addr_t pindex1 = paddr0 >> TARGET_PAGE_BITS;
|
||||
+ tb_page_addr_t pindex1 = paddr1 >> TARGET_PAGE_BITS;
|
||||
|
||||
assert(paddr0 != -1);
|
||||
if (unlikely(paddr1 != -1) && pindex0 != pindex1) {
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
39
exec-memop-Remove-unused-memop_big_endian-helper.patch
Normal file
39
exec-memop-Remove-unused-memop_big_endian-helper.patch
Normal file
@ -0,0 +1,39 @@
|
||||
From 9a12c439cb9d1e59175be4b96adf0732dca39db3 Mon Sep 17 00:00:00 2001
|
||||
From: Zhang Jiao <zhangjiao2_yewu@cmss.chinamobile.com>
|
||||
Date: Tue, 12 Nov 2024 13:30:29 +0800
|
||||
Subject: [PATCH] exec/memop: Remove unused memop_big_endian() helper
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
cheery-pick from 5caa0e1b1bf8597ea7277391b0e17e8584fad18f
|
||||
|
||||
Last use of memop_big_endian() was removed in commit 592134617c9
|
||||
("accel/tcg: Reorg system mode store helpers").
|
||||
|
||||
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
Reviewed-by: Thomas Huth <thuth@redhat.com>
|
||||
Message-Id: <20241003234211.53644-3-philmd@linaro.org>
|
||||
Signed-off-by: Zhang Jiao <zhangjiao2_yewu@cmss.chinamobile.com>
|
||||
---
|
||||
include/exec/memop.h | 6 ------
|
||||
1 file changed, 6 deletions(-)
|
||||
|
||||
diff --git a/include/exec/memop.h b/include/exec/memop.h
|
||||
index a86dc6743a..5b9064819c 100644
|
||||
--- a/include/exec/memop.h
|
||||
+++ b/include/exec/memop.h
|
||||
@@ -164,10 +164,4 @@ static inline MemOp size_memop(unsigned size)
|
||||
return ctz32(size);
|
||||
}
|
||||
|
||||
-/* Big endianness from MemOp. */
|
||||
-static inline bool memop_big_endian(MemOp op)
|
||||
-{
|
||||
- return (op & MO_BSWAP) == MO_BE;
|
||||
-}
|
||||
-
|
||||
#endif
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
211
hvf-arm-Fix-encodings-for-ID_AA64PFR1_EL1-and-debug-.patch
Normal file
211
hvf-arm-Fix-encodings-for-ID_AA64PFR1_EL1-and-debug-.patch
Normal file
@ -0,0 +1,211 @@
|
||||
From ab7c657e05f896600c310c74e7584fc345ff235c Mon Sep 17 00:00:00 2001
|
||||
From: Zenghui Yu <zenghui.yu@linux.dev>
|
||||
Date: Thu, 23 May 2024 16:06:19 +0100
|
||||
Subject: [PATCH] hvf: arm: Fix encodings for ID_AA64PFR1_EL1 and debug System
|
||||
registers
|
||||
|
||||
We wrongly encoded ID_AA64PFR1_EL1 using {3,0,0,4,2} in hvf_sreg_match[] so
|
||||
we fail to get the expected ARMCPRegInfo from cp_regs hash table with the
|
||||
wrong key.
|
||||
|
||||
Fix it with the correct encoding {3,0,0,4,1}. With that fixed, the Linux
|
||||
guest can properly detect FEAT_SSBS2 on my M1 HW.
|
||||
|
||||
All DBG{B,W}{V,C}R_EL1 registers are also wrongly encoded with op0 == 14.
|
||||
It happens to work because HVF_SYSREG(CRn, CRm, 14, op1, op2) equals to
|
||||
HVF_SYSREG(CRn, CRm, 2, op1, op2), by definition. But we shouldn't rely on
|
||||
it.
|
||||
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Fixes: a1477da3ddeb ("hvf: Add Apple Silicon support")
|
||||
Signed-off-by: Zenghui Yu <zenghui.yu@linux.dev>
|
||||
Reviewed-by: Alexander Graf <agraf@csgraf.de>
|
||||
Message-id: 20240503153453.54389-1-zenghui.yu@linux.dev
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
(cherry picked from commit 19ed42e8adc87a3c739f61608b66a046bb9237e2)
|
||||
Signed-off-by: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
|
||||
---
|
||||
target/arm/hvf/hvf.c | 160 +++++++++++++++++++++----------------------
|
||||
1 file changed, 80 insertions(+), 80 deletions(-)
|
||||
|
||||
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
|
||||
index b4e98a99e2..d7cc00a084 100644
|
||||
--- a/target/arm/hvf/hvf.c
|
||||
+++ b/target/arm/hvf/hvf.c
|
||||
@@ -392,85 +392,85 @@ struct hvf_sreg_match {
|
||||
};
|
||||
|
||||
static struct hvf_sreg_match hvf_sreg_match[] = {
|
||||
- { HV_SYS_REG_DBGBVR0_EL1, HVF_SYSREG(0, 0, 14, 0, 4) },
|
||||
- { HV_SYS_REG_DBGBCR0_EL1, HVF_SYSREG(0, 0, 14, 0, 5) },
|
||||
- { HV_SYS_REG_DBGWVR0_EL1, HVF_SYSREG(0, 0, 14, 0, 6) },
|
||||
- { HV_SYS_REG_DBGWCR0_EL1, HVF_SYSREG(0, 0, 14, 0, 7) },
|
||||
-
|
||||
- { HV_SYS_REG_DBGBVR1_EL1, HVF_SYSREG(0, 1, 14, 0, 4) },
|
||||
- { HV_SYS_REG_DBGBCR1_EL1, HVF_SYSREG(0, 1, 14, 0, 5) },
|
||||
- { HV_SYS_REG_DBGWVR1_EL1, HVF_SYSREG(0, 1, 14, 0, 6) },
|
||||
- { HV_SYS_REG_DBGWCR1_EL1, HVF_SYSREG(0, 1, 14, 0, 7) },
|
||||
-
|
||||
- { HV_SYS_REG_DBGBVR2_EL1, HVF_SYSREG(0, 2, 14, 0, 4) },
|
||||
- { HV_SYS_REG_DBGBCR2_EL1, HVF_SYSREG(0, 2, 14, 0, 5) },
|
||||
- { HV_SYS_REG_DBGWVR2_EL1, HVF_SYSREG(0, 2, 14, 0, 6) },
|
||||
- { HV_SYS_REG_DBGWCR2_EL1, HVF_SYSREG(0, 2, 14, 0, 7) },
|
||||
-
|
||||
- { HV_SYS_REG_DBGBVR3_EL1, HVF_SYSREG(0, 3, 14, 0, 4) },
|
||||
- { HV_SYS_REG_DBGBCR3_EL1, HVF_SYSREG(0, 3, 14, 0, 5) },
|
||||
- { HV_SYS_REG_DBGWVR3_EL1, HVF_SYSREG(0, 3, 14, 0, 6) },
|
||||
- { HV_SYS_REG_DBGWCR3_EL1, HVF_SYSREG(0, 3, 14, 0, 7) },
|
||||
-
|
||||
- { HV_SYS_REG_DBGBVR4_EL1, HVF_SYSREG(0, 4, 14, 0, 4) },
|
||||
- { HV_SYS_REG_DBGBCR4_EL1, HVF_SYSREG(0, 4, 14, 0, 5) },
|
||||
- { HV_SYS_REG_DBGWVR4_EL1, HVF_SYSREG(0, 4, 14, 0, 6) },
|
||||
- { HV_SYS_REG_DBGWCR4_EL1, HVF_SYSREG(0, 4, 14, 0, 7) },
|
||||
-
|
||||
- { HV_SYS_REG_DBGBVR5_EL1, HVF_SYSREG(0, 5, 14, 0, 4) },
|
||||
- { HV_SYS_REG_DBGBCR5_EL1, HVF_SYSREG(0, 5, 14, 0, 5) },
|
||||
- { HV_SYS_REG_DBGWVR5_EL1, HVF_SYSREG(0, 5, 14, 0, 6) },
|
||||
- { HV_SYS_REG_DBGWCR5_EL1, HVF_SYSREG(0, 5, 14, 0, 7) },
|
||||
-
|
||||
- { HV_SYS_REG_DBGBVR6_EL1, HVF_SYSREG(0, 6, 14, 0, 4) },
|
||||
- { HV_SYS_REG_DBGBCR6_EL1, HVF_SYSREG(0, 6, 14, 0, 5) },
|
||||
- { HV_SYS_REG_DBGWVR6_EL1, HVF_SYSREG(0, 6, 14, 0, 6) },
|
||||
- { HV_SYS_REG_DBGWCR6_EL1, HVF_SYSREG(0, 6, 14, 0, 7) },
|
||||
-
|
||||
- { HV_SYS_REG_DBGBVR7_EL1, HVF_SYSREG(0, 7, 14, 0, 4) },
|
||||
- { HV_SYS_REG_DBGBCR7_EL1, HVF_SYSREG(0, 7, 14, 0, 5) },
|
||||
- { HV_SYS_REG_DBGWVR7_EL1, HVF_SYSREG(0, 7, 14, 0, 6) },
|
||||
- { HV_SYS_REG_DBGWCR7_EL1, HVF_SYSREG(0, 7, 14, 0, 7) },
|
||||
-
|
||||
- { HV_SYS_REG_DBGBVR8_EL1, HVF_SYSREG(0, 8, 14, 0, 4) },
|
||||
- { HV_SYS_REG_DBGBCR8_EL1, HVF_SYSREG(0, 8, 14, 0, 5) },
|
||||
- { HV_SYS_REG_DBGWVR8_EL1, HVF_SYSREG(0, 8, 14, 0, 6) },
|
||||
- { HV_SYS_REG_DBGWCR8_EL1, HVF_SYSREG(0, 8, 14, 0, 7) },
|
||||
-
|
||||
- { HV_SYS_REG_DBGBVR9_EL1, HVF_SYSREG(0, 9, 14, 0, 4) },
|
||||
- { HV_SYS_REG_DBGBCR9_EL1, HVF_SYSREG(0, 9, 14, 0, 5) },
|
||||
- { HV_SYS_REG_DBGWVR9_EL1, HVF_SYSREG(0, 9, 14, 0, 6) },
|
||||
- { HV_SYS_REG_DBGWCR9_EL1, HVF_SYSREG(0, 9, 14, 0, 7) },
|
||||
-
|
||||
- { HV_SYS_REG_DBGBVR10_EL1, HVF_SYSREG(0, 10, 14, 0, 4) },
|
||||
- { HV_SYS_REG_DBGBCR10_EL1, HVF_SYSREG(0, 10, 14, 0, 5) },
|
||||
- { HV_SYS_REG_DBGWVR10_EL1, HVF_SYSREG(0, 10, 14, 0, 6) },
|
||||
- { HV_SYS_REG_DBGWCR10_EL1, HVF_SYSREG(0, 10, 14, 0, 7) },
|
||||
-
|
||||
- { HV_SYS_REG_DBGBVR11_EL1, HVF_SYSREG(0, 11, 14, 0, 4) },
|
||||
- { HV_SYS_REG_DBGBCR11_EL1, HVF_SYSREG(0, 11, 14, 0, 5) },
|
||||
- { HV_SYS_REG_DBGWVR11_EL1, HVF_SYSREG(0, 11, 14, 0, 6) },
|
||||
- { HV_SYS_REG_DBGWCR11_EL1, HVF_SYSREG(0, 11, 14, 0, 7) },
|
||||
-
|
||||
- { HV_SYS_REG_DBGBVR12_EL1, HVF_SYSREG(0, 12, 14, 0, 4) },
|
||||
- { HV_SYS_REG_DBGBCR12_EL1, HVF_SYSREG(0, 12, 14, 0, 5) },
|
||||
- { HV_SYS_REG_DBGWVR12_EL1, HVF_SYSREG(0, 12, 14, 0, 6) },
|
||||
- { HV_SYS_REG_DBGWCR12_EL1, HVF_SYSREG(0, 12, 14, 0, 7) },
|
||||
-
|
||||
- { HV_SYS_REG_DBGBVR13_EL1, HVF_SYSREG(0, 13, 14, 0, 4) },
|
||||
- { HV_SYS_REG_DBGBCR13_EL1, HVF_SYSREG(0, 13, 14, 0, 5) },
|
||||
- { HV_SYS_REG_DBGWVR13_EL1, HVF_SYSREG(0, 13, 14, 0, 6) },
|
||||
- { HV_SYS_REG_DBGWCR13_EL1, HVF_SYSREG(0, 13, 14, 0, 7) },
|
||||
-
|
||||
- { HV_SYS_REG_DBGBVR14_EL1, HVF_SYSREG(0, 14, 14, 0, 4) },
|
||||
- { HV_SYS_REG_DBGBCR14_EL1, HVF_SYSREG(0, 14, 14, 0, 5) },
|
||||
- { HV_SYS_REG_DBGWVR14_EL1, HVF_SYSREG(0, 14, 14, 0, 6) },
|
||||
- { HV_SYS_REG_DBGWCR14_EL1, HVF_SYSREG(0, 14, 14, 0, 7) },
|
||||
-
|
||||
- { HV_SYS_REG_DBGBVR15_EL1, HVF_SYSREG(0, 15, 14, 0, 4) },
|
||||
- { HV_SYS_REG_DBGBCR15_EL1, HVF_SYSREG(0, 15, 14, 0, 5) },
|
||||
- { HV_SYS_REG_DBGWVR15_EL1, HVF_SYSREG(0, 15, 14, 0, 6) },
|
||||
- { HV_SYS_REG_DBGWCR15_EL1, HVF_SYSREG(0, 15, 14, 0, 7) },
|
||||
+ { HV_SYS_REG_DBGBVR0_EL1, HVF_SYSREG(0, 0, 2, 0, 4) },
|
||||
+ { HV_SYS_REG_DBGBCR0_EL1, HVF_SYSREG(0, 0, 2, 0, 5) },
|
||||
+ { HV_SYS_REG_DBGWVR0_EL1, HVF_SYSREG(0, 0, 2, 0, 6) },
|
||||
+ { HV_SYS_REG_DBGWCR0_EL1, HVF_SYSREG(0, 0, 2, 0, 7) },
|
||||
+
|
||||
+ { HV_SYS_REG_DBGBVR1_EL1, HVF_SYSREG(0, 1, 2, 0, 4) },
|
||||
+ { HV_SYS_REG_DBGBCR1_EL1, HVF_SYSREG(0, 1, 2, 0, 5) },
|
||||
+ { HV_SYS_REG_DBGWVR1_EL1, HVF_SYSREG(0, 1, 2, 0, 6) },
|
||||
+ { HV_SYS_REG_DBGWCR1_EL1, HVF_SYSREG(0, 1, 2, 0, 7) },
|
||||
+
|
||||
+ { HV_SYS_REG_DBGBVR2_EL1, HVF_SYSREG(0, 2, 2, 0, 4) },
|
||||
+ { HV_SYS_REG_DBGBCR2_EL1, HVF_SYSREG(0, 2, 2, 0, 5) },
|
||||
+ { HV_SYS_REG_DBGWVR2_EL1, HVF_SYSREG(0, 2, 2, 0, 6) },
|
||||
+ { HV_SYS_REG_DBGWCR2_EL1, HVF_SYSREG(0, 2, 2, 0, 7) },
|
||||
+
|
||||
+ { HV_SYS_REG_DBGBVR3_EL1, HVF_SYSREG(0, 3, 2, 0, 4) },
|
||||
+ { HV_SYS_REG_DBGBCR3_EL1, HVF_SYSREG(0, 3, 2, 0, 5) },
|
||||
+ { HV_SYS_REG_DBGWVR3_EL1, HVF_SYSREG(0, 3, 2, 0, 6) },
|
||||
+ { HV_SYS_REG_DBGWCR3_EL1, HVF_SYSREG(0, 3, 2, 0, 7) },
|
||||
+
|
||||
+ { HV_SYS_REG_DBGBVR4_EL1, HVF_SYSREG(0, 4, 2, 0, 4) },
|
||||
+ { HV_SYS_REG_DBGBCR4_EL1, HVF_SYSREG(0, 4, 2, 0, 5) },
|
||||
+ { HV_SYS_REG_DBGWVR4_EL1, HVF_SYSREG(0, 4, 2, 0, 6) },
|
||||
+ { HV_SYS_REG_DBGWCR4_EL1, HVF_SYSREG(0, 4, 2, 0, 7) },
|
||||
+
|
||||
+ { HV_SYS_REG_DBGBVR5_EL1, HVF_SYSREG(0, 5, 2, 0, 4) },
|
||||
+ { HV_SYS_REG_DBGBCR5_EL1, HVF_SYSREG(0, 5, 2, 0, 5) },
|
||||
+ { HV_SYS_REG_DBGWVR5_EL1, HVF_SYSREG(0, 5, 2, 0, 6) },
|
||||
+ { HV_SYS_REG_DBGWCR5_EL1, HVF_SYSREG(0, 5, 2, 0, 7) },
|
||||
+
|
||||
+ { HV_SYS_REG_DBGBVR6_EL1, HVF_SYSREG(0, 6, 2, 0, 4) },
|
||||
+ { HV_SYS_REG_DBGBCR6_EL1, HVF_SYSREG(0, 6, 2, 0, 5) },
|
||||
+ { HV_SYS_REG_DBGWVR6_EL1, HVF_SYSREG(0, 6, 2, 0, 6) },
|
||||
+ { HV_SYS_REG_DBGWCR6_EL1, HVF_SYSREG(0, 6, 2, 0, 7) },
|
||||
+
|
||||
+ { HV_SYS_REG_DBGBVR7_EL1, HVF_SYSREG(0, 7, 2, 0, 4) },
|
||||
+ { HV_SYS_REG_DBGBCR7_EL1, HVF_SYSREG(0, 7, 2, 0, 5) },
|
||||
+ { HV_SYS_REG_DBGWVR7_EL1, HVF_SYSREG(0, 7, 2, 0, 6) },
|
||||
+ { HV_SYS_REG_DBGWCR7_EL1, HVF_SYSREG(0, 7, 2, 0, 7) },
|
||||
+
|
||||
+ { HV_SYS_REG_DBGBVR8_EL1, HVF_SYSREG(0, 8, 2, 0, 4) },
|
||||
+ { HV_SYS_REG_DBGBCR8_EL1, HVF_SYSREG(0, 8, 2, 0, 5) },
|
||||
+ { HV_SYS_REG_DBGWVR8_EL1, HVF_SYSREG(0, 8, 2, 0, 6) },
|
||||
+ { HV_SYS_REG_DBGWCR8_EL1, HVF_SYSREG(0, 8, 2, 0, 7) },
|
||||
+
|
||||
+ { HV_SYS_REG_DBGBVR9_EL1, HVF_SYSREG(0, 9, 2, 0, 4) },
|
||||
+ { HV_SYS_REG_DBGBCR9_EL1, HVF_SYSREG(0, 9, 2, 0, 5) },
|
||||
+ { HV_SYS_REG_DBGWVR9_EL1, HVF_SYSREG(0, 9, 2, 0, 6) },
|
||||
+ { HV_SYS_REG_DBGWCR9_EL1, HVF_SYSREG(0, 9, 2, 0, 7) },
|
||||
+
|
||||
+ { HV_SYS_REG_DBGBVR10_EL1, HVF_SYSREG(0, 10, 2, 0, 4) },
|
||||
+ { HV_SYS_REG_DBGBCR10_EL1, HVF_SYSREG(0, 10, 2, 0, 5) },
|
||||
+ { HV_SYS_REG_DBGWVR10_EL1, HVF_SYSREG(0, 10, 2, 0, 6) },
|
||||
+ { HV_SYS_REG_DBGWCR10_EL1, HVF_SYSREG(0, 10, 2, 0, 7) },
|
||||
+
|
||||
+ { HV_SYS_REG_DBGBVR11_EL1, HVF_SYSREG(0, 11, 2, 0, 4) },
|
||||
+ { HV_SYS_REG_DBGBCR11_EL1, HVF_SYSREG(0, 11, 2, 0, 5) },
|
||||
+ { HV_SYS_REG_DBGWVR11_EL1, HVF_SYSREG(0, 11, 2, 0, 6) },
|
||||
+ { HV_SYS_REG_DBGWCR11_EL1, HVF_SYSREG(0, 11, 2, 0, 7) },
|
||||
+
|
||||
+ { HV_SYS_REG_DBGBVR12_EL1, HVF_SYSREG(0, 12, 2, 0, 4) },
|
||||
+ { HV_SYS_REG_DBGBCR12_EL1, HVF_SYSREG(0, 12, 2, 0, 5) },
|
||||
+ { HV_SYS_REG_DBGWVR12_EL1, HVF_SYSREG(0, 12, 2, 0, 6) },
|
||||
+ { HV_SYS_REG_DBGWCR12_EL1, HVF_SYSREG(0, 12, 2, 0, 7) },
|
||||
+
|
||||
+ { HV_SYS_REG_DBGBVR13_EL1, HVF_SYSREG(0, 13, 2, 0, 4) },
|
||||
+ { HV_SYS_REG_DBGBCR13_EL1, HVF_SYSREG(0, 13, 2, 0, 5) },
|
||||
+ { HV_SYS_REG_DBGWVR13_EL1, HVF_SYSREG(0, 13, 2, 0, 6) },
|
||||
+ { HV_SYS_REG_DBGWCR13_EL1, HVF_SYSREG(0, 13, 2, 0, 7) },
|
||||
+
|
||||
+ { HV_SYS_REG_DBGBVR14_EL1, HVF_SYSREG(0, 14, 2, 0, 4) },
|
||||
+ { HV_SYS_REG_DBGBCR14_EL1, HVF_SYSREG(0, 14, 2, 0, 5) },
|
||||
+ { HV_SYS_REG_DBGWVR14_EL1, HVF_SYSREG(0, 14, 2, 0, 6) },
|
||||
+ { HV_SYS_REG_DBGWCR14_EL1, HVF_SYSREG(0, 14, 2, 0, 7) },
|
||||
+
|
||||
+ { HV_SYS_REG_DBGBVR15_EL1, HVF_SYSREG(0, 15, 2, 0, 4) },
|
||||
+ { HV_SYS_REG_DBGBCR15_EL1, HVF_SYSREG(0, 15, 2, 0, 5) },
|
||||
+ { HV_SYS_REG_DBGWVR15_EL1, HVF_SYSREG(0, 15, 2, 0, 6) },
|
||||
+ { HV_SYS_REG_DBGWCR15_EL1, HVF_SYSREG(0, 15, 2, 0, 7) },
|
||||
|
||||
#ifdef SYNC_NO_RAW_REGS
|
||||
/*
|
||||
@@ -482,7 +482,7 @@ static struct hvf_sreg_match hvf_sreg_match[] = {
|
||||
{ HV_SYS_REG_MPIDR_EL1, HVF_SYSREG(0, 0, 3, 0, 5) },
|
||||
{ HV_SYS_REG_ID_AA64PFR0_EL1, HVF_SYSREG(0, 4, 3, 0, 0) },
|
||||
#endif
|
||||
- { HV_SYS_REG_ID_AA64PFR1_EL1, HVF_SYSREG(0, 4, 3, 0, 2) },
|
||||
+ { HV_SYS_REG_ID_AA64PFR1_EL1, HVF_SYSREG(0, 4, 3, 0, 1) },
|
||||
{ HV_SYS_REG_ID_AA64DFR0_EL1, HVF_SYSREG(0, 5, 3, 0, 0) },
|
||||
{ HV_SYS_REG_ID_AA64DFR1_EL1, HVF_SYSREG(0, 5, 3, 0, 1) },
|
||||
{ HV_SYS_REG_ID_AA64ISAR0_EL1, HVF_SYSREG(0, 6, 3, 0, 0) },
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
50
hw-arm-mps2-tz.c-fix-RX-TX-interrupts-order.patch
Normal file
50
hw-arm-mps2-tz.c-fix-RX-TX-interrupts-order.patch
Normal file
@ -0,0 +1,50 @@
|
||||
From 322f39889ff60a6fda87d7d95a6f233efb558e8a Mon Sep 17 00:00:00 2001
|
||||
From: Marco Palumbi <Marco.Palumbi@tii.ae>
|
||||
Date: Thu, 1 Aug 2024 10:15:02 +0100
|
||||
Subject: [PATCH] hw/arm/mps2-tz.c: fix RX/TX interrupts order
|
||||
|
||||
The order of the RX and TX interrupts are swapped.
|
||||
This commit fixes the order as per the following documents:
|
||||
* https://developer.arm.com/documentation/dai0505/latest/
|
||||
* https://developer.arm.com/documentation/dai0521/latest/
|
||||
* https://developer.arm.com/documentation/dai0524/latest/
|
||||
* https://developer.arm.com/documentation/dai0547/latest/
|
||||
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Signed-off-by: Marco Palumbi <Marco.Palumbi@tii.ae>
|
||||
Message-id: 20240730073123.72992-1-marco@palumbi.it
|
||||
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
(cherry picked from commit 5a558be93ad628e5bed6e0ee062870f49251725c)
|
||||
Signed-off-by: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
|
||||
---
|
||||
hw/arm/mps2-tz.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
|
||||
index 668db5ed61..9d9c263ef8 100644
|
||||
--- a/hw/arm/mps2-tz.c
|
||||
+++ b/hw/arm/mps2-tz.c
|
||||
@@ -435,7 +435,7 @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
|
||||
const char *name, hwaddr size,
|
||||
const int *irqs, const PPCExtraData *extradata)
|
||||
{
|
||||
- /* The irq[] array is tx, rx, combined, in that order */
|
||||
+ /* The irq[] array is rx, tx, combined, in that order */
|
||||
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
|
||||
CMSDKAPBUART *uart = opaque;
|
||||
int i = uart - &mms->uart[0];
|
||||
@@ -447,8 +447,8 @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
|
||||
qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", mmc->apb_periph_frq);
|
||||
sysbus_realize(SYS_BUS_DEVICE(uart), &error_fatal);
|
||||
s = SYS_BUS_DEVICE(uart);
|
||||
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
|
||||
- sysbus_connect_irq(s, 1, get_sse_irq_in(mms, irqs[1]));
|
||||
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[1]));
|
||||
+ sysbus_connect_irq(s, 1, get_sse_irq_in(mms, irqs[0]));
|
||||
sysbus_connect_irq(s, 2, qdev_get_gpio_in(orgate_dev, i * 2));
|
||||
sysbus_connect_irq(s, 3, qdev_get_gpio_in(orgate_dev, i * 2 + 1));
|
||||
sysbus_connect_irq(s, 4, get_sse_irq_in(mms, irqs[2]));
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
324
hw-i386-add-mem2-option-for-qemu.patch
Normal file
324
hw-i386-add-mem2-option-for-qemu.patch
Normal file
@ -0,0 +1,324 @@
|
||||
From d29bc8738131dcaaa1a1ae2870ea29b59a137f30 Mon Sep 17 00:00:00 2001
|
||||
From: xiongmengbiao <xiongmengbiao@hygon.cn>
|
||||
Date: Wed, 29 May 2024 00:05:44 +0800
|
||||
Subject: [PATCH] hw/i386: add mem2 option for qemu
|
||||
|
||||
The '-mem2' option is used to create a set of hugepages
|
||||
of memory and map them to a fixed address range of the guest.
|
||||
|
||||
This allows some devices to easily obtain continuous host
|
||||
physical address ranges for performing DMA operations.
|
||||
|
||||
Signed-off-by: xiongmengbiao <xiongmengbiao@hygon.cn>
|
||||
---
|
||||
hw/i386/pc.c | 121 ++++++++++++++++++++++++++++++++++++++++++++
|
||||
include/hw/boards.h | 2 +
|
||||
qemu-options.hx | 12 +++++
|
||||
system/vl.c | 76 ++++++++++++++++++++++++++++
|
||||
4 files changed, 211 insertions(+)
|
||||
|
||||
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
|
||||
index 29b9964733..204e34db86 100644
|
||||
--- a/hw/i386/pc.c
|
||||
+++ b/hw/i386/pc.c
|
||||
@@ -743,6 +743,111 @@ void xen_load_linux(PCMachineState *pcms)
|
||||
x86ms->fw_cfg = fw_cfg;
|
||||
}
|
||||
|
||||
+static int try_create_2MB_page(uint32_t page_num)
|
||||
+{
|
||||
+ char nr_hp_num_s[256] = {0};
|
||||
+ char free_hp_num_s[256] = {0};
|
||||
+ const char *nr_hugepages_dir = "/sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages";
|
||||
+ const char *free_hugepages_dir = "/sys/kernel/mm/hugepages/hugepages-2048kB/free_hugepages";
|
||||
+ int nr_hp_num = -1, free_hp_num = -1, ret = -1;
|
||||
+ int nr_fd = qemu_open_old(nr_hugepages_dir, O_RDWR);
|
||||
+ int free_fd = qemu_open_old(free_hugepages_dir, O_RDONLY);
|
||||
+
|
||||
+ if (nr_fd < 0 || free_fd < 0) {
|
||||
+ error_report("%s: qemu_open failed: %s\n", __func__, strerror(errno));
|
||||
+ goto end;
|
||||
+ }
|
||||
+
|
||||
+ if (read(nr_fd, nr_hp_num_s, 256) < 0)
|
||||
+ goto end;
|
||||
+ if (read(free_fd, free_hp_num_s, 256) < 0)
|
||||
+ goto end;
|
||||
+
|
||||
+ nr_hp_num = atoi(nr_hp_num_s);
|
||||
+ free_hp_num = atoi(free_hp_num_s);
|
||||
+ if (nr_hp_num < 0 || free_hp_num < 0)
|
||||
+ goto end;
|
||||
+
|
||||
+ if (page_num <= free_hp_num) {
|
||||
+ ret = 0;
|
||||
+ goto end;
|
||||
+ }
|
||||
+
|
||||
+ nr_hp_num += (page_num - free_hp_num);
|
||||
+ snprintf (nr_hp_num_s, 256, "%d", nr_hp_num);
|
||||
+ if (write(nr_fd, nr_hp_num_s, strlen(nr_hp_num_s)) < 0)
|
||||
+ goto end;
|
||||
+
|
||||
+ ret = 0;
|
||||
+end:
|
||||
+ if (nr_fd >= 0)
|
||||
+ close(nr_fd);
|
||||
+ if (free_fd >= 0)
|
||||
+ close(free_fd);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+#define HUGEPAGE_NUM_MAX 128
|
||||
+#define HUGEPAGE_SIZE (1024*1024*2)
|
||||
+static void mem2_init(MachineState *ms, MemoryRegion *system_memory)
|
||||
+{
|
||||
+ MemoryRegion *mem2_mr;
|
||||
+ char mr_name[128] = {0};
|
||||
+ void *ram = NULL;
|
||||
+ int ret = 0, lock_fd;
|
||||
+ const char *lock_file = "/sys/kernel/mm/hugepages/hugepages-2048kB/nr_overcommit_hugepages";
|
||||
+ uint32_t page_num = ms->ram2_size / HUGEPAGE_SIZE, i;
|
||||
+
|
||||
+ if (HUGEPAGE_NUM_MAX < page_num) {
|
||||
+ error_report("\"-mem2 'size='\" needs to Less than %dM\n",
|
||||
+ (HUGEPAGE_SIZE * HUGEPAGE_NUM_MAX) / (1024 * 1024));
|
||||
+ exit(EXIT_FAILURE);
|
||||
+ }
|
||||
+
|
||||
+ // Apply for hugepages from OS and use them, which needs to be synchronized
|
||||
+ lock_fd = qemu_open_old(lock_file, O_WRONLY);
|
||||
+ if (lock_fd < 0) {
|
||||
+ error_report("%s: open %s failed: %s\n", __func__, lock_file, strerror(errno));
|
||||
+ exit(EXIT_FAILURE);
|
||||
+ }
|
||||
+
|
||||
+ while (qemu_lock_fd(lock_fd, 0, 0, true)) {
|
||||
+ if (errno != EACCES && errno != EAGAIN) {
|
||||
+ error_report("qemu_lock_fd failed: %s\n", strerror(errno));
|
||||
+ exit(EXIT_FAILURE);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /** try to create hugepage.
|
||||
+ * If there are enough free hugepages, then do nothing.
|
||||
+ */
|
||||
+ ret = try_create_2MB_page(page_num);
|
||||
+ if (ret) {
|
||||
+ error_report("%s: Failed to allocate hugepage\n", __func__);
|
||||
+ goto unlock;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < page_num; ++i) {
|
||||
+ mem2_mr = g_malloc(sizeof(*mem2_mr));
|
||||
+ ram = mmap(NULL, HUGEPAGE_SIZE, PROT_READ | PROT_WRITE,
|
||||
+ MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE | MAP_HUGETLB, -1, 0);
|
||||
+ if (ram == MAP_FAILED) {
|
||||
+ error_report("%s: mmap failed: %s", __func__, strerror(errno));
|
||||
+ goto unlock;
|
||||
+ }
|
||||
+
|
||||
+ sprintf(mr_name, "mem2-%d", i);
|
||||
+ memory_region_init_ram_ptr(mem2_mr, NULL, mr_name, HUGEPAGE_SIZE, ram);
|
||||
+ memory_region_add_subregion(system_memory, ms->ram2_base + (i * HUGEPAGE_SIZE), mem2_mr);
|
||||
+ }
|
||||
+
|
||||
+ ret = 0;
|
||||
+unlock:
|
||||
+ qemu_unlock_fd(lock_fd, 0, 0);
|
||||
+ if (ret)
|
||||
+ exit(EXIT_FAILURE);
|
||||
+}
|
||||
+
|
||||
#define PC_ROM_MIN_VGA 0xc0000
|
||||
#define PC_ROM_MIN_OPTION 0xc8000
|
||||
#define PC_ROM_MAX 0xe0000
|
||||
@@ -965,6 +1070,22 @@ void pc_memory_init(PCMachineState *pcms,
|
||||
E820_RAM);
|
||||
}
|
||||
|
||||
+ if (machine->ram2_size && machine->ram2_base) {
|
||||
+ if (0x100000000ULL + x86ms->above_4g_mem_size > machine->ram2_base) {
|
||||
+ error_report("\"-mem2 'base'\" needs to greater 0x%llx\n",
|
||||
+ 0x100000000ULL + x86ms->above_4g_mem_size);
|
||||
+ exit(EXIT_FAILURE);
|
||||
+ }
|
||||
+ if (machine->ram2_base & (HUGEPAGE_SIZE - 1) ||
|
||||
+ machine->ram2_size & (HUGEPAGE_SIZE - 1)) {
|
||||
+ error_report("\"-mem2 'base|size'\" needs to aligned to 0x%x\n", HUGEPAGE_SIZE);
|
||||
+ exit(EXIT_FAILURE);
|
||||
+ }
|
||||
+
|
||||
+ mem2_init(machine, system_memory);
|
||||
+ e820_add_entry(machine->ram2_base, machine->ram2_size, E820_RAM);
|
||||
+ }
|
||||
+
|
||||
if (pcms->sgx_epc.size != 0) {
|
||||
e820_add_entry(pcms->sgx_epc.base, pcms->sgx_epc.size, E820_RESERVED);
|
||||
}
|
||||
diff --git a/include/hw/boards.h b/include/hw/boards.h
|
||||
index da85f86efb..8ac8cad2a2 100644
|
||||
--- a/include/hw/boards.h
|
||||
+++ b/include/hw/boards.h
|
||||
@@ -389,6 +389,8 @@ struct MachineState {
|
||||
|
||||
ram_addr_t ram_size;
|
||||
ram_addr_t maxram_size;
|
||||
+ ram_addr_t ram2_base;
|
||||
+ ram_addr_t ram2_size;
|
||||
uint64_t ram_slots;
|
||||
BootConfiguration boot_config;
|
||||
char *kernel_filename;
|
||||
diff --git a/qemu-options.hx b/qemu-options.hx
|
||||
index 42fd09e4de..bc8e66a037 100644
|
||||
--- a/qemu-options.hx
|
||||
+++ b/qemu-options.hx
|
||||
@@ -5845,6 +5845,18 @@ SRST
|
||||
(qemu) qom-set /objects/iothread1 poll-max-ns 100000
|
||||
ERST
|
||||
|
||||
+DEF("mem2", HAS_ARG, QEMU_OPTION_mem2,
|
||||
+ "-mem2 base=addr[G],size=n[MG]\n"
|
||||
+ " Map guest memory using host hugepages\n"
|
||||
+ " base: starting position of guest physical address\n"
|
||||
+ " size: the size of mmaped memory\n"
|
||||
+ "NOTE: Both `base` and `size` need to be aligned according to 2MB\n",
|
||||
+ QEMU_ARCH_I386)
|
||||
+SRST
|
||||
+``-mem2 base=addr[G],size=n[MG]``
|
||||
+ Map the host's large page memory at the specified guest address
|
||||
+ so that some devices can use larger contiguous physical memory.
|
||||
+ERST
|
||||
|
||||
HXCOMM This is the last statement. Insert new options before this line!
|
||||
|
||||
diff --git a/system/vl.c b/system/vl.c
|
||||
index 8e3357c578..a1e5e68773 100644
|
||||
--- a/system/vl.c
|
||||
+++ b/system/vl.c
|
||||
@@ -173,6 +173,8 @@ static QemuPluginList plugin_list = QTAILQ_HEAD_INITIALIZER(plugin_list);
|
||||
static BlockdevOptionsQueue bdo_queue = QSIMPLEQ_HEAD_INITIALIZER(bdo_queue);
|
||||
static bool nographic = false;
|
||||
static int mem_prealloc; /* force preallocation of physical target memory */
|
||||
+static ram_addr_t ram2_base;
|
||||
+static ram_addr_t ram2_size;
|
||||
static const char *vga_model = NULL;
|
||||
static DisplayOptions dpy;
|
||||
static int num_serial_hds;
|
||||
@@ -504,6 +506,23 @@ static QemuOptsList qemu_action_opts = {
|
||||
},
|
||||
};
|
||||
|
||||
+static QemuOptsList qemu_mem2_opts = {
|
||||
+ .name = "mem2",
|
||||
+ .merge_lists = true,
|
||||
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_mem2_opts.head),
|
||||
+ .desc = {
|
||||
+ {
|
||||
+ .name = "base",
|
||||
+ .type = QEMU_OPT_SIZE,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "size",
|
||||
+ .type = QEMU_OPT_SIZE,
|
||||
+ },
|
||||
+ { /* end of list */ }
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
const char *qemu_get_vm_name(void)
|
||||
{
|
||||
return qemu_name;
|
||||
@@ -1932,6 +1951,9 @@ static void qemu_apply_machine_options(QDict *qdict)
|
||||
{
|
||||
object_set_properties_from_keyval(OBJECT(current_machine), qdict, false, &error_fatal);
|
||||
|
||||
+ current_machine->ram2_size = ram2_size;
|
||||
+ current_machine->ram2_base = ram2_base;
|
||||
+
|
||||
if (semihosting_enabled(false) && !semihosting_get_argc()) {
|
||||
/* fall back to the -kernel/-append */
|
||||
semihosting_arg_fallback(current_machine->kernel_filename, current_machine->kernel_cmdline);
|
||||
@@ -2094,11 +2116,57 @@ static void parse_memory_options(void)
|
||||
loc_pop(&loc);
|
||||
}
|
||||
|
||||
+static void set_mem2_options(void)
|
||||
+{
|
||||
+ uint64_t sz, base;
|
||||
+ const char *mem_str;
|
||||
+ QemuOpts *opts = qemu_find_opts_singleton("mem2");
|
||||
+ Location loc;
|
||||
+
|
||||
+ loc_push_none(&loc);
|
||||
+ qemu_opts_loc_restore(opts);
|
||||
+
|
||||
+ mem_str = qemu_opt_get(opts, "base");
|
||||
+ if (mem_str) {
|
||||
+ if (!*mem_str) {
|
||||
+ error_report("missing 'base' option value");
|
||||
+ exit(EXIT_FAILURE);
|
||||
+ }
|
||||
+
|
||||
+ base = qemu_opt_get_size(opts, "base", ram2_base);
|
||||
+ ram2_base = base;
|
||||
+ }
|
||||
+
|
||||
+ mem_str = qemu_opt_get(opts, "size");
|
||||
+ if (mem_str) {
|
||||
+ if (!*mem_str) {
|
||||
+ error_report("missing 'base' option value");
|
||||
+ exit(EXIT_FAILURE);
|
||||
+ }
|
||||
+
|
||||
+ sz = qemu_opt_get_size(opts, "size", ram2_size);
|
||||
+ ram2_size = sz;
|
||||
+ }
|
||||
+
|
||||
+ if (ram2_base && !ram2_size){
|
||||
+ error_report("missing 'size' option value");
|
||||
+ exit(EXIT_FAILURE);
|
||||
+ }
|
||||
+ if (!ram2_base && ram2_size){
|
||||
+ error_report("missing 'base' option value");
|
||||
+ exit(EXIT_FAILURE);
|
||||
+ }
|
||||
+
|
||||
+ loc_pop(&loc);
|
||||
+}
|
||||
+
|
||||
static void qemu_create_machine(QDict *qdict)
|
||||
{
|
||||
MachineClass *machine_class = select_machine(qdict, &error_fatal);
|
||||
object_set_machine_compat_props(machine_class->compat_props);
|
||||
|
||||
+ set_mem2_options();
|
||||
+
|
||||
current_machine = MACHINE(object_new_with_class(OBJECT_CLASS(machine_class)));
|
||||
object_property_add_child(object_get_root(), "machine",
|
||||
OBJECT(current_machine));
|
||||
@@ -2777,6 +2845,7 @@ void qemu_init(int argc, char **argv)
|
||||
qemu_add_opts(&qemu_semihosting_config_opts);
|
||||
qemu_add_opts(&qemu_fw_cfg_opts);
|
||||
qemu_add_opts(&qemu_action_opts);
|
||||
+ qemu_add_opts(&qemu_mem2_opts);
|
||||
qemu_add_run_with_opts();
|
||||
module_call_init(MODULE_INIT_OPTS);
|
||||
|
||||
@@ -3596,6 +3665,13 @@ void qemu_init(int argc, char **argv)
|
||||
case QEMU_OPTION_nouserconfig:
|
||||
/* Nothing to be parsed here. Especially, do not error out below. */
|
||||
break;
|
||||
+ case QEMU_OPTION_mem2:
|
||||
+ opts = qemu_opts_parse_noisily(qemu_find_opts("mem2"),
|
||||
+ optarg, false);
|
||||
+ if (!opts) {
|
||||
+ exit(EXIT_FAILURE);
|
||||
+ }
|
||||
+ break;
|
||||
#if defined(CONFIG_POSIX)
|
||||
case QEMU_OPTION_runas:
|
||||
if (!os_set_runas(optarg)) {
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
50
hw-i386-amd_iommu-Don-t-leak-memory-in-amdvi_update_.patch
Normal file
50
hw-i386-amd_iommu-Don-t-leak-memory-in-amdvi_update_.patch
Normal file
@ -0,0 +1,50 @@
|
||||
From 1b0d08faf1daaed39809ed1a3516eaa0f7d61534 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Maydell <peter.maydell@linaro.org>
|
||||
Date: Wed, 31 Jul 2024 18:00:19 +0100
|
||||
Subject: [PATCH] hw/i386/amd_iommu: Don't leak memory in amdvi_update_iotlb()
|
||||
|
||||
In amdvi_update_iotlb() we will only put a new entry in the hash
|
||||
table if to_cache.perm is not IOMMU_NONE. However we allocate the
|
||||
memory for the new AMDVIIOTLBEntry and for the hash table key
|
||||
regardless. This means that in the IOMMU_NONE case we will leak the
|
||||
memory we alloacted.
|
||||
|
||||
Move the allocations into the if() to the point where we know we're
|
||||
going to add the item to the hash table.
|
||||
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2452
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
Message-Id: <20240731170019.3590563-1-peter.maydell@linaro.org>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
(cherry picked from commit 9a45b0761628cc59267b3283a85d15294464ac31)
|
||||
Signed-off-by: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
|
||||
---
|
||||
hw/i386/amd_iommu.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c
|
||||
index 4203144da9..12742b1433 100644
|
||||
--- a/hw/i386/amd_iommu.c
|
||||
+++ b/hw/i386/amd_iommu.c
|
||||
@@ -346,12 +346,12 @@ static void amdvi_update_iotlb(AMDVIState *s, uint16_t devid,
|
||||
uint64_t gpa, IOMMUTLBEntry to_cache,
|
||||
uint16_t domid)
|
||||
{
|
||||
- AMDVIIOTLBEntry *entry = g_new(AMDVIIOTLBEntry, 1);
|
||||
- uint64_t *key = g_new(uint64_t, 1);
|
||||
- uint64_t gfn = gpa >> AMDVI_PAGE_SHIFT_4K;
|
||||
-
|
||||
/* don't cache erroneous translations */
|
||||
if (to_cache.perm != IOMMU_NONE) {
|
||||
+ AMDVIIOTLBEntry *entry = g_new(AMDVIIOTLBEntry, 1);
|
||||
+ uint64_t *key = g_new(uint64_t, 1);
|
||||
+ uint64_t gfn = gpa >> AMDVI_PAGE_SHIFT_4K;
|
||||
+
|
||||
trace_amdvi_cache_update(domid, PCI_BUS_NUM(devid), PCI_SLOT(devid),
|
||||
PCI_FUNC(devid), gpa, to_cache.translated_addr);
|
||||
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
61
hw-intc-arm_gic-Fix-handling-of-NS-view-of-GICC_APR-.patch
Normal file
61
hw-intc-arm_gic-Fix-handling-of-NS-view-of-GICC_APR-.patch
Normal file
@ -0,0 +1,61 @@
|
||||
From 20541823659dc78a6a7be427f8fc03ccc58c88d1 Mon Sep 17 00:00:00 2001
|
||||
From: Andrey Shumilin <shum.sdl@nppct.ru>
|
||||
Date: Thu, 23 May 2024 16:06:20 +0100
|
||||
Subject: [PATCH] hw/intc/arm_gic: Fix handling of NS view of GICC_APR<n>
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
In gic_cpu_read() and gic_cpu_write(), we delegate the handling of
|
||||
reading and writing the Non-Secure view of the GICC_APR<n> registers
|
||||
to functions gic_apr_ns_view() and gic_apr_write_ns_view().
|
||||
Unfortunately we got the order of the arguments wrong, swapping the
|
||||
CPU number and the register number (which the compiler doesn't catch
|
||||
because they're both integers).
|
||||
|
||||
Most guests probably didn't notice this bug because directly
|
||||
accessing the APR registers is typically something only done by
|
||||
firmware when it is doing state save for going into a sleep mode.
|
||||
|
||||
Correct the mismatched call arguments.
|
||||
|
||||
Found by Linux Verification Center (linuxtesting.org) with SVACE.
|
||||
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Fixes: 51fd06e0ee ("hw/intc/arm_gic: Fix handling of GICC_APR<n>, GICC_NSAPR<n> registers")
|
||||
Signed-off-by: Andrey Shumilin <shum.sdl@nppct.ru>
|
||||
[PMM: Rewrote commit message]
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
Reviewed-by: Alex Bennée<alex.bennee@linaro.org>
|
||||
(cherry picked from commit daafa78b297291fea36fb4daeed526705fa7c035)
|
||||
Signed-off-by: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
|
||||
---
|
||||
hw/intc/arm_gic.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
|
||||
index dfe7a0a729..f0582f7a49 100644
|
||||
--- a/hw/intc/arm_gic.c
|
||||
+++ b/hw/intc/arm_gic.c
|
||||
@@ -1663,7 +1663,7 @@ static MemTxResult gic_cpu_read(GICState *s, int cpu, int offset,
|
||||
*data = s->h_apr[gic_get_vcpu_real_id(cpu)];
|
||||
} else if (gic_cpu_ns_access(s, cpu, attrs)) {
|
||||
/* NS view of GICC_APR<n> is the top half of GIC_NSAPR<n> */
|
||||
- *data = gic_apr_ns_view(s, regno, cpu);
|
||||
+ *data = gic_apr_ns_view(s, cpu, regno);
|
||||
} else {
|
||||
*data = s->apr[regno][cpu];
|
||||
}
|
||||
@@ -1751,7 +1751,7 @@ static MemTxResult gic_cpu_write(GICState *s, int cpu, int offset,
|
||||
s->h_apr[gic_get_vcpu_real_id(cpu)] = value;
|
||||
} else if (gic_cpu_ns_access(s, cpu, attrs)) {
|
||||
/* NS view of GICC_APR<n> is the top half of GIC_NSAPR<n> */
|
||||
- gic_apr_write_ns_view(s, regno, cpu, value);
|
||||
+ gic_apr_write_ns_view(s, cpu, regno, value);
|
||||
} else {
|
||||
s->apr[regno][cpu] = value;
|
||||
}
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
212
hw-misc-psp-Pin-the-hugepage-memory-specified-by-mem.patch
Normal file
212
hw-misc-psp-Pin-the-hugepage-memory-specified-by-mem.patch
Normal file
@ -0,0 +1,212 @@
|
||||
From ddaa38853d386e5b9f9fa1c3813048872c8ad687 Mon Sep 17 00:00:00 2001
|
||||
From: niuyongwen <niuyongwen@hygon.cn>
|
||||
Date: Sun, 29 Sep 2024 09:45:15 +0800
|
||||
Subject: [PATCH] hw/misc/psp: Pin the hugepage memory specified by mem2 during
|
||||
use for psp
|
||||
|
||||
Signed-off-by: niuyongwen <niuyongwen@hygon.cn>
|
||||
---
|
||||
hw/misc/psp.c | 138 +++++++++++++++++++++++++++++++++++++++++++-------
|
||||
1 file changed, 121 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/hw/misc/psp.c b/hw/misc/psp.c
|
||||
index 4eb5ca0e0b..03e8663027 100644
|
||||
--- a/hw/misc/psp.c
|
||||
+++ b/hw/misc/psp.c
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "sysemu/runstate.h"
|
||||
#include "exec/memory.h"
|
||||
#include "exec/address-spaces.h"
|
||||
+#include "exec/ramblock.h"
|
||||
#include "hw/i386/e820_memory_layout.h"
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
@@ -38,6 +39,8 @@ struct PSPDevState {
|
||||
* the TKM module uses different key spaces based on different vids.
|
||||
*/
|
||||
uint32_t vid;
|
||||
+ /* pinned hugepage numbers */
|
||||
+ int hp_num;
|
||||
};
|
||||
|
||||
#define PSP_DEV_PATH "/dev/hygon_psp_config"
|
||||
@@ -45,6 +48,8 @@ struct PSPDevState {
|
||||
#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)
|
||||
+#define PSP_IOC_PIN_USER_PAGE _IOWR(HYGON_PSP_IOC_TYPE, 4, NULL)
|
||||
+#define PSP_IOC_UNPIN_USER_PAGE _IOWR(HYGON_PSP_IOC_TYPE, 5, NULL)
|
||||
|
||||
enum VPSP_DEV_CTRL_OPCODE {
|
||||
VPSP_OP_VID_ADD,
|
||||
@@ -69,6 +74,109 @@ struct psp_dev_ctrl {
|
||||
} __attribute__ ((packed)) data;
|
||||
};
|
||||
|
||||
+static MemoryRegion *find_memory_region_by_name(MemoryRegion *root, const char *name) {
|
||||
+ MemoryRegion *subregion;
|
||||
+ MemoryRegion *result;
|
||||
+
|
||||
+ if (strcmp(root->name, name) == 0)
|
||||
+ return root;
|
||||
+
|
||||
+ QTAILQ_FOREACH(subregion, &root->subregions, subregions_link) {
|
||||
+ result = find_memory_region_by_name(subregion, name);
|
||||
+ if (result) {
|
||||
+ return result;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static int pin_user_hugepage(int fd, uint64_t vaddr)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = ioctl(fd, PSP_IOC_PIN_USER_PAGE, vaddr);
|
||||
+ /* 22: Invalid argument, some old kernel doesn't support this ioctl command */
|
||||
+ if (ret != 0 && errno == EINVAL) {
|
||||
+ ret = 0;
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int unpin_user_hugepage(int fd, uint64_t vaddr)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = ioctl(fd, PSP_IOC_UNPIN_USER_PAGE, vaddr);
|
||||
+ /* 22: Invalid argument, some old kernel doesn't support this ioctl command */
|
||||
+ if (ret != 0 && errno == EINVAL) {
|
||||
+ ret = 0;
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int pin_psp_user_hugepages(struct PSPDevState *state, MemoryRegion *root)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+ char mr_name[128] = {0};
|
||||
+ int i, pinned_num;
|
||||
+ MemoryRegion *find_mr = NULL;
|
||||
+
|
||||
+ for (i = 0 ; i < state->hp_num; ++i) {
|
||||
+ sprintf(mr_name, "mem2-%d", i);
|
||||
+ find_mr = find_memory_region_by_name(root, mr_name);
|
||||
+ if (!find_mr) {
|
||||
+ error_report("fail to find memory region by name %s.", mr_name);
|
||||
+ ret = -ENOMEM;
|
||||
+ goto end;
|
||||
+ }
|
||||
+
|
||||
+ ret = pin_user_hugepage(state->dev_fd, (uint64_t)find_mr->ram_block->host);
|
||||
+ if (ret) {
|
||||
+ error_report("fail to pin_user_hugepage, ret: %d.", ret);
|
||||
+ goto end;
|
||||
+ }
|
||||
+ }
|
||||
+end:
|
||||
+ if (ret) {
|
||||
+ pinned_num = i;
|
||||
+ for (i = 0 ; i < pinned_num; ++i) {
|
||||
+ sprintf(mr_name, "mem2-%d", i);
|
||||
+ find_mr = find_memory_region_by_name(root, mr_name);
|
||||
+ if (!find_mr) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ unpin_user_hugepage(state->dev_fd, (uint64_t)find_mr->ram_block->host);
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int unpin_psp_user_hugepages(struct PSPDevState *state, MemoryRegion *root)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+ char mr_name[128] = {0};
|
||||
+ int i;
|
||||
+ MemoryRegion *find_mr = NULL;
|
||||
+
|
||||
+ for (i = 0 ; i < state->hp_num; ++i) {
|
||||
+ sprintf(mr_name, "mem2-%d", i);
|
||||
+ find_mr = find_memory_region_by_name(root, mr_name);
|
||||
+ if (!find_mr) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ ret = unpin_user_hugepage(state->dev_fd, (uint64_t)find_mr->ram_block->host);
|
||||
+ if (ret) {
|
||||
+ error_report("fail to unpin_user_hugepage, ret: %d.", ret);
|
||||
+ goto end;
|
||||
+ }
|
||||
+ }
|
||||
+end:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static void psp_dev_destroy(PSPDevState *state)
|
||||
{
|
||||
struct psp_dev_ctrl ctrl = { 0 };
|
||||
@@ -77,6 +185,11 @@ static void psp_dev_destroy(PSPDevState *state)
|
||||
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);
|
||||
+ }
|
||||
+
|
||||
+ /* Unpin hugepage memory */
|
||||
+ if (unpin_psp_user_hugepages(state, get_system_memory())) {
|
||||
+ error_report("unpin_psp_user_hugepages failed");
|
||||
} else {
|
||||
state->enabled = false;
|
||||
}
|
||||
@@ -99,23 +212,6 @@ static void psp_dev_shutdown_notify(Notifier *notifier, void *data)
|
||||
psp_dev_destroy(state);
|
||||
}
|
||||
|
||||
-static MemoryRegion *find_memory_region_by_name(MemoryRegion *root, const char *name) {
|
||||
- MemoryRegion *subregion;
|
||||
- MemoryRegion *result;
|
||||
-
|
||||
- if (strcmp(root->name, name) == 0)
|
||||
- return root;
|
||||
-
|
||||
- QTAILQ_FOREACH(subregion, &root->subregions, subregions_link) {
|
||||
- result = find_memory_region_by_name(subregion, name);
|
||||
- if (result) {
|
||||
- return result;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- return NULL;
|
||||
-}
|
||||
-
|
||||
static void psp_dev_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
int i;
|
||||
@@ -150,6 +246,8 @@ static void psp_dev_realize(DeviceState *dev, Error **errp)
|
||||
ram2_end = find_mr->addr + find_mr->size - 1;
|
||||
}
|
||||
|
||||
+ state->hp_num = i;
|
||||
+
|
||||
if (ram2_start != ram2_end) {
|
||||
ctrl.op = VPSP_OP_SET_GPA;
|
||||
ctrl.data.gpa.gpa_start = ram2_start;
|
||||
@@ -159,6 +257,12 @@ static void psp_dev_realize(DeviceState *dev, Error **errp)
|
||||
ram2_start, ram2_end, -errno);
|
||||
goto del_vid;
|
||||
}
|
||||
+
|
||||
+ /* Pin hugepage memory */
|
||||
+ if(pin_psp_user_hugepages(state, root_mr)) {
|
||||
+ error_setg(errp, "pin_psp_user_hugepages failed.");
|
||||
+ goto del_vid;
|
||||
+ }
|
||||
}
|
||||
|
||||
state->enabled = true;
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
123
hw-misc-support-tkm-use-mem2-memory.patch
Normal file
123
hw-misc-support-tkm-use-mem2-memory.patch
Normal file
@ -0,0 +1,123 @@
|
||||
From 884c4d6bc101454f0e0f3c779bc1155024b056c3 Mon Sep 17 00:00:00 2001
|
||||
From: xiongmengbiao <xiongmengbiao@hygon.cn>
|
||||
Date: Wed, 29 May 2024 15:18:55 +0800
|
||||
Subject: [PATCH] hw/misc: support tkm use mem2 memory
|
||||
|
||||
Signed-off-by: xiongmengbiao <xiongmengbiao@hygon.cn>
|
||||
---
|
||||
hw/misc/psp.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 63 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/misc/psp.c b/hw/misc/psp.c
|
||||
index 6ff2ceec10..4eb5ca0e0b 100644
|
||||
--- a/hw/misc/psp.c
|
||||
+++ b/hw/misc/psp.c
|
||||
@@ -15,6 +15,9 @@
|
||||
#include "migration/vmstate.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "sysemu/runstate.h"
|
||||
+#include "exec/memory.h"
|
||||
+#include "exec/address-spaces.h"
|
||||
+#include "hw/i386/e820_memory_layout.h"
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#define TYPE_PSP_DEV "psp"
|
||||
@@ -46,14 +49,24 @@ struct PSPDevState {
|
||||
enum VPSP_DEV_CTRL_OPCODE {
|
||||
VPSP_OP_VID_ADD,
|
||||
VPSP_OP_VID_DEL,
|
||||
+ VPSP_OP_SET_DEFAULT_VID_PERMISSION,
|
||||
+ VPSP_OP_GET_DEFAULT_VID_PERMISSION,
|
||||
+ VPSP_OP_SET_GPA,
|
||||
};
|
||||
|
||||
struct psp_dev_ctrl {
|
||||
unsigned char op;
|
||||
+ unsigned char resv[3];
|
||||
union {
|
||||
unsigned int vid;
|
||||
+ // Set or check the permissions for the default VID
|
||||
+ unsigned int def_vid_perm;
|
||||
+ struct {
|
||||
+ uint64_t gpa_start;
|
||||
+ uint64_t gpa_end;
|
||||
+ } gpa;
|
||||
unsigned char reserved[128];
|
||||
- } data;
|
||||
+ } __attribute__ ((packed)) data;
|
||||
};
|
||||
|
||||
static void psp_dev_destroy(PSPDevState *state)
|
||||
@@ -86,10 +99,32 @@ static void psp_dev_shutdown_notify(Notifier *notifier, void *data)
|
||||
psp_dev_destroy(state);
|
||||
}
|
||||
|
||||
+static MemoryRegion *find_memory_region_by_name(MemoryRegion *root, const char *name) {
|
||||
+ MemoryRegion *subregion;
|
||||
+ MemoryRegion *result;
|
||||
+
|
||||
+ if (strcmp(root->name, name) == 0)
|
||||
+ return root;
|
||||
+
|
||||
+ QTAILQ_FOREACH(subregion, &root->subregions, subregions_link) {
|
||||
+ result = find_memory_region_by_name(subregion, name);
|
||||
+ if (result) {
|
||||
+ return result;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
static void psp_dev_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
+ int i;
|
||||
+ char mr_name[128] = {0};
|
||||
struct psp_dev_ctrl ctrl = { 0 };
|
||||
PSPDevState *state = PSP_DEV(dev);
|
||||
+ MemoryRegion *root_mr = get_system_memory();
|
||||
+ MemoryRegion *find_mr = NULL;
|
||||
+ uint64_t ram2_start = 0, ram2_end = 0;
|
||||
|
||||
state->dev_fd = qemu_open_old(PSP_DEV_PATH, O_RDWR);
|
||||
if (state->dev_fd < 0) {
|
||||
@@ -104,9 +139,36 @@ static void psp_dev_realize(DeviceState *dev, Error **errp)
|
||||
goto end;
|
||||
}
|
||||
|
||||
+ for (i = 0 ;; ++i) {
|
||||
+ sprintf(mr_name, "mem2-%d", i);
|
||||
+ find_mr = find_memory_region_by_name(root_mr, mr_name);
|
||||
+ if (!find_mr)
|
||||
+ break;
|
||||
+
|
||||
+ if (!ram2_start)
|
||||
+ ram2_start = find_mr->addr;
|
||||
+ ram2_end = find_mr->addr + find_mr->size - 1;
|
||||
+ }
|
||||
+
|
||||
+ if (ram2_start != ram2_end) {
|
||||
+ ctrl.op = VPSP_OP_SET_GPA;
|
||||
+ ctrl.data.gpa.gpa_start = ram2_start;
|
||||
+ ctrl.data.gpa.gpa_end = ram2_end;
|
||||
+ if (ioctl(state->dev_fd, PSP_IOC_VPSP_OPT, &ctrl) < 0) {
|
||||
+ error_setg(errp, "psp_dev_realize VPSP_OP_SET_GPA (start 0x%lx, end 0x%lx), return %d",
|
||||
+ ram2_start, ram2_end, -errno);
|
||||
+ goto del_vid;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
state->enabled = true;
|
||||
state->shutdown_notifier.notify = psp_dev_shutdown_notify;
|
||||
qemu_register_shutdown_notifier(&state->shutdown_notifier);
|
||||
+
|
||||
+ return;
|
||||
+del_vid:
|
||||
+ ctrl.op = VPSP_OP_VID_DEL;
|
||||
+ ioctl(state->dev_fd, PSP_IOC_VPSP_OPT, &ctrl);
|
||||
end:
|
||||
return;
|
||||
}
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
102
hw-nvme-fix-handling-of-over-committed-queues.patch
Normal file
102
hw-nvme-fix-handling-of-over-committed-queues.patch
Normal file
@ -0,0 +1,102 @@
|
||||
From c4423b70160eb7ae91dac9f2cf61513758ee017d Mon Sep 17 00:00:00 2001
|
||||
From: Klaus Jensen <k.jensen@samsung.com>
|
||||
Date: Tue, 29 Oct 2024 13:15:19 +0100
|
||||
Subject: [PATCH] hw/nvme: fix handling of over-committed queues
|
||||
|
||||
If a host chooses to use the SQHD "hint" in the CQE to know if there is
|
||||
room in the submission queue for additional commands, it may result in a
|
||||
situation where there are not enough internal resources (struct
|
||||
NvmeRequest) available to process the command. For a lack of a better
|
||||
term, the host may "over-commit" the device (i.e., it may have more
|
||||
inflight commands than the queue size).
|
||||
|
||||
For example, assume a queue with N entries. The host submits N commands
|
||||
and all are picked up for processing, advancing the head and emptying
|
||||
the queue. Regardless of which of these N commands complete first, the
|
||||
SQHD field of that CQE will indicate to the host that the queue is
|
||||
empty, which allows the host to issue N commands again. However, if the
|
||||
device has not posted CQEs for all the previous commands yet, the device
|
||||
will have less than N resources available to process the commands, so
|
||||
queue processing is suspended.
|
||||
|
||||
And here lies an 11 year latent bug. In the absense of any additional
|
||||
tail updates on the submission queue, we never schedule the processing
|
||||
bottom-half again unless we observe a head update on an associated full
|
||||
completion queue. This has been sufficient to handle N-to-1 SQ/CQ setups
|
||||
(in the absense of over-commit of course). Incidentially, that "kick all
|
||||
associated SQs" mechanism can now be killed since we now just schedule
|
||||
queue processing when we return a processing resource to a non-empty
|
||||
submission queue, which happens to cover both edge cases. However, we
|
||||
must retain kicking the CQ if it was previously full.
|
||||
|
||||
So, apparently, no previous driver tested with hw/nvme has ever used
|
||||
SQHD (e.g., neither the Linux NVMe driver or SPDK uses it). But then OSv
|
||||
shows up with the driver that actually does. I salute you.
|
||||
|
||||
Fixes: f3c507adcd7b ("NVMe: Initial commit for new storage interface")
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2388
|
||||
Reported-by: Waldemar Kozaczuk <jwkozaczuk@gmail.com>
|
||||
Reviewed-by: Keith Busch <kbusch@kernel.org>
|
||||
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
|
||||
Signed-off-by: Zhongrui Tang <tangzhongrui_yewu@cmss.chinamobile.com>
|
||||
---
|
||||
hw/nvme/ctrl.c | 21 ++++++++++++---------
|
||||
1 file changed, 12 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
|
||||
index 104aebc5ea..29445938d5 100644
|
||||
--- a/hw/nvme/ctrl.c
|
||||
+++ b/hw/nvme/ctrl.c
|
||||
@@ -1516,9 +1516,16 @@ static void nvme_post_cqes(void *opaque)
|
||||
stl_le_p(&n->bar.csts, NVME_CSTS_FAILED);
|
||||
break;
|
||||
}
|
||||
+
|
||||
QTAILQ_REMOVE(&cq->req_list, req, entry);
|
||||
+
|
||||
nvme_inc_cq_tail(cq);
|
||||
nvme_sg_unmap(&req->sg);
|
||||
+
|
||||
+ if (QTAILQ_EMPTY(&sq->req_list) && !nvme_sq_empty(sq)) {
|
||||
+ qemu_bh_schedule(sq->bh);
|
||||
+ }
|
||||
+
|
||||
QTAILQ_INSERT_TAIL(&sq->req_list, req, entry);
|
||||
}
|
||||
if (cq->tail != cq->head) {
|
||||
@@ -7575,7 +7582,6 @@ static void nvme_process_db(NvmeCtrl *n, hwaddr addr, int val)
|
||||
/* Completion queue doorbell write */
|
||||
|
||||
uint16_t new_head = val & 0xffff;
|
||||
- int start_sqs;
|
||||
NvmeCQueue *cq;
|
||||
|
||||
qid = (addr - (0x1000 + (1 << 2))) >> 3;
|
||||
@@ -7626,18 +7632,15 @@ static void nvme_process_db(NvmeCtrl *n, hwaddr addr, int val)
|
||||
|
||||
trace_pci_nvme_mmio_doorbell_cq(cq->cqid, new_head);
|
||||
|
||||
- start_sqs = nvme_cq_full(cq) ? 1 : 0;
|
||||
+ /* scheduled deferred cqe posting if queue was previously full */
|
||||
+ if (nvme_cq_full(cq)) {
|
||||
+ qemu_bh_schedule(cq->bh);
|
||||
+ }
|
||||
+
|
||||
cq->head = new_head;
|
||||
if (!qid && n->dbbuf_enabled) {
|
||||
stl_le_pci_dma(pci, cq->db_addr, cq->head, MEMTXATTRS_UNSPECIFIED);
|
||||
}
|
||||
- if (start_sqs) {
|
||||
- NvmeSQueue *sq;
|
||||
- QTAILQ_FOREACH(sq, &cq->sq_list, entry) {
|
||||
- qemu_bh_schedule(sq->bh);
|
||||
- }
|
||||
- qemu_bh_schedule(cq->bh);
|
||||
- }
|
||||
|
||||
if (cq->tail == cq->head) {
|
||||
if (cq->irq_enabled) {
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
44
hw-ppc-e500-Add-missing-device-tree-properties-to-i2.patch
Normal file
44
hw-ppc-e500-Add-missing-device-tree-properties-to-i2.patch
Normal file
@ -0,0 +1,44 @@
|
||||
From e025c40fac7d6cc5b4752c392a9c66a074dcaa0b Mon Sep 17 00:00:00 2001
|
||||
From: Zhang Jiao <zhangjiao2_yewu@cmss.chinamobile.com>
|
||||
Date: Thu, 14 Nov 2024 14:24:58 +0800
|
||||
Subject: [PATCH] hw/ppc/e500: Add missing device tree properties to i2c
|
||||
controller node
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
cheery-pick from b5d65592d931d07d4f4bcb915d018ec9598058b4
|
||||
|
||||
When compiling a decompiled device tree blob created with dumpdtb, dtc complains
|
||||
with:
|
||||
|
||||
/soc@e0000000/i2c@3000: incorrect #address-cells for I2C bus
|
||||
/soc@e0000000/i2c@3000: incorrect #size-cells for I2C bus
|
||||
|
||||
Fix this by adding the missing device tree properties.
|
||||
|
||||
Reviewed-by: Cédric Le Goater <clg@redhat.com>
|
||||
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
|
||||
Message-ID: <20241103133412.73536-6-shentey@gmail.com>
|
||||
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
Signed-off-by: Zhang Jiao <zhangjiao2_yewu@cmss.chinamobile.com>
|
||||
---
|
||||
hw/ppc/e500.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
|
||||
index 384226296b..8d394d749a 100644
|
||||
--- a/hw/ppc/e500.c
|
||||
+++ b/hw/ppc/e500.c
|
||||
@@ -203,6 +203,8 @@ static void dt_i2c_create(void *fdt, const char *soc, const char *mpic,
|
||||
qemu_fdt_setprop_cells(fdt, i2c, "cell-index", 0);
|
||||
qemu_fdt_setprop_cells(fdt, i2c, "interrupts", irq0, 0x2);
|
||||
qemu_fdt_setprop_phandle(fdt, i2c, "interrupt-parent", mpic);
|
||||
+ qemu_fdt_setprop_cell(fdt, i2c, "#size-cells", 0);
|
||||
+ qemu_fdt_setprop_cell(fdt, i2c, "#address-cells", 1);
|
||||
qemu_fdt_setprop_string(fdt, "/aliases", alias, i2c);
|
||||
|
||||
g_free(i2c);
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
44
hw-ppc-e500-Prefer-QOM-cast.patch
Normal file
44
hw-ppc-e500-Prefer-QOM-cast.patch
Normal file
@ -0,0 +1,44 @@
|
||||
From b85c8374d8b78a6ec1c250bb7562423e6f5d89a0 Mon Sep 17 00:00:00 2001
|
||||
From: Zhang Jiao <zhangjiao2_yewu@cmss.chinamobile.com>
|
||||
Date: Thu, 14 Nov 2024 15:12:32 +0800
|
||||
Subject: [PATCH] hw/ppc/e500: Prefer QOM cast
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
cheery-pick from c620b4ee92ed3664a3d98e0fbb0b651e19fba5b6
|
||||
|
||||
Reviewed-by: BALATON Zoltan <balaton@eik.bme.hu>
|
||||
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
|
||||
Message-ID: <20241103133412.73536-4-shentey@gmail.com>
|
||||
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
Signed-off-by: Zhang Jiao <zhangjiao2_yewu@cmss.chinamobile.com>
|
||||
---
|
||||
hw/ppc/e500.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
|
||||
index 384226296b..df5a20d3ec 100644
|
||||
--- a/hw/ppc/e500.c
|
||||
+++ b/hw/ppc/e500.c
|
||||
@@ -1024,7 +1024,7 @@ void ppce500_init(MachineState *machine)
|
||||
sysbus_connect_irq(s, 0, qdev_get_gpio_in(mpicdev, MPC8544_I2C_IRQ));
|
||||
memory_region_add_subregion(ccsr_addr_space, MPC8544_I2C_REGS_OFFSET,
|
||||
sysbus_mmio_get_region(s, 0));
|
||||
- i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
|
||||
+ i2c = I2C_BUS(qdev_get_child_bus(dev, "i2c"));
|
||||
i2c_slave_create_simple(i2c, "ds1338", RTC_REGS_OFFSET);
|
||||
|
||||
/* eSDHC */
|
||||
@@ -1073,7 +1073,7 @@ void ppce500_init(MachineState *machine)
|
||||
memory_region_add_subregion(ccsr_addr_space, MPC8544_PCI_REGS_OFFSET,
|
||||
sysbus_mmio_get_region(s, 0));
|
||||
|
||||
- pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci.0");
|
||||
+ pci_bus = PCI_BUS(qdev_get_child_bus(dev, "pci.0"));
|
||||
if (!pci_bus)
|
||||
printf("couldn't create PCI controller!\n");
|
||||
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
44
hw-ppc-e500-Remove-unused-irqs-parameter.patch
Normal file
44
hw-ppc-e500-Remove-unused-irqs-parameter.patch
Normal file
@ -0,0 +1,44 @@
|
||||
From 239e256d5510b9aaa3e099359dcda54970e2f08a Mon Sep 17 00:00:00 2001
|
||||
From: Zhang Jiao <zhangjiao2_yewu@cmss.chinamobile.com>
|
||||
Date: Thu, 14 Nov 2024 14:40:02 +0800
|
||||
Subject: [PATCH] hw/ppc/e500: Remove unused "irqs" parameter
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
cheery-pick from 2a309354ac5decf78763c9de999bfb42c8612069
|
||||
|
||||
Reviewed-by: BALATON Zoltan <balaton@eik.bme.hu>
|
||||
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
|
||||
Message-ID: <20241103133412.73536-5-shentey@gmail.com>
|
||||
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
Signed-off-by: Zhang Jiao <zhangjiao2_yewu@cmss.chinamobile.com>
|
||||
---
|
||||
hw/ppc/e500.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
|
||||
index 384226296b..8ab1ccc969 100644
|
||||
--- a/hw/ppc/e500.c
|
||||
+++ b/hw/ppc/e500.c
|
||||
@@ -832,7 +832,7 @@ static DeviceState *ppce500_init_mpic_qemu(PPCE500MachineState *pms,
|
||||
}
|
||||
|
||||
static DeviceState *ppce500_init_mpic_kvm(const PPCE500MachineClass *pmc,
|
||||
- IrqLines *irqs, Error **errp)
|
||||
+ Error **errp)
|
||||
{
|
||||
#ifdef CONFIG_KVM
|
||||
DeviceState *dev;
|
||||
@@ -872,7 +872,7 @@ static DeviceState *ppce500_init_mpic(PPCE500MachineState *pms,
|
||||
Error *err = NULL;
|
||||
|
||||
if (kvm_kernel_irqchip_allowed()) {
|
||||
- dev = ppce500_init_mpic_kvm(pmc, irqs, &err);
|
||||
+ dev = ppce500_init_mpic_kvm(pmc, &err);
|
||||
}
|
||||
if (kvm_kernel_irqchip_required() && !dev) {
|
||||
error_reportf_err(err,
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
111
kvm-add-support-for-guest-physical-bits.patch
Normal file
111
kvm-add-support-for-guest-physical-bits.patch
Normal file
@ -0,0 +1,111 @@
|
||||
From a2383a2a0537750794223f21156241b1b1e78d2e Mon Sep 17 00:00:00 2001
|
||||
From: Gerd Hoffmann <kraxel@redhat.com>
|
||||
Date: Mon, 18 Mar 2024 16:53:35 +0100
|
||||
Subject: [PATCH] kvm: add support for guest physical bits
|
||||
|
||||
commit 0d08c423688edcca857f88dab20f1fc56de2b281 upstream.
|
||||
|
||||
Query kvm for supported guest physical address bits, in cpuid
|
||||
function 80000008, eax[23:16]. Usually this is identical to host
|
||||
physical address bits. With NPT or EPT being used this might be
|
||||
restricted to 48 (max 4-level paging address space size) even if
|
||||
the host cpu supports more physical address bits.
|
||||
|
||||
When set pass this to the guest, using cpuid too. Guest firmware
|
||||
can use this to figure how big the usable guest physical address
|
||||
space is, so PCI bar mapping are actually reachable.
|
||||
|
||||
Intel-SIG: commit 0d08c423688e kvm: add support for guest physical bits
|
||||
|
||||
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||
Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
|
||||
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
|
||||
Message-ID: <20240318155336.156197-2-kraxel@redhat.com>
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Signed-off-by: Jason Zeng <jason.zeng@intel.com>
|
||||
---
|
||||
target/i386/kvm/kvm-cpu.c | 50 ++++++++++++++++++++++++++++++++-------
|
||||
1 file changed, 42 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c
|
||||
index 9c791b7b05..f76972e47e 100644
|
||||
--- a/target/i386/kvm/kvm-cpu.c
|
||||
+++ b/target/i386/kvm/kvm-cpu.c
|
||||
@@ -18,10 +18,32 @@
|
||||
#include "kvm_i386.h"
|
||||
#include "hw/core/accel-cpu.h"
|
||||
|
||||
+static void kvm_set_guest_phys_bits(CPUState *cs)
|
||||
+{
|
||||
+ X86CPU *cpu = X86_CPU(cs);
|
||||
+ uint32_t eax, guest_phys_bits;
|
||||
+
|
||||
+ eax = kvm_arch_get_supported_cpuid(cs->kvm_state, 0x80000008, 0, R_EAX);
|
||||
+ guest_phys_bits = (eax >> 16) & 0xff;
|
||||
+ if (!guest_phys_bits) {
|
||||
+ return;
|
||||
+ }
|
||||
+ cpu->guest_phys_bits = guest_phys_bits;
|
||||
+ if (cpu->guest_phys_bits > cpu->phys_bits) {
|
||||
+ cpu->guest_phys_bits = cpu->phys_bits;
|
||||
+ }
|
||||
+
|
||||
+ if (cpu->host_phys_bits && cpu->host_phys_bits_limit &&
|
||||
+ cpu->guest_phys_bits > cpu->host_phys_bits_limit) {
|
||||
+ cpu->guest_phys_bits = cpu->host_phys_bits_limit;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static bool kvm_cpu_realizefn(CPUState *cs, Error **errp)
|
||||
{
|
||||
X86CPU *cpu = X86_CPU(cs);
|
||||
CPUX86State *env = &cpu->env;
|
||||
+ bool ret;
|
||||
|
||||
/*
|
||||
* The realize order is important, since x86_cpu_realize() checks if
|
||||
@@ -32,13 +54,15 @@ static bool kvm_cpu_realizefn(CPUState *cs, Error **errp)
|
||||
*
|
||||
* realize order:
|
||||
*
|
||||
- * x86_cpu_realize():
|
||||
- * -> x86_cpu_expand_features()
|
||||
- * -> cpu_exec_realizefn():
|
||||
- * -> accel_cpu_common_realize()
|
||||
- * kvm_cpu_realizefn() -> host_cpu_realizefn()
|
||||
- * -> cpu_common_realizefn()
|
||||
- * -> check/update ucode_rev, phys_bits, mwait
|
||||
+ * x86_cpu_realizefn():
|
||||
+ * x86_cpu_expand_features()
|
||||
+ * cpu_exec_realizefn():
|
||||
+ * accel_cpu_common_realize()
|
||||
+ * kvm_cpu_realizefn()
|
||||
+ * host_cpu_realizefn()
|
||||
+ * kvm_set_guest_phys_bits()
|
||||
+ * check/update ucode_rev, phys_bits, guest_phys_bits, mwait
|
||||
+ * cpu_common_realizefn() (via xcc->parent_realize)
|
||||
*/
|
||||
if (cpu->max_features) {
|
||||
if (enable_cpu_pm && kvm_has_waitpkg()) {
|
||||
@@ -50,7 +74,17 @@ static bool kvm_cpu_realizefn(CPUState *cs, Error **errp)
|
||||
MSR_IA32_UCODE_REV);
|
||||
}
|
||||
}
|
||||
- return host_cpu_realizefn(cs, errp);
|
||||
+ ret = host_cpu_realizefn(cs, errp);
|
||||
+ if (!ret) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ if ((env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) &&
|
||||
+ cpu->guest_phys_bits == -1) {
|
||||
+ kvm_set_guest_phys_bits(cs);
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
}
|
||||
|
||||
static bool lmce_supported(void)
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
79
linux-headers-update-kernel-headers-to-include-CSV3-.patch
Normal file
79
linux-headers-update-kernel-headers-to-include-CSV3-.patch
Normal file
@ -0,0 +1,79 @@
|
||||
From 454079664e1492eeb9b90d1d05598e84dc436f11 Mon Sep 17 00:00:00 2001
|
||||
From: jiangxin <jiangxin@hygon.cn>
|
||||
Date: Fri, 17 Jun 2022 09:25:19 +0800
|
||||
Subject: [PATCH] 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 <jiangxin@hygon.cn>
|
||||
Signed-off-by: hanliyang <hanliyang@hygon.cn>
|
||||
---
|
||||
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 8487d0889b..8543db844e 100644
|
||||
--- a/linux-headers/linux/kvm.h
|
||||
+++ b/linux-headers/linux/kvm.h
|
||||
@@ -2115,6 +2115,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 {
|
||||
@@ -2127,6 +2133,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.41.0.windows.1
|
||||
|
||||
65
migration-Fix-file-migration-with-fdset.patch
Normal file
65
migration-Fix-file-migration-with-fdset.patch
Normal file
@ -0,0 +1,65 @@
|
||||
From 6c76354fdfbebca55e080fea5ae6bfc8a3db2d91 Mon Sep 17 00:00:00 2001
|
||||
From: Fabiano Rosas <farosas@suse.de>
|
||||
Date: Mon, 17 Jun 2024 15:57:17 -0300
|
||||
Subject: [PATCH] migration: Fix file migration with fdset
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
When the "file:" migration support was added we missed the special
|
||||
case in the qemu_open_old implementation that allows for a particular
|
||||
file name format to be used to refer to a set of file descriptors that
|
||||
have been previously provided to QEMU via the add-fd QMP command.
|
||||
|
||||
When using this fdset feature, we should not truncate the migration
|
||||
file because being given an fd means that the management layer is in
|
||||
control of the file and will likely already have some data written to
|
||||
it. This is further indicated by the presence of the 'offset'
|
||||
argument, which indicates the start of the region where QEMU is
|
||||
allowed to write.
|
||||
|
||||
Fix the issue by replacing the O_TRUNC flag on open by an ftruncate
|
||||
call, which will take the offset into consideration.
|
||||
|
||||
Fixes: 385f510df5 ("migration: file URI offset")
|
||||
Suggested-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
Reviewed-by: Prasad Pandit <pjp@fedoraproject.org>
|
||||
Reviewed-by: Peter Xu <peterx@redhat.com>
|
||||
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
Signed-off-by: Fabiano Rosas <farosas@suse.de>
|
||||
(cherry picked from commit 6d3279655ac49b806265f08415165f471d33e032)
|
||||
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
|
||||
Signed-off-by: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
|
||||
---
|
||||
migration/file.c | 11 +++++++++--
|
||||
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/migration/file.c b/migration/file.c
|
||||
index 5d4975f43e..fb3f743e54 100644
|
||||
--- a/migration/file.c
|
||||
+++ b/migration/file.c
|
||||
@@ -46,12 +46,19 @@ void file_start_outgoing_migration(MigrationState *s,
|
||||
|
||||
trace_migration_file_outgoing(filename);
|
||||
|
||||
- fioc = qio_channel_file_new_path(filename, O_CREAT | O_WRONLY | O_TRUNC,
|
||||
- 0600, errp);
|
||||
+ fioc = qio_channel_file_new_path(filename, O_CREAT | O_WRONLY, 0600, errp);
|
||||
if (!fioc) {
|
||||
return;
|
||||
}
|
||||
|
||||
+ if (ftruncate(fioc->fd, offset)) {
|
||||
+ error_setg_errno(errp, errno,
|
||||
+ "failed to truncate migration file to offset %" PRIx64,
|
||||
+ offset);
|
||||
+ object_unref(OBJECT(fioc));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
ioc = QIO_CHANNEL(fioc);
|
||||
if (offset && qio_channel_io_seek(ioc, offset, SEEK_SET, errp) < 0) {
|
||||
return;
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
35
migration-fix-possible-int-overflow.patch
Normal file
35
migration-fix-possible-int-overflow.patch
Normal file
@ -0,0 +1,35 @@
|
||||
From 254c67a88ab54fdfe1eb55d7efaf4386a9597cd0 Mon Sep 17 00:00:00 2001
|
||||
From: tangzhongrui <tangzhongrui@cmss.chinamobile.com>
|
||||
Date: Sat, 16 Nov 2024 17:38:50 +0800
|
||||
Subject: [PATCH] migration: fix-possible-int-overflow
|
||||
|
||||
stat64_add() takes uint64_t as 2nd argument, but both
|
||||
"p->next_packet_size" and "p->packet_len" are uint32_t.
|
||||
Thus, theyr sum may overflow uint32_t.
|
||||
|
||||
Found by Linux Verification Center (linuxtesting.org) with SVACE.
|
||||
|
||||
Signed-off-by: Dmitry Frolov <frolov@swemel.ru>
|
||||
Link: https://lore.kernel.org/r/20241113140509.325732-2-frolov@swemel.ru
|
||||
Signed-off-by: Peter Xu <peterx@redhat.com>
|
||||
Signed-off-by: Zhongrui Tang <tangzhongrui_yewu@cmss.chinamobile.com>
|
||||
---
|
||||
migration/multifd.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/migration/multifd.c b/migration/multifd.c
|
||||
index 7d373a245e..f3bf6888c0 100644
|
||||
--- a/migration/multifd.c
|
||||
+++ b/migration/multifd.c
|
||||
@@ -735,7 +735,7 @@ static void *multifd_send_thread(void *opaque)
|
||||
}
|
||||
|
||||
stat64_add(&mig_stats.multifd_bytes,
|
||||
- p->next_packet_size + p->packet_len);
|
||||
+ (uint64_t)p->next_packet_size + p->packet_len);
|
||||
p->next_packet_size = 0;
|
||||
qemu_mutex_lock(&p->mutex);
|
||||
p->pending_job--;
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
224
next-kbd-convert-to-use-qemu_input_handler_register.patch
Normal file
224
next-kbd-convert-to-use-qemu_input_handler_register.patch
Normal file
@ -0,0 +1,224 @@
|
||||
From 91e07a78026caafa181134beeb8c5b79157718ad Mon Sep 17 00:00:00 2001
|
||||
From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
|
||||
Date: Wed, 6 Nov 2024 12:09:27 +0000
|
||||
Subject: [PATCH] next-kbd: convert to use qemu_input_handler_register()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Convert the next-kbd device from the legacy UI qemu_add_kbd_event_handler()
|
||||
function to use qemu_input_handler_register().
|
||||
|
||||
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
|
||||
Reviewed-by: Thomas Huth <huth@tuxfamily.org>
|
||||
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
Message-ID: <20241106120928.242443-2-mark.cave-ayland@ilande.co.uk>
|
||||
[thuth: Removed the NEXTKBD_NO_KEY definition - replaced by 0 now]
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
Signed-off-by: Zhongrui Tang <tangzhongrui_yewu@cmss.chinamobile.com>
|
||||
---
|
||||
hw/m68k/next-kbd.c | 158 +++++++++++++++++++++++++++++----------------
|
||||
1 file changed, 103 insertions(+), 55 deletions(-)
|
||||
|
||||
diff --git a/hw/m68k/next-kbd.c b/hw/m68k/next-kbd.c
|
||||
index 0c348c18cf..880ebe3602 100644
|
||||
--- a/hw/m68k/next-kbd.c
|
||||
+++ b/hw/m68k/next-kbd.c
|
||||
@@ -68,7 +68,6 @@ struct NextKBDState {
|
||||
uint16_t shift;
|
||||
};
|
||||
|
||||
-static void queue_code(void *opaque, int code);
|
||||
|
||||
/* lots of magic numbers here */
|
||||
static uint32_t kbd_read_byte(void *opaque, hwaddr addr)
|
||||
@@ -166,68 +165,70 @@ static const MemoryRegionOps kbd_ops = {
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
};
|
||||
|
||||
-static void nextkbd_event(void *opaque, int ch)
|
||||
-{
|
||||
- /*
|
||||
- * Will want to set vars for caps/num lock
|
||||
- * if (ch & 0x80) -> key release
|
||||
- * there's also e0 escaped scancodes that might need to be handled
|
||||
- */
|
||||
- queue_code(opaque, ch);
|
||||
-}
|
||||
-
|
||||
-static const unsigned char next_keycodes[128] = {
|
||||
- 0x00, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x50, 0x4F,
|
||||
- 0x4E, 0x1E, 0x1F, 0x20, 0x1D, 0x1C, 0x1B, 0x00,
|
||||
- 0x42, 0x43, 0x44, 0x45, 0x48, 0x47, 0x46, 0x06,
|
||||
- 0x07, 0x08, 0x00, 0x00, 0x2A, 0x00, 0x39, 0x3A,
|
||||
- 0x3B, 0x3C, 0x3D, 0x40, 0x3F, 0x3E, 0x2D, 0x2C,
|
||||
- 0x2B, 0x26, 0x00, 0x00, 0x31, 0x32, 0x33, 0x34,
|
||||
- 0x35, 0x37, 0x36, 0x2e, 0x2f, 0x30, 0x00, 0x00,
|
||||
- 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
+static const int qcode_to_nextkbd_keycode[] = {
|
||||
+ [Q_KEY_CODE_ESC] = 0x49,
|
||||
+ [Q_KEY_CODE_1] = 0x4a,
|
||||
+ [Q_KEY_CODE_2] = 0x4b,
|
||||
+ [Q_KEY_CODE_3] = 0x4c,
|
||||
+ [Q_KEY_CODE_4] = 0x4d,
|
||||
+ [Q_KEY_CODE_5] = 0x50,
|
||||
+ [Q_KEY_CODE_6] = 0x4f,
|
||||
+ [Q_KEY_CODE_7] = 0x4e,
|
||||
+ [Q_KEY_CODE_8] = 0x1e,
|
||||
+ [Q_KEY_CODE_9] = 0x1f,
|
||||
+ [Q_KEY_CODE_0] = 0x20,
|
||||
+ [Q_KEY_CODE_MINUS] = 0x1d,
|
||||
+ [Q_KEY_CODE_EQUAL] = 0x1c,
|
||||
+ [Q_KEY_CODE_BACKSPACE] = 0x1b,
|
||||
+
|
||||
+ [Q_KEY_CODE_Q] = 0x42,
|
||||
+ [Q_KEY_CODE_W] = 0x43,
|
||||
+ [Q_KEY_CODE_E] = 0x44,
|
||||
+ [Q_KEY_CODE_R] = 0x45,
|
||||
+ [Q_KEY_CODE_T] = 0x48,
|
||||
+ [Q_KEY_CODE_Y] = 0x47,
|
||||
+ [Q_KEY_CODE_U] = 0x46,
|
||||
+ [Q_KEY_CODE_I] = 0x06,
|
||||
+ [Q_KEY_CODE_O] = 0x07,
|
||||
+ [Q_KEY_CODE_P] = 0x08,
|
||||
+ [Q_KEY_CODE_RET] = 0x2a,
|
||||
+ [Q_KEY_CODE_A] = 0x39,
|
||||
+ [Q_KEY_CODE_S] = 0x3a,
|
||||
+
|
||||
+ [Q_KEY_CODE_D] = 0x3b,
|
||||
+ [Q_KEY_CODE_F] = 0x3c,
|
||||
+ [Q_KEY_CODE_G] = 0x3d,
|
||||
+ [Q_KEY_CODE_H] = 0x40,
|
||||
+ [Q_KEY_CODE_J] = 0x3f,
|
||||
+ [Q_KEY_CODE_K] = 0x3e,
|
||||
+ [Q_KEY_CODE_L] = 0x2d,
|
||||
+ [Q_KEY_CODE_SEMICOLON] = 0x2c,
|
||||
+ [Q_KEY_CODE_APOSTROPHE] = 0x2b,
|
||||
+ [Q_KEY_CODE_GRAVE_ACCENT] = 0x26,
|
||||
+ [Q_KEY_CODE_Z] = 0x31,
|
||||
+ [Q_KEY_CODE_X] = 0x32,
|
||||
+ [Q_KEY_CODE_C] = 0x33,
|
||||
+ [Q_KEY_CODE_V] = 0x34,
|
||||
+
|
||||
+ [Q_KEY_CODE_B] = 0x35,
|
||||
+ [Q_KEY_CODE_N] = 0x37,
|
||||
+ [Q_KEY_CODE_M] = 0x36,
|
||||
+ [Q_KEY_CODE_COMMA] = 0x2e,
|
||||
+ [Q_KEY_CODE_DOT] = 0x2f,
|
||||
+ [Q_KEY_CODE_SLASH] = 0x30,
|
||||
+
|
||||
+ [Q_KEY_CODE_SPC] = 0x38,
|
||||
};
|
||||
|
||||
-static void queue_code(void *opaque, int code)
|
||||
+static void nextkbd_put_keycode(NextKBDState *s, int keycode)
|
||||
{
|
||||
- NextKBDState *s = NEXTKBD(opaque);
|
||||
KBDQueue *q = &s->queue;
|
||||
- int key = code & KD_KEYMASK;
|
||||
- int release = code & 0x80;
|
||||
- static int ext;
|
||||
-
|
||||
- if (code == 0xE0) {
|
||||
- ext = 1;
|
||||
- }
|
||||
-
|
||||
- if (code == 0x2A || code == 0x1D || code == 0x36) {
|
||||
- if (code == 0x2A) {
|
||||
- s->shift = KD_LSHIFT;
|
||||
- } else if (code == 0x36) {
|
||||
- s->shift = KD_RSHIFT;
|
||||
- ext = 0;
|
||||
- } else if (code == 0x1D && !ext) {
|
||||
- s->shift = KD_LCOMM;
|
||||
- } else if (code == 0x1D && ext) {
|
||||
- ext = 0;
|
||||
- s->shift = KD_RCOMM;
|
||||
- }
|
||||
- return;
|
||||
- } else if (code == (0x2A | 0x80) || code == (0x1D | 0x80) ||
|
||||
- code == (0x36 | 0x80)) {
|
||||
- s->shift = 0;
|
||||
- return;
|
||||
- }
|
||||
|
||||
if (q->count >= KBD_QUEUE_SIZE) {
|
||||
return;
|
||||
}
|
||||
|
||||
- q->data[q->wptr] = next_keycodes[key] | release;
|
||||
-
|
||||
+ q->data[q->wptr] = keycode;
|
||||
if (++q->wptr == KBD_QUEUE_SIZE) {
|
||||
q->wptr = 0;
|
||||
}
|
||||
@@ -241,6 +242,53 @@ static void queue_code(void *opaque, int code)
|
||||
/* s->update_irq(s->update_arg, 1); */
|
||||
}
|
||||
|
||||
+static void nextkbd_event(DeviceState *dev, QemuConsole *src, InputEvent *evt)
|
||||
+{
|
||||
+ NextKBDState *s = NEXTKBD(dev);
|
||||
+ int qcode, keycode;
|
||||
+ bool key_down = evt->u.key.data->down;
|
||||
+
|
||||
+ qcode = qemu_input_key_value_to_qcode(evt->u.key.data->key);
|
||||
+ if (qcode >= ARRAY_SIZE(qcode_to_nextkbd_keycode)) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* Shift key currently has no keycode, so handle separately */
|
||||
+ if (qcode == Q_KEY_CODE_SHIFT) {
|
||||
+ if (key_down) {
|
||||
+ s->shift |= KD_LSHIFT;
|
||||
+ } else {
|
||||
+ s->shift &= ~KD_LSHIFT;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (qcode == Q_KEY_CODE_SHIFT_R) {
|
||||
+ if (key_down) {
|
||||
+ s->shift |= KD_RSHIFT;
|
||||
+ } else {
|
||||
+ s->shift &= ~KD_RSHIFT;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ keycode = qcode_to_nextkbd_keycode[qcode];
|
||||
+ if (!keycode) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* If key release event, create keyboard break code */
|
||||
+ if (!key_down) {
|
||||
+ keycode |= 0x80;
|
||||
+ }
|
||||
+
|
||||
+ nextkbd_put_keycode(s, keycode);
|
||||
+}
|
||||
+
|
||||
+static const QemuInputHandler nextkbd_handler = {
|
||||
+ .name = "QEMU NeXT Keyboard",
|
||||
+ .mask = INPUT_EVENT_MASK_KEY,
|
||||
+ .event = nextkbd_event,
|
||||
+};
|
||||
+
|
||||
static void nextkbd_reset(DeviceState *dev)
|
||||
{
|
||||
NextKBDState *nks = NEXTKBD(dev);
|
||||
@@ -256,7 +304,7 @@ static void nextkbd_realize(DeviceState *dev, Error **errp)
|
||||
memory_region_init_io(&s->mr, OBJECT(dev), &kbd_ops, s, "next.kbd", 0x1000);
|
||||
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mr);
|
||||
|
||||
- qemu_add_kbd_event_handler(nextkbd_event, s);
|
||||
+ qemu_input_handler_register(dev, &nextkbd_handler);
|
||||
}
|
||||
|
||||
static const VMStateDescription nextkbd_vmstate = {
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
37
qemu-bswap-Undefine-CPU_CONVERT-once-done.patch
Normal file
37
qemu-bswap-Undefine-CPU_CONVERT-once-done.patch
Normal file
@ -0,0 +1,37 @@
|
||||
From 4fc36060bec2ac7de500068211b1282c38e3e073 Mon Sep 17 00:00:00 2001
|
||||
From: Zhang Jiao <zhangjiao2_yewu@cmss.chinamobile.com>
|
||||
Date: Tue, 12 Nov 2024 14:05:45 +0800
|
||||
Subject: [PATCH] qemu/bswap: Undefine CPU_CONVERT() once done
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
cheery-pick from 1d73353f236209e9b5987d7c6b30b2a32b739210
|
||||
|
||||
Better undefined macros once we are done with them,
|
||||
like we do few lines later with DO_STN_LDN_P().
|
||||
|
||||
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
Reviewed-by: Thomas Huth <thuth@redhat.com>
|
||||
Message-Id: <20241003234211.53644-2-philmd@linaro.org>
|
||||
Signed-off-by: Zhang Jiao <zhangjiao2_yewu@cmss.chinamobile.com>
|
||||
---
|
||||
include/qemu/bswap.h | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
|
||||
index 933a66ee87..49e4944457 100644
|
||||
--- a/include/qemu/bswap.h
|
||||
+++ b/include/qemu/bswap.h
|
||||
@@ -138,6 +138,8 @@ CPU_CONVERT(le, 16, uint16_t)
|
||||
CPU_CONVERT(le, 32, uint32_t)
|
||||
CPU_CONVERT(le, 64, uint64_t)
|
||||
|
||||
+#undef CPU_CONVERT
|
||||
+
|
||||
/*
|
||||
* Same as cpu_to_le{16,32,64}, except that gcc will figure the result is
|
||||
* a compile-time constant if you pass in a constant. So this can be
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
48
qemu-options-Fix-CXL-Fixed-Memory-Window-interleave-.patch
Normal file
48
qemu-options-Fix-CXL-Fixed-Memory-Window-interleave-.patch
Normal file
@ -0,0 +1,48 @@
|
||||
From 34fc72b12cc4887cb2b551b171f6a76c860b6997 Mon Sep 17 00:00:00 2001
|
||||
From: Yuquan Wang <wangyuquan1236@phytium.com.cn>
|
||||
Date: Sun, 7 Apr 2024 16:35:39 +0800
|
||||
Subject: [PATCH] qemu-options: Fix CXL Fixed Memory Window
|
||||
interleave-granularity typo
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Fix the unit typo of interleave-granularity of CXL Fixed Memory
|
||||
Window in qemu-option.hx.
|
||||
|
||||
Fixes: 03b39fcf64 ("hw/cxl: Make the CFMW a machine parameter.")
|
||||
Signed-off-by: Yuquan Wang wangyuquan1236@phytium.com.cn
|
||||
Message-ID: <20240407083539.1488172-2-wangyuquan1236@phytium.com.cn>
|
||||
[PMD: Reworded]
|
||||
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
(cherry picked from commit aa88f99c87c0e5d195d6d96190374650553ea61f)
|
||||
Signed-off-by: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
|
||||
---
|
||||
qemu-options.hx | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/qemu-options.hx b/qemu-options.hx
|
||||
index 9829b1020a..4df4dcea21 100644
|
||||
--- a/qemu-options.hx
|
||||
+++ b/qemu-options.hx
|
||||
@@ -149,14 +149,14 @@ SRST
|
||||
platform and configuration dependent.
|
||||
|
||||
``interleave-granularity=granularity`` sets the granularity of
|
||||
- interleave. Default 256KiB. Only 256KiB, 512KiB, 1024KiB, 2048KiB
|
||||
- 4096KiB, 8192KiB and 16384KiB granularities supported.
|
||||
+ interleave. Default 256 (bytes). Only 256, 512, 1k, 2k,
|
||||
+ 4k, 8k and 16k granularities supported.
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
|
||||
- -machine cxl-fmw.0.targets.0=cxl.0,cxl-fmw.0.targets.1=cxl.1,cxl-fmw.0.size=128G,cxl-fmw.0.interleave-granularity=512k
|
||||
+ -machine cxl-fmw.0.targets.0=cxl.0,cxl-fmw.0.targets.1=cxl.1,cxl-fmw.0.size=128G,cxl-fmw.0.interleave-granularity=512
|
||||
ERST
|
||||
|
||||
DEF("M", HAS_ARG, QEMU_OPTION_M,
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
92
qemu.spec
92
qemu.spec
@ -3,7 +3,7 @@
|
||||
|
||||
Name: qemu
|
||||
Version: 8.2.0
|
||||
Release: 25
|
||||
Release: 26
|
||||
Epoch: 11
|
||||
Summary: QEMU is a generic and open source machine emulator and virtualizer
|
||||
License: GPLv2 and BSD and MIT and CC-BY-SA-4.0
|
||||
@ -441,6 +441,50 @@ Patch0424: target-i386-sev-Add-support-for-reuse-ASID-for-diffe.patch
|
||||
Patch0425: Add-virtCCA-Coda-annotation.patch
|
||||
Patch0426: cvm-Add-support-for-TEE-based-national-encryption-ac.patch
|
||||
Patch0427: hw-arm-virt-Keep-Guest-L1-cache-type-consistent-with.patch
|
||||
Patch0428: target-i386-add-guest-phys-bits-cpu-property.patch
|
||||
Patch0429: kvm-add-support-for-guest-physical-bits.patch
|
||||
Patch0430: hw-i386-add-mem2-option-for-qemu.patch
|
||||
Patch0431: hw-misc-support-tkm-use-mem2-memory.patch
|
||||
Patch0432: hw-misc-psp-Pin-the-hugepage-memory-specified-by-mem.patch
|
||||
Patch0433: 9pfs-fix-crash-on-Treaddir-request.patch
|
||||
Patch0434: hw-nvme-fix-handling-of-over-committed-queues.patch
|
||||
Patch0435: exec-memop-Remove-unused-memop_big_endian-helper.patch
|
||||
Patch0436: qemu-bswap-Undefine-CPU_CONVERT-once-done.patch
|
||||
Patch0437: next-kbd-convert-to-use-qemu_input_handler_register.patch
|
||||
Patch0438: target-i386-csv-Add-CSV3-context.patch
|
||||
Patch0439: target-i386-csv-Add-command-to-initialize-CSV3-conte.patch
|
||||
Patch0440: target-i386-csv-Add-command-to-load-data-to-CSV3-gue.patch
|
||||
Patch0441: target-i386-csv-Add-command-to-load-vmcb-to-CSV3-gue.patch
|
||||
Patch0442: target-i386-cpu-Populate-CPUID-0x8000_001F-when-CSV3.patch
|
||||
Patch0443: target-i386-csv-Do-not-register-unregister-guest-sec.patch
|
||||
Patch0444: target-i386-csv-Load-initial-image-to-private-memory.patch
|
||||
Patch0445: vga-Force-full-update-for-CSV3-guest.patch
|
||||
Patch0446: vfio-Only-map-shared-region-for-CSV3-virtual-machine.patch
|
||||
Patch0447: linux-headers-update-kernel-headers-to-include-CSV3-.patch
|
||||
Patch0448: target-i386-csv-Add-support-to-migrate-the-outgoing-.patch
|
||||
Patch0449: target-i386-csv-Add-support-to-migrate-the-incoming-.patch
|
||||
Patch0450: target-i386-csv-Add-support-to-migrate-the-outgoing--new.patch
|
||||
Patch0451: target-i386-csv-Add-support-to-migrate-the-incoming--new.patch
|
||||
Patch0452: hw-arm-mps2-tz.c-fix-RX-TX-interrupts-order.patch
|
||||
Patch0453: hw-i386-amd_iommu-Don-t-leak-memory-in-amdvi_update_.patch
|
||||
Patch0454: hw-ppc-e500-Add-missing-device-tree-properties-to-i2.patch
|
||||
Patch0455: hw-ppc-e500-Remove-unused-irqs-parameter.patch
|
||||
Patch0456: sphinx-qapidoc-Fix-to-generate-doc-for-explicit-unbo.patch
|
||||
Patch0457: hw-ppc-e500-Prefer-QOM-cast.patch
|
||||
Patch0458: target-arm-Fix-FJCVTZS-vs-flush-to-zero.patch
|
||||
Patch0459: ui-vnc-don-t-return-an-empty-SASL-mechlist-to-the-cl.patch
|
||||
Patch0460: migration-Fix-file-migration-with-fdset.patch
|
||||
Patch0461: tcg-loongarch64-Fix-tcg_out_movi-vs-some-pcrel-point.patch
|
||||
Patch0462: accel-tcg-Fix-typo-causing-tb-page_addr-1-to-not-be-.patch
|
||||
Patch0463: target-riscv-Fix-the-element-agnostic-function-probl.patch
|
||||
Patch0464: qio-Inherit-follow_coroutine_ctx-across-TLS.patch
|
||||
Patch0465: hw-intc-arm_gic-Fix-handling-of-NS-view-of-GICC_APR-.patch
|
||||
Patch0466: hvf-arm-Fix-encodings-for-ID_AA64PFR1_EL1-and-debug-.patch
|
||||
Patch0467: qemu-options-Fix-CXL-Fixed-Memory-Window-interleave-.patch
|
||||
Patch0468: target-m68k-Map-FPU-exceptions-to-FPSR-register.patch
|
||||
Patch0469: migration-fix-possible-int-overflow.patch
|
||||
Patch0470: tcg-Allow-top-bit-of-SIMD_DATA_BITS-to-be-set-in-sim.patch
|
||||
Patch0471: vdpa-dev-Fix-initialisation-order-to-restore-VDUSE-c.patch
|
||||
|
||||
BuildRequires: flex
|
||||
BuildRequires: gcc
|
||||
@ -1038,6 +1082,52 @@ getent passwd qemu >/dev/null || \
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Thu Dec 12 2024 Jiabo Feng <fengjiabo1@huawei.com> - 11:8.2.0-26
|
||||
- vdpa-dev: Fix initialisation order to restore VDUSE compatibility
|
||||
- tcg: Allow top bit of SIMD_DATA_BITS to be set in simd_desc()
|
||||
- migration: fix-possible-int-overflow
|
||||
- target/m68k: Map FPU exceptions to FPSR register
|
||||
- qemu-options: Fix CXL Fixed Memory Window interleave-granularity typo
|
||||
- hvf: arm: Fix encodings for ID_AA64PFR1_EL1 and debug System registers
|
||||
- hw/intc/arm_gic: Fix handling of NS view of GICC_APR<n>
|
||||
- qio: Inherit follow_coroutine_ctx across TLS
|
||||
- target/riscv: Fix the element agnostic function problem
|
||||
- accel/tcg: Fix typo causing tb->page_addr[1] to not be recorded
|
||||
- tcg/loongarch64: Fix tcg_out_movi vs some pcrel pointers
|
||||
- migration: Fix file migration with fdset
|
||||
- ui/vnc: don't return an empty SASL mechlist to the client
|
||||
- target/arm: Fix FJCVTZS vs flush-to-zero
|
||||
- hw/ppc/e500: Prefer QOM cast
|
||||
- sphinx/qapidoc: Fix to generate doc for explicit, unboxed arguments
|
||||
- hw/ppc/e500: Remove unused "irqs" parameter
|
||||
- hw/ppc/e500: Add missing device tree properties to i2c controller node
|
||||
- hw/i386/amd_iommu: Don't leak memory in amdvi_update_iotlb()
|
||||
- hw/arm/mps2-tz.c: fix RX/TX interrupts order
|
||||
- target/i386: csv: Add support to migrate the incoming context for CSV3 guest
|
||||
- target/i386: csv: Add support to migrate the outgoing context for CSV3 guest
|
||||
- target/i386: csv: Add support to migrate the incoming page for CSV3 guest
|
||||
- target/i386: csv: Add support to migrate the outgoing page for CSV3 guest
|
||||
- linux-headers: update kernel headers to include CSV3 migration cmds
|
||||
- vfio: Only map shared region for CSV3 virtual machine
|
||||
- vga: Force full update for CSV3 guest
|
||||
- target/i386: csv: Load initial image to private memory for CSV3 guest
|
||||
- target/i386: csv: Do not register/unregister guest secure memory for CSV3 guest
|
||||
- target/i386: cpu: Populate CPUID 0x8000_001F when CSV3 is active
|
||||
- target/i386: csv: Add command to load vmcb to CSV3 guest memory
|
||||
- target/i386: csv: Add command to load data to CSV3 guest memory
|
||||
- target/i386: csv: Add command to initialize CSV3 context
|
||||
- target/i386: csv: Add CSV3 context
|
||||
- next-kbd: convert to use qemu_input_handler_register()
|
||||
- qemu/bswap: Undefine CPU_CONVERT() once done
|
||||
- exec/memop: Remove unused memop_big_endian() helper
|
||||
- hw/nvme: fix handling of over-committed queues
|
||||
- 9pfs: fix crash on 'Treaddir' request
|
||||
- hw/misc/psp: Pin the hugepage memory specified by mem2 during use for psp
|
||||
- hw/misc: support tkm use mem2 memory
|
||||
- hw/i386: add mem2 option for qemu
|
||||
- kvm: add support for guest physical bits
|
||||
- target/i386: add guest-phys-bits cpu property
|
||||
|
||||
* Sat Nov 30 2024 Jiabo Feng <fengjiabo1@huawei.com> - 11:8.2.0-25
|
||||
- hw/arm/virt:Keep Guest L1 cache type consistent with KVM
|
||||
- cvm : Add support for TEE-based national encryption acceleration.
|
||||
|
||||
121
qio-Inherit-follow_coroutine_ctx-across-TLS.patch
Normal file
121
qio-Inherit-follow_coroutine_ctx-across-TLS.patch
Normal file
@ -0,0 +1,121 @@
|
||||
From 4dccc6603af2cd3deefb6ac94c3e7aec4b60485d Mon Sep 17 00:00:00 2001
|
||||
From: Eric Blake <eblake@redhat.com>
|
||||
Date: Fri, 17 May 2024 21:50:14 -0500
|
||||
Subject: [PATCH] qio: Inherit follow_coroutine_ctx across TLS
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Since qemu 8.2, the combination of NBD + TLS + iothread crashes on an
|
||||
assertion failure:
|
||||
|
||||
qemu-kvm: ../io/channel.c:534: void qio_channel_restart_read(void *): Assertion `qemu_get_current_aio_context() == qemu_coroutine_get_aio_context(co)' failed.
|
||||
|
||||
It turns out that when we removed AioContext locking, we did so by
|
||||
having NBD tell its qio channels that it wanted to opt in to
|
||||
qio_channel_set_follow_coroutine_ctx(); but while we opted in on the
|
||||
main channel, we did not opt in on the TLS wrapper channel.
|
||||
qemu-iotests has coverage of NBD+iothread and NBD+TLS, but apparently
|
||||
no coverage of NBD+TLS+iothread, or we would have noticed this
|
||||
regression sooner. (I'll add that in the next patch)
|
||||
|
||||
But while we could manually opt in to the TLS channel in nbd/server.c
|
||||
(a one-line change), it is more generic if all qio channels that wrap
|
||||
other channels inherit the follow status, in the same way that they
|
||||
inherit feature bits.
|
||||
|
||||
CC: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
CC: Daniel P. Berrangé <berrange@redhat.com>
|
||||
CC: qemu-stable@nongnu.org
|
||||
Fixes: https://issues.redhat.com/browse/RHEL-34786
|
||||
Fixes: 06e0f098 ("io: follow coroutine AioContext in qio_channel_yield()", v8.2.0)
|
||||
Signed-off-by: Eric Blake <eblake@redhat.com>
|
||||
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
Message-ID: <20240518025246.791593-5-eblake@redhat.com>
|
||||
(cherry picked from commit 199e84de1c903ba5aa1f7256310bbc4a20dd930b)
|
||||
Signed-off-by: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
|
||||
---
|
||||
io/channel-tls.c | 26 +++++++++++++++-----------
|
||||
io/channel-websock.c | 1 +
|
||||
2 files changed, 16 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/io/channel-tls.c b/io/channel-tls.c
|
||||
index 58fe1aceee..a8ad89c3d1 100644
|
||||
--- a/io/channel-tls.c
|
||||
+++ b/io/channel-tls.c
|
||||
@@ -69,37 +69,40 @@ qio_channel_tls_new_server(QIOChannel *master,
|
||||
const char *aclname,
|
||||
Error **errp)
|
||||
{
|
||||
- QIOChannelTLS *ioc;
|
||||
+ QIOChannelTLS *tioc;
|
||||
+ QIOChannel *ioc;
|
||||
|
||||
- ioc = QIO_CHANNEL_TLS(object_new(TYPE_QIO_CHANNEL_TLS));
|
||||
+ tioc = QIO_CHANNEL_TLS(object_new(TYPE_QIO_CHANNEL_TLS));
|
||||
+ ioc = QIO_CHANNEL(tioc);
|
||||
|
||||
- ioc->master = master;
|
||||
+ tioc->master = master;
|
||||
+ ioc->follow_coroutine_ctx = master->follow_coroutine_ctx;
|
||||
if (qio_channel_has_feature(master, QIO_CHANNEL_FEATURE_SHUTDOWN)) {
|
||||
- qio_channel_set_feature(QIO_CHANNEL(ioc), QIO_CHANNEL_FEATURE_SHUTDOWN);
|
||||
+ qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_SHUTDOWN);
|
||||
}
|
||||
object_ref(OBJECT(master));
|
||||
|
||||
- ioc->session = qcrypto_tls_session_new(
|
||||
+ tioc->session = qcrypto_tls_session_new(
|
||||
creds,
|
||||
NULL,
|
||||
aclname,
|
||||
QCRYPTO_TLS_CREDS_ENDPOINT_SERVER,
|
||||
errp);
|
||||
- if (!ioc->session) {
|
||||
+ if (!tioc->session) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
qcrypto_tls_session_set_callbacks(
|
||||
- ioc->session,
|
||||
+ tioc->session,
|
||||
qio_channel_tls_write_handler,
|
||||
qio_channel_tls_read_handler,
|
||||
- ioc);
|
||||
+ tioc);
|
||||
|
||||
- trace_qio_channel_tls_new_server(ioc, master, creds, aclname);
|
||||
- return ioc;
|
||||
+ trace_qio_channel_tls_new_server(tioc, master, creds, aclname);
|
||||
+ return tioc;
|
||||
|
||||
error:
|
||||
- object_unref(OBJECT(ioc));
|
||||
+ object_unref(OBJECT(tioc));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -116,6 +119,7 @@ qio_channel_tls_new_client(QIOChannel *master,
|
||||
ioc = QIO_CHANNEL(tioc);
|
||||
|
||||
tioc->master = master;
|
||||
+ ioc->follow_coroutine_ctx = master->follow_coroutine_ctx;
|
||||
if (qio_channel_has_feature(master, QIO_CHANNEL_FEATURE_SHUTDOWN)) {
|
||||
qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_SHUTDOWN);
|
||||
}
|
||||
diff --git a/io/channel-websock.c b/io/channel-websock.c
|
||||
index a12acc27cf..de39f0d182 100644
|
||||
--- a/io/channel-websock.c
|
||||
+++ b/io/channel-websock.c
|
||||
@@ -883,6 +883,7 @@ qio_channel_websock_new_server(QIOChannel *master)
|
||||
ioc = QIO_CHANNEL(wioc);
|
||||
|
||||
wioc->master = master;
|
||||
+ ioc->follow_coroutine_ctx = master->follow_coroutine_ctx;
|
||||
if (qio_channel_has_feature(master, QIO_CHANNEL_FEATURE_SHUTDOWN)) {
|
||||
qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_SHUTDOWN);
|
||||
}
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
156
sphinx-qapidoc-Fix-to-generate-doc-for-explicit-unbo.patch
Normal file
156
sphinx-qapidoc-Fix-to-generate-doc-for-explicit-unbo.patch
Normal file
@ -0,0 +1,156 @@
|
||||
From c7fe47e4aab35c1817c4c53f0025a741a9e2ad57 Mon Sep 17 00:00:00 2001
|
||||
From: Markus Armbruster <armbru@redhat.com>
|
||||
Date: Fri, 28 Jun 2024 13:27:56 +0200
|
||||
Subject: [PATCH] sphinx/qapidoc: Fix to generate doc for explicit, unboxed
|
||||
arguments
|
||||
|
||||
When a command's arguments are specified as an explicit type T,
|
||||
generated documentation points to the members of T.
|
||||
|
||||
Example:
|
||||
|
||||
##
|
||||
# @announce-self:
|
||||
#
|
||||
# Trigger generation of broadcast RARP frames to update network
|
||||
[...]
|
||||
##
|
||||
{ 'command': 'announce-self', 'boxed': true,
|
||||
'data' : 'AnnounceParameters'}
|
||||
|
||||
generates
|
||||
|
||||
"announce-self" (Command)
|
||||
-------------------------
|
||||
|
||||
Trigger generation of broadcast RARP frames to update network
|
||||
[...]
|
||||
|
||||
Arguments
|
||||
~~~~~~~~~
|
||||
|
||||
The members of "AnnounceParameters"
|
||||
|
||||
Except when the command takes its arguments unboxed , i.e. it doesn't
|
||||
have 'boxed': true, we generate *nothing*. A few commands have a
|
||||
reference in their doc comment to compensate, but most don't.
|
||||
|
||||
Example:
|
||||
|
||||
##
|
||||
# @blockdev-snapshot-sync:
|
||||
#
|
||||
# Takes a synchronous snapshot of a block device.
|
||||
#
|
||||
# For the arguments, see the documentation of BlockdevSnapshotSync.
|
||||
[...]
|
||||
##
|
||||
{ 'command': 'blockdev-snapshot-sync',
|
||||
'data': 'BlockdevSnapshotSync',
|
||||
'allow-preconfig': true }
|
||||
|
||||
generates
|
||||
|
||||
"blockdev-snapshot-sync" (Command)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Takes a synchronous snapshot of a block device.
|
||||
|
||||
For the arguments, see the documentation of BlockdevSnapshotSync.
|
||||
[...]
|
||||
|
||||
Same for event data.
|
||||
|
||||
Fix qapidoc.py to generate the reference regardless of boxing. Delete
|
||||
now redundant references in the doc comments.
|
||||
|
||||
Fixes: 4078ee5469e5 (docs/sphinx: Add new qapi-doc Sphinx extension)
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
||||
Message-ID: <20240628112756.794237-1-armbru@redhat.com>
|
||||
Reviewed-by: John Snow <jsnow@redhat.com>
|
||||
(cherry picked from commit e389929d19a543ea5b34d02553b355f9f1c03162)
|
||||
Signed-off-by: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
|
||||
---
|
||||
docs/sphinx/qapidoc.py | 12 +++++-------
|
||||
qapi/block-core.json | 7 -------
|
||||
2 files changed, 5 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/docs/sphinx/qapidoc.py b/docs/sphinx/qapidoc.py
|
||||
index 658c288f8f..3d19853444 100644
|
||||
--- a/docs/sphinx/qapidoc.py
|
||||
+++ b/docs/sphinx/qapidoc.py
|
||||
@@ -229,15 +229,15 @@ def _nodes_for_enum_values(self, doc):
|
||||
section += dlnode
|
||||
return [section]
|
||||
|
||||
- def _nodes_for_arguments(self, doc, boxed_arg_type):
|
||||
+ def _nodes_for_arguments(self, doc, arg_type):
|
||||
"""Return list of doctree nodes for the arguments section"""
|
||||
- if boxed_arg_type:
|
||||
+ if arg_type and not arg_type.is_implicit():
|
||||
assert not doc.args
|
||||
section = self._make_section('Arguments')
|
||||
dlnode = nodes.definition_list()
|
||||
dlnode += self._make_dlitem(
|
||||
[nodes.Text('The members of '),
|
||||
- nodes.literal('', boxed_arg_type.name)],
|
||||
+ nodes.literal('', arg_type.name)],
|
||||
None)
|
||||
section += dlnode
|
||||
return [section]
|
||||
@@ -341,8 +341,7 @@ def visit_command(self, name, info, ifcond, features, arg_type,
|
||||
allow_preconfig, coroutine):
|
||||
doc = self._cur_doc
|
||||
self._add_doc('Command',
|
||||
- self._nodes_for_arguments(doc,
|
||||
- arg_type if boxed else None)
|
||||
+ self._nodes_for_arguments(doc, arg_type)
|
||||
+ self._nodes_for_features(doc)
|
||||
+ self._nodes_for_sections(doc)
|
||||
+ self._nodes_for_if_section(ifcond))
|
||||
@@ -350,8 +349,7 @@ def visit_command(self, name, info, ifcond, features, arg_type,
|
||||
def visit_event(self, name, info, ifcond, features, arg_type, boxed):
|
||||
doc = self._cur_doc
|
||||
self._add_doc('Event',
|
||||
- self._nodes_for_arguments(doc,
|
||||
- arg_type if boxed else None)
|
||||
+ self._nodes_for_arguments(doc, arg_type)
|
||||
+ self._nodes_for_features(doc)
|
||||
+ self._nodes_for_sections(doc)
|
||||
+ self._nodes_for_if_section(ifcond))
|
||||
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||
index ded6f0f6d2..0fa184698a 100644
|
||||
--- a/qapi/block-core.json
|
||||
+++ b/qapi/block-core.json
|
||||
@@ -1662,8 +1662,6 @@
|
||||
#
|
||||
# Takes a synchronous snapshot of a block device.
|
||||
#
|
||||
-# For the arguments, see the documentation of BlockdevSnapshotSync.
|
||||
-#
|
||||
# Returns:
|
||||
# - nothing on success
|
||||
# - If @device is not a valid block device, DeviceNotFound
|
||||
@@ -1693,8 +1691,6 @@
|
||||
# device, the block device changes to using 'overlay' as its new
|
||||
# active image.
|
||||
#
|
||||
-# For the arguments, see the documentation of BlockdevSnapshot.
|
||||
-#
|
||||
# Features:
|
||||
#
|
||||
# @allow-write-only-overlay: If present, the check whether this
|
||||
@@ -6037,9 +6033,6 @@
|
||||
# string, or a snapshot with name already exists, the operation will
|
||||
# fail.
|
||||
#
|
||||
-# For the arguments, see the documentation of
|
||||
-# BlockdevSnapshotInternal.
|
||||
-#
|
||||
# Returns:
|
||||
# - nothing on success
|
||||
# - If @device is not a valid block device, GenericError
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
106
target-arm-Fix-FJCVTZS-vs-flush-to-zero.patch
Normal file
106
target-arm-Fix-FJCVTZS-vs-flush-to-zero.patch
Normal file
@ -0,0 +1,106 @@
|
||||
From 148e01eba8041bad93081a19a240034bb8138988 Mon Sep 17 00:00:00 2001
|
||||
From: Richard Henderson <richard.henderson@linaro.org>
|
||||
Date: Tue, 25 Jun 2024 11:35:26 -0700
|
||||
Subject: [PATCH] target/arm: Fix FJCVTZS vs flush-to-zero
|
||||
|
||||
Input denormals cause the Javascript inexact bit
|
||||
(output to Z) to be set.
|
||||
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Fixes: 6c1f6f2733a ("target/arm: Implement ARMv8.3-JSConv")
|
||||
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2375
|
||||
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
Message-id: 20240625183536.1672454-4-richard.henderson@linaro.org
|
||||
[PMM: fixed hardcoded tab in test case]
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
(cherry picked from commit 7619129f0d4a14d918227c5c47ad7433662e9ccc)
|
||||
Signed-off-by: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
|
||||
---
|
||||
target/arm/vfp_helper.c | 18 +++++++++---------
|
||||
tests/tcg/aarch64/Makefile.target | 3 ++-
|
||||
tests/tcg/aarch64/test-2375.c | 21 +++++++++++++++++++++
|
||||
3 files changed, 32 insertions(+), 10 deletions(-)
|
||||
create mode 100644 tests/tcg/aarch64/test-2375.c
|
||||
|
||||
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
|
||||
index 3e5e37abbe..ff59bc5522 100644
|
||||
--- a/target/arm/vfp_helper.c
|
||||
+++ b/target/arm/vfp_helper.c
|
||||
@@ -1121,8 +1121,8 @@ const FloatRoundMode arm_rmode_to_sf_map[] = {
|
||||
uint64_t HELPER(fjcvtzs)(float64 value, void *vstatus)
|
||||
{
|
||||
float_status *status = vstatus;
|
||||
- uint32_t inexact, frac;
|
||||
- uint32_t e_old, e_new;
|
||||
+ uint32_t frac, e_old, e_new;
|
||||
+ bool inexact;
|
||||
|
||||
e_old = get_float_exception_flags(status);
|
||||
set_float_exception_flags(0, status);
|
||||
@@ -1130,13 +1130,13 @@ uint64_t HELPER(fjcvtzs)(float64 value, void *vstatus)
|
||||
e_new = get_float_exception_flags(status);
|
||||
set_float_exception_flags(e_old | e_new, status);
|
||||
|
||||
- if (value == float64_chs(float64_zero)) {
|
||||
- /* While not inexact for IEEE FP, -0.0 is inexact for JavaScript. */
|
||||
- inexact = 1;
|
||||
- } else {
|
||||
- /* Normal inexact or overflow or NaN */
|
||||
- inexact = e_new & (float_flag_inexact | float_flag_invalid);
|
||||
- }
|
||||
+ /* Normal inexact, denormal with flush-to-zero, or overflow or NaN */
|
||||
+ inexact = e_new & (float_flag_inexact |
|
||||
+ float_flag_input_denormal |
|
||||
+ float_flag_invalid);
|
||||
+
|
||||
+ /* While not inexact for IEEE FP, -0.0 is inexact for JavaScript. */
|
||||
+ inexact |= value == float64_chs(float64_zero);
|
||||
|
||||
/* Pack the result and the env->ZF representation of Z together. */
|
||||
return deposit64(frac, 32, 32, inexact);
|
||||
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
|
||||
index cded1d01fc..6d593c6392 100644
|
||||
--- a/tests/tcg/aarch64/Makefile.target
|
||||
+++ b/tests/tcg/aarch64/Makefile.target
|
||||
@@ -40,8 +40,9 @@ endif
|
||||
|
||||
# Pauth Tests
|
||||
ifneq ($(CROSS_CC_HAS_ARMV8_3),)
|
||||
-AARCH64_TESTS += pauth-1 pauth-2 pauth-4 pauth-5
|
||||
+AARCH64_TESTS += pauth-1 pauth-2 pauth-4 pauth-5 test-2375
|
||||
pauth-%: CFLAGS += -march=armv8.3-a
|
||||
+test-2375: CFLAGS += -march=armv8.3-a
|
||||
run-pauth-1: QEMU_OPTS += -cpu max
|
||||
run-pauth-2: QEMU_OPTS += -cpu max
|
||||
# Choose a cpu with FEAT_Pauth but without FEAT_FPAC for pauth-[45].
|
||||
diff --git a/tests/tcg/aarch64/test-2375.c b/tests/tcg/aarch64/test-2375.c
|
||||
new file mode 100644
|
||||
index 0000000000..84c7e7de71
|
||||
--- /dev/null
|
||||
+++ b/tests/tcg/aarch64/test-2375.c
|
||||
@@ -0,0 +1,21 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
+/* Copyright (c) 2024 Linaro Ltd */
|
||||
+/* See https://gitlab.com/qemu-project/qemu/-/issues/2375 */
|
||||
+
|
||||
+#include <assert.h>
|
||||
+
|
||||
+int main(void)
|
||||
+{
|
||||
+ int r, z;
|
||||
+
|
||||
+ asm("msr fpcr, %2\n\t"
|
||||
+ "fjcvtzs %w0, %d3\n\t"
|
||||
+ "cset %1, eq"
|
||||
+ : "=r"(r), "=r"(z)
|
||||
+ : "r"(0x01000000L), /* FZ = 1 */
|
||||
+ "w"(0xfcff00L)); /* denormal */
|
||||
+
|
||||
+ assert(r == 0);
|
||||
+ assert(z == 0);
|
||||
+ return 0;
|
||||
+}
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
106
target-i386-add-guest-phys-bits-cpu-property.patch
Normal file
106
target-i386-add-guest-phys-bits-cpu-property.patch
Normal file
@ -0,0 +1,106 @@
|
||||
From b6bfee023b15f25c1db077df7bfd2e9212cda762 Mon Sep 17 00:00:00 2001
|
||||
From: Gerd Hoffmann <kraxel@redhat.com>
|
||||
Date: Mon, 18 Mar 2024 16:53:36 +0100
|
||||
Subject: [PATCH] target/i386: add guest-phys-bits cpu property
|
||||
|
||||
commit 513ba32dccc659c80722b3a43233b26eaa50309a upstream.
|
||||
|
||||
Allows to set guest-phys-bits (cpuid leaf 80000008, eax[23:16])
|
||||
via -cpu $model,guest-phys-bits=$nr.
|
||||
|
||||
Intel-SIG: commit 513ba32dccc6 target/i386: add guest-phys-bits cpu property
|
||||
|
||||
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||
Message-ID: <20240318155336.156197-3-kraxel@redhat.com>
|
||||
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
[jz: compatible property for 9.0 machines not included]
|
||||
Signed-off-by: Jason Zeng <jason.zeng@intel.com>
|
||||
---
|
||||
target/i386/cpu.c | 22 ++++++++++++++++++++++
|
||||
target/i386/cpu.h | 8 ++++++++
|
||||
2 files changed, 30 insertions(+)
|
||||
|
||||
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
|
||||
index ca7e5337b0..93f88b7bf8 100644
|
||||
--- a/target/i386/cpu.c
|
||||
+++ b/target/i386/cpu.c
|
||||
@@ -6827,6 +6827,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
||||
if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
|
||||
/* 64 bit processor */
|
||||
*eax |= (cpu_x86_virtual_addr_width(env) << 8);
|
||||
+ *eax |= (cpu->guest_phys_bits << 16);
|
||||
}
|
||||
*ebx = env->features[FEAT_8000_0008_EBX];
|
||||
if (cs->nr_cores * cs->nr_threads > 1) {
|
||||
@@ -7603,6 +7604,14 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
|
||||
goto out;
|
||||
}
|
||||
|
||||
+ if (cpu->guest_phys_bits == -1) {
|
||||
+ /*
|
||||
+ * If it was not set by the user, or by the accelerator via
|
||||
+ * cpu_exec_realizefn, clear.
|
||||
+ */
|
||||
+ cpu->guest_phys_bits = 0;
|
||||
+ }
|
||||
+
|
||||
if (cpu->ucode_rev == 0) {
|
||||
/*
|
||||
* The default is the same as KVM's. Note that this check
|
||||
@@ -7653,6 +7662,14 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
|
||||
if (cpu->phys_bits == 0) {
|
||||
cpu->phys_bits = TCG_PHYS_ADDR_BITS;
|
||||
}
|
||||
+ if (cpu->guest_phys_bits &&
|
||||
+ (cpu->guest_phys_bits > cpu->phys_bits ||
|
||||
+ cpu->guest_phys_bits < 32)) {
|
||||
+ error_setg(errp, "guest-phys-bits should be between 32 and %u "
|
||||
+ " (but is %u)",
|
||||
+ cpu->phys_bits, cpu->guest_phys_bits);
|
||||
+ return;
|
||||
+ }
|
||||
} else {
|
||||
/* For 32 bit systems don't use the user set value, but keep
|
||||
* phys_bits consistent with what we tell the guest.
|
||||
@@ -7661,6 +7678,10 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
|
||||
error_setg(errp, "phys-bits is not user-configurable in 32 bit");
|
||||
return;
|
||||
}
|
||||
+ if (cpu->guest_phys_bits != 0) {
|
||||
+ error_setg(errp, "guest-phys-bits is not user-configurable in 32 bit");
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
if (env->features[FEAT_1_EDX] & (CPUID_PSE36 | CPUID_PAE)) {
|
||||
cpu->phys_bits = 36;
|
||||
@@ -8167,6 +8188,7 @@ static Property x86_cpu_properties[] = {
|
||||
DEFINE_PROP_BOOL("x-force-features", X86CPU, force_features, false),
|
||||
DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true),
|
||||
DEFINE_PROP_UINT32("phys-bits", X86CPU, phys_bits, 0),
|
||||
+ DEFINE_PROP_UINT32("guest-phys-bits", X86CPU, guest_phys_bits, -1),
|
||||
DEFINE_PROP_BOOL("host-phys-bits", X86CPU, host_phys_bits, false),
|
||||
DEFINE_PROP_UINT8("host-phys-bits-limit", X86CPU, host_phys_bits_limit, 0),
|
||||
DEFINE_PROP_BOOL("fill-mtrr-mask", X86CPU, fill_mtrr_mask, false),
|
||||
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
|
||||
index 34f9615b98..d6fdcc04ca 100644
|
||||
--- a/target/i386/cpu.h
|
||||
+++ b/target/i386/cpu.h
|
||||
@@ -2029,6 +2029,14 @@ struct ArchCPU {
|
||||
/* Number of physical address bits supported */
|
||||
uint32_t phys_bits;
|
||||
|
||||
+ /*
|
||||
+ * Number of guest physical address bits available. Usually this is
|
||||
+ * identical to host physical address bits. With NPT or EPT 4-level
|
||||
+ * paging, guest physical address space might be restricted to 48 bits
|
||||
+ * even if the host cpu supports more physical address bits.
|
||||
+ */
|
||||
+ uint32_t guest_phys_bits;
|
||||
+
|
||||
/* in order to simplify APIC support, we leave this pointer to the
|
||||
user */
|
||||
struct DeviceState *apic_state;
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
41
target-i386-cpu-Populate-CPUID-0x8000_001F-when-CSV3.patch
Normal file
41
target-i386-cpu-Populate-CPUID-0x8000_001F-when-CSV3.patch
Normal file
@ -0,0 +1,41 @@
|
||||
From 120d0b9e5c92de91c69fb9fbea038b51c820013d Mon Sep 17 00:00:00 2001
|
||||
From: jiangxin <jiangxin@hygon.cn>
|
||||
Date: Tue, 24 Aug 2021 17:31:28 +0800
|
||||
Subject: [PATCH] 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 <jiangxin@hygon.cn>
|
||||
Signed-off-by: hanliyang <hanliyang@hygon.cn>
|
||||
---
|
||||
target/i386/cpu.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
|
||||
index ca7e5337b0..36f7ad6460 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"
|
||||
@@ -6943,6 +6944,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.41.0.windows.1
|
||||
|
||||
85
target-i386-csv-Add-CSV3-context.patch
Normal file
85
target-i386-csv-Add-CSV3-context.patch
Normal file
@ -0,0 +1,85 @@
|
||||
From 54648e0e5a45acf2e472430ee83bb8dfa057fb30 Mon Sep 17 00:00:00 2001
|
||||
From: jiangxin <jiangxin@hygon.cn>
|
||||
Date: Tue, 24 Aug 2021 14:57:28 +0800
|
||||
Subject: [PATCH] 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 <jiangxin@hygon.cn>
|
||||
Signed-off-by: hanliyang <hanliyang@hygon.cn>
|
||||
---
|
||||
target/i386/csv.c | 11 +++++++++++
|
||||
target/i386/csv.h | 17 +++++++++++++++++
|
||||
2 files changed, 28 insertions(+)
|
||||
|
||||
diff --git a/target/i386/csv.c b/target/i386/csv.c
|
||||
index 88fb05ac37..9a1de04db7 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 05e7fd8dc1..ea87c1ba27 100644
|
||||
--- a/target/i386/csv.h
|
||||
+++ b/target/i386/csv.h
|
||||
@@ -14,6 +14,9 @@
|
||||
#ifndef I386_CSV_H
|
||||
#define I386_CSV_H
|
||||
|
||||
+#include "qapi/qapi-commands-misc-target.h"
|
||||
+
|
||||
+#define GUEST_POLICY_CSV3_BIT (1 << 6)
|
||||
#define GUEST_POLICY_REUSE_ASID (1 << 7)
|
||||
|
||||
#ifdef CONFIG_CSV
|
||||
@@ -40,9 +43,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
|
||||
|
||||
@@ -66,4 +72,15 @@ 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 */
|
||||
+struct Csv3GuestState {
|
||||
+ uint32_t policy;
|
||||
+ int sev_fd;
|
||||
+ void *state;
|
||||
+};
|
||||
+
|
||||
+typedef struct Csv3GuestState Csv3GuestState;
|
||||
+
|
||||
+extern struct Csv3GuestState csv3_guest;
|
||||
+
|
||||
#endif
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
201
target-i386-csv-Add-command-to-initialize-CSV3-conte.patch
Normal file
201
target-i386-csv-Add-command-to-initialize-CSV3-conte.patch
Normal file
@ -0,0 +1,201 @@
|
||||
From 4ce59de673b1b190cde76c458ac9e92a6413172d Mon Sep 17 00:00:00 2001
|
||||
From: jiangxin <jiangxin@hygon.cn>
|
||||
Date: Wed, 25 Aug 2021 11:07:41 +0800
|
||||
Subject: [PATCH] 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 <jiangxin@hygon.cn>
|
||||
Signed-off-by: hanliyang <hanliyang@hygon.cn>
|
||||
---
|
||||
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 8dc00808ec..90869068c8 100644
|
||||
--- a/linux-headers/linux/kvm.h
|
||||
+++ b/linux-headers/linux/kvm.h
|
||||
@@ -2108,6 +2108,17 @@ struct kvm_csv_init {
|
||||
__u32 len;
|
||||
};
|
||||
|
||||
+/* 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 5874e4cc1d..72f0f5c772 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 9a1de04db7..fd3ea291ca 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 <linux/kvm.h>
|
||||
+
|
||||
+#ifdef CONFIG_NUMA
|
||||
+#include <numaif.h>
|
||||
+#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 ea87c1ba27..4096e8658b 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"
|
||||
|
||||
#define GUEST_POLICY_CSV3_BIT (1 << 6)
|
||||
#define GUEST_POLICY_REUSE_ASID (1 << 7)
|
||||
@@ -77,10 +78,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 af61ca5ba8..1c453b3148 100644
|
||||
--- a/target/i386/sev.c
|
||||
+++ b/target/i386/sev.c
|
||||
@@ -1225,6 +1225,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.
|
||||
@@ -2635,6 +2647,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 0bfe3879ef..e91431e0f7 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.41.0.windows.1
|
||||
|
||||
166
target-i386-csv-Add-command-to-load-data-to-CSV3-gue.patch
Normal file
166
target-i386-csv-Add-command-to-load-data-to-CSV3-gue.patch
Normal file
@ -0,0 +1,166 @@
|
||||
From 53cba8da8fb18cc9a463ec1f57990e8558cd4008 Mon Sep 17 00:00:00 2001
|
||||
From: jiangxin <jiangxin@hygon.cn>
|
||||
Date: Wed, 25 Aug 2021 09:59:16 +0800
|
||||
Subject: [PATCH] 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 <jiangxin@hygon.cn>
|
||||
Signed-off-by: hanliyang <hanliyang@hygon.cn>
|
||||
---
|
||||
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 90869068c8..dd6d9c2e07 100644
|
||||
--- a/linux-headers/linux/kvm.h
|
||||
+++ b/linux-headers/linux/kvm.h
|
||||
@@ -2113,6 +2113,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 72f0f5c772..b0ccbd2f18 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 fd3ea291ca..2a596681b8 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 <linux/kvm.h>
|
||||
|
||||
@@ -20,6 +21,7 @@
|
||||
#include <numaif.h>
|
||||
#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;
|
||||
+}
|
||||
+
|
||||
+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 4096e8658b..27b66f7857 100644
|
||||
--- a/target/i386/csv.h
|
||||
+++ b/target/i386/csv.h
|
||||
@@ -87,4 +87,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 87b765c73c..34c205ffda 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%" PRIx64
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
108
target-i386-csv-Add-command-to-load-vmcb-to-CSV3-gue.patch
Normal file
108
target-i386-csv-Add-command-to-load-vmcb-to-CSV3-gue.patch
Normal file
@ -0,0 +1,108 @@
|
||||
From 368bf2c044fcdd21f10545de103af7cd2a5986f9 Mon Sep 17 00:00:00 2001
|
||||
From: jiangxin <jiangxin@hygon.cn>
|
||||
Date: Wed, 25 Aug 2021 12:25:05 +0800
|
||||
Subject: [PATCH] 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 <jiangxin@hygon.cn>
|
||||
Signed-off-by: hanliyang <hanliyang@hygon.cn>
|
||||
---
|
||||
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 dd6d9c2e07..8487d0889b 100644
|
||||
--- a/linux-headers/linux/kvm.h
|
||||
+++ b/linux-headers/linux/kvm.h
|
||||
@@ -2114,6 +2114,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 b0ccbd2f18..23d885f0f3 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 2a596681b8..12282ba451 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 27b66f7857..3caf216743 100644
|
||||
--- a/target/i386/csv.h
|
||||
+++ b/target/i386/csv.h
|
||||
@@ -86,6 +86,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 1c453b3148..6ff8891678 100644
|
||||
--- a/target/i386/sev.c
|
||||
+++ b/target/i386/sev.c
|
||||
@@ -880,8 +880,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.41.0.windows.1
|
||||
|
||||
110
target-i386-csv-Add-support-to-migrate-the-incoming--new.patch
Normal file
110
target-i386-csv-Add-support-to-migrate-the-incoming--new.patch
Normal file
@ -0,0 +1,110 @@
|
||||
From b31be8b06440deccdf00de2a7886d04fe87dc802 Mon Sep 17 00:00:00 2001
|
||||
From: jiangxin <jiangxin@hygon.cn>
|
||||
Date: Fri, 17 Jun 2022 10:00:46 +0800
|
||||
Subject: [PATCH] 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 <jiangxin@hygon.cn>
|
||||
Signed-off-by: hanliyang <hanliyang@hygon.cn>
|
||||
---
|
||||
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 cc90b57e5b..571beeb61f 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 \
|
||||
@@ -644,6 +645,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;
|
||||
@@ -651,3 +688,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 9f83a271fd..8621f0b6fd 100644
|
||||
--- a/target/i386/csv.h
|
||||
+++ b/target/i386/csv.h
|
||||
@@ -123,6 +123,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 043412c569..ad3cfb9612 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.41.0.windows.1
|
||||
|
||||
205
target-i386-csv-Add-support-to-migrate-the-incoming-.patch
Normal file
205
target-i386-csv-Add-support-to-migrate-the-incoming-.patch
Normal file
@ -0,0 +1,205 @@
|
||||
From 3434042340ca031b6d355cc79dd00e166bd2e2fd Mon Sep 17 00:00:00 2001
|
||||
From: jiangxin <jiangxin@hygon.cn>
|
||||
Date: Fri, 17 Jun 2022 09:45:45 +0800
|
||||
Subject: [PATCH] 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 <jiangxin@hygon.cn>
|
||||
Signed-off-by: hanliyang <hanliyang@hygon.cn>
|
||||
---
|
||||
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 22e709a95c..ac080b3766 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;
|
||||
}
|
||||
@@ -483,3 +487,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 12c1b22659..afcd59180c 100644
|
||||
--- a/target/i386/csv.h
|
||||
+++ b/target/i386/csv.h
|
||||
@@ -108,6 +108,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;
|
||||
@@ -121,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_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 5a96b0b452..5124bf3dee 100644
|
||||
--- a/target/i386/sev.c
|
||||
+++ b/target/i386/sev.c
|
||||
@@ -2665,10 +2665,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 8ccef22a95..647b426b16 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 a4a58b12a1..b3cb9aaf71 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%" PRIx64
|
||||
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.41.0.windows.1
|
||||
|
||||
139
target-i386-csv-Add-support-to-migrate-the-outgoing--new.patch
Normal file
139
target-i386-csv-Add-support-to-migrate-the-outgoing--new.patch
Normal file
@ -0,0 +1,139 @@
|
||||
From 0ebf32463e858c5f9cbd98e3f2fe494d0fbea259 Mon Sep 17 00:00:00 2001
|
||||
From: jiangxin <jiangxin@hygon.cn>
|
||||
Date: Fri, 17 Jun 2022 09:52:31 +0800
|
||||
Subject: [PATCH] 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 <jiangxin@hygon.cn>
|
||||
Signed-off-by: hanliyang <hanliyang@hygon.cn>
|
||||
---
|
||||
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 ac080b3766..cc90b57e5b 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 \
|
||||
@@ -570,3 +571,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 afcd59180c..9f83a271fd 100644
|
||||
--- a/target/i386/csv.h
|
||||
+++ b/target/i386/csv.h
|
||||
@@ -125,5 +125,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 b3cb9aaf71..043412c569 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%" PRIx64
|
||||
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.41.0.windows.1
|
||||
|
||||
452
target-i386-csv-Add-support-to-migrate-the-outgoing-.patch
Normal file
452
target-i386-csv-Add-support-to-migrate-the-outgoing-.patch
Normal file
@ -0,0 +1,452 @@
|
||||
From 13bd2629b78f528b0b4684a643f59d30b7274aa8 Mon Sep 17 00:00:00 2001
|
||||
From: jiangxin <jiangxin@hygon.cn>
|
||||
Date: Fri, 17 Jun 2022 09:37:56 +0800
|
||||
Subject: [PATCH] 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 <jiangxin@hygon.cn>
|
||||
Signed-off-by: hanliyang <hanliyang@hygon.cn>
|
||||
---
|
||||
migration/ram.c | 87 +++++++++++++++++++
|
||||
target/i386/csv.c | 182 +++++++++++++++++++++++++++++++++++++++
|
||||
target/i386/csv.h | 22 +++++
|
||||
target/i386/sev.c | 14 ++-
|
||||
target/i386/sev.h | 1 +
|
||||
target/i386/trace-events | 1 +
|
||||
6 files changed, 306 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/migration/ram.c b/migration/ram.c
|
||||
index 1377b9eb37..1f9348fd06 100644
|
||||
--- a/migration/ram.c
|
||||
+++ b/migration/ram.c
|
||||
@@ -2480,6 +2480,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
|
||||
*
|
||||
@@ -2515,6 +2599,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 e4706efa27..22e709a95c 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 <linux/kvm.h>
|
||||
+#include <linux/psp-sev.h>
|
||||
|
||||
#ifdef CONFIG_NUMA
|
||||
#include <numaif.h>
|
||||
@@ -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,166 @@ 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;
|
||||
+
|
||||
+ 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 12733341b3..12c1b22659 100644
|
||||
--- a/target/i386/csv.h
|
||||
+++ b/target/i386/csv.h
|
||||
@@ -81,6 +81,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;
|
||||
@@ -89,11 +101,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);
|
||||
|
||||
@@ -101,5 +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_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 0012a5efb0..5a96b0b452 100644
|
||||
--- a/target/i386/sev.c
|
||||
+++ b/target/i386/sev.c
|
||||
@@ -1270,7 +1270,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 */
|
||||
@@ -2654,9 +2658,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 e91431e0f7..8ccef22a95 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 34c205ffda..a4a58b12a1 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%" PRIx64
|
||||
+kvm_csv3_send_encrypt_data(void *dst, int len) "trans %p len %d"
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
35
target-i386-csv-Do-not-register-unregister-guest-sec.patch
Normal file
35
target-i386-csv-Do-not-register-unregister-guest-sec.patch
Normal file
@ -0,0 +1,35 @@
|
||||
From a3e8267b93d1e77dc547fff6fb9af6f8d48a674f Mon Sep 17 00:00:00 2001
|
||||
From: jiangxin <jiangxin@hygon.cn>
|
||||
Date: Wed, 25 Aug 2021 12:36:00 +0800
|
||||
Subject: [PATCH] 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 <jiangxin@hygon.cn>
|
||||
Signed-off-by: hanliyang <hanliyang@hygon.cn>
|
||||
---
|
||||
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 6ff8891678..0012a5efb0 100644
|
||||
--- a/target/i386/sev.c
|
||||
+++ b/target/i386/sev.c
|
||||
@@ -1262,7 +1262,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.41.0.windows.1
|
||||
|
||||
52
target-i386-csv-Load-initial-image-to-private-memory.patch
Normal file
52
target-i386-csv-Load-initial-image-to-private-memory.patch
Normal file
@ -0,0 +1,52 @@
|
||||
From ed3c233cc00d4c30718fc64b3afc48a51b4eb438 Mon Sep 17 00:00:00 2001
|
||||
From: jiangxin <jiangxin@hygon.cn>
|
||||
Date: Wed, 25 Aug 2021 14:29:40 +0800
|
||||
Subject: [PATCH] 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 <jiangxin@hygon.cn>
|
||||
Signed-off-by: hanliyang <hanliyang@hygon.cn>
|
||||
---
|
||||
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 c8d9e71b88..2bbcbb8d35 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.41.0.windows.1
|
||||
|
||||
218
target-m68k-Map-FPU-exceptions-to-FPSR-register.patch
Normal file
218
target-m68k-Map-FPU-exceptions-to-FPSR-register.patch
Normal file
@ -0,0 +1,218 @@
|
||||
From a8a621a06d54b987502d277f33021547d00fd133 Mon Sep 17 00:00:00 2001
|
||||
From: Keith Packard <keithp@keithp.com>
|
||||
Date: Wed, 2 Aug 2023 20:52:31 -0700
|
||||
Subject: [PATCH] target/m68k: Map FPU exceptions to FPSR register
|
||||
|
||||
Add helpers for reading/writing the 68881 FPSR register so that
|
||||
changes in floating point exception state can be seen by the
|
||||
application.
|
||||
|
||||
Call these helpers in pre_load/post_load hooks to synchronize
|
||||
exception state.
|
||||
|
||||
Signed-off-by: Keith Packard <keithp@keithp.com>
|
||||
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
Message-Id: <20230803035231.429697-1-keithp@keithp.com>
|
||||
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
(cherry picked from commit 5888357942da1fd5a50efb6e4a6af8b1a27a5af8)
|
||||
Signed-off-by: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
|
||||
---
|
||||
target/m68k/cpu.c | 12 +++++--
|
||||
target/m68k/cpu.h | 3 +-
|
||||
target/m68k/fpu_helper.c | 72 ++++++++++++++++++++++++++++++++++++++++
|
||||
target/m68k/helper.c | 4 +--
|
||||
target/m68k/helper.h | 2 ++
|
||||
target/m68k/translate.c | 4 +--
|
||||
6 files changed, 90 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
|
||||
index 11c7e0a790..d95deaafcd 100644
|
||||
--- a/target/m68k/cpu.c
|
||||
+++ b/target/m68k/cpu.c
|
||||
@@ -396,12 +396,19 @@ static const VMStateDescription vmstate_freg = {
|
||||
}
|
||||
};
|
||||
|
||||
-static int fpu_post_load(void *opaque, int version)
|
||||
+static int fpu_pre_save(void *opaque)
|
||||
{
|
||||
M68kCPU *s = opaque;
|
||||
|
||||
- cpu_m68k_restore_fp_status(&s->env);
|
||||
+ s->env.fpsr = cpu_m68k_get_fpsr(&s->env);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int fpu_post_load(void *opaque, int version)
|
||||
+{
|
||||
+ M68kCPU *s = opaque;
|
||||
|
||||
+ cpu_m68k_set_fpsr(&s->env, s->env.fpsr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -410,6 +417,7 @@ const VMStateDescription vmmstate_fpu = {
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.needed = fpu_needed,
|
||||
+ .pre_save = fpu_pre_save,
|
||||
.post_load = fpu_post_load,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT32(env.fpcr, M68kCPU),
|
||||
diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h
|
||||
index 6cfc696d2b..4d78da9d5f 100644
|
||||
--- a/target/m68k/cpu.h
|
||||
+++ b/target/m68k/cpu.h
|
||||
@@ -199,7 +199,8 @@ void cpu_m68k_set_ccr(CPUM68KState *env, uint32_t);
|
||||
void cpu_m68k_set_sr(CPUM68KState *env, uint32_t);
|
||||
void cpu_m68k_restore_fp_status(CPUM68KState *env);
|
||||
void cpu_m68k_set_fpcr(CPUM68KState *env, uint32_t val);
|
||||
-
|
||||
+uint32_t cpu_m68k_get_fpsr(CPUM68KState *env);
|
||||
+void cpu_m68k_set_fpsr(CPUM68KState *env, uint32_t val);
|
||||
|
||||
/*
|
||||
* Instead of computing the condition codes after each m68k instruction,
|
||||
diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
|
||||
index ab120b5f59..8314791f50 100644
|
||||
--- a/target/m68k/fpu_helper.c
|
||||
+++ b/target/m68k/fpu_helper.c
|
||||
@@ -164,6 +164,78 @@ void HELPER(set_fpcr)(CPUM68KState *env, uint32_t val)
|
||||
cpu_m68k_set_fpcr(env, val);
|
||||
}
|
||||
|
||||
+/* Convert host exception flags to cpu_m68k form. */
|
||||
+static int cpu_m68k_exceptbits_from_host(int host_bits)
|
||||
+{
|
||||
+ int target_bits = 0;
|
||||
+
|
||||
+ if (host_bits & float_flag_invalid) {
|
||||
+ target_bits |= 0x80;
|
||||
+ }
|
||||
+ if (host_bits & float_flag_overflow) {
|
||||
+ target_bits |= 0x40;
|
||||
+ }
|
||||
+ if (host_bits & (float_flag_underflow | float_flag_output_denormal)) {
|
||||
+ target_bits |= 0x20;
|
||||
+ }
|
||||
+ if (host_bits & float_flag_divbyzero) {
|
||||
+ target_bits |= 0x10;
|
||||
+ }
|
||||
+ if (host_bits & float_flag_inexact) {
|
||||
+ target_bits |= 0x08;
|
||||
+ }
|
||||
+ return target_bits;
|
||||
+}
|
||||
+
|
||||
+/* Convert cpu_m68k exception flags to target form. */
|
||||
+static int cpu_m68k_exceptbits_to_host(int target_bits)
|
||||
+{
|
||||
+ int host_bits = 0;
|
||||
+
|
||||
+ if (target_bits & 0x80) {
|
||||
+ host_bits |= float_flag_invalid;
|
||||
+ }
|
||||
+ if (target_bits & 0x40) {
|
||||
+ host_bits |= float_flag_overflow;
|
||||
+ }
|
||||
+ if (target_bits & 0x20) {
|
||||
+ host_bits |= float_flag_underflow;
|
||||
+ }
|
||||
+ if (target_bits & 0x10) {
|
||||
+ host_bits |= float_flag_divbyzero;
|
||||
+ }
|
||||
+ if (target_bits & 0x08) {
|
||||
+ host_bits |= float_flag_inexact;
|
||||
+ }
|
||||
+ return host_bits;
|
||||
+}
|
||||
+
|
||||
+uint32_t cpu_m68k_get_fpsr(CPUM68KState *env)
|
||||
+{
|
||||
+ int host_flags = get_float_exception_flags(&env->fp_status);
|
||||
+ int target_flags = cpu_m68k_exceptbits_from_host(host_flags);
|
||||
+ int except = (env->fpsr & ~(0xf8)) | target_flags;
|
||||
+ return except;
|
||||
+}
|
||||
+
|
||||
+uint32_t HELPER(get_fpsr)(CPUM68KState *env)
|
||||
+{
|
||||
+ return cpu_m68k_get_fpsr(env);
|
||||
+}
|
||||
+
|
||||
+void cpu_m68k_set_fpsr(CPUM68KState *env, uint32_t val)
|
||||
+{
|
||||
+ env->fpsr = val;
|
||||
+
|
||||
+ int host_flags = cpu_m68k_exceptbits_to_host((int) env->fpsr);
|
||||
+ set_float_exception_flags(host_flags, &env->fp_status);
|
||||
+}
|
||||
+
|
||||
+void HELPER(set_fpsr)(CPUM68KState *env, uint32_t val)
|
||||
+{
|
||||
+ cpu_m68k_set_fpsr(env, val);
|
||||
+}
|
||||
+
|
||||
#define PREC_BEGIN(prec) \
|
||||
do { \
|
||||
FloatX80RoundPrec old = \
|
||||
diff --git a/target/m68k/helper.c b/target/m68k/helper.c
|
||||
index 0a1544cd68..beab4b96bc 100644
|
||||
--- a/target/m68k/helper.c
|
||||
+++ b/target/m68k/helper.c
|
||||
@@ -118,7 +118,7 @@ static int m68k_fpu_gdb_get_reg(CPUM68KState *env, GByteArray *mem_buf, int n)
|
||||
case 8: /* fpcontrol */
|
||||
return gdb_get_reg32(mem_buf, env->fpcr);
|
||||
case 9: /* fpstatus */
|
||||
- return gdb_get_reg32(mem_buf, env->fpsr);
|
||||
+ return gdb_get_reg32(mem_buf, cpu_m68k_get_fpsr(env));
|
||||
case 10: /* fpiar, not implemented */
|
||||
return gdb_get_reg32(mem_buf, 0);
|
||||
}
|
||||
@@ -137,7 +137,7 @@ static int m68k_fpu_gdb_set_reg(CPUM68KState *env, uint8_t *mem_buf, int n)
|
||||
cpu_m68k_set_fpcr(env, ldl_p(mem_buf));
|
||||
return 4;
|
||||
case 9: /* fpstatus */
|
||||
- env->fpsr = ldl_p(mem_buf);
|
||||
+ cpu_m68k_set_fpsr(env, ldl_p(mem_buf));
|
||||
return 4;
|
||||
case 10: /* fpiar, not implemented */
|
||||
return 4;
|
||||
diff --git a/target/m68k/helper.h b/target/m68k/helper.h
|
||||
index 2bbe0dc032..95aa5e53bb 100644
|
||||
--- a/target/m68k/helper.h
|
||||
+++ b/target/m68k/helper.h
|
||||
@@ -54,6 +54,8 @@ DEF_HELPER_4(fsdiv, void, env, fp, fp, fp)
|
||||
DEF_HELPER_4(fddiv, void, env, fp, fp, fp)
|
||||
DEF_HELPER_4(fsgldiv, void, env, fp, fp, fp)
|
||||
DEF_HELPER_FLAGS_3(fcmp, TCG_CALL_NO_RWG, void, env, fp, fp)
|
||||
+DEF_HELPER_2(set_fpsr, void, env, i32)
|
||||
+DEF_HELPER_1(get_fpsr, i32, env)
|
||||
DEF_HELPER_FLAGS_2(set_fpcr, TCG_CALL_NO_RWG, void, env, i32)
|
||||
DEF_HELPER_FLAGS_2(ftst, TCG_CALL_NO_RWG, void, env, fp)
|
||||
DEF_HELPER_3(fconst, void, env, fp, i32)
|
||||
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
|
||||
index 4a0b0b2703..f8eeb70379 100644
|
||||
--- a/target/m68k/translate.c
|
||||
+++ b/target/m68k/translate.c
|
||||
@@ -4686,7 +4686,7 @@ static void gen_load_fcr(DisasContext *s, TCGv res, int reg)
|
||||
tcg_gen_movi_i32(res, 0);
|
||||
break;
|
||||
case M68K_FPSR:
|
||||
- tcg_gen_ld_i32(res, tcg_env, offsetof(CPUM68KState, fpsr));
|
||||
+ gen_helper_get_fpsr(res, tcg_env);
|
||||
break;
|
||||
case M68K_FPCR:
|
||||
tcg_gen_ld_i32(res, tcg_env, offsetof(CPUM68KState, fpcr));
|
||||
@@ -4700,7 +4700,7 @@ static void gen_store_fcr(DisasContext *s, TCGv val, int reg)
|
||||
case M68K_FPIAR:
|
||||
break;
|
||||
case M68K_FPSR:
|
||||
- tcg_gen_st_i32(val, tcg_env, offsetof(CPUM68KState, fpsr));
|
||||
+ gen_helper_set_fpsr(tcg_env, val);
|
||||
break;
|
||||
case M68K_FPCR:
|
||||
gen_helper_set_fpcr(tcg_env, val);
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
60
target-riscv-Fix-the-element-agnostic-function-probl.patch
Normal file
60
target-riscv-Fix-the-element-agnostic-function-probl.patch
Normal file
@ -0,0 +1,60 @@
|
||||
From 194c3cadc1879ff4c3d2fc6c5f962ad751c83d9c Mon Sep 17 00:00:00 2001
|
||||
From: Huang Tao <eric.huang@linux.alibaba.com>
|
||||
Date: Mon, 25 Mar 2024 10:16:54 +0800
|
||||
Subject: [PATCH] target/riscv: Fix the element agnostic function problem
|
||||
|
||||
In RVV and vcrypto instructions, the masked and tail elements are set to 1s
|
||||
using vext_set_elems_1s function if the vma/vta bit is set. It is the element
|
||||
agnostic policy.
|
||||
|
||||
However, this function can't deal the big endian situation. This patch fixes
|
||||
the problem by adding handling of such case.
|
||||
|
||||
Signed-off-by: Huang Tao <eric.huang@linux.alibaba.com>
|
||||
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
|
||||
Cc: qemu-stable <qemu-stable@nongnu.org>
|
||||
Message-ID: <20240325021654.6594-1-eric.huang@linux.alibaba.com>
|
||||
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
|
||||
(cherry picked from commit 75115d880c6d396f8a2d56aab8c12236d85a90e0)
|
||||
Signed-off-by: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
|
||||
---
|
||||
target/riscv/vector_internals.c | 22 ++++++++++++++++++++++
|
||||
1 file changed, 22 insertions(+)
|
||||
|
||||
diff --git a/target/riscv/vector_internals.c b/target/riscv/vector_internals.c
|
||||
index 9cf5c17cde..be6eb040d2 100644
|
||||
--- a/target/riscv/vector_internals.c
|
||||
+++ b/target/riscv/vector_internals.c
|
||||
@@ -29,6 +29,28 @@ void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
|
||||
if (tot - cnt == 0) {
|
||||
return ;
|
||||
}
|
||||
+
|
||||
+ if (HOST_BIG_ENDIAN) {
|
||||
+ /*
|
||||
+ * Deal the situation when the elements are insdie
|
||||
+ * only one uint64 block including setting the
|
||||
+ * masked-off element.
|
||||
+ */
|
||||
+ if (((tot - 1) ^ cnt) < 8) {
|
||||
+ memset(base + H1(tot - 1), -1, tot - cnt);
|
||||
+ return;
|
||||
+ }
|
||||
+ /*
|
||||
+ * Otherwise, at least cross two uint64_t blocks.
|
||||
+ * Set first unaligned block.
|
||||
+ */
|
||||
+ if (cnt % 8 != 0) {
|
||||
+ uint32_t j = ROUND_UP(cnt, 8);
|
||||
+ memset(base + H1(j - 1), -1, j - cnt);
|
||||
+ cnt = j;
|
||||
+ }
|
||||
+ /* Set other 64bit aligend blocks */
|
||||
+ }
|
||||
memset(base + cnt, -1, tot - cnt);
|
||||
}
|
||||
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
69
tcg-Allow-top-bit-of-SIMD_DATA_BITS-to-be-set-in-sim.patch
Normal file
69
tcg-Allow-top-bit-of-SIMD_DATA_BITS-to-be-set-in-sim.patch
Normal file
@ -0,0 +1,69 @@
|
||||
From d0b24cfdeb8bd64fa55154d79574352be33ecc51 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Maydell <peter.maydell@linaro.org>
|
||||
Date: Fri, 15 Nov 2024 17:25:15 +0000
|
||||
Subject: [PATCH] tcg: Allow top bit of SIMD_DATA_BITS to be set in simd_desc()
|
||||
|
||||
In simd_desc() we create a SIMD descriptor from various pieces
|
||||
including an arbitrary data value from the caller. We try to
|
||||
sanitize these to make sure everything will fit: the 'data' value
|
||||
needs to fit in the SIMD_DATA_BITS (== 22) sized field. However we
|
||||
do that sanitizing with:
|
||||
tcg_debug_assert(data == sextract32(data, 0, SIMD_DATA_BITS));
|
||||
|
||||
This works for the case where the data is supposed to be considered
|
||||
as a signed integer (which can then be returned via simd_data()).
|
||||
However, some callers want to treat the data value as unsigned.
|
||||
|
||||
Specifically, for the Arm SVE operations, make_svemte_desc()
|
||||
assembles a data value as a collection of fields, and it needs to use
|
||||
all 22 bits. Currently if MTE is enabled then its MTEDESC SIZEM1
|
||||
field may have the most significant bit set, and then it will trip
|
||||
this assertion.
|
||||
|
||||
Loosen the assertion so that we only check that the data value will
|
||||
fit into the field in some way, either as a signed or as an unsigned
|
||||
value. This means we will fail to detect some kinds of bug in the
|
||||
callers, but we won't spuriously assert for intentional use of the
|
||||
data field as unsigned.
|
||||
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Fixes: db432672dc50e ("tcg: Add generic vector expanders")
|
||||
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2601
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
Message-ID: <20241115172515.1229393-1-peter.maydell@linaro.org>
|
||||
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
Signed-off-by: Zhongrui Tang <tangzhongrui_yewu@cmss.chinamobile.com>
|
||||
---
|
||||
tcg/tcg-op-gvec.c | 15 ++++++++++++++-
|
||||
1 file changed, 14 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tcg/tcg-op-gvec.c b/tcg/tcg-op-gvec.c
|
||||
index bb88943f79..733b44f105 100644
|
||||
--- a/tcg/tcg-op-gvec.c
|
||||
+++ b/tcg/tcg-op-gvec.c
|
||||
@@ -88,7 +88,20 @@ uint32_t simd_desc(uint32_t oprsz, uint32_t maxsz, int32_t data)
|
||||
uint32_t desc = 0;
|
||||
|
||||
check_size_align(oprsz, maxsz, 0);
|
||||
- tcg_debug_assert(data == sextract32(data, 0, SIMD_DATA_BITS));
|
||||
+
|
||||
+ /*
|
||||
+ * We want to check that 'data' will fit into SIMD_DATA_BITS.
|
||||
+ * However, some callers want to treat the data as a signed
|
||||
+ * value (which they can later get back with simd_data())
|
||||
+ * and some want to treat it as an unsigned value.
|
||||
+ * So here we assert only that the data will fit into the
|
||||
+ * field in at least one way. This means that some invalid
|
||||
+ * values from the caller will not be detected, e.g. if the
|
||||
+ * caller wants to handle the value as a signed integer but
|
||||
+ * incorrectly passes us 1 << (SIMD_DATA_BITS - 1).
|
||||
+ */
|
||||
+ tcg_debug_assert(data == sextract32(data, 0, SIMD_DATA_BITS) ||
|
||||
+ data == extract32(data, 0, SIMD_DATA_BITS));
|
||||
|
||||
oprsz = (oprsz / 8) - 1;
|
||||
maxsz = (maxsz / 8) - 1;
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
77
tcg-loongarch64-Fix-tcg_out_movi-vs-some-pcrel-point.patch
Normal file
77
tcg-loongarch64-Fix-tcg_out_movi-vs-some-pcrel-point.patch
Normal file
@ -0,0 +1,77 @@
|
||||
From 6477ff9d89317a6124f3a46215b1567306b6ebe4 Mon Sep 17 00:00:00 2001
|
||||
From: Richard Henderson <richard.henderson@linaro.org>
|
||||
Date: Wed, 19 Jun 2024 05:41:13 +0000
|
||||
Subject: [PATCH] tcg/loongarch64: Fix tcg_out_movi vs some pcrel pointers
|
||||
|
||||
Simplify the logic for two-part, 32-bit pc-relative addresses.
|
||||
Rather than assume all such fit in int32_t, do some arithmetic
|
||||
and assert a result, do some arithmetic first and then check
|
||||
to see if the pieces are in range.
|
||||
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Fixes: dacc51720db ("tcg/loongarch64: Implement tcg_out_mov and tcg_out_movi")
|
||||
Reviewed-by: Song Gao <gaosong@loongson.cn>
|
||||
Reported-by: Song Gao <gaosong@loongson.cn>
|
||||
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
(cherry picked from commit 521d7fb3ebdf88112ed13556a93e3037742b9eb8)
|
||||
Signed-off-by: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
|
||||
---
|
||||
tcg/loongarch64/tcg-target.c.inc | 32 +++++++++++++++-----------------
|
||||
1 file changed, 15 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
|
||||
index bab0a173a3..ad2690b90d 100644
|
||||
--- a/tcg/loongarch64/tcg-target.c.inc
|
||||
+++ b/tcg/loongarch64/tcg-target.c.inc
|
||||
@@ -365,8 +365,7 @@ static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd,
|
||||
* back to the slow path.
|
||||
*/
|
||||
|
||||
- intptr_t pc_offset;
|
||||
- tcg_target_long val_lo, val_hi, pc_hi, offset_hi;
|
||||
+ intptr_t src_rx, pc_offset;
|
||||
tcg_target_long hi12, hi32, hi52;
|
||||
|
||||
/* Value fits in signed i32. */
|
||||
@@ -376,24 +375,23 @@ static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd,
|
||||
}
|
||||
|
||||
/* PC-relative cases. */
|
||||
- pc_offset = tcg_pcrel_diff(s, (void *)val);
|
||||
- if (pc_offset == sextreg(pc_offset, 0, 22) && (pc_offset & 3) == 0) {
|
||||
- /* Single pcaddu2i. */
|
||||
- tcg_out_opc_pcaddu2i(s, rd, pc_offset >> 2);
|
||||
- return;
|
||||
+ src_rx = (intptr_t)tcg_splitwx_to_rx(s->code_ptr);
|
||||
+ if ((val & 3) == 0) {
|
||||
+ pc_offset = val - src_rx;
|
||||
+ if (pc_offset == sextreg(pc_offset, 0, 22)) {
|
||||
+ /* Single pcaddu2i. */
|
||||
+ tcg_out_opc_pcaddu2i(s, rd, pc_offset >> 2);
|
||||
+ return;
|
||||
+ }
|
||||
}
|
||||
|
||||
- if (pc_offset == (int32_t)pc_offset) {
|
||||
- /* Offset within 32 bits; load with pcalau12i + ori. */
|
||||
- val_lo = sextreg(val, 0, 12);
|
||||
- val_hi = val >> 12;
|
||||
- pc_hi = (val - pc_offset) >> 12;
|
||||
- offset_hi = val_hi - pc_hi;
|
||||
-
|
||||
- tcg_debug_assert(offset_hi == sextreg(offset_hi, 0, 20));
|
||||
- tcg_out_opc_pcalau12i(s, rd, offset_hi);
|
||||
+ pc_offset = (val >> 12) - (src_rx >> 12);
|
||||
+ if (pc_offset == sextreg(pc_offset, 0, 20)) {
|
||||
+ /* Load with pcalau12i + ori. */
|
||||
+ tcg_target_long val_lo = val & 0xfff;
|
||||
+ tcg_out_opc_pcalau12i(s, rd, pc_offset);
|
||||
if (val_lo != 0) {
|
||||
- tcg_out_opc_ori(s, rd, rd, val_lo & 0xfff);
|
||||
+ tcg_out_opc_ori(s, rd, rd, val_lo);
|
||||
}
|
||||
return;
|
||||
}
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
47
ui-vnc-don-t-return-an-empty-SASL-mechlist-to-the-cl.patch
Normal file
47
ui-vnc-don-t-return-an-empty-SASL-mechlist-to-the-cl.patch
Normal file
@ -0,0 +1,47 @@
|
||||
From 838c585cf6c899a0b48683a0b46ed01cc24d835c Mon Sep 17 00:00:00 2001
|
||||
From: Susanooo <zhangchujun_yewu@cmss.chinamobile.com>
|
||||
Date: Fri, 25 Oct 2024 10:08:39 +0800
|
||||
Subject: [PATCH] ui/vnc: don't return an empty SASL mechlist to the client
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The SASL initialization phase may determine that there are no valid
|
||||
mechanisms available to use. This may be because the host OS admin
|
||||
forgot to install some packages, or it might be because the requested
|
||||
SSF level is incompatible with available mechanisms, or other unknown
|
||||
reasons.
|
||||
|
||||
If we return an empty mechlist to the client, they're going to get a
|
||||
failure from the SASL library on their end and drop the connection.
|
||||
Thus there is no point even sending this back to the client, we can
|
||||
just drop the connection immediately.
|
||||
|
||||
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
Signed-off-by: zhangchujun <zhangchujun_yewu@cmss.chinamobile.com>
|
||||
---
|
||||
ui/vnc-auth-sasl.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/ui/vnc-auth-sasl.c b/ui/vnc-auth-sasl.c
|
||||
index 47fdae5b21..e321c9decc 100644
|
||||
--- a/ui/vnc-auth-sasl.c
|
||||
+++ b/ui/vnc-auth-sasl.c
|
||||
@@ -674,6 +674,13 @@ void start_auth_sasl(VncState *vs)
|
||||
}
|
||||
trace_vnc_auth_sasl_mech_list(vs, mechlist);
|
||||
|
||||
+ if (g_str_equal(mechlist, "")) {
|
||||
+ trace_vnc_auth_fail(vs, vs->auth, "no available SASL mechanisms", "");
|
||||
+ sasl_dispose(&vs->sasl.conn);
|
||||
+ vs->sasl.conn = NULL;
|
||||
+ goto authabort;
|
||||
+ }
|
||||
+
|
||||
vs->sasl.mechlist = g_strdup(mechlist);
|
||||
mechlistlen = strlen(mechlist);
|
||||
vnc_write_u32(vs, mechlistlen);
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
180
vdpa-dev-Fix-initialisation-order-to-restore-VDUSE-c.patch
Normal file
180
vdpa-dev-Fix-initialisation-order-to-restore-VDUSE-c.patch
Normal file
@ -0,0 +1,180 @@
|
||||
From 9ab31c6abf095d8f7c986676cf6a70132a3441b7 Mon Sep 17 00:00:00 2001
|
||||
From: Adttil <2429917001@qq.com>
|
||||
Date: Tue, 10 Dec 2024 00:33:28 +0800
|
||||
Subject: [PATCH] vdpa-dev: Fix initialisation order to restore VDUSE
|
||||
compatibility
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
VDUSE requires that virtqueues are first enabled before the DRIVER_OK
|
||||
status flag is set; with the current API of the kernel module, it is
|
||||
impossible to enable the opposite order in our block export code because
|
||||
userspace is not notified when a virtqueue is enabled.
|
||||
|
||||
This requirement also mathces the normal initialisation order as done by
|
||||
the generic vhost code in QEMU. However, commit 6c48254 accidentally
|
||||
changed the order for vdpa-dev and broke access to VDUSE devices with
|
||||
this.
|
||||
|
||||
This changes vdpa-dev to use the normal order again and use the standard
|
||||
vhost callback .vhost_set_vring_enable for this. VDUSE devices can be
|
||||
used with vdpa-dev again after this fix.
|
||||
|
||||
vhost_net intentionally avoided enabling the vrings for vdpa and does
|
||||
this manually later while it does enable them for other vhost backends.
|
||||
Reflect this in the vhost_net code and return early for vdpa, so that
|
||||
the behaviour doesn't change for this device.
|
||||
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Fixes: 6c48254 ('vdpa: move vhost_vdpa_set_vring_ready to the caller')
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Message-ID: <20240315155949.86066-1-kwolf@redhat.com>
|
||||
Reviewed-by: Eugenio Pérez <eperezma@redhat.com>
|
||||
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
hw/net/vhost_net.c | 10 ++++++++++
|
||||
hw/virtio/trace-events | 2 +-
|
||||
hw/virtio/vdpa-dev.c | 5 +----
|
||||
hw/virtio/vhost-vdpa.c | 29 ++++++++++++++++++++++++++---
|
||||
hw/virtio/vhost.c | 8 +++++++-
|
||||
5 files changed, 45 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
|
||||
index e48c373b14..a02d65d208 100644
|
||||
--- a/hw/net/vhost_net.c
|
||||
+++ b/hw/net/vhost_net.c
|
||||
@@ -599,6 +599,16 @@ int vhost_set_vring_enable(NetClientState *nc, int enable)
|
||||
VHostNetState *net = get_vhost_net(nc);
|
||||
const VhostOps *vhost_ops = net->dev.vhost_ops;
|
||||
|
||||
+ /*
|
||||
+ * vhost-vdpa network devices need to enable dataplane virtqueues after
|
||||
+ * DRIVER_OK, so they can recover device state before starting dataplane.
|
||||
+ * Because of that, we don't enable virtqueues here and leave it to
|
||||
+ * net/vhost-vdpa.c.
|
||||
+ */
|
||||
+ if (nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
nc->vring_enable = enable;
|
||||
|
||||
if (vhost_ops && vhost_ops->vhost_set_vring_enable) {
|
||||
diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
|
||||
index 637cac4edf..f136815072 100644
|
||||
--- a/hw/virtio/trace-events
|
||||
+++ b/hw/virtio/trace-events
|
||||
@@ -48,7 +48,7 @@ vhost_vdpa_set_features(void *dev, uint64_t features) "dev: %p features: 0x%"PRI
|
||||
vhost_vdpa_get_device_id(void *dev, uint32_t device_id) "dev: %p device_id %"PRIu32
|
||||
vhost_vdpa_reset_device(void *dev) "dev: %p"
|
||||
vhost_vdpa_get_vq_index(void *dev, int idx, int vq_idx) "dev: %p idx: %d vq idx: %d"
|
||||
-vhost_vdpa_set_vring_ready(void *dev, unsigned i, int r) "dev: %p, idx: %u, r: %d"
|
||||
+vhost_vdpa_set_vring_enable_one(void *dev, unsigned i, int enable, int r) "dev: %p, idx: %u, enable: %u, r: %d"
|
||||
vhost_vdpa_dump_config(void *dev, const char *line) "dev: %p %s"
|
||||
vhost_vdpa_set_config(void *dev, uint32_t offset, uint32_t size, uint32_t flags) "dev: %p offset: %"PRIu32" size: %"PRIu32" flags: 0x%"PRIx32
|
||||
vhost_vdpa_get_config(void *dev, void *config, uint32_t config_len) "dev: %p config: %p config_len: %"PRIu32
|
||||
diff --git a/hw/virtio/vdpa-dev.c b/hw/virtio/vdpa-dev.c
|
||||
index 91e71847b0..7b2b19dfb8 100644
|
||||
--- a/hw/virtio/vdpa-dev.c
|
||||
+++ b/hw/virtio/vdpa-dev.c
|
||||
@@ -259,14 +259,11 @@ static int vhost_vdpa_device_start(VirtIODevice *vdev, Error **errp)
|
||||
|
||||
s->dev.acked_features = vdev->guest_features;
|
||||
|
||||
- ret = vhost_dev_start(&s->dev, vdev, false);
|
||||
+ ret = vhost_dev_start(&s->dev, vdev, true);
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret, "Error starting vhost");
|
||||
goto err_guest_notifiers;
|
||||
}
|
||||
- for (i = 0; i < s->dev.nvqs; ++i) {
|
||||
- vhost_vdpa_set_vring_ready(&s->vdpa, i);
|
||||
- }
|
||||
s->started = true;
|
||||
|
||||
/*
|
||||
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
|
||||
index d49826845f..7e172eee49 100644
|
||||
--- a/hw/virtio/vhost-vdpa.c
|
||||
+++ b/hw/virtio/vhost-vdpa.c
|
||||
@@ -883,12 +883,13 @@ static int vhost_vdpa_get_vq_index(struct vhost_dev *dev, int idx)
|
||||
return idx;
|
||||
}
|
||||
|
||||
-int vhost_vdpa_set_vring_ready(struct vhost_vdpa *v, unsigned idx)
|
||||
+static int vhost_vdpa_set_vring_enable_one(struct vhost_vdpa *v, unsigned idx,
|
||||
+ int enable)
|
||||
{
|
||||
struct vhost_dev *dev = v->dev;
|
||||
struct vhost_vring_state state = {
|
||||
.index = idx,
|
||||
- .num = 1,
|
||||
+ .num = enable,
|
||||
};
|
||||
hwaddr addr = virtio_queue_get_desc_addr(dev->vdev, idx);
|
||||
if (addr == 0) {
|
||||
@@ -897,10 +898,31 @@ int vhost_vdpa_set_vring_ready(struct vhost_vdpa *v, unsigned idx)
|
||||
|
||||
int r = vhost_vdpa_call(dev, VHOST_VDPA_SET_VRING_ENABLE, &state);
|
||||
|
||||
- trace_vhost_vdpa_set_vring_ready(dev, idx, r);
|
||||
+ trace_vhost_vdpa_set_vring_enable_one(dev, idx, enable, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
+static int vhost_vdpa_set_vring_enable(struct vhost_dev *dev, int enable)
|
||||
+{
|
||||
+ struct vhost_vdpa *v = dev->opaque;
|
||||
+ unsigned int i;
|
||||
+ int ret;
|
||||
+
|
||||
+ for (i = 0; i < dev->nvqs; ++i) {
|
||||
+ ret = vhost_vdpa_set_vring_enable_one(v, i, enable);
|
||||
+ if (ret < 0) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int vhost_vdpa_set_vring_ready(struct vhost_vdpa *v, unsigned idx)
|
||||
+{
|
||||
+ return vhost_vdpa_set_vring_enable_one(v, idx, 1);
|
||||
+}
|
||||
+
|
||||
static int vhost_vdpa_set_config_call(struct vhost_dev *dev,
|
||||
int fd)
|
||||
{
|
||||
@@ -1584,6 +1606,7 @@ const VhostOps vdpa_ops = {
|
||||
.vhost_set_features = vhost_vdpa_set_features,
|
||||
.vhost_reset_device = vhost_vdpa_reset_device,
|
||||
.vhost_get_vq_index = vhost_vdpa_get_vq_index,
|
||||
+ .vhost_set_vring_enable = vhost_vdpa_set_vring_enable,
|
||||
.vhost_get_config = vhost_vdpa_get_config,
|
||||
.vhost_set_config = vhost_vdpa_set_config,
|
||||
.vhost_requires_shm_log = NULL,
|
||||
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
|
||||
index d073a6d5a5..d29075aa04 100644
|
||||
--- a/hw/virtio/vhost.c
|
||||
+++ b/hw/virtio/vhost.c
|
||||
@@ -2063,7 +2063,13 @@ static int vhost_dev_set_vring_enable(struct vhost_dev *hdev, int enable)
|
||||
return hdev->vhost_ops->vhost_set_vring_enable(hdev, enable);
|
||||
}
|
||||
|
||||
-/* Host notifiers must be enabled at this point. */
|
||||
+/*
|
||||
+ * Host notifiers must be enabled at this point.
|
||||
+ *
|
||||
+ * If @vrings is true, this function will enable all vrings before starting the
|
||||
+ * device. If it is false, the vring initialization is left to be done by the
|
||||
+ * caller.
|
||||
+ */
|
||||
int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings)
|
||||
{
|
||||
int i, r;
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
||||
397
vfio-Only-map-shared-region-for-CSV3-virtual-machine.patch
Normal file
397
vfio-Only-map-shared-region-for-CSV3-virtual-machine.patch
Normal file
@ -0,0 +1,397 @@
|
||||
From 5631d7e167d87c4e2f9283cfac39f2f4107203cc Mon Sep 17 00:00:00 2001
|
||||
From: liuyafei <liuyafei@hygon.cn>
|
||||
Date: Mon, 22 May 2023 20:37:40 +0800
|
||||
Subject: [PATCH] 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 <liuyafei@hygon.cn>
|
||||
Signed-off-by: hanliyang <hanliyang@hygon.cn>
|
||||
---
|
||||
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 422235a221..77e61cfedd 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"
|
||||
@@ -534,6 +535,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)
|
||||
{
|
||||
@@ -681,7 +708,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;
|
||||
@@ -697,7 +729,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);
|
||||
@@ -731,7 +767,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 73d274d8f3..542c9da918 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 1ae03074f3..9db07fd832 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 23d885f0f3..db22c299a6 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 65d87de003..e4706efa27 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 <linux/kvm.h>
|
||||
|
||||
@@ -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 3caf216743..12733341b3 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"
|
||||
|
||||
#define GUEST_POLICY_CSV3_BIT (1 << 6)
|
||||
@@ -74,12 +76,19 @@ int csv_save_outgoing_cpu_state(QEMUFile *f, uint64_t *bytes_sent);
|
||||
int csv_load_incoming_cpu_state(QEMUFile *f);
|
||||
|
||||
/* CSV3 */
|
||||
+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;
|
||||
@@ -90,4 +99,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 2866a6d0ec..925f4f8040 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.41.0.windows.1
|
||||
|
||||
129
vga-Force-full-update-for-CSV3-guest.patch
Normal file
129
vga-Force-full-update-for-CSV3-guest.patch
Normal file
@ -0,0 +1,129 @@
|
||||
From b791d13a0630e6640b3c39dc90671a2150734a24 Mon Sep 17 00:00:00 2001
|
||||
From: Xin Jiang <jiangxin@hygon.cn>
|
||||
Date: Thu, 13 Jul 2023 09:35:10 +0800
|
||||
Subject: [PATCH] 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 <jiangxin@hygon.cn>
|
||||
Signed-off-by: hanliyang <hanliyang@hygon.cn>
|
||||
---
|
||||
accel/kvm/kvm-all.c | 1 +
|
||||
accel/stubs/kvm-stub.c | 2 ++
|
||||
hw/display/vga.c | 7 +++++++
|
||||
include/sysemu/kvm.h | 8 ++++++++
|
||||
target/i386/csv.c | 3 +++
|
||||
5 files changed, 21 insertions(+)
|
||||
|
||||
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
|
||||
index 8077630825..8028caddf9 100644
|
||||
--- a/accel/kvm/kvm-all.c
|
||||
+++ b/accel/kvm/kvm-all.c
|
||||
@@ -103,6 +103,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 ad39a434c4..b071afee45 100644
|
||||
--- a/accel/stubs/kvm-stub.c
|
||||
+++ b/accel/stubs/kvm-stub.c
|
||||
@@ -27,6 +27,8 @@ bool kvm_msi_use_devid;
|
||||
|
||||
bool virtcca_cvm_allowed;
|
||||
|
||||
+bool kvm_csv3_allowed;
|
||||
+
|
||||
void kvm_flush_coalesced_mmio_buffer(void)
|
||||
{
|
||||
}
|
||||
diff --git a/hw/display/vga.c b/hw/display/vga.c
|
||||
index cb6b6ee2ca..3f1358676b 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
|
||||
|
||||
@@ -1790,6 +1792,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 31af5f0e24..fd8634cc8f 100644
|
||||
--- a/include/sysemu/kvm.h
|
||||
+++ b/include/sysemu/kvm.h
|
||||
@@ -44,6 +44,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)
|
||||
#define virtcca_cvm_enabled() (virtcca_cvm_allowed)
|
||||
@@ -147,6 +148,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)
|
||||
@@ -163,6 +170,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 12282ba451..65d87de003 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 <linux/kvm.h>
|
||||
|
||||
@@ -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.41.0.windows.1
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user