Accepting request 574394 from home:bfrogers:branches:Virtualization
- Add AMD SEV (Secure Encrypted Virtualization) support by taking the v7 series of the patches posted to qemu ml. (fate#322124) - Update python3 related patches now that they are upstream OBS-URL: https://build.opensuse.org/request/show/574394 OBS-URL: https://build.opensuse.org/package/show/Virtualization/qemu?expand=0&rev=390
This commit is contained in:
parent
d368a28510
commit
49812da5a8
@ -97,13 +97,13 @@ index b3fdd0827d..d64ad081b7 100644
|
||||
+ error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
|
||||
+ "integer");
|
||||
+ return;
|
||||
}
|
||||
+ }
|
||||
+
|
||||
+ parse_str(siv, name, true, errp);
|
||||
+
|
||||
+ if (!siv->ranges) {
|
||||
+ goto error;
|
||||
+ }
|
||||
}
|
||||
+
|
||||
+ if (!siv->cur_range) {
|
||||
+ Range *r;
|
||||
|
@ -17,18 +17,18 @@ diff --git a/tests/test-string-input-visitor.c b/tests/test-string-input-visitor
|
||||
index 4f9c36bef1..470f58e0ab 100644
|
||||
--- a/tests/test-string-input-visitor.c
|
||||
+++ b/tests/test-string-input-visitor.c
|
||||
@@ -58,6 +58,14 @@ static void test_visitor_in_int(TestInputVisitorData *data,
|
||||
visit_type_int(v, NULL, &res, &err);
|
||||
g_assert(!err);
|
||||
g_assert_cmpint(res, ==, value);
|
||||
@@ -55,6 +55,14 @@ static void test_visitor_in_int(TestInputVisitorData *data,
|
||||
|
||||
v = visitor_input_test_init(data, "-42");
|
||||
|
||||
+ visit_type_int(v, NULL, &res, &err);
|
||||
+ g_assert(!err);
|
||||
+ g_assert_cmpint(res, ==, value);
|
||||
+ visitor_input_teardown(data, unused);
|
||||
+
|
||||
+ value = INT64_MAX;
|
||||
+ v = visitor_input_test_init(data, g_strdup_printf("%" PRId64, value));
|
||||
+
|
||||
+ visit_type_int(v, NULL, &res, &err);
|
||||
+ g_assert(!err);
|
||||
+ g_assert_cmpint(res, ==, value);
|
||||
|
||||
v = visitor_input_test_init(data, "not an int");
|
||||
|
||||
visit_type_int(v, NULL, &res, &err);
|
||||
g_assert(!err);
|
||||
g_assert_cmpint(res, ==, value);
|
||||
|
@ -1,6 +1,6 @@
|
||||
From 613ea1552bdffe9d3d913df26922a4edb4afa56d Mon Sep 17 00:00:00 2001
|
||||
From 3d847a60ddc9b6310b08c4264d1cbdbee4cfb0ef Mon Sep 17 00:00:00 2001
|
||||
From: "Daniel P. Berrange" <berrange@redhat.com>
|
||||
Date: Mon, 15 Jan 2018 17:02:31 +0000
|
||||
Date: Tue, 16 Jan 2018 13:42:05 +0000
|
||||
Subject: [PATCH] qapi: use items()/values() intead of iteritems()/itervalues()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
@ -14,6 +14,13 @@ efficiency is a net win.
|
||||
|
||||
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
|
||||
Message-Id: <20180116134217.8725-3-berrange@redhat.com>
|
||||
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
|
||||
(cherry picked from commit 2f8480447067d6f42af52a886385284ead052af9)
|
||||
[BR: BSC#1077564 - note that this patch also includes commit
|
||||
ef9d9108917d6d5f903bca31602827e512a51c50 squashed in, which is how
|
||||
I originally included patch. This avoids renaming of the patch queue]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
scripts/qapi.py | 24 ++++++++++++------------
|
||||
scripts/qapi2texi.py | 11 ++++++-----
|
||||
|
@ -1,6 +1,6 @@
|
||||
From 020f50663afabc52c305a3956def8c94af7b5531 Mon Sep 17 00:00:00 2001
|
||||
From f38441aecb1a927d05b3fc47c34852169eb9c8c6 Mon Sep 17 00:00:00 2001
|
||||
From: "Daniel P. Berrange" <berrange@redhat.com>
|
||||
Date: Mon, 15 Jan 2018 17:39:47 -0700
|
||||
Date: Tue, 16 Jan 2018 13:42:06 +0000
|
||||
Subject: [PATCH] qapi: Use OrderedDict from standard library if available
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
@ -12,6 +12,11 @@ local backport if available.
|
||||
|
||||
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
|
||||
Message-Id: <20180116134217.8725-4-berrange@redhat.com>
|
||||
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
|
||||
(cherry picked from commit 38710a8994911d98acbe183a39ec3a53638de510)
|
||||
[BR: BSC#1077564]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
scripts/qapi.py | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
@ -1,6 +1,6 @@
|
||||
From 63783441945c3c156bb6acfaac0ace8055c74c52 Mon Sep 17 00:00:00 2001
|
||||
From 16d6ac6a4239900f57ce871bd447c7371c3e07ca Mon Sep 17 00:00:00 2001
|
||||
From: "Daniel P. Berrange" <berrange@redhat.com>
|
||||
Date: Mon, 15 Jan 2018 17:40:05 -0700
|
||||
Date: Tue, 16 Jan 2018 13:42:07 +0000
|
||||
Subject: [PATCH] qapi: adapt to moved location of StringIO module in py3
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
@ -8,6 +8,11 @@ Content-Transfer-Encoding: 8bit
|
||||
|
||||
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
|
||||
Message-Id: <20180116134217.8725-5-berrange@redhat.com>
|
||||
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
|
||||
(cherry picked from commit 5f90af8e6b34f9e6b60eb05a15707a95a0febbde)
|
||||
[BR: BSC#1077564]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
scripts/qapi.py | 7 +++++--
|
||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||
|
@ -1,9 +1,15 @@
|
||||
From 9bf5e7d570de8a98434e3c51d8e60fe6fab02f5c Mon Sep 17 00:00:00 2001
|
||||
From d4df07ca6bc5fb2ff8faa2d74c854be921b1f5bf Mon Sep 17 00:00:00 2001
|
||||
From: "Daniel P. Berrange" <berrange@redhat.com>
|
||||
Date: Mon, 15 Jan 2018 17:40:16 -0700
|
||||
Date: Tue, 16 Jan 2018 13:42:08 +0000
|
||||
Subject: [PATCH] qapi: Adapt to moved location of 'maketrans' function in py3
|
||||
|
||||
Reviewed-by: Eric Blake <eblake@redhat.com>
|
||||
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
|
||||
Message-Id: <20180116134217.8725-6-berrange@redhat.com>
|
||||
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
|
||||
(cherry picked from commit 52c4272c6c916a53cde65b997e1a4e891c14dcef)
|
||||
[BR: BSC#1077564]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
scripts/qapi.py | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
@ -1,6 +1,6 @@
|
||||
From 0f22752bba33bdffc996ce119d6ec20faad20637 Mon Sep 17 00:00:00 2001
|
||||
From 0b18b7d8af17cb10779ca45efd40d791595d7cf5 Mon Sep 17 00:00:00 2001
|
||||
From: "Daniel P. Berrange" <berrange@redhat.com>
|
||||
Date: Mon, 15 Jan 2018 17:40:25 -0700
|
||||
Date: Tue, 16 Jan 2018 13:42:09 +0000
|
||||
Subject: [PATCH] qapi: remove '-q' arg to diff when comparing QAPI output
|
||||
|
||||
When the qapi schema tests fail they merely print that the expected
|
||||
@ -9,7 +9,13 @@ trying diagnose what went wrong. Removing the '-q' arg to diff
|
||||
means that it is still silent on successful tests, but when it
|
||||
fails we'll see details of the incorrect output.
|
||||
|
||||
Reviewed-by: Eric Blake <eblake@redhat.com>
|
||||
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
|
||||
Message-Id: <20180116134217.8725-7-berrange@redhat.com>
|
||||
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
|
||||
(cherry picked from commit 46ec4fcea95204a8e5bab9295cbfaa3606d78dc9)
|
||||
[BR: BSC#1077564]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
tests/Makefile.include | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
@ -1,6 +1,6 @@
|
||||
From 24a63e2bd19a5294ed9a8793663e8f62e5e0029a Mon Sep 17 00:00:00 2001
|
||||
From a16a7259aace92ff5cf815b31e1201310fc344a0 Mon Sep 17 00:00:00 2001
|
||||
From: "Daniel P. Berrange" <berrange@redhat.com>
|
||||
Date: Mon, 15 Jan 2018 17:40:33 -0700
|
||||
Date: Tue, 16 Jan 2018 13:42:10 +0000
|
||||
Subject: [PATCH] qapi: ensure stable sort ordering when checking QAPI entities
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
@ -13,6 +13,11 @@ to get a stable ordering.
|
||||
|
||||
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
|
||||
Message-Id: <20180116134217.8725-8-berrange@redhat.com>
|
||||
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
|
||||
(cherry picked from commit f7a5376d4b667cf6c83c1d640e32d22456d7b5ee)
|
||||
[BR: BSC#1077564]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
scripts/qapi.py | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
@ -1,6 +1,6 @@
|
||||
From f9d26c21e4bdf6c82e1b9346fa9c416c71b827e5 Mon Sep 17 00:00:00 2001
|
||||
From 125a29fae71588b8857f1a513bf03ec6ef52f713 Mon Sep 17 00:00:00 2001
|
||||
From: "Daniel P. Berrange" <berrange@redhat.com>
|
||||
Date: Mon, 15 Jan 2018 17:40:41 -0700
|
||||
Date: Tue, 16 Jan 2018 13:42:11 +0000
|
||||
Subject: [PATCH] qapi: force a UTF-8 locale for running Python
|
||||
|
||||
Python2 did not validate locale correctness when reading input data, so
|
||||
@ -24,32 +24,40 @@ Traceback (most recent call last):
|
||||
File "/usr/lib64/python3.5/encodings/ascii.py", line 26, in decode
|
||||
return codecs.ascii_decode(input, self.errors)[0]
|
||||
|
||||
More background on this can be seen in
|
||||
|
||||
https://www.python.org/dev/peps/pep-0538/
|
||||
|
||||
Many distros support a new C.UTF-8 locale that is like the C locale,
|
||||
but with UTF-8 instead of 7-bit ASCII. That is not entirely portable
|
||||
though, so this patch instead forces the en_US.UTF-8 locale, which
|
||||
is pretty similar but more widely available.
|
||||
|
||||
We set LANG, rather than only LC_CTYPE, since generated source ought
|
||||
to be independant of all of the user's locale settings.
|
||||
though. This patch thus sets the LANG to "C", but overrides LC_CTYPE
|
||||
to be en_US.UTF-8 locale. This gets us pretty close to C.UTF-8, but
|
||||
in a way that should be portable to everywhere QEMU builds.
|
||||
|
||||
This patch only forces UTF-8 for QAPI scripts, since that is the one
|
||||
showing the immediate error under Python3 with C locale, but potentially
|
||||
we ought to force this for all python scripts used in the build process.
|
||||
|
||||
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
|
||||
Message-Id: <20180116134217.8725-9-berrange@redhat.com>
|
||||
Reviewed-by: Eric Blake <eblake@redhat.com>
|
||||
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
|
||||
(cherry picked from commit d4e5ec877ca698a87dabe68814c6f93668f50c60)
|
||||
[BR: BSC#1077564]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
Makefile | 22 ++++++++++++----------
|
||||
1 file changed, 12 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 4be3366e27..8b6dee004e 100644
|
||||
index 4be3366e27..eec3a8d430 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -14,6 +14,8 @@ ifneq ($(wildcard config-host.mak),)
|
||||
all:
|
||||
include config-host.mak
|
||||
|
||||
+PYTHON_UTF8 = LANG=en_US.UTF-8 $(PYTHON)
|
||||
+PYTHON_UTF8 = LC_ALL= LANG=C LC_CTYPE=en_US.UTF-8 $(PYTHON)
|
||||
+
|
||||
git-submodule-update:
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
From e7be302421da46c1282c6ff592c87a5268e7f05a Mon Sep 17 00:00:00 2001
|
||||
From 680774bf1e3bfd349b503e375f01244a04ca975b Mon Sep 17 00:00:00 2001
|
||||
From: "Daniel P. Berrange" <berrange@redhat.com>
|
||||
Date: Mon, 15 Jan 2018 17:40:47 -0700
|
||||
Date: Tue, 16 Jan 2018 13:42:12 +0000
|
||||
Subject: [PATCH] scripts: ensure signrom treats data as bytes
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
@ -8,6 +8,11 @@ Content-Transfer-Encoding: 8bit
|
||||
|
||||
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
|
||||
Message-Id: <20180116134217.8725-10-berrange@redhat.com>
|
||||
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
|
||||
(cherry picked from commit 31d8f92e646f7d4cfbb4ffab440ab41a3c838fd3)
|
||||
[BR: BSC#1077564]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
scripts/signrom.py | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
@ -1,9 +1,15 @@
|
||||
From b4a1eeb9e139d9e20a19b4c2aea3d69bef7a8fec Mon Sep 17 00:00:00 2001
|
||||
From bb4e9dd3678fe461b85345736cb296641be01413 Mon Sep 17 00:00:00 2001
|
||||
From: "Daniel P. Berrange" <berrange@redhat.com>
|
||||
Date: Mon, 15 Jan 2018 17:40:53 -0700
|
||||
Date: Tue, 16 Jan 2018 13:42:13 +0000
|
||||
Subject: [PATCH] configure: allow use of python 3
|
||||
|
||||
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
|
||||
Message-Id: <20180116134217.8725-11-berrange@redhat.com>
|
||||
Reviewed-by: Eric Blake <eblake@redhat.com>
|
||||
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
|
||||
(cherry picked from commit c21965a0c8b979c306e927f158257e5b0fa3a1f9)
|
||||
[BR: BSC#1077564]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
configure | 5 ++---
|
||||
1 file changed, 2 insertions(+), 3 deletions(-)
|
||||
|
@ -1,11 +1,20 @@
|
||||
From 3279607f70ff31e79924ff86c82fdca1da49c28e Mon Sep 17 00:00:00 2001
|
||||
From 88c1526efb8132cc1ea6d4dcb8ef84daa08a1d9d Mon Sep 17 00:00:00 2001
|
||||
From: Miika S <miika9764@gmail.com>
|
||||
Date: Tue, 16 Jan 2018 13:46:04 -0700
|
||||
Date: Tue, 16 Jan 2018 13:42:14 +0000
|
||||
Subject: [PATCH] input: add missing JIS keys to virtio input
|
||||
|
||||
keycodemapdb updated to add the QKeyCodes muhenkan and katakanahiragana
|
||||
|
||||
Signed-off-by: Miika S <miika9764@gmail.com>
|
||||
Message-Id: <20180116134217.8725-12-berrange@redhat.com>
|
||||
Reviewed-by: Eric Blake <eblake@redhat.com>
|
||||
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
|
||||
(cherry picked from commit 280b8da3b842177de538de4f73d3d63db077e39b)
|
||||
[BR: BSC#1077564 - added changes to hw/input/virtio-input-hid.c which
|
||||
were in an earlier proposed version of patch, but removed since that
|
||||
file had become autogenerated. In 2.11, it is not autogenerated so those
|
||||
previously proposed changes make sense for us.]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
hw/input/virtio-input-hid.c | 7 +++++++
|
||||
qapi/ui.json | 5 ++++-
|
||||
|
@ -1,8 +1,12 @@
|
||||
From b55eb09255a4ad8e0053d9cb7c393162d7fc3bae Mon Sep 17 00:00:00 2001
|
||||
From 8bcfb45ee625f82a7324491c2640c5dfb60465a9 Mon Sep 17 00:00:00 2001
|
||||
From: Bruce Rogers <brogers@suse.com>
|
||||
Date: Thu, 25 Jan 2018 14:16:10 -0700
|
||||
Subject: [PATCH] Make installed scripts explicitly python2
|
||||
|
||||
This is one step towards having our python support be explicitly
|
||||
either python2 or python3.
|
||||
|
||||
[BR: BSC#1077564]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
scripts/analyze-migration.py | 2 +-
|
||||
|
@ -1,4 +1,4 @@
|
||||
From aaac044c06d93bd90ffa35eb091ec10c67f3ef7e Mon Sep 17 00:00:00 2001
|
||||
From c97089489583ab5e1b748a5731915bc3727931b4 Mon Sep 17 00:00:00 2001
|
||||
From: Haozhong Zhang <haozhong.zhang@intel.com>
|
||||
Date: Fri, 22 Dec 2017 09:51:20 +0800
|
||||
Subject: [PATCH] pc: fail memory hot-plug/unplug with -no-acpi and Q35 machine
|
||||
|
39
0046-memattrs-add-debug-attribute.patch
Normal file
39
0046-memattrs-add-debug-attribute.patch
Normal file
@ -0,0 +1,39 @@
|
||||
From 8e76b032dc33ce4330da6ec73c10113cdc172b25 Mon Sep 17 00:00:00 2001
|
||||
From: Brijesh Singh <brijesh.singh@amd.com>
|
||||
Date: Tue, 6 Feb 2018 19:08:07 -0600
|
||||
Subject: [PATCH] memattrs: add debug attribute
|
||||
|
||||
Extend the MemTxAttrs to include 'debug' flag. The flag can be used as
|
||||
general indicator that operation was triggered by the debugger.
|
||||
|
||||
Later in the patch series we set the debug=1 when issuing a memory access
|
||||
from the gdbstub or HMP commands. This patch is prerequisite to support
|
||||
debugging the encrypted guest. If we see request with debug=1 then we
|
||||
will need to use encryption APIs to access the guest memory.
|
||||
|
||||
Cc: Alistair Francis <alistair.francis@xilinx.com>
|
||||
Cc: Peter Maydell <peter.maydell@linaro.org>
|
||||
Cc: Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
|
||||
Cc: Richard Henderson <richard.henderson@linaro.org>
|
||||
Cc: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Reviewed-by: Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
|
||||
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
|
||||
[BR: FATE#322124]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
include/exec/memattrs.h | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/include/exec/memattrs.h b/include/exec/memattrs.h
|
||||
index d4a1642098..08099e4f7e 100644
|
||||
--- a/include/exec/memattrs.h
|
||||
+++ b/include/exec/memattrs.h
|
||||
@@ -37,6 +37,8 @@ typedef struct MemTxAttrs {
|
||||
unsigned int user:1;
|
||||
/* Requester ID (for MSI for example) */
|
||||
unsigned int requester_id:16;
|
||||
+ /* Memory access request from the debugger */
|
||||
+ unsigned int debug:1;
|
||||
} MemTxAttrs;
|
||||
|
||||
/* Bus masters which don't specify any attributes will get this,
|
230
0047-exec-add-ram_debug_ops-support.patch
Normal file
230
0047-exec-add-ram_debug_ops-support.patch
Normal file
@ -0,0 +1,230 @@
|
||||
From faf4862946a9e236e8e4fb956adad2dc11577fe0 Mon Sep 17 00:00:00 2001
|
||||
From: Brijesh Singh <brijesh.singh@amd.com>
|
||||
Date: Tue, 6 Feb 2018 19:08:07 -0600
|
||||
Subject: [PATCH] exec: add ram_debug_ops support
|
||||
|
||||
Currently, the guest memory access for the debug purpose is performed
|
||||
using the memcpy(). Lets extend the 'struct MemoryRegion' to include
|
||||
ram_debug_ops callbacks. The ram_debug_ops can be used to override
|
||||
memcpy() with something else.
|
||||
|
||||
The feature can be used by encrypted guest -- which can register
|
||||
callbacks to override memcpy() with memory encryption/decryption APIs.
|
||||
|
||||
a typical usage:
|
||||
|
||||
mem_read(uint8_t *dst, uint8_t *src, uint32_t len, MemTxAttrs *attrs);
|
||||
mem_write(uint8_t *dst, uint8_t *src, uint32_t len, MemTxAttrs *attrs);
|
||||
|
||||
MemoryRegionRAMReadWriteOps ops;
|
||||
ops.read = mem_read;
|
||||
ops.write = mem_write;
|
||||
|
||||
memory_region_init_ram(mem, NULL, "memory", size, NULL);
|
||||
memory_region_set_ram_debug_ops(mem, ops);
|
||||
|
||||
Cc: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Cc: Peter Crosthwaite <crosthwaite.peter@gmail.com>
|
||||
Cc: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
|
||||
[BR: FATE#322124]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
exec.c | 66 ++++++++++++++++++++++++++++++++++++++-------------
|
||||
include/exec/memory.h | 28 ++++++++++++++++++++++
|
||||
2 files changed, 78 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/exec.c b/exec.c
|
||||
index 1ca0f9e0ab..5da6a782e1 100644
|
||||
--- a/exec.c
|
||||
+++ b/exec.c
|
||||
@@ -2983,7 +2983,11 @@ static MemTxResult flatview_write_continue(FlatView *fv, hwaddr addr,
|
||||
} else {
|
||||
/* RAM case */
|
||||
ptr = qemu_ram_ptr_length(mr->ram_block, addr1, &l, false);
|
||||
- memcpy(ptr, buf, l);
|
||||
+ if (attrs.debug && mr->ram_debug_ops) {
|
||||
+ mr->ram_debug_ops->write(ptr, buf, l, attrs);
|
||||
+ } else {
|
||||
+ memcpy(ptr, buf, l);
|
||||
+ }
|
||||
invalidate_and_set_dirty(mr, addr1, l);
|
||||
}
|
||||
|
||||
@@ -3081,7 +3085,11 @@ MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr,
|
||||
} else {
|
||||
/* RAM case */
|
||||
ptr = qemu_ram_ptr_length(mr->ram_block, addr1, &l, false);
|
||||
- memcpy(buf, ptr, l);
|
||||
+ if (attrs.debug && mr->ram_debug_ops) {
|
||||
+ mr->ram_debug_ops->read(buf, ptr, l, attrs);
|
||||
+ } else {
|
||||
+ memcpy(buf, ptr, l);
|
||||
+ }
|
||||
}
|
||||
|
||||
if (release_lock) {
|
||||
@@ -3151,11 +3159,13 @@ void cpu_physical_memory_rw(hwaddr addr, uint8_t *buf,
|
||||
|
||||
enum write_rom_type {
|
||||
WRITE_DATA,
|
||||
+ READ_DATA,
|
||||
FLUSH_CACHE,
|
||||
};
|
||||
|
||||
-static inline void cpu_physical_memory_write_rom_internal(AddressSpace *as,
|
||||
- hwaddr addr, const uint8_t *buf, int len, enum write_rom_type type)
|
||||
+static inline void cpu_physical_memory_rw_internal(AddressSpace *as,
|
||||
+ hwaddr addr, uint8_t *buf, int len, MemTxAttrs attrs,
|
||||
+ enum write_rom_type type)
|
||||
{
|
||||
hwaddr l;
|
||||
uint8_t *ptr;
|
||||
@@ -3170,12 +3180,33 @@ static inline void cpu_physical_memory_write_rom_internal(AddressSpace *as,
|
||||
if (!(memory_region_is_ram(mr) ||
|
||||
memory_region_is_romd(mr))) {
|
||||
l = memory_access_size(mr, l, addr1);
|
||||
+ /* Pass MMIO down to address address_space_rw */
|
||||
+ switch (type) {
|
||||
+ case READ_DATA:
|
||||
+ case WRITE_DATA:
|
||||
+ address_space_rw(as, addr1, attrs, buf, l,
|
||||
+ type == WRITE_DATA);
|
||||
+ break;
|
||||
+ case FLUSH_CACHE:
|
||||
+ break;
|
||||
+ }
|
||||
} else {
|
||||
/* ROM/RAM case */
|
||||
ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
|
||||
switch (type) {
|
||||
+ case READ_DATA:
|
||||
+ if (mr->ram_debug_ops) {
|
||||
+ mr->ram_debug_ops->read(buf, ptr, l, attrs);
|
||||
+ } else {
|
||||
+ memcpy(buf, ptr, l);
|
||||
+ }
|
||||
+ break;
|
||||
case WRITE_DATA:
|
||||
- memcpy(ptr, buf, l);
|
||||
+ if (mr->ram_debug_ops) {
|
||||
+ mr->ram_debug_ops->write(ptr, buf, l, attrs);
|
||||
+ } else {
|
||||
+ memcpy(ptr, buf, l);
|
||||
+ }
|
||||
invalidate_and_set_dirty(mr, addr1, l);
|
||||
break;
|
||||
case FLUSH_CACHE:
|
||||
@@ -3194,7 +3225,8 @@ static inline void cpu_physical_memory_write_rom_internal(AddressSpace *as,
|
||||
void cpu_physical_memory_write_rom(AddressSpace *as, hwaddr addr,
|
||||
const uint8_t *buf, int len)
|
||||
{
|
||||
- cpu_physical_memory_write_rom_internal(as, addr, buf, len, WRITE_DATA);
|
||||
+ cpu_physical_memory_rw_internal(as, addr, (uint8_t *)buf, len,
|
||||
+ MEMTXATTRS_UNSPECIFIED, WRITE_DATA);
|
||||
}
|
||||
|
||||
void cpu_flush_icache_range(hwaddr start, int len)
|
||||
@@ -3209,8 +3241,10 @@ void cpu_flush_icache_range(hwaddr start, int len)
|
||||
return;
|
||||
}
|
||||
|
||||
- cpu_physical_memory_write_rom_internal(&address_space_memory,
|
||||
- start, NULL, len, FLUSH_CACHE);
|
||||
+ cpu_physical_memory_rw_internal(&address_space_memory,
|
||||
+ start, NULL, len,
|
||||
+ MEMTXATTRS_UNSPECIFIED,
|
||||
+ FLUSH_CACHE);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
@@ -3516,6 +3550,7 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
|
||||
int l;
|
||||
hwaddr phys_addr;
|
||||
target_ulong page;
|
||||
+ int type = is_write ? WRITE_DATA : READ_DATA;
|
||||
|
||||
cpu_synchronize_state(cpu);
|
||||
while (len > 0) {
|
||||
@@ -3525,6 +3560,10 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
|
||||
page = addr & TARGET_PAGE_MASK;
|
||||
phys_addr = cpu_get_phys_page_attrs_debug(cpu, page, &attrs);
|
||||
asidx = cpu_asidx_from_attrs(cpu, attrs);
|
||||
+
|
||||
+ /* set debug attrs to indicate memory access is from the debugger */
|
||||
+ attrs.debug = 1;
|
||||
+
|
||||
/* if no physical page mapped, return an error */
|
||||
if (phys_addr == -1)
|
||||
return -1;
|
||||
@@ -3532,14 +3571,9 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
|
||||
if (l > len)
|
||||
l = len;
|
||||
phys_addr += (addr & ~TARGET_PAGE_MASK);
|
||||
- if (is_write) {
|
||||
- cpu_physical_memory_write_rom(cpu->cpu_ases[asidx].as,
|
||||
- phys_addr, buf, l);
|
||||
- } else {
|
||||
- address_space_rw(cpu->cpu_ases[asidx].as, phys_addr,
|
||||
- MEMTXATTRS_UNSPECIFIED,
|
||||
- buf, l, 0);
|
||||
- }
|
||||
+ cpu_physical_memory_rw_internal(cpu->cpu_ases[asidx].as,
|
||||
+ phys_addr, buf, l, attrs,
|
||||
+ type);
|
||||
len -= l;
|
||||
buf += l;
|
||||
addr += l;
|
||||
diff --git a/include/exec/memory.h b/include/exec/memory.h
|
||||
index 5ed4042f87..557f75c7ae 100644
|
||||
--- a/include/exec/memory.h
|
||||
+++ b/include/exec/memory.h
|
||||
@@ -215,6 +215,18 @@ typedef struct IOMMUMemoryRegionClass {
|
||||
typedef struct CoalescedMemoryRange CoalescedMemoryRange;
|
||||
typedef struct MemoryRegionIoeventfd MemoryRegionIoeventfd;
|
||||
|
||||
+/* Memory Region RAM debug callback */
|
||||
+typedef struct MemoryRegionRAMReadWriteOps MemoryRegionRAMReadWriteOps;
|
||||
+
|
||||
+struct MemoryRegionRAMReadWriteOps {
|
||||
+ /* Write data into guest memory */
|
||||
+ int (*write) (uint8_t *dest, const uint8_t *src,
|
||||
+ uint32_t len, MemTxAttrs attrs);
|
||||
+ /* Read data from guest memory */
|
||||
+ int (*read) (uint8_t *dest, const uint8_t *src,
|
||||
+ uint32_t len, MemTxAttrs attrs);
|
||||
+};
|
||||
+
|
||||
struct MemoryRegion {
|
||||
Object parent_obj;
|
||||
|
||||
@@ -254,6 +266,7 @@ struct MemoryRegion {
|
||||
const char *name;
|
||||
unsigned ioeventfd_nb;
|
||||
MemoryRegionIoeventfd *ioeventfds;
|
||||
+ const MemoryRegionRAMReadWriteOps *ram_debug_ops;
|
||||
};
|
||||
|
||||
struct IOMMUMemoryRegion {
|
||||
@@ -620,6 +633,21 @@ void memory_region_init_rom_device_nomigrate(MemoryRegion *mr,
|
||||
uint64_t size,
|
||||
Error **errp);
|
||||
|
||||
+/**
|
||||
+ * memory_region_set_ram_debug_ops: Set debug access ops for a given memory
|
||||
+ * region.
|
||||
+ *
|
||||
+ * @mr: the #MemoryRegion to be initialized
|
||||
+ * @ops: a function that will be used for when accessing @target region during
|
||||
+ * debug
|
||||
+ */
|
||||
+static inline void
|
||||
+memory_region_set_ram_debug_ops(MemoryRegion *mr,
|
||||
+ const MemoryRegionRAMReadWriteOps *ops)
|
||||
+{
|
||||
+ mr->ram_debug_ops = ops;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* memory_region_init_reservation: Initialize a memory region that reserves
|
||||
* I/O space.
|
107
0048-exec-add-debug-version-of-physical-.patch
Normal file
107
0048-exec-add-debug-version-of-physical-.patch
Normal file
@ -0,0 +1,107 @@
|
||||
From 8c55cf176a4b6d6411e8b1e6385ff6a78b0e55f2 Mon Sep 17 00:00:00 2001
|
||||
From: Brijesh Singh <brijesh.singh@amd.com>
|
||||
Date: Tue, 6 Feb 2018 19:08:07 -0600
|
||||
Subject: [PATCH] exec: add debug version of physical memory read and write API
|
||||
|
||||
Adds the following new APIs
|
||||
- cpu_physical_memory_read_debug
|
||||
- cpu_physical_memory_write_debug
|
||||
- cpu_physical_memory_rw_debug
|
||||
- ldl_phys_debug
|
||||
- ldq_phys_debug
|
||||
|
||||
Cc: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Cc: Peter Crosthwaite <crosthwaite.peter@gmail.com>
|
||||
Cc: Richard Henderson <rth@twiddle.net>
|
||||
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
|
||||
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
[BR: FATE#322124]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
exec.c | 41 +++++++++++++++++++++++++++++++++++++++++
|
||||
include/exec/cpu-common.h | 15 +++++++++++++++
|
||||
2 files changed, 56 insertions(+)
|
||||
|
||||
diff --git a/exec.c b/exec.c
|
||||
index 5da6a782e1..561e4290dc 100644
|
||||
--- a/exec.c
|
||||
+++ b/exec.c
|
||||
@@ -3543,6 +3543,47 @@ void address_space_cache_destroy(MemoryRegionCache *cache)
|
||||
#define RCU_READ_UNLOCK() rcu_read_unlock()
|
||||
#include "memory_ldst.inc.c"
|
||||
|
||||
+uint32_t ldl_phys_debug(CPUState *cpu, hwaddr addr)
|
||||
+{
|
||||
+ MemTxAttrs attrs;
|
||||
+ int asidx = cpu_asidx_from_attrs(cpu, attrs);
|
||||
+ uint32_t val;
|
||||
+
|
||||
+ /* set debug attrs to indicate memory access is from the debugger */
|
||||
+ attrs.debug = 1;
|
||||
+
|
||||
+ cpu_physical_memory_rw_internal(cpu->cpu_ases[asidx].as,
|
||||
+ addr, (void *) &val,
|
||||
+ 4, attrs, READ_DATA);
|
||||
+ return tswap32(val);
|
||||
+}
|
||||
+
|
||||
+uint64_t ldq_phys_debug(CPUState *cpu, hwaddr addr)
|
||||
+{
|
||||
+ MemTxAttrs attrs;
|
||||
+ int asidx = cpu_asidx_from_attrs(cpu, attrs);
|
||||
+ uint64_t val;
|
||||
+
|
||||
+ /* set debug attrs to indicate memory access is from the debugger */
|
||||
+ attrs.debug = 1;
|
||||
+
|
||||
+ cpu_physical_memory_rw_internal(cpu->cpu_ases[asidx].as,
|
||||
+ addr, (void *) &val,
|
||||
+ 8, attrs, READ_DATA);
|
||||
+ return val;
|
||||
+}
|
||||
+
|
||||
+void cpu_physical_memory_rw_debug(hwaddr addr, uint8_t *buf,
|
||||
+ int len, int is_write)
|
||||
+{
|
||||
+ MemTxAttrs attrs;
|
||||
+
|
||||
+ /* set debug attrs to indicate memory access is from the debugger */
|
||||
+ attrs.debug = 1;
|
||||
+
|
||||
+ address_space_rw(&address_space_memory, addr, attrs, buf, len, is_write);
|
||||
+}
|
||||
+
|
||||
/* virtual memory access for debug (includes writing to ROM) */
|
||||
int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
|
||||
uint8_t *buf, int len, int is_write)
|
||||
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
|
||||
index 74341b19d2..fa01385d4f 100644
|
||||
--- a/include/exec/cpu-common.h
|
||||
+++ b/include/exec/cpu-common.h
|
||||
@@ -77,11 +77,26 @@ size_t qemu_ram_pagesize_largest(void);
|
||||
|
||||
void cpu_physical_memory_rw(hwaddr addr, uint8_t *buf,
|
||||
int len, int is_write);
|
||||
+void cpu_physical_memory_rw_debug(hwaddr addr, uint8_t *buf,
|
||||
+ int len, int is_write);
|
||||
static inline void cpu_physical_memory_read(hwaddr addr,
|
||||
void *buf, int len)
|
||||
{
|
||||
cpu_physical_memory_rw(addr, buf, len, 0);
|
||||
}
|
||||
+static inline void cpu_physical_memory_read_debug(hwaddr addr,
|
||||
+ void *buf, int len)
|
||||
+{
|
||||
+ cpu_physical_memory_rw_debug(addr, buf, len, 0);
|
||||
+}
|
||||
+static inline void cpu_physical_memory_write_debug(hwaddr addr,
|
||||
+ const void *buf, int len)
|
||||
+{
|
||||
+ cpu_physical_memory_rw_debug(addr, (void *)buf, len, 1);
|
||||
+}
|
||||
+uint32_t ldl_phys_debug(CPUState *cpu, hwaddr addr);
|
||||
+uint64_t ldq_phys_debug(CPUState *cpu, hwaddr addr);
|
||||
+
|
||||
static inline void cpu_physical_memory_write(hwaddr addr,
|
||||
const void *buf, int len)
|
||||
{
|
368
0049-monitor-i386-use-debug-APIs-when-ac.patch
Normal file
368
0049-monitor-i386-use-debug-APIs-when-ac.patch
Normal file
@ -0,0 +1,368 @@
|
||||
From 5a0c3e3ff1a772c572b810851e04e0deb2930367 Mon Sep 17 00:00:00 2001
|
||||
From: Brijesh Singh <brijesh.singh@amd.com>
|
||||
Date: Tue, 6 Feb 2018 19:08:07 -0600
|
||||
Subject: [PATCH] monitor/i386: use debug APIs when accessing guest memory
|
||||
|
||||
Updates HMP commands to use the debug version of APIs when accessing the
|
||||
guest memory.
|
||||
|
||||
Cc: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Cc: Peter Crosthwaite <crosthwaite.peter@gmail.com>
|
||||
Cc: Richard Henderson <rth@twiddle.net>
|
||||
Cc: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
|
||||
Cc: Markus Armbruster <armbru@redhat.com>
|
||||
Cc: Eduardo Habkost <ehabkost@redhat.com>
|
||||
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
|
||||
[BR: FATE#322124]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
cpus.c | 2 +-
|
||||
disas.c | 2 +-
|
||||
monitor.c | 8 ++++---
|
||||
target/i386/helper.c | 14 ++++++------
|
||||
target/i386/monitor.c | 60 +++++++++++++++++++++++++++------------------------
|
||||
5 files changed, 46 insertions(+), 40 deletions(-)
|
||||
|
||||
diff --git a/cpus.c b/cpus.c
|
||||
index 114c29b6a0..d1e7e28993 100644
|
||||
--- a/cpus.c
|
||||
+++ b/cpus.c
|
||||
@@ -2026,7 +2026,7 @@ void qmp_pmemsave(int64_t addr, int64_t size, const char *filename,
|
||||
l = sizeof(buf);
|
||||
if (l > size)
|
||||
l = size;
|
||||
- cpu_physical_memory_read(addr, buf, l);
|
||||
+ cpu_physical_memory_read_debug(addr, buf, l);
|
||||
if (fwrite(buf, 1, l, f) != l) {
|
||||
error_setg(errp, QERR_IO_ERROR);
|
||||
goto exit;
|
||||
diff --git a/disas.c b/disas.c
|
||||
index d4ad1089ef..fcedbf2633 100644
|
||||
--- a/disas.c
|
||||
+++ b/disas.c
|
||||
@@ -586,7 +586,7 @@ static int
|
||||
physical_read_memory(bfd_vma memaddr, bfd_byte *myaddr, int length,
|
||||
struct disassemble_info *info)
|
||||
{
|
||||
- cpu_physical_memory_read(memaddr, myaddr, length);
|
||||
+ cpu_physical_memory_read_debug(memaddr, myaddr, length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/monitor.c b/monitor.c
|
||||
index e36fb5308d..3b456fc6c5 100644
|
||||
--- a/monitor.c
|
||||
+++ b/monitor.c
|
||||
@@ -1359,7 +1359,7 @@ static void memory_dump(Monitor *mon, int count, int format, int wsize,
|
||||
if (l > line_size)
|
||||
l = line_size;
|
||||
if (is_physical) {
|
||||
- cpu_physical_memory_read(addr, buf, l);
|
||||
+ cpu_physical_memory_read_debug(addr, buf, l);
|
||||
} else {
|
||||
if (cpu_memory_rw_debug(cs, addr, buf, l, 0) < 0) {
|
||||
monitor_printf(mon, " Cannot access memory\n");
|
||||
@@ -1565,8 +1565,10 @@ static void hmp_sum(Monitor *mon, const QDict *qdict)
|
||||
|
||||
sum = 0;
|
||||
for(addr = start; addr < (start + size); addr++) {
|
||||
- uint8_t val = address_space_ldub(&address_space_memory, addr,
|
||||
- MEMTXATTRS_UNSPECIFIED, NULL);
|
||||
+ uint8_t buf[0];
|
||||
+ uint8_t val;
|
||||
+ cpu_physical_memory_read_debug(addr, buf, 1);
|
||||
+ val = ldub_p(buf);
|
||||
/* BSD sum algorithm ('sum' Unix command) */
|
||||
sum = (sum >> 1) | (sum << 15);
|
||||
sum += val;
|
||||
diff --git a/target/i386/helper.c b/target/i386/helper.c
|
||||
index f63eb3d3f4..5dc9e8839b 100644
|
||||
--- a/target/i386/helper.c
|
||||
+++ b/target/i386/helper.c
|
||||
@@ -757,7 +757,7 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||
if (la57) {
|
||||
pml5e_addr = ((env->cr[3] & ~0xfff) +
|
||||
(((addr >> 48) & 0x1ff) << 3)) & a20_mask;
|
||||
- pml5e = x86_ldq_phys(cs, pml5e_addr);
|
||||
+ pml5e = ldq_phys_debug(cs, pml5e_addr);
|
||||
if (!(pml5e & PG_PRESENT_MASK)) {
|
||||
return -1;
|
||||
}
|
||||
@@ -767,7 +767,7 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||
|
||||
pml4e_addr = ((pml5e & PG_ADDRESS_MASK) +
|
||||
(((addr >> 39) & 0x1ff) << 3)) & a20_mask;
|
||||
- pml4e = x86_ldq_phys(cs, pml4e_addr);
|
||||
+ pml4e = ldq_phys_debug(cs, pml4e_addr);
|
||||
if (!(pml4e & PG_PRESENT_MASK)) {
|
||||
return -1;
|
||||
}
|
||||
@@ -788,14 +788,14 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||
{
|
||||
pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
|
||||
a20_mask;
|
||||
- pdpe = x86_ldq_phys(cs, pdpe_addr);
|
||||
+ pdpe = ldq_phys_debug(cs, pdpe_addr);
|
||||
if (!(pdpe & PG_PRESENT_MASK))
|
||||
return -1;
|
||||
}
|
||||
|
||||
pde_addr = ((pdpe & PG_ADDRESS_MASK) +
|
||||
(((addr >> 21) & 0x1ff) << 3)) & a20_mask;
|
||||
- pde = x86_ldq_phys(cs, pde_addr);
|
||||
+ pde = ldq_phys_debug(cs, pde_addr);
|
||||
if (!(pde & PG_PRESENT_MASK)) {
|
||||
return -1;
|
||||
}
|
||||
@@ -808,7 +808,7 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||
pte_addr = ((pde & PG_ADDRESS_MASK) +
|
||||
(((addr >> 12) & 0x1ff) << 3)) & a20_mask;
|
||||
page_size = 4096;
|
||||
- pte = x86_ldq_phys(cs, pte_addr);
|
||||
+ pte = ldq_phys_debug(cs, pte_addr);
|
||||
}
|
||||
if (!(pte & PG_PRESENT_MASK)) {
|
||||
return -1;
|
||||
@@ -818,7 +818,7 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||
|
||||
/* page directory entry */
|
||||
pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & a20_mask;
|
||||
- pde = x86_ldl_phys(cs, pde_addr);
|
||||
+ pde = ldl_phys_debug(cs, pde_addr);
|
||||
if (!(pde & PG_PRESENT_MASK))
|
||||
return -1;
|
||||
if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
|
||||
@@ -827,7 +827,7 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||
} else {
|
||||
/* page directory entry */
|
||||
pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & a20_mask;
|
||||
- pte = x86_ldl_phys(cs, pte_addr);
|
||||
+ pte = ldl_phys_debug(cs, pte_addr);
|
||||
if (!(pte & PG_PRESENT_MASK)) {
|
||||
return -1;
|
||||
}
|
||||
diff --git a/target/i386/monitor.c b/target/i386/monitor.c
|
||||
index 75e155ffb1..63f7125ba8 100644
|
||||
--- a/target/i386/monitor.c
|
||||
+++ b/target/i386/monitor.c
|
||||
@@ -66,7 +66,7 @@ static void tlb_info_32(Monitor *mon, CPUArchState *env)
|
||||
|
||||
pgd = env->cr[3] & ~0xfff;
|
||||
for(l1 = 0; l1 < 1024; l1++) {
|
||||
- cpu_physical_memory_read(pgd + l1 * 4, &pde, 4);
|
||||
+ cpu_physical_memory_read_debug(pgd + l1 * 4, &pde, 4);
|
||||
pde = le32_to_cpu(pde);
|
||||
if (pde & PG_PRESENT_MASK) {
|
||||
if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
|
||||
@@ -74,7 +74,8 @@ static void tlb_info_32(Monitor *mon, CPUArchState *env)
|
||||
print_pte(mon, env, (l1 << 22), pde, ~((1 << 21) - 1));
|
||||
} else {
|
||||
for(l2 = 0; l2 < 1024; l2++) {
|
||||
- cpu_physical_memory_read((pde & ~0xfff) + l2 * 4, &pte, 4);
|
||||
+ cpu_physical_memory_read_debug((pde & ~0xfff) + l2 * 4,
|
||||
+ &pte, 4);
|
||||
pte = le32_to_cpu(pte);
|
||||
if (pte & PG_PRESENT_MASK) {
|
||||
print_pte(mon, env, (l1 << 22) + (l2 << 12),
|
||||
@@ -95,12 +96,12 @@ static void tlb_info_pae32(Monitor *mon, CPUArchState *env)
|
||||
|
||||
pdp_addr = env->cr[3] & ~0x1f;
|
||||
for (l1 = 0; l1 < 4; l1++) {
|
||||
- cpu_physical_memory_read(pdp_addr + l1 * 8, &pdpe, 8);
|
||||
+ cpu_physical_memory_read_debug(pdp_addr + l1 * 8, &pdpe, 8);
|
||||
pdpe = le64_to_cpu(pdpe);
|
||||
if (pdpe & PG_PRESENT_MASK) {
|
||||
pd_addr = pdpe & 0x3fffffffff000ULL;
|
||||
for (l2 = 0; l2 < 512; l2++) {
|
||||
- cpu_physical_memory_read(pd_addr + l2 * 8, &pde, 8);
|
||||
+ cpu_physical_memory_read_debug(pd_addr + l2 * 8, &pde, 8);
|
||||
pde = le64_to_cpu(pde);
|
||||
if (pde & PG_PRESENT_MASK) {
|
||||
if (pde & PG_PSE_MASK) {
|
||||
@@ -110,7 +111,8 @@ static void tlb_info_pae32(Monitor *mon, CPUArchState *env)
|
||||
} else {
|
||||
pt_addr = pde & 0x3fffffffff000ULL;
|
||||
for (l3 = 0; l3 < 512; l3++) {
|
||||
- cpu_physical_memory_read(pt_addr + l3 * 8, &pte, 8);
|
||||
+ cpu_physical_memory_read_debug(pt_addr + l3 * 8,
|
||||
+ &pte, 8);
|
||||
pte = le64_to_cpu(pte);
|
||||
if (pte & PG_PRESENT_MASK) {
|
||||
print_pte(mon, env, (l1 << 30) + (l2 << 21)
|
||||
@@ -135,7 +137,7 @@ static void tlb_info_la48(Monitor *mon, CPUArchState *env,
|
||||
uint64_t pdp_addr, pd_addr, pt_addr;
|
||||
|
||||
for (l1 = 0; l1 < 512; l1++) {
|
||||
- cpu_physical_memory_read(pml4_addr + l1 * 8, &pml4e, 8);
|
||||
+ cpu_physical_memory_read_debug(pml4_addr + l1 * 8, &pml4e, 8);
|
||||
pml4e = le64_to_cpu(pml4e);
|
||||
if (!(pml4e & PG_PRESENT_MASK)) {
|
||||
continue;
|
||||
@@ -143,7 +145,7 @@ static void tlb_info_la48(Monitor *mon, CPUArchState *env,
|
||||
|
||||
pdp_addr = pml4e & 0x3fffffffff000ULL;
|
||||
for (l2 = 0; l2 < 512; l2++) {
|
||||
- cpu_physical_memory_read(pdp_addr + l2 * 8, &pdpe, 8);
|
||||
+ cpu_physical_memory_read_debug(pdp_addr + l2 * 8, &pdpe, 8);
|
||||
pdpe = le64_to_cpu(pdpe);
|
||||
if (!(pdpe & PG_PRESENT_MASK)) {
|
||||
continue;
|
||||
@@ -158,7 +160,7 @@ static void tlb_info_la48(Monitor *mon, CPUArchState *env,
|
||||
|
||||
pd_addr = pdpe & 0x3fffffffff000ULL;
|
||||
for (l3 = 0; l3 < 512; l3++) {
|
||||
- cpu_physical_memory_read(pd_addr + l3 * 8, &pde, 8);
|
||||
+ cpu_physical_memory_read_debug(pd_addr + l3 * 8, &pde, 8);
|
||||
pde = le64_to_cpu(pde);
|
||||
if (!(pde & PG_PRESENT_MASK)) {
|
||||
continue;
|
||||
@@ -173,9 +175,7 @@ static void tlb_info_la48(Monitor *mon, CPUArchState *env,
|
||||
|
||||
pt_addr = pde & 0x3fffffffff000ULL;
|
||||
for (l4 = 0; l4 < 512; l4++) {
|
||||
- cpu_physical_memory_read(pt_addr
|
||||
- + l4 * 8,
|
||||
- &pte, 8);
|
||||
+ cpu_physical_memory_read_debug(pt_addr + l4 * 8, &pte, 8);
|
||||
pte = le64_to_cpu(pte);
|
||||
if (pte & PG_PRESENT_MASK) {
|
||||
print_pte(mon, env, (l0 << 48) + (l1 << 39) +
|
||||
@@ -196,7 +196,7 @@ static void tlb_info_la57(Monitor *mon, CPUArchState *env)
|
||||
|
||||
pml5_addr = env->cr[3] & 0x3fffffffff000ULL;
|
||||
for (l0 = 0; l0 < 512; l0++) {
|
||||
- cpu_physical_memory_read(pml5_addr + l0 * 8, &pml5e, 8);
|
||||
+ cpu_physical_memory_read_debug(pml5_addr + l0 * 8, &pml5e, 8);
|
||||
pml5e = le64_to_cpu(pml5e);
|
||||
if (pml5e & PG_PRESENT_MASK) {
|
||||
tlb_info_la48(mon, env, l0, pml5e & 0x3fffffffff000ULL);
|
||||
@@ -271,7 +271,7 @@ static void mem_info_32(Monitor *mon, CPUArchState *env)
|
||||
last_prot = 0;
|
||||
start = -1;
|
||||
for(l1 = 0; l1 < 1024; l1++) {
|
||||
- cpu_physical_memory_read(pgd + l1 * 4, &pde, 4);
|
||||
+ cpu_physical_memory_read_debug(pgd + l1 * 4, &pde, 4);
|
||||
pde = le32_to_cpu(pde);
|
||||
end = l1 << 22;
|
||||
if (pde & PG_PRESENT_MASK) {
|
||||
@@ -280,7 +280,8 @@ static void mem_info_32(Monitor *mon, CPUArchState *env)
|
||||
mem_print(mon, &start, &last_prot, end, prot);
|
||||
} else {
|
||||
for(l2 = 0; l2 < 1024; l2++) {
|
||||
- cpu_physical_memory_read((pde & ~0xfff) + l2 * 4, &pte, 4);
|
||||
+ cpu_physical_memory_read_debug((pde & ~0xfff) + l2 * 4,
|
||||
+ &pte, 4);
|
||||
pte = le32_to_cpu(pte);
|
||||
end = (l1 << 22) + (l2 << 12);
|
||||
if (pte & PG_PRESENT_MASK) {
|
||||
@@ -313,13 +314,13 @@ static void mem_info_pae32(Monitor *mon, CPUArchState *env)
|
||||
last_prot = 0;
|
||||
start = -1;
|
||||
for (l1 = 0; l1 < 4; l1++) {
|
||||
- cpu_physical_memory_read(pdp_addr + l1 * 8, &pdpe, 8);
|
||||
+ cpu_physical_memory_read_debug(pdp_addr + l1 * 8, &pdpe, 8);
|
||||
pdpe = le64_to_cpu(pdpe);
|
||||
end = l1 << 30;
|
||||
if (pdpe & PG_PRESENT_MASK) {
|
||||
pd_addr = pdpe & 0x3fffffffff000ULL;
|
||||
for (l2 = 0; l2 < 512; l2++) {
|
||||
- cpu_physical_memory_read(pd_addr + l2 * 8, &pde, 8);
|
||||
+ cpu_physical_memory_read_debug(pd_addr + l2 * 8, &pde, 8);
|
||||
pde = le64_to_cpu(pde);
|
||||
end = (l1 << 30) + (l2 << 21);
|
||||
if (pde & PG_PRESENT_MASK) {
|
||||
@@ -330,7 +331,8 @@ static void mem_info_pae32(Monitor *mon, CPUArchState *env)
|
||||
} else {
|
||||
pt_addr = pde & 0x3fffffffff000ULL;
|
||||
for (l3 = 0; l3 < 512; l3++) {
|
||||
- cpu_physical_memory_read(pt_addr + l3 * 8, &pte, 8);
|
||||
+ cpu_physical_memory_read_debug(pt_addr + l3 * 8,
|
||||
+ &pte, 8);
|
||||
pte = le64_to_cpu(pte);
|
||||
end = (l1 << 30) + (l2 << 21) + (l3 << 12);
|
||||
if (pte & PG_PRESENT_MASK) {
|
||||
@@ -369,13 +371,13 @@ static void mem_info_la48(Monitor *mon, CPUArchState *env)
|
||||
last_prot = 0;
|
||||
start = -1;
|
||||
for (l1 = 0; l1 < 512; l1++) {
|
||||
- cpu_physical_memory_read(pml4_addr + l1 * 8, &pml4e, 8);
|
||||
+ cpu_physical_memory_read_debug(pml4_addr + l1 * 8, &pml4e, 8);
|
||||
pml4e = le64_to_cpu(pml4e);
|
||||
end = l1 << 39;
|
||||
if (pml4e & PG_PRESENT_MASK) {
|
||||
pdp_addr = pml4e & 0x3fffffffff000ULL;
|
||||
for (l2 = 0; l2 < 512; l2++) {
|
||||
- cpu_physical_memory_read(pdp_addr + l2 * 8, &pdpe, 8);
|
||||
+ cpu_physical_memory_read_debug(pdp_addr + l2 * 8, &pdpe, 8);
|
||||
pdpe = le64_to_cpu(pdpe);
|
||||
end = (l1 << 39) + (l2 << 30);
|
||||
if (pdpe & PG_PRESENT_MASK) {
|
||||
@@ -387,7 +389,8 @@ static void mem_info_la48(Monitor *mon, CPUArchState *env)
|
||||
} else {
|
||||
pd_addr = pdpe & 0x3fffffffff000ULL;
|
||||
for (l3 = 0; l3 < 512; l3++) {
|
||||
- cpu_physical_memory_read(pd_addr + l3 * 8, &pde, 8);
|
||||
+ cpu_physical_memory_read_debug(pd_addr + l3 * 8,
|
||||
+ &pde, 8);
|
||||
pde = le64_to_cpu(pde);
|
||||
end = (l1 << 39) + (l2 << 30) + (l3 << 21);
|
||||
if (pde & PG_PRESENT_MASK) {
|
||||
@@ -399,9 +402,9 @@ static void mem_info_la48(Monitor *mon, CPUArchState *env)
|
||||
} else {
|
||||
pt_addr = pde & 0x3fffffffff000ULL;
|
||||
for (l4 = 0; l4 < 512; l4++) {
|
||||
- cpu_physical_memory_read(pt_addr
|
||||
- + l4 * 8,
|
||||
- &pte, 8);
|
||||
+ cpu_physical_memory_read_debug(pt_addr
|
||||
+ + l4 * 8,
|
||||
+ &pte, 8);
|
||||
pte = le64_to_cpu(pte);
|
||||
end = (l1 << 39) + (l2 << 30) +
|
||||
(l3 << 21) + (l4 << 12);
|
||||
@@ -446,7 +449,7 @@ static void mem_info_la57(Monitor *mon, CPUArchState *env)
|
||||
last_prot = 0;
|
||||
start = -1;
|
||||
for (l0 = 0; l0 < 512; l0++) {
|
||||
- cpu_physical_memory_read(pml5_addr + l0 * 8, &pml5e, 8);
|
||||
+ cpu_physical_memory_read_debug(pml5_addr + l0 * 8, &pml5e, 8);
|
||||
pml5e = le64_to_cpu(pml5e);
|
||||
end = l0 << 48;
|
||||
if (!(pml5e & PG_PRESENT_MASK)) {
|
||||
@@ -457,7 +460,7 @@ static void mem_info_la57(Monitor *mon, CPUArchState *env)
|
||||
|
||||
pml4_addr = pml5e & 0x3fffffffff000ULL;
|
||||
for (l1 = 0; l1 < 512; l1++) {
|
||||
- cpu_physical_memory_read(pml4_addr + l1 * 8, &pml4e, 8);
|
||||
+ cpu_physical_memory_read_debug(pml4_addr + l1 * 8, &pml4e, 8);
|
||||
pml4e = le64_to_cpu(pml4e);
|
||||
end = (l0 << 48) + (l1 << 39);
|
||||
if (!(pml4e & PG_PRESENT_MASK)) {
|
||||
@@ -468,7 +471,7 @@ static void mem_info_la57(Monitor *mon, CPUArchState *env)
|
||||
|
||||
pdp_addr = pml4e & 0x3fffffffff000ULL;
|
||||
for (l2 = 0; l2 < 512; l2++) {
|
||||
- cpu_physical_memory_read(pdp_addr + l2 * 8, &pdpe, 8);
|
||||
+ cpu_physical_memory_read_debug(pdp_addr + l2 * 8, &pdpe, 8);
|
||||
pdpe = le64_to_cpu(pdpe);
|
||||
end = (l0 << 48) + (l1 << 39) + (l2 << 30);
|
||||
if (pdpe & PG_PRESENT_MASK) {
|
||||
@@ -487,7 +490,7 @@ static void mem_info_la57(Monitor *mon, CPUArchState *env)
|
||||
|
||||
pd_addr = pdpe & 0x3fffffffff000ULL;
|
||||
for (l3 = 0; l3 < 512; l3++) {
|
||||
- cpu_physical_memory_read(pd_addr + l3 * 8, &pde, 8);
|
||||
+ cpu_physical_memory_read_debug(pd_addr + l3 * 8, &pde, 8);
|
||||
pde = le64_to_cpu(pde);
|
||||
end = (l0 << 48) + (l1 << 39) + (l2 << 30) + (l3 << 21);
|
||||
if (pde & PG_PRESENT_MASK) {
|
||||
@@ -506,7 +509,8 @@ static void mem_info_la57(Monitor *mon, CPUArchState *env)
|
||||
|
||||
pt_addr = pde & 0x3fffffffff000ULL;
|
||||
for (l4 = 0; l4 < 512; l4++) {
|
||||
- cpu_physical_memory_read(pt_addr + l4 * 8, &pte, 8);
|
||||
+ cpu_physical_memory_read_debug(pt_addr + l4 * 8,
|
||||
+ &pte, 8);
|
||||
pte = le64_to_cpu(pte);
|
||||
end = (l0 << 48) + (l1 << 39) + (l2 << 30) +
|
||||
(l3 << 21) + (l4 << 12);
|
137
0050-target-i386-add-memory-encryption-f.patch
Normal file
137
0050-target-i386-add-memory-encryption-f.patch
Normal file
@ -0,0 +1,137 @@
|
||||
From 7fee871608f1ab458151d03712fb0b89cf5c5668 Mon Sep 17 00:00:00 2001
|
||||
From: Brijesh Singh <brijesh.singh@amd.com>
|
||||
Date: Tue, 6 Feb 2018 19:08:07 -0600
|
||||
Subject: [PATCH] target/i386: add memory encryption feature cpuid support
|
||||
|
||||
AMD EPYC processors support memory encryption feature. The feature
|
||||
is reported through CPUID 8000_001F[EAX].
|
||||
|
||||
Fn8000_001F [EAX]:
|
||||
Bit 0 Secure Memory Encryption (SME) supported
|
||||
Bit 1 Secure Encrypted Virtualization (SEV) supported
|
||||
Bit 2 Page flush MSR supported
|
||||
Bit 3 Ecrypted State (SEV-ES) support
|
||||
|
||||
when memory encryption feature is reported, CPUID 8000_001F[EBX] should
|
||||
provide additional information regarding the feature (such as which page
|
||||
table bit is used to mark pages as encrypted etc). The information in EBX
|
||||
and ECX may vary from one family to another hence we use the host cpuid
|
||||
to populate the EBX information.
|
||||
|
||||
The details for memory encryption CPUID is available in AMD APM
|
||||
(https://support.amd.com/TechDocs/24594.pdf) Section E.4.17
|
||||
|
||||
Cc: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Cc: Richard Henderson <rth@twiddle.net>
|
||||
Cc: Eduardo Habkost <ehabkost@redhat.com>
|
||||
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
|
||||
[BR: FATE#322124]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
target/i386/cpu.c | 36 ++++++++++++++++++++++++++++++++++++
|
||||
target/i386/cpu.h | 6 ++++++
|
||||
2 files changed, 42 insertions(+)
|
||||
|
||||
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
|
||||
index 4a403b1e7b..98cd293c4f 100644
|
||||
--- a/target/i386/cpu.c
|
||||
+++ b/target/i386/cpu.c
|
||||
@@ -233,6 +233,7 @@ static void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
|
||||
#define TCG_EXT4_FEATURES 0
|
||||
#define TCG_SVM_FEATURES 0
|
||||
#define TCG_KVM_FEATURES 0
|
||||
+#define TCG_MEM_ENCRYPT_FEATURES 0
|
||||
#define TCG_7_0_EBX_FEATURES (CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_SMAP | \
|
||||
CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ADX | \
|
||||
CPUID_7_0_EBX_PCOMMIT | CPUID_7_0_EBX_CLFLUSHOPT | \
|
||||
@@ -528,6 +529,20 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
|
||||
.cpuid_reg = R_EDX,
|
||||
.tcg_features = ~0U,
|
||||
},
|
||||
+ [FEAT_MEM_ENCRYPT] = {
|
||||
+ .feat_names = {
|
||||
+ "sme", "sev", "page-flush-msr", "sev-es",
|
||||
+ NULL, NULL, NULL, NULL,
|
||||
+ NULL, NULL, NULL, NULL,
|
||||
+ NULL, NULL, NULL, NULL,
|
||||
+ NULL, NULL, NULL, NULL,
|
||||
+ NULL, NULL, NULL, NULL,
|
||||
+ NULL, NULL, NULL, NULL,
|
||||
+ NULL, NULL, NULL, NULL,
|
||||
+ },
|
||||
+ .cpuid_eax = 0x8000001F, .cpuid_reg = R_EAX,
|
||||
+ .tcg_features = TCG_MEM_ENCRYPT_FEATURES,
|
||||
+ }
|
||||
};
|
||||
|
||||
typedef struct X86RegisterInfo32 {
|
||||
@@ -1562,6 +1577,9 @@ static X86CPUDefinition builtin_x86_defs[] = {
|
||||
CPUID_XSAVE_XGETBV1,
|
||||
.features[FEAT_6_EAX] =
|
||||
CPUID_6_EAX_ARAT,
|
||||
+ /* Missing: SEV_ES */
|
||||
+ .features[FEAT_MEM_ENCRYPT] =
|
||||
+ CPUID_8000_001F_EAX_SME | CPUID_8000_001F_EAX_SEV,
|
||||
.xlevel = 0x8000000A,
|
||||
.model_id = "AMD EPYC Processor",
|
||||
},
|
||||
@@ -3111,6 +3129,19 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
||||
*edx = 0;
|
||||
}
|
||||
break;
|
||||
+ case 0x8000001F:
|
||||
+ if (env->features[FEAT_MEM_ENCRYPT] & CPUID_8000_001F_EAX_SEV) {
|
||||
+ *eax = env->features[FEAT_MEM_ENCRYPT];
|
||||
+ host_cpuid(0x8000001F, 0, NULL, ebx, NULL, NULL);
|
||||
+ *ecx = 0;
|
||||
+ *edx = 0;
|
||||
+ } else {
|
||||
+ *eax = 0;
|
||||
+ *ebx = 0;
|
||||
+ *ecx = 0;
|
||||
+ *edx = 0;
|
||||
+ }
|
||||
+ break;
|
||||
case 0xC0000000:
|
||||
*eax = env->cpuid_xlevel2;
|
||||
*ebx = 0;
|
||||
@@ -3550,10 +3581,15 @@ static void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
|
||||
x86_cpu_adjust_feat_level(cpu, FEAT_C000_0001_EDX);
|
||||
x86_cpu_adjust_feat_level(cpu, FEAT_SVM);
|
||||
x86_cpu_adjust_feat_level(cpu, FEAT_XSAVE);
|
||||
+ x86_cpu_adjust_feat_level(cpu, FEAT_MEM_ENCRYPT);
|
||||
/* SVM requires CPUID[0x8000000A] */
|
||||
if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
|
||||
x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel, 0x8000000A);
|
||||
}
|
||||
+ /* SEV requires CPUID[0x8000001F] */
|
||||
+ if ((env->features[FEAT_MEM_ENCRYPT] & CPUID_8000_001F_EAX_SEV)) {
|
||||
+ x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel, 0x8000001F);
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Set cpuid_*level* based on cpuid_min_*level, if not explicitly set */
|
||||
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
|
||||
index d9ecf7a368..224ac5413f 100644
|
||||
--- a/target/i386/cpu.h
|
||||
+++ b/target/i386/cpu.h
|
||||
@@ -464,6 +464,7 @@ typedef enum FeatureWord {
|
||||
FEAT_6_EAX, /* CPUID[6].EAX */
|
||||
FEAT_XSAVE_COMP_LO, /* CPUID[EAX=0xd,ECX=0].EAX */
|
||||
FEAT_XSAVE_COMP_HI, /* CPUID[EAX=0xd,ECX=0].EDX */
|
||||
+ FEAT_MEM_ENCRYPT, /* CPUID[8000_001F].EAX */
|
||||
FEATURE_WORDS,
|
||||
} FeatureWord;
|
||||
|
||||
@@ -652,6 +653,11 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
|
||||
|
||||
#define CPUID_6_EAX_ARAT (1U << 2)
|
||||
|
||||
+#define CPUID_8000_001F_EAX_SME (1U << 0) /* SME */
|
||||
+#define CPUID_8000_001F_EAX_SEV (1U << 1) /* SEV */
|
||||
+#define CPUID_8000_001F_EAX_PAGE_FLUSH_MSR (1U << 2) /* Page flush MSR */
|
||||
+#define CPUID_8000_001F_EAX_SEV_ES (1U << 3) /* SEV-ES */
|
||||
+
|
||||
/* CPUID[0x80000007].EDX flags: */
|
||||
#define CPUID_APM_INVTSC (1U << 8)
|
||||
|
86
0051-machine-add-memory-encryption-prope.patch
Normal file
86
0051-machine-add-memory-encryption-prope.patch
Normal file
@ -0,0 +1,86 @@
|
||||
From 80b31eed583af21eee2e2f152d2c24e6aa13b2b7 Mon Sep 17 00:00:00 2001
|
||||
From: Brijesh Singh <brijesh.singh@amd.com>
|
||||
Date: Tue, 6 Feb 2018 19:08:08 -0600
|
||||
Subject: [PATCH] machine: add -memory-encryption property
|
||||
|
||||
When CPU supports memory encryption feature, the property can be used to
|
||||
specify the encryption object to use when launching an encrypted guest.
|
||||
|
||||
Cc: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Cc: Eduardo Habkost <ehabkost@redhat.com>
|
||||
Cc: Marcel Apfelbaum <marcel@redhat.com>
|
||||
Cc: Stefan Hajnoczi <stefanha@gmail.com>
|
||||
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
|
||||
[BR: FATE#322124]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
hw/core/machine.c | 22 ++++++++++++++++++++++
|
||||
include/hw/boards.h | 1 +
|
||||
qemu-options.hx | 2 ++
|
||||
3 files changed, 25 insertions(+)
|
||||
|
||||
diff --git a/hw/core/machine.c b/hw/core/machine.c
|
||||
index 36c2fb069c..132c57bc51 100644
|
||||
--- a/hw/core/machine.c
|
||||
+++ b/hw/core/machine.c
|
||||
@@ -335,6 +335,22 @@ static bool machine_get_enforce_config_section(Object *obj, Error **errp)
|
||||
return ms->enforce_config_section;
|
||||
}
|
||||
|
||||
+static char *machine_get_memory_encryption(Object *obj, Error **errp)
|
||||
+{
|
||||
+ MachineState *ms = MACHINE(obj);
|
||||
+
|
||||
+ return g_strdup(ms->memory_encryption);
|
||||
+}
|
||||
+
|
||||
+static void machine_set_memory_encryption(Object *obj, const char *value,
|
||||
+ Error **errp)
|
||||
+{
|
||||
+ MachineState *ms = MACHINE(obj);
|
||||
+
|
||||
+ g_free(ms->memory_encryption);
|
||||
+ ms->memory_encryption = g_strdup(value);
|
||||
+}
|
||||
+
|
||||
static void error_on_sysbus_device(SysBusDevice *sbdev, void *opaque)
|
||||
{
|
||||
error_report("Option '-device %s' cannot be handled by this machine",
|
||||
@@ -598,6 +614,12 @@ static void machine_class_init(ObjectClass *oc, void *data)
|
||||
&error_abort);
|
||||
object_class_property_set_description(oc, "enforce-config-section",
|
||||
"Set on to enforce configuration section migration", &error_abort);
|
||||
+
|
||||
+ object_class_property_add_str(oc, "memory-encryption",
|
||||
+ machine_get_memory_encryption, machine_set_memory_encryption,
|
||||
+ &error_abort);
|
||||
+ object_class_property_set_description(oc, "memory-encryption",
|
||||
+ "Set memory encyption object to use", &error_abort);
|
||||
}
|
||||
|
||||
static void machine_class_base_init(ObjectClass *oc, void *data)
|
||||
diff --git a/include/hw/boards.h b/include/hw/boards.h
|
||||
index 156b16f7a6..41fa577955 100644
|
||||
--- a/include/hw/boards.h
|
||||
+++ b/include/hw/boards.h
|
||||
@@ -238,6 +238,7 @@ struct MachineState {
|
||||
bool suppress_vmdesc;
|
||||
bool enforce_config_section;
|
||||
bool enable_graphics;
|
||||
+ char *memory_encryption;
|
||||
|
||||
ram_addr_t ram_size;
|
||||
ram_addr_t maxram_size;
|
||||
diff --git a/qemu-options.hx b/qemu-options.hx
|
||||
index f11c4ac960..5385832707 100644
|
||||
--- a/qemu-options.hx
|
||||
+++ b/qemu-options.hx
|
||||
@@ -104,6 +104,8 @@ code to send configuration section even if the machine-type sets the
|
||||
@option{migration.send-configuration} property to @var{off}.
|
||||
NOTE: this parameter is deprecated. Please use @option{-global}
|
||||
@option{migration.send-configuration}=@var{on|off} instead.
|
||||
+@item memory-encryption=@var{}
|
||||
+Memory encryption object to use. The default is none.
|
||||
@end table
|
||||
ETEXI
|
||||
|
118
0052-kvm-update-kvm.h-to-include-memory-.patch
Normal file
118
0052-kvm-update-kvm.h-to-include-memory-.patch
Normal file
@ -0,0 +1,118 @@
|
||||
From fd981d8bae5ef3b9056845add32a0830356b3b7f Mon Sep 17 00:00:00 2001
|
||||
From: Brijesh Singh <brijesh.singh@amd.com>
|
||||
Date: Tue, 6 Feb 2018 19:08:08 -0600
|
||||
Subject: [PATCH] kvm: update kvm.h to include memory encryption ioctls
|
||||
|
||||
Updates kmv.h to include memory encryption ioctls and SEV commands.
|
||||
|
||||
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
|
||||
Cc: Cornelia Huck <cornelia.huck@de.ibm.com>
|
||||
Cc: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
|
||||
[BR: FATE#322124]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
linux-headers/linux/kvm.h | 90 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 90 insertions(+)
|
||||
|
||||
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
|
||||
index dd8a91801e..04b5801d03 100644
|
||||
--- a/linux-headers/linux/kvm.h
|
||||
+++ b/linux-headers/linux/kvm.h
|
||||
@@ -1356,6 +1356,96 @@ struct kvm_s390_ucas_mapping {
|
||||
/* Available with KVM_CAP_S390_CMMA_MIGRATION */
|
||||
#define KVM_S390_GET_CMMA_BITS _IOWR(KVMIO, 0xb8, struct kvm_s390_cmma_log)
|
||||
#define KVM_S390_SET_CMMA_BITS _IOW(KVMIO, 0xb9, struct kvm_s390_cmma_log)
|
||||
+/* Memory Encryption Commands */
|
||||
+#define KVM_MEMORY_ENCRYPT_OP _IOWR(KVMIO, 0xba, unsigned long)
|
||||
+
|
||||
+struct kvm_enc_region {
|
||||
+ __u64 addr;
|
||||
+ __u64 size;
|
||||
+};
|
||||
+
|
||||
+#define KVM_MEMORY_ENCRYPT_REG_REGION _IOR(KVMIO, 0xbb, struct kvm_enc_region)
|
||||
+#define KVM_MEMORY_ENCRYPT_UNREG_REGION _IOR(KVMIO, 0xbc, struct kvm_enc_region)
|
||||
+
|
||||
+/* Secure Encrypted Virtualization command */
|
||||
+enum sev_cmd_id {
|
||||
+ /* Guest initialization commands */
|
||||
+ KVM_SEV_INIT = 0,
|
||||
+ KVM_SEV_ES_INIT,
|
||||
+ /* Guest launch commands */
|
||||
+ KVM_SEV_LAUNCH_START,
|
||||
+ KVM_SEV_LAUNCH_UPDATE_DATA,
|
||||
+ KVM_SEV_LAUNCH_UPDATE_VMSA,
|
||||
+ KVM_SEV_LAUNCH_SECRET,
|
||||
+ KVM_SEV_LAUNCH_MEASURE,
|
||||
+ KVM_SEV_LAUNCH_FINISH,
|
||||
+ /* Guest migration commands (outgoing) */
|
||||
+ KVM_SEV_SEND_START,
|
||||
+ KVM_SEV_SEND_UPDATE_DATA,
|
||||
+ KVM_SEV_SEND_UPDATE_VMSA,
|
||||
+ KVM_SEV_SEND_FINISH,
|
||||
+ /* Guest migration commands (incoming) */
|
||||
+ KVM_SEV_RECEIVE_START,
|
||||
+ KVM_SEV_RECEIVE_UPDATE_DATA,
|
||||
+ KVM_SEV_RECEIVE_UPDATE_VMSA,
|
||||
+ KVM_SEV_RECEIVE_FINISH,
|
||||
+ /* Guest status and debug commands */
|
||||
+ KVM_SEV_GUEST_STATUS,
|
||||
+ KVM_SEV_DBG_DECRYPT,
|
||||
+ KVM_SEV_DBG_ENCRYPT,
|
||||
+ /* Guest certificates commands */
|
||||
+ KVM_SEV_CERT_EXPORT,
|
||||
+
|
||||
+ KVM_SEV_NR_MAX,
|
||||
+};
|
||||
+
|
||||
+struct kvm_sev_cmd {
|
||||
+ __u32 id;
|
||||
+ __u64 data;
|
||||
+ __u32 error;
|
||||
+ __u32 sev_fd;
|
||||
+};
|
||||
+
|
||||
+struct kvm_sev_launch_start {
|
||||
+ __u32 handle;
|
||||
+ __u32 policy;
|
||||
+ __u64 dh_uaddr;
|
||||
+ __u32 dh_len;
|
||||
+ __u64 session_uaddr;
|
||||
+ __u32 session_len;
|
||||
+};
|
||||
+
|
||||
+struct kvm_sev_launch_update_data {
|
||||
+ __u64 uaddr;
|
||||
+ __u32 len;
|
||||
+};
|
||||
+
|
||||
+
|
||||
+struct kvm_sev_launch_secret {
|
||||
+ __u64 hdr_uaddr;
|
||||
+ __u32 hdr_len;
|
||||
+ __u64 guest_uaddr;
|
||||
+ __u32 guest_len;
|
||||
+ __u64 trans_uaddr;
|
||||
+ __u32 trans_len;
|
||||
+};
|
||||
+
|
||||
+struct kvm_sev_launch_measure {
|
||||
+ __u64 uaddr;
|
||||
+ __u32 len;
|
||||
+};
|
||||
+
|
||||
+struct kvm_sev_guest_status {
|
||||
+ __u32 handle;
|
||||
+ __u32 policy;
|
||||
+ __u32 state;
|
||||
+};
|
||||
+
|
||||
+struct kvm_sev_dbg {
|
||||
+ __u64 src_uaddr;
|
||||
+ __u64 dst_uaddr;
|
||||
+ __u32 len;
|
||||
+};
|
||||
|
||||
#define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0)
|
||||
#define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1)
|
115
0053-docs-add-AMD-Secure-Encrypted-Virtu.patch
Normal file
115
0053-docs-add-AMD-Secure-Encrypted-Virtu.patch
Normal file
@ -0,0 +1,115 @@
|
||||
From e31dff17694578d6f14f94fce81f446827502318 Mon Sep 17 00:00:00 2001
|
||||
From: Brijesh Singh <brijesh.singh@amd.com>
|
||||
Date: Tue, 6 Feb 2018 19:08:08 -0600
|
||||
Subject: [PATCH] docs: add AMD Secure Encrypted Virtualization (SEV)
|
||||
|
||||
Create a documentation entry to describe the AMD Secure Encrypted
|
||||
Virtualization (SEV) feature.
|
||||
|
||||
Cc: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
|
||||
[BR: FATE#322124]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
docs/amd-memory-encryption.txt | 92 ++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 92 insertions(+)
|
||||
create mode 100644 docs/amd-memory-encryption.txt
|
||||
|
||||
diff --git a/docs/amd-memory-encryption.txt b/docs/amd-memory-encryption.txt
|
||||
new file mode 100644
|
||||
index 0000000000..72a92b6c63
|
||||
--- /dev/null
|
||||
+++ b/docs/amd-memory-encryption.txt
|
||||
@@ -0,0 +1,92 @@
|
||||
+Secure Encrypted Virtualization (SEV) is a feature found on AMD processors.
|
||||
+
|
||||
+SEV is an extension to the AMD-V architecture which supports running encrypted
|
||||
+virtual machine (VMs) under the control of KVM. Encrypted VMs have their pages
|
||||
+(code and data) secured such that only the guest itself has access to the
|
||||
+unencrypted version. Each encrypted VM is associated with a unique encryption
|
||||
+key; if its data is accessed to a different entity using a different key the
|
||||
+encrypted guests data will be incorrectly decrypted, leading to unintelligible
|
||||
+data.
|
||||
+
|
||||
+The key management of this feature is handled by separate processor known as
|
||||
+AMD secure processor (AMD-SP) which is present in AMD SOCs. Firmware running
|
||||
+inside the AMD-SP provide commands to support common VM lifecycle. This
|
||||
+includes commands for launching, snapshotting, migrating and debugging the
|
||||
+encrypted guest. Those SEV command can be issued via KVM_MEMORY_ENCRYPT_OP
|
||||
+ioctls.
|
||||
+
|
||||
+Launching
|
||||
+---------
|
||||
+Boot images (such as bios) must be encrypted before guest can be booted.
|
||||
+MEMORY_ENCRYPT_OP ioctl provides commands to encrypt the images :LAUNCH_START,
|
||||
+LAUNCH_UPDATE_DATA, LAUNCH_MEASURE and LAUNCH_FINISH. These four commands
|
||||
+together generate a fresh memory encryption key for the VM, encrypt the boot
|
||||
+images and provide a measurement than can be used as an attestation of the
|
||||
+successful launch.
|
||||
+
|
||||
+LAUNCH_START is called first to create a cryptographic launch context within
|
||||
+the firmware. To create this context, guest owner must provides guest policy,
|
||||
+its public Diffie-Hellman key (PDH) and session parameters. These inputs
|
||||
+should be treated as binary blob and must be passed as-is to the SEV firmware.
|
||||
+
|
||||
+The guest policy is passed as plaintext and hypervisor may able to read it
|
||||
+but should not modify it (any modification of the policy bits will result
|
||||
+in bad measurement). The guest policy is a 4-byte data structure containing
|
||||
+several flags that restricts what can be done on running SEV guest.
|
||||
+See KM Spec section 3 and 6.2 for more details.
|
||||
+
|
||||
+Guest owners provided DH certificate and session parameters will be used to
|
||||
+establish a cryptographic session with the guest owner to negotiate keys used
|
||||
+for the attestation.
|
||||
+
|
||||
+LAUNCH_UPDATE_DATA encrypts the memory region using the cryptographic context
|
||||
+created via LAUNCH_START command. If required, this command can be called
|
||||
+multiple times to encrypt different memory regions. The command also calculates
|
||||
+the measurement of the memory contents as it encrypts.
|
||||
+
|
||||
+LAUNCH_MEASURE command can be used to retrieve the measurement of encrypted
|
||||
+memory. This measurement is a signature of the memory contents that can be
|
||||
+sent to the guest owner as an attestation that the memory was encrypted
|
||||
+correctly by the firmware. The guest owner may wait to provide the guest
|
||||
+confidential information until it can verify the attestation measurement.
|
||||
+Since the guest owner knows the initial contents of the guest at boot, the
|
||||
+attestation measurement can be verified by comparing it to what the guest owner
|
||||
+expects.
|
||||
+
|
||||
+LAUNCH_FINISH command finalizes the guest launch and destroy's the cryptographic
|
||||
+context.
|
||||
+
|
||||
+See SEV KM API Spec [1] 'Launching a guest' usage flow (Appendix A) for the
|
||||
+complete flow chart.
|
||||
+
|
||||
+Debugging
|
||||
+-----------
|
||||
+Since memory contents of SEV guest is encrypted hence hypervisor access to the
|
||||
+guest memory will get a cipher text. If guest policy allows debugging, then
|
||||
+hypervisor can use DEBUG_DECRYPT and DEBUG_ENCRYPT commands access the guest
|
||||
+memory region for debug purposes.
|
||||
+
|
||||
+Snapshot/Restore
|
||||
+-----------------
|
||||
+TODO
|
||||
+
|
||||
+Live Migration
|
||||
+----------------
|
||||
+TODO
|
||||
+
|
||||
+References
|
||||
+-----------------
|
||||
+
|
||||
+AMD Memory Encryption whitepaper:
|
||||
+http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2013/12/AMD_Memory_Encryption_Whitepaper_v7-Public.pdf
|
||||
+
|
||||
+Secure Encrypted Virutualization Key Management:
|
||||
+[1] http://support.amd.com/TechDocs/55766_SEV-KM API_Specification.pdf
|
||||
+
|
||||
+KVM Forum slides:
|
||||
+http://www.linux-kvm.org/images/7/74/02x08A-Thomas_Lendacky-AMDs_Virtualizatoin_Memory_Encryption_Technology.pdf
|
||||
+
|
||||
+AMD64 Architecture Programmer's Manual:
|
||||
+ http://support.amd.com/TechDocs/24593.pdf
|
||||
+ SME is section 7.10
|
||||
+ SEV is section 15.34
|
403
0054-accel-add-Secure-Encrypted-Virtuliz.patch
Normal file
403
0054-accel-add-Secure-Encrypted-Virtuliz.patch
Normal file
@ -0,0 +1,403 @@
|
||||
From 725b55269e39ee0c64daf556b019d1eb70940b21 Mon Sep 17 00:00:00 2001
|
||||
From: Brijesh Singh <brijesh.singh@amd.com>
|
||||
Date: Tue, 6 Feb 2018 19:08:08 -0600
|
||||
Subject: [PATCH] accel: add Secure Encrypted Virtulization (SEV) object
|
||||
|
||||
Add a new memory encryption object 'sev-guest'. The object will be used
|
||||
to create enrypted VMs on AMD EPYC CPU. The object provides the properties
|
||||
to pass guest owner's public Diffie-hellman key, guest policy and session
|
||||
information required to create the memory encryption context within the
|
||||
SEV firmware.
|
||||
|
||||
e.g to launch SEV guest
|
||||
# $QEMU \
|
||||
-object sev-guest,id=sev0 \
|
||||
-machine ....,memory-encryption=sev0
|
||||
|
||||
Cc: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
|
||||
[BR: FATE#322124]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
accel/kvm/Makefile.objs | 2 +-
|
||||
accel/kvm/sev.c | 214 +++++++++++++++++++++++++++++++++++++++++
|
||||
docs/amd-memory-encryption.txt | 17 ++++
|
||||
include/sysemu/sev.h | 54 +++++++++++
|
||||
qemu-options.hx | 36 +++++++
|
||||
5 files changed, 322 insertions(+), 1 deletion(-)
|
||||
create mode 100644 accel/kvm/sev.c
|
||||
create mode 100644 include/sysemu/sev.h
|
||||
|
||||
diff --git a/accel/kvm/Makefile.objs b/accel/kvm/Makefile.objs
|
||||
index 85351e7de7..666ceef3da 100644
|
||||
--- a/accel/kvm/Makefile.objs
|
||||
+++ b/accel/kvm/Makefile.objs
|
||||
@@ -1 +1 @@
|
||||
-obj-$(CONFIG_KVM) += kvm-all.o
|
||||
+obj-$(CONFIG_KVM) += kvm-all.o sev.o
|
||||
diff --git a/accel/kvm/sev.c b/accel/kvm/sev.c
|
||||
new file mode 100644
|
||||
index 0000000000..57e092a0bd
|
||||
--- /dev/null
|
||||
+++ b/accel/kvm/sev.c
|
||||
@@ -0,0 +1,214 @@
|
||||
+/*
|
||||
+ * QEMU SEV support
|
||||
+ *
|
||||
+ * Copyright Advanced Micro Devices 2016-2018
|
||||
+ *
|
||||
+ * Author:
|
||||
+ * Brijesh Singh <brijesh.singh@amd.com>
|
||||
+ *
|
||||
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||||
+ * See the COPYING file in the top-level directory.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include "qemu/osdep.h"
|
||||
+#include "qapi/error.h"
|
||||
+#include "qom/object_interfaces.h"
|
||||
+#include "qemu/base64.h"
|
||||
+#include "sysemu/kvm.h"
|
||||
+#include "sysemu/sev.h"
|
||||
+#include "sysemu/sysemu.h"
|
||||
+
|
||||
+#define DEFAULT_GUEST_POLICY 0x1 /* disable debug */
|
||||
+#define DEFAULT_SEV_DEVICE "/dev/sev"
|
||||
+
|
||||
+static void
|
||||
+qsev_guest_finalize(Object *obj)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static char *
|
||||
+qsev_guest_get_session_file(Object *obj, Error **errp)
|
||||
+{
|
||||
+ QSevGuestInfo *s = QSEV_GUEST_INFO(obj);
|
||||
+
|
||||
+ return s->session_file ? g_strdup(s->session_file) : NULL;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+qsev_guest_set_session_file(Object *obj, const char *value, Error **errp)
|
||||
+{
|
||||
+ QSevGuestInfo *s = QSEV_GUEST_INFO(obj);
|
||||
+
|
||||
+ s->session_file = g_strdup(value);
|
||||
+}
|
||||
+
|
||||
+static char *
|
||||
+qsev_guest_get_dh_cert_file(Object *obj, Error **errp)
|
||||
+{
|
||||
+ QSevGuestInfo *s = QSEV_GUEST_INFO(obj);
|
||||
+
|
||||
+ return g_strdup(s->dh_cert_file);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+qsev_guest_set_dh_cert_file(Object *obj, const char *value, Error **errp)
|
||||
+{
|
||||
+ QSevGuestInfo *s = QSEV_GUEST_INFO(obj);
|
||||
+
|
||||
+ s->dh_cert_file = g_strdup(value);
|
||||
+}
|
||||
+
|
||||
+static char *
|
||||
+qsev_guest_get_sev_device(Object *obj, Error **errp)
|
||||
+{
|
||||
+ QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
|
||||
+
|
||||
+ return g_strdup(sev->sev_device);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+qsev_guest_set_sev_device(Object *obj, const char *value, Error **errp)
|
||||
+{
|
||||
+ QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
|
||||
+
|
||||
+ sev->sev_device = g_strdup(value);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+qsev_guest_class_init(ObjectClass *oc, void *data)
|
||||
+{
|
||||
+ object_class_property_add_str(oc, "sev-device",
|
||||
+ qsev_guest_get_sev_device,
|
||||
+ qsev_guest_set_sev_device,
|
||||
+ NULL);
|
||||
+ object_class_property_set_description(oc, "sev-device",
|
||||
+ "SEV device to use", NULL);
|
||||
+ object_class_property_add_str(oc, "dh-cert-file",
|
||||
+ qsev_guest_get_dh_cert_file,
|
||||
+ qsev_guest_set_dh_cert_file,
|
||||
+ NULL);
|
||||
+ object_class_property_set_description(oc, "dh-cert-file",
|
||||
+ "guest owners DH certificate (encoded with base64)", NULL);
|
||||
+ object_class_property_add_str(oc, "session-file",
|
||||
+ qsev_guest_get_session_file,
|
||||
+ qsev_guest_set_session_file,
|
||||
+ NULL);
|
||||
+ object_class_property_set_description(oc, "session-file",
|
||||
+ "guest owners session parameters (encoded with base64)", NULL);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+qsev_guest_set_handle(Object *obj, Visitor *v, const char *name,
|
||||
+ void *opaque, Error **errp)
|
||||
+{
|
||||
+ QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
|
||||
+ uint32_t value;
|
||||
+
|
||||
+ visit_type_uint32(v, name, &value, errp);
|
||||
+ sev->handle = value;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+qsev_guest_set_policy(Object *obj, Visitor *v, const char *name,
|
||||
+ void *opaque, Error **errp)
|
||||
+{
|
||||
+ QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
|
||||
+ uint32_t value;
|
||||
+
|
||||
+ visit_type_uint32(v, name, &value, errp);
|
||||
+ sev->policy = value;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+qsev_guest_set_cbitpos(Object *obj, Visitor *v, const char *name,
|
||||
+ void *opaque, Error **errp)
|
||||
+{
|
||||
+ QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
|
||||
+ uint32_t value;
|
||||
+
|
||||
+ visit_type_uint32(v, name, &value, errp);
|
||||
+ sev->cbitpos = value;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+qsev_guest_get_policy(Object *obj, Visitor *v, const char *name,
|
||||
+ void *opaque, Error **errp)
|
||||
+{
|
||||
+ uint32_t value;
|
||||
+ QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
|
||||
+
|
||||
+ value = sev->policy;
|
||||
+ visit_type_uint32(v, name, &value, errp);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+qsev_guest_get_handle(Object *obj, Visitor *v, const char *name,
|
||||
+ void *opaque, Error **errp)
|
||||
+{
|
||||
+ uint32_t value;
|
||||
+ QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
|
||||
+
|
||||
+ value = sev->handle;
|
||||
+ visit_type_uint32(v, name, &value, errp);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+qsev_guest_get_cbitpos(Object *obj, Visitor *v, const char *name,
|
||||
+ void *opaque, Error **errp)
|
||||
+{
|
||||
+ uint32_t value;
|
||||
+ QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
|
||||
+
|
||||
+ value = sev->cbitpos;
|
||||
+ visit_type_uint32(v, name, &value, errp);
|
||||
+}
|
||||
+
|
||||
+static uint32_t
|
||||
+sev_get_host_cbitpos(void)
|
||||
+{
|
||||
+ uint32_t ebx;
|
||||
+
|
||||
+ host_cpuid(0x8000001F, 0, NULL, &ebx, NULL, NULL);
|
||||
+
|
||||
+ return ebx & 0x3f;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+qsev_guest_init(Object *obj)
|
||||
+{
|
||||
+ QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
|
||||
+
|
||||
+ sev->sev_device = g_strdup(DEFAULT_SEV_DEVICE);
|
||||
+ sev->policy = DEFAULT_GUEST_POLICY;
|
||||
+ sev->cbitpos = sev_get_host_cbitpos();
|
||||
+ object_property_add(obj, "policy", "uint32", qsev_guest_get_policy,
|
||||
+ qsev_guest_set_policy, NULL, NULL, NULL);
|
||||
+ object_property_add(obj, "handle", "uint32", qsev_guest_get_handle,
|
||||
+ qsev_guest_set_handle, NULL, NULL, NULL);
|
||||
+ object_property_add(obj, "cbitpos", "uint32", qsev_guest_get_cbitpos,
|
||||
+ qsev_guest_set_cbitpos, NULL, NULL, NULL);
|
||||
+}
|
||||
+
|
||||
+/* sev guest info */
|
||||
+static const TypeInfo qsev_guest_info = {
|
||||
+ .parent = TYPE_OBJECT,
|
||||
+ .name = TYPE_QSEV_GUEST_INFO,
|
||||
+ .instance_size = sizeof(QSevGuestInfo),
|
||||
+ .instance_finalize = qsev_guest_finalize,
|
||||
+ .class_size = sizeof(QSevGuestInfoClass),
|
||||
+ .class_init = qsev_guest_class_init,
|
||||
+ .instance_init = qsev_guest_init,
|
||||
+ .interfaces = (InterfaceInfo[]) {
|
||||
+ { TYPE_USER_CREATABLE },
|
||||
+ { }
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+static void
|
||||
+sev_register_types(void)
|
||||
+{
|
||||
+ type_register_static(&qsev_guest_info);
|
||||
+}
|
||||
+
|
||||
+type_init(sev_register_types);
|
||||
diff --git a/docs/amd-memory-encryption.txt b/docs/amd-memory-encryption.txt
|
||||
index 72a92b6c63..1527f603ea 100644
|
||||
--- a/docs/amd-memory-encryption.txt
|
||||
+++ b/docs/amd-memory-encryption.txt
|
||||
@@ -35,10 +35,21 @@ in bad measurement). The guest policy is a 4-byte data structure containing
|
||||
several flags that restricts what can be done on running SEV guest.
|
||||
See KM Spec section 3 and 6.2 for more details.
|
||||
|
||||
+The guest policy can be provided via the 'policy' property (see below)
|
||||
+
|
||||
+# ${QEMU} \
|
||||
+ sev-guest,id=sev0,policy=0x1...\
|
||||
+
|
||||
Guest owners provided DH certificate and session parameters will be used to
|
||||
establish a cryptographic session with the guest owner to negotiate keys used
|
||||
for the attestation.
|
||||
|
||||
+The DH certificate and session blob can be provided via 'dh-cert-file' and
|
||||
+'session-file' property (see below
|
||||
+
|
||||
+# ${QEMU} \
|
||||
+ sev-guest,id=sev0,dh-cert-file=<file1>,session-file=<file2>
|
||||
+
|
||||
LAUNCH_UPDATE_DATA encrypts the memory region using the cryptographic context
|
||||
created via LAUNCH_START command. If required, this command can be called
|
||||
multiple times to encrypt different memory regions. The command also calculates
|
||||
@@ -59,6 +70,12 @@ context.
|
||||
See SEV KM API Spec [1] 'Launching a guest' usage flow (Appendix A) for the
|
||||
complete flow chart.
|
||||
|
||||
+To launch a SEV guest
|
||||
+
|
||||
+# ${QEMU} \
|
||||
+ -machine ...,memory-encryption=sev0 \
|
||||
+ -object sev-guest,id=sev0
|
||||
+
|
||||
Debugging
|
||||
-----------
|
||||
Since memory contents of SEV guest is encrypted hence hypervisor access to the
|
||||
diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h
|
||||
new file mode 100644
|
||||
index 0000000000..eed679653d
|
||||
--- /dev/null
|
||||
+++ b/include/sysemu/sev.h
|
||||
@@ -0,0 +1,54 @@
|
||||
+/*
|
||||
+ * QEMU Secure Encrypted Virutualization (SEV) support
|
||||
+ *
|
||||
+ * Copyright: Advanced Micro Devices, 2016-2018
|
||||
+ *
|
||||
+ * Authors:
|
||||
+ * Brijesh Singh <brijesh.singh@amd.com>
|
||||
+ *
|
||||
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||||
+ * See the COPYING file in the top-level directory.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#ifndef QEMU_SEV_H
|
||||
+#define QEMU_SEV_H
|
||||
+
|
||||
+#include "qom/object.h"
|
||||
+#include "qapi/error.h"
|
||||
+#include "sysemu/kvm.h"
|
||||
+#include "qemu/error-report.h"
|
||||
+
|
||||
+#define TYPE_QSEV_GUEST_INFO "sev-guest"
|
||||
+#define QSEV_GUEST_INFO(obj) \
|
||||
+ OBJECT_CHECK(QSevGuestInfo, (obj), TYPE_QSEV_GUEST_INFO)
|
||||
+
|
||||
+typedef struct QSevGuestInfo QSevGuestInfo;
|
||||
+typedef struct QSevGuestInfoClass QSevGuestInfoClass;
|
||||
+
|
||||
+/**
|
||||
+ * QSevGuestInfo:
|
||||
+ *
|
||||
+ * The QSevGuestInfo object is used for creating a SEV guest.
|
||||
+ *
|
||||
+ * # $QEMU \
|
||||
+ * -object sev-guest,id=sev0 \
|
||||
+ * -machine ...,memory-encryption=sev0
|
||||
+ */
|
||||
+struct QSevGuestInfo {
|
||||
+ Object parent_obj;
|
||||
+
|
||||
+ char *sev_device;
|
||||
+ uint32_t policy;
|
||||
+ uint32_t handle;
|
||||
+ char *dh_cert_file;
|
||||
+ char *session_file;
|
||||
+ uint32_t cbitpos;
|
||||
+};
|
||||
+
|
||||
+struct QSevGuestInfoClass {
|
||||
+ ObjectClass parent_class;
|
||||
+};
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
diff --git a/qemu-options.hx b/qemu-options.hx
|
||||
index 5385832707..5acf180991 100644
|
||||
--- a/qemu-options.hx
|
||||
+++ b/qemu-options.hx
|
||||
@@ -4470,6 +4470,42 @@ contents of @code{iv.b64} to the second secret
|
||||
data=$SECRET,iv=$(<iv.b64)
|
||||
@end example
|
||||
|
||||
+@item -object sev-guest,id=@var{id},sev-device=@var{string}[cbitpos=@var{cbitpos},policy=@var{policy},handle=@var{handle},dh-cert-file=@var{file},session-file=@var{file}]
|
||||
+
|
||||
+Create a Secure Encrypted Virtualization (SEV) guest object, which can be used
|
||||
+to provide the guest memory encryption support on AMD processors.
|
||||
+
|
||||
+The @option{sev-device} provides the device file to use for communicating with
|
||||
+the SEV firmware running inside AMD Secure Processor. The default device is
|
||||
+'/dev/sev'. If hardware supports memory encryption then /dev/sev devices are
|
||||
+created by CCP driver.
|
||||
+
|
||||
+The @option{cbitpos} provide the C-bit location in guest page table entry to use.
|
||||
+
|
||||
+The @option{policy} provides the guest policy to be enforced by the SEV firmware
|
||||
+and restrict what configuration and operational commands can be performed on this
|
||||
+guest by the hypervisor. The policy should be provided by the guest owner and is
|
||||
+bound to the guest and cannot be changed throughout the lifetime of the guest.
|
||||
+The default is 0.
|
||||
+
|
||||
+If guest @option{policy} allows sharing the key with another SEV guest then
|
||||
+@option{handle} can be use to provide handle of the guest from which to share
|
||||
+the key.
|
||||
+
|
||||
+The @option{dh-cert-file} and @option{session-file} provides the guest owner's
|
||||
+Public Diffie-Hillman key defined in SEV spec. The PDH and session parameters
|
||||
+are used for establishing a cryptographic session with the guest owner to
|
||||
+negotiate keys used for attestation. The file must be encoded in base64.
|
||||
+
|
||||
+e.g to launch a SEV guest
|
||||
+@example
|
||||
+ # $QEMU \
|
||||
+ ......
|
||||
+ -object sev-guest,id=sev0 \
|
||||
+ -machine ...,memory-encryption=sev0
|
||||
+ .....
|
||||
+
|
||||
+@end example
|
||||
@end table
|
||||
|
||||
ETEXI
|
349
0055-sev-add-command-to-initialize-the-m.patch
Normal file
349
0055-sev-add-command-to-initialize-the-m.patch
Normal file
@ -0,0 +1,349 @@
|
||||
From 8ed2f96e975993d82495273bca7be2e6a8eb81ed Mon Sep 17 00:00:00 2001
|
||||
From: Brijesh Singh <brijesh.singh@amd.com>
|
||||
Date: Tue, 6 Feb 2018 19:08:08 -0600
|
||||
Subject: [PATCH] sev: add command to initialize the memory encryption context
|
||||
|
||||
When memory encryption is enabled, KVM_SEV_INIT command is used to
|
||||
initialize the platform. The command loads the SEV related persistent
|
||||
data from non-volatile storage and initializes the platform context.
|
||||
This command should be first issued before invoking any other guest
|
||||
commands provided by the SEV firmware.
|
||||
|
||||
Cc: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
|
||||
[BR: FATE#322124]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
accel/kvm/kvm-all.c | 15 +++++
|
||||
accel/kvm/sev.c | 161 +++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
accel/kvm/trace-events | 2 +
|
||||
accel/stubs/kvm-stub.c | 28 +++++++++
|
||||
include/sysemu/sev.h | 16 +++++
|
||||
5 files changed, 222 insertions(+)
|
||||
|
||||
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
|
||||
index f290f487a5..6e5f3fd650 100644
|
||||
--- a/accel/kvm/kvm-all.c
|
||||
+++ b/accel/kvm/kvm-all.c
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "qemu/event_notifier.h"
|
||||
#include "trace.h"
|
||||
#include "hw/irq.h"
|
||||
+#include "sysemu/sev.h"
|
||||
|
||||
#include "hw/boards.h"
|
||||
|
||||
@@ -103,6 +104,9 @@ struct KVMState
|
||||
#endif
|
||||
KVMMemoryListener memory_listener;
|
||||
QLIST_HEAD(, KVMParkedVcpu) kvm_parked_vcpus;
|
||||
+
|
||||
+ /* memory encryption */
|
||||
+ void *memcrypt_handle;
|
||||
};
|
||||
|
||||
KVMState *kvm_state;
|
||||
@@ -1632,6 +1636,17 @@ static int kvm_init(MachineState *ms)
|
||||
|
||||
kvm_state = s;
|
||||
|
||||
+ /*
|
||||
+ * if memory encryption object is specified then initialize the memory
|
||||
+ * encryption context.
|
||||
+ */
|
||||
+ if (ms->memory_encryption) {
|
||||
+ kvm_state->memcrypt_handle = sev_guest_init(ms->memory_encryption);
|
||||
+ if (!kvm_state->memcrypt_handle) {
|
||||
+ goto err;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
ret = kvm_arch_init(ms, s);
|
||||
if (ret < 0) {
|
||||
goto err;
|
||||
diff --git a/accel/kvm/sev.c b/accel/kvm/sev.c
|
||||
index 57e092a0bd..d5fd975792 100644
|
||||
--- a/accel/kvm/sev.c
|
||||
+++ b/accel/kvm/sev.c
|
||||
@@ -18,10 +18,74 @@
|
||||
#include "sysemu/kvm.h"
|
||||
#include "sysemu/sev.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
+#include "trace.h"
|
||||
|
||||
#define DEFAULT_GUEST_POLICY 0x1 /* disable debug */
|
||||
#define DEFAULT_SEV_DEVICE "/dev/sev"
|
||||
|
||||
+static uint64_t me_mask;
|
||||
+static bool sev_active;
|
||||
+static int sev_fd;
|
||||
+
|
||||
+#define SEV_FW_MAX_ERROR 0x17
|
||||
+
|
||||
+static const char *const sev_fw_errlist[] = {
|
||||
+ "",
|
||||
+ "Platform state is invalid",
|
||||
+ "Guest state is invalid",
|
||||
+ "Platform configuration is invalid",
|
||||
+ "Buffer too small",
|
||||
+ "Platform is already owned",
|
||||
+ "Certificate is invalid",
|
||||
+ "Policy is not allowed",
|
||||
+ "Guest is not active",
|
||||
+ "Invalid address",
|
||||
+ "Bad signature",
|
||||
+ "Bad measurement",
|
||||
+ "Asid is already owned",
|
||||
+ "Invalid ASID",
|
||||
+ "WBINVD is required",
|
||||
+ "DF_FLUSH is required",
|
||||
+ "Guest handle is invalid",
|
||||
+ "Invalid command",
|
||||
+ "Guest is active",
|
||||
+ "Hardware error",
|
||||
+ "Hardware unsafe",
|
||||
+ "Feature not supported",
|
||||
+ "Invalid parameter"
|
||||
+};
|
||||
+
|
||||
+static int
|
||||
+sev_ioctl(int cmd, void *data, int *error)
|
||||
+{
|
||||
+ int r;
|
||||
+ struct kvm_sev_cmd input;
|
||||
+
|
||||
+ memset(&input, 0x0, sizeof(input));
|
||||
+
|
||||
+ input.id = cmd;
|
||||
+ input.sev_fd = sev_fd;
|
||||
+ input.data = (__u64)data;
|
||||
+
|
||||
+ r = kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_OP, &input);
|
||||
+
|
||||
+ if (error) {
|
||||
+ *error = input.error;
|
||||
+ }
|
||||
+
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
+static const char *
|
||||
+fw_error_to_str(int code)
|
||||
+{
|
||||
+ if (code >= SEV_FW_MAX_ERROR) {
|
||||
+ return "unknown error";
|
||||
+ }
|
||||
+
|
||||
+ return sev_fw_errlist[code];
|
||||
+}
|
||||
+
|
||||
static void
|
||||
qsev_guest_finalize(Object *obj)
|
||||
{
|
||||
@@ -205,6 +269,103 @@ static const TypeInfo qsev_guest_info = {
|
||||
}
|
||||
};
|
||||
|
||||
+static QSevGuestInfo *
|
||||
+lookup_sev_guest_info(const char *id)
|
||||
+{
|
||||
+ Object *obj;
|
||||
+ QSevGuestInfo *info;
|
||||
+
|
||||
+ obj = object_resolve_path_component(object_get_objects_root(), id);
|
||||
+ if (!obj) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ info = (QSevGuestInfo *)
|
||||
+ object_dynamic_cast(obj, TYPE_QSEV_GUEST_INFO);
|
||||
+ if (!info) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ return info;
|
||||
+}
|
||||
+
|
||||
+uint64_t
|
||||
+sev_get_me_mask(void)
|
||||
+{
|
||||
+ return ~me_mask;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+sev_get_current_state(char **state)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+bool
|
||||
+sev_enabled(void)
|
||||
+{
|
||||
+ return sev_active;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+sev_get_fw_version(uint8_t *major, uint8_t *minor, uint8_t *build)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+sev_get_policy(uint32_t *policy)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+void *
|
||||
+sev_guest_init(const char *id)
|
||||
+{
|
||||
+ SEVState *s;
|
||||
+ char *devname;
|
||||
+ int ret, fw_error;
|
||||
+ uint32_t host_cbitpos, cbitpos;
|
||||
+
|
||||
+ s = g_new0(SEVState, 1);
|
||||
+ s->sev_info = lookup_sev_guest_info(id);
|
||||
+ if (!s->sev_info) {
|
||||
+ error_report("%s: '%s' is not a valid '%s' object",
|
||||
+ __func__, id, TYPE_QSEV_GUEST_INFO);
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ host_cbitpos = sev_get_host_cbitpos();
|
||||
+ cbitpos = object_property_get_int(OBJECT(s->sev_info), "cbitpos", NULL);
|
||||
+ if (host_cbitpos != cbitpos) {
|
||||
+ error_report("%s: cbitpos check failed, host '%d' request '%d'",
|
||||
+ __func__, host_cbitpos, cbitpos);
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ me_mask = (1UL << cbitpos);
|
||||
+
|
||||
+ devname = object_property_get_str(OBJECT(s->sev_info), "sev-device", NULL);
|
||||
+ sev_fd = open(devname, O_RDWR);
|
||||
+ if (sev_fd < 0) {
|
||||
+ error_report("%s: Failed to open %s '%s'", __func__,
|
||||
+ devname, strerror(errno));
|
||||
+ goto err;
|
||||
+ }
|
||||
+ g_free(devname);
|
||||
+
|
||||
+ trace_kvm_sev_init();
|
||||
+ ret = sev_ioctl(KVM_SEV_INIT, NULL, &fw_error);
|
||||
+ if (ret) {
|
||||
+ error_report("%s: failed to initialize ret=%d fw_error=%d '%s'",
|
||||
+ __func__, ret, fw_error, fw_error_to_str(fw_error));
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ sev_active = true;
|
||||
+ return s;
|
||||
+err:
|
||||
+ g_free(s);
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
sev_register_types(void)
|
||||
{
|
||||
diff --git a/accel/kvm/trace-events b/accel/kvm/trace-events
|
||||
index f89ba5578d..ea487e5a59 100644
|
||||
--- a/accel/kvm/trace-events
|
||||
+++ b/accel/kvm/trace-events
|
||||
@@ -13,3 +13,5 @@ kvm_irqchip_add_msi_route(char *name, int vector, int virq) "dev %s vector %d vi
|
||||
kvm_irqchip_update_msi_route(int virq) "Updating MSI route virq=%d"
|
||||
kvm_irqchip_release_virq(int virq) "virq %d"
|
||||
|
||||
+# sev.c
|
||||
+kvm_sev_init(void) ""
|
||||
diff --git a/accel/stubs/kvm-stub.c b/accel/stubs/kvm-stub.c
|
||||
index c964af3e1c..bb78a1f1b9 100644
|
||||
--- a/accel/stubs/kvm-stub.c
|
||||
+++ b/accel/stubs/kvm-stub.c
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "qemu-common.h"
|
||||
#include "cpu.h"
|
||||
#include "sysemu/kvm.h"
|
||||
+#include "sysemu/sev.h"
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
#include "hw/pci/msi.h"
|
||||
@@ -33,6 +34,11 @@ bool kvm_readonly_mem_allowed;
|
||||
bool kvm_ioeventfd_any_length_allowed;
|
||||
bool kvm_msi_use_devid;
|
||||
|
||||
+bool sev_allowed;
|
||||
+uint8_t sev_fw_major;
|
||||
+uint8_t sev_fw_minor;
|
||||
+uint8_t sev_fw_build;
|
||||
+
|
||||
int kvm_destroy_vcpu(CPUState *cpu)
|
||||
{
|
||||
return -ENOSYS;
|
||||
@@ -105,6 +111,28 @@ int kvm_on_sigbus(int code, void *addr)
|
||||
return 1;
|
||||
}
|
||||
|
||||
+void sev_get_current_state(char **state)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+bool sev_enabled(void)
|
||||
+{
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+uint64_t sev_get_me_mask(void)
|
||||
+{
|
||||
+ return ~0UL;
|
||||
+}
|
||||
+
|
||||
+void sev_get_fw_version(uint8_t *major, uint8_t *minor, uint8_t *build)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+void sev_get_policy(uint32_t *policy)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
int kvm_irqchip_add_msi_route(KVMState *s, int vector, PCIDevice *dev)
|
||||
{
|
||||
diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h
|
||||
index eed679653d..121e7e4aa4 100644
|
||||
--- a/include/sysemu/sev.h
|
||||
+++ b/include/sysemu/sev.h
|
||||
@@ -14,6 +14,8 @@
|
||||
#ifndef QEMU_SEV_H
|
||||
#define QEMU_SEV_H
|
||||
|
||||
+#include <linux/kvm.h>
|
||||
+
|
||||
#include "qom/object.h"
|
||||
#include "qapi/error.h"
|
||||
#include "sysemu/kvm.h"
|
||||
@@ -23,6 +25,12 @@
|
||||
#define QSEV_GUEST_INFO(obj) \
|
||||
OBJECT_CHECK(QSevGuestInfo, (obj), TYPE_QSEV_GUEST_INFO)
|
||||
|
||||
+extern bool sev_enabled(void);
|
||||
+extern uint64_t sev_get_me_mask(void);
|
||||
+extern void sev_get_current_state(char **state);
|
||||
+extern void sev_get_fw_version(uint8_t *major, uint8_t *minor, uint8_t *build);
|
||||
+extern void sev_get_policy(uint32_t *policy);
|
||||
+
|
||||
typedef struct QSevGuestInfo QSevGuestInfo;
|
||||
typedef struct QSevGuestInfoClass QSevGuestInfoClass;
|
||||
|
||||
@@ -50,5 +58,13 @@ struct QSevGuestInfoClass {
|
||||
ObjectClass parent_class;
|
||||
};
|
||||
|
||||
+struct SEVState {
|
||||
+ QSevGuestInfo *sev_info;
|
||||
+};
|
||||
+
|
||||
+typedef struct SEVState SEVState;
|
||||
+
|
||||
+void *sev_guest_init(const char *id);
|
||||
+
|
||||
#endif
|
||||
|
94
0056-sev-register-the-guest-memory-range.patch
Normal file
94
0056-sev-register-the-guest-memory-range.patch
Normal file
@ -0,0 +1,94 @@
|
||||
From 127890da09ac0ebb4945f52b0e23e582d93fc698 Mon Sep 17 00:00:00 2001
|
||||
From: Brijesh Singh <brijesh.singh@amd.com>
|
||||
Date: Tue, 6 Feb 2018 19:08:09 -0600
|
||||
Subject: [PATCH] sev: register the guest memory range which may contain
|
||||
encrypted data
|
||||
|
||||
When SEV is enabled, the hardware encryption engine uses a tweak such
|
||||
that the two identical plaintext at different location will have a
|
||||
different ciphertexts. So swapping or moving a ciphertexts of two guest
|
||||
pages will not result in plaintexts being swapped. Hence relocating
|
||||
a physical backing pages of the SEV guest will require some additional
|
||||
steps in KVM driver. The KVM_MEMORY_ENCRYPT_{UN,}REG_REGION ioctl can be
|
||||
used to register/unregister the guest memory region which may contain the
|
||||
encrypted data. KVM driver will internally handle the relocating physical
|
||||
backing pages of registered memory regions.
|
||||
|
||||
Cc: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
|
||||
[BR: FATE#322124]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
accel/kvm/sev.c | 41 +++++++++++++++++++++++++++++++++++++++++
|
||||
accel/kvm/trace-events | 2 ++
|
||||
2 files changed, 43 insertions(+)
|
||||
|
||||
diff --git a/accel/kvm/sev.c b/accel/kvm/sev.c
|
||||
index d5fd975792..2c4bbba3c3 100644
|
||||
--- a/accel/kvm/sev.c
|
||||
+++ b/accel/kvm/sev.c
|
||||
@@ -86,6 +86,45 @@ fw_error_to_str(int code)
|
||||
return sev_fw_errlist[code];
|
||||
}
|
||||
|
||||
+static void
|
||||
+sev_ram_block_added(RAMBlockNotifier *n, void *host, size_t size)
|
||||
+{
|
||||
+ int r;
|
||||
+ struct kvm_enc_region range;
|
||||
+
|
||||
+ range.addr = (__u64)host;
|
||||
+ range.size = size;
|
||||
+
|
||||
+ trace_kvm_memcrypt_register_region(host, size);
|
||||
+ r = kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_REG_REGION, &range);
|
||||
+ if (r) {
|
||||
+ error_report("%s: failed to register region (%p+%#lx)",
|
||||
+ __func__, host, size);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+sev_ram_block_removed(RAMBlockNotifier *n, void *host, size_t size)
|
||||
+{
|
||||
+ int r;
|
||||
+ struct kvm_enc_region range;
|
||||
+
|
||||
+ range.addr = (__u64)host;
|
||||
+ range.size = size;
|
||||
+
|
||||
+ trace_kvm_memcrypt_unregister_region(host, size);
|
||||
+ r = kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_UNREG_REGION, &range);
|
||||
+ if (r) {
|
||||
+ error_report("%s: failed to unregister region (%p+%#lx)",
|
||||
+ __func__, host, size);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static struct RAMBlockNotifier sev_ram_notifier = {
|
||||
+ .ram_block_added = sev_ram_block_added,
|
||||
+ .ram_block_removed = sev_ram_block_removed,
|
||||
+};
|
||||
+
|
||||
static void
|
||||
qsev_guest_finalize(Object *obj)
|
||||
{
|
||||
@@ -360,6 +399,8 @@ sev_guest_init(const char *id)
|
||||
}
|
||||
|
||||
sev_active = true;
|
||||
+ ram_block_notifier_add(&sev_ram_notifier);
|
||||
+
|
||||
return s;
|
||||
err:
|
||||
g_free(s);
|
||||
diff --git a/accel/kvm/trace-events b/accel/kvm/trace-events
|
||||
index ea487e5a59..364c84bd7a 100644
|
||||
--- a/accel/kvm/trace-events
|
||||
+++ b/accel/kvm/trace-events
|
||||
@@ -15,3 +15,5 @@ kvm_irqchip_release_virq(int virq) "virq %d"
|
||||
|
||||
# sev.c
|
||||
kvm_sev_init(void) ""
|
||||
+kvm_memcrypt_register_region(void *addr, size_t len) "addr %p len 0x%lu"
|
||||
+kvm_memcrypt_unregister_region(void *addr, size_t len) "addr %p len 0x%lu"
|
129
0057-kvm-introduce-memory-encryption-API.patch
Normal file
129
0057-kvm-introduce-memory-encryption-API.patch
Normal file
@ -0,0 +1,129 @@
|
||||
From f2a1359c865cf33fc5960e1b9e6912827075f567 Mon Sep 17 00:00:00 2001
|
||||
From: Brijesh Singh <brijesh.singh@amd.com>
|
||||
Date: Tue, 6 Feb 2018 19:08:09 -0600
|
||||
Subject: [PATCH] kvm: introduce memory encryption APIs
|
||||
|
||||
Inorder to integerate the Secure Encryption Virtualization (SEV) support
|
||||
add few high-level memory encryption APIs which can be used for encrypting
|
||||
the guest memory region.
|
||||
|
||||
Cc: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Cc: kvm@vger.kernel.org
|
||||
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
|
||||
[BR: FATE#322124]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
accel/kvm/kvm-all.c | 30 ++++++++++++++++++++++++++++++
|
||||
accel/stubs/kvm-stub.c | 14 ++++++++++++++
|
||||
include/sysemu/kvm.h | 25 +++++++++++++++++++++++++
|
||||
3 files changed, 69 insertions(+)
|
||||
|
||||
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
|
||||
index 6e5f3fd650..f1fb826f06 100644
|
||||
--- a/accel/kvm/kvm-all.c
|
||||
+++ b/accel/kvm/kvm-all.c
|
||||
@@ -107,6 +107,8 @@ struct KVMState
|
||||
|
||||
/* memory encryption */
|
||||
void *memcrypt_handle;
|
||||
+ int (*memcrypt_encrypt_data)(void *handle, uint8_t *ptr, uint64_t len);
|
||||
+ void (*memcrypt_debug_ops)(void *handle, MemoryRegion *mr);
|
||||
};
|
||||
|
||||
KVMState *kvm_state;
|
||||
@@ -142,6 +144,34 @@ int kvm_get_max_memslots(void)
|
||||
return s->nr_slots;
|
||||
}
|
||||
|
||||
+bool kvm_memcrypt_enabled(void)
|
||||
+{
|
||||
+ if (kvm_state && kvm_state->memcrypt_handle) {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+int kvm_memcrypt_encrypt_data(uint8_t *ptr, uint64_t len)
|
||||
+{
|
||||
+ if (kvm_state->memcrypt_handle &&
|
||||
+ kvm_state->memcrypt_encrypt_data) {
|
||||
+ return kvm_state->memcrypt_encrypt_data(kvm_state->memcrypt_handle,
|
||||
+ ptr, len);
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+void kvm_memcrypt_set_debug_ops(MemoryRegion *mr)
|
||||
+{
|
||||
+ if (kvm_state->memcrypt_handle &&
|
||||
+ kvm_state->memcrypt_debug_ops) {
|
||||
+ kvm_state->memcrypt_debug_ops(kvm_state->memcrypt_handle, mr);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static KVMSlot *kvm_get_free_slot(KVMMemoryListener *kml)
|
||||
{
|
||||
KVMState *s = kvm_state;
|
||||
diff --git a/accel/stubs/kvm-stub.c b/accel/stubs/kvm-stub.c
|
||||
index bb78a1f1b9..e7d579e3e5 100644
|
||||
--- a/accel/stubs/kvm-stub.c
|
||||
+++ b/accel/stubs/kvm-stub.c
|
||||
@@ -133,6 +133,20 @@ void sev_get_policy(uint32_t *policy)
|
||||
{
|
||||
}
|
||||
|
||||
+bool kvm_memcrypt_enabled(void)
|
||||
+{
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+int kvm_memcrypt_encrypt_data(uint8_t *ptr, uint64_t len)
|
||||
+{
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+void kvm_memcrypt_set_debug_ops(MemoryRegion *mr)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
int kvm_irqchip_add_msi_route(KVMState *s, int vector, PCIDevice *dev)
|
||||
{
|
||||
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
|
||||
index bbf12a1723..4a5db5dde3 100644
|
||||
--- a/include/sysemu/kvm.h
|
||||
+++ b/include/sysemu/kvm.h
|
||||
@@ -231,6 +231,31 @@ int kvm_destroy_vcpu(CPUState *cpu);
|
||||
*/
|
||||
bool kvm_arm_supports_user_irq(void);
|
||||
|
||||
+/**
|
||||
+ * kvm_memcrypt_enabled - return boolean indicating whether memory encryption
|
||||
+ * is enabled
|
||||
+ * Returns: 1 memory encryption is enabled
|
||||
+ * 0 memory encryption is disabled
|
||||
+ */
|
||||
+bool kvm_memcrypt_enabled(void);
|
||||
+
|
||||
+/**
|
||||
+ * kvm_memcrypt_encrypt_data: encrypt the memory range
|
||||
+ *
|
||||
+ * Return: 1 failed to encrypt the range
|
||||
+ * 0 succesfully encrypted memory region
|
||||
+ */
|
||||
+int kvm_memcrypt_encrypt_data(uint8_t *ptr, uint64_t len);
|
||||
+
|
||||
+/**
|
||||
+ * kvm_memcrypt_set_debug_ram_ops: set debug_ram_ops callback
|
||||
+ *
|
||||
+ * When debug_ram_ops is set, debug access to this memory region will use
|
||||
+ * memory encryption APIs.
|
||||
+ */
|
||||
+void kvm_memcrypt_set_debug_ops(MemoryRegion *mr);
|
||||
+
|
||||
+
|
||||
#ifdef NEED_CPU_H
|
||||
#include "cpu.h"
|
||||
|
108
0058-qmp-add-query-sev-command.patch
Normal file
108
0058-qmp-add-query-sev-command.patch
Normal file
@ -0,0 +1,108 @@
|
||||
From 839e76e0c43407cff82395ee6d4e3eb94fd07fa3 Mon Sep 17 00:00:00 2001
|
||||
From: Brijesh Singh <brijesh.singh@amd.com>
|
||||
Date: Tue, 6 Feb 2018 19:08:09 -0600
|
||||
Subject: [PATCH] qmp: add query-sev command
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The QMP query command can used to retrieve the SEV information when
|
||||
memory encryption is enabled on AMD platform.
|
||||
|
||||
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
|
||||
Cc: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
|
||||
Cc: Markus Armbruster <armbru@redhat.com>
|
||||
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
|
||||
[BR: FATE#322124]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
qapi-schema.json | 47 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
qmp.c | 16 ++++++++++++++++
|
||||
2 files changed, 63 insertions(+)
|
||||
|
||||
diff --git a/qapi-schema.json b/qapi-schema.json
|
||||
index 18457954a8..40c2de3026 100644
|
||||
--- a/qapi-schema.json
|
||||
+++ b/qapi-schema.json
|
||||
@@ -3200,3 +3200,50 @@
|
||||
# Since: 2.11
|
||||
##
|
||||
{ 'command': 'watchdog-set-action', 'data' : {'action': 'WatchdogAction'} }
|
||||
+
|
||||
+##
|
||||
+# @SevInfo:
|
||||
+#
|
||||
+# Information about SEV support
|
||||
+#
|
||||
+# @enabled: true if SEV is active
|
||||
+#
|
||||
+# @api_major: SEV API major version
|
||||
+#
|
||||
+# @api_minor: SEV API minor version
|
||||
+#
|
||||
+# @build_id: SEV FW build id
|
||||
+#
|
||||
+# @policy: SEV policy value
|
||||
+#
|
||||
+# @state: SEV guest state
|
||||
+#
|
||||
+# Since: 2.12
|
||||
+##
|
||||
+{ 'struct': 'SevInfo',
|
||||
+ 'data': { 'enabled': 'bool',
|
||||
+ 'api_major': 'uint8',
|
||||
+ 'api_minor' : 'uint8',
|
||||
+ 'build_id' : 'uint8',
|
||||
+ 'policy' : 'uint32',
|
||||
+ 'state' : 'str'
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+##
|
||||
+# @query-sev:
|
||||
+#
|
||||
+# Returns information about SEV
|
||||
+#
|
||||
+# Returns: @SevInfo
|
||||
+#
|
||||
+# Since: 2.12
|
||||
+#
|
||||
+# Example:
|
||||
+#
|
||||
+# -> { "execute": "query-sev" }
|
||||
+# <- { "return": { "enabled": true, "api-major" : 0, "api-minor" : 0,
|
||||
+# "build-id" : 0, "policy" : 0, "state" : "running" } }
|
||||
+#
|
||||
+##
|
||||
+{ 'command': 'query-sev', 'returns': 'SevInfo' }
|
||||
diff --git a/qmp.c b/qmp.c
|
||||
index e8c303116a..4cd01ea666 100644
|
||||
--- a/qmp.c
|
||||
+++ b/qmp.c
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "qom/object_interfaces.h"
|
||||
#include "hw/mem/pc-dimm.h"
|
||||
#include "hw/acpi/acpi_dev_interface.h"
|
||||
+#include "sysemu/sev.h"
|
||||
|
||||
NameInfo *qmp_query_name(Error **errp)
|
||||
{
|
||||
@@ -722,3 +723,18 @@ MemoryInfo *qmp_query_memory_size_summary(Error **errp)
|
||||
|
||||
return mem_info;
|
||||
}
|
||||
+
|
||||
+SevInfo *qmp_query_sev(Error **errp)
|
||||
+{
|
||||
+ SevInfo *info = g_malloc0(sizeof(*info));
|
||||
+
|
||||
+ info->enabled = sev_enabled();
|
||||
+ if (info->enabled) {
|
||||
+ sev_get_fw_version(&info->api_major,
|
||||
+ &info->api_minor, &info->build_id);
|
||||
+ sev_get_policy(&info->policy);
|
||||
+ sev_get_current_state(&info->state);
|
||||
+ }
|
||||
+
|
||||
+ return info;
|
||||
+}
|
86
0059-hmp-add-info-sev-command.patch
Normal file
86
0059-hmp-add-info-sev-command.patch
Normal file
@ -0,0 +1,86 @@
|
||||
From d363eb37dad9acacbcd688f8275c16334ca69fbe Mon Sep 17 00:00:00 2001
|
||||
From: Brijesh Singh <brijesh.singh@amd.com>
|
||||
Date: Tue, 6 Feb 2018 19:08:09 -0600
|
||||
Subject: [PATCH] hmp: add 'info sev' command
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The command can be used to show the SEV information when memory
|
||||
encryption is enabled on AMD platform.
|
||||
|
||||
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
|
||||
Cc: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
|
||||
Cc: Markus Armbruster <armbru@redhat.com>
|
||||
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
|
||||
[BR: FATE#322124]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
hmp-commands-info.hx | 14 ++++++++++++++
|
||||
hmp.c | 19 +++++++++++++++++++
|
||||
hmp.h | 1 +
|
||||
3 files changed, 34 insertions(+)
|
||||
|
||||
diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
|
||||
index 54c3e5eac6..83491f84f6 100644
|
||||
--- a/hmp-commands-info.hx
|
||||
+++ b/hmp-commands-info.hx
|
||||
@@ -865,6 +865,20 @@ STEXI
|
||||
@findex info memory_size_summary
|
||||
Display the amount of initially allocated and present hotpluggable (if
|
||||
enabled) memory in bytes.
|
||||
+ETEXI
|
||||
+
|
||||
+ {
|
||||
+ .name = "sev",
|
||||
+ .args_type = "",
|
||||
+ .params = "",
|
||||
+ .help = "show SEV information",
|
||||
+ .cmd = hmp_info_sev,
|
||||
+ },
|
||||
+
|
||||
+STEXI
|
||||
+@item info sev
|
||||
+@findex info sev
|
||||
+Show SEV information.
|
||||
ETEXI
|
||||
|
||||
STEXI
|
||||
diff --git a/hmp.c b/hmp.c
|
||||
index 35a7041824..7214a904dd 100644
|
||||
--- a/hmp.c
|
||||
+++ b/hmp.c
|
||||
@@ -2918,3 +2918,22 @@ void hmp_info_memory_size_summary(Monitor *mon, const QDict *qdict)
|
||||
}
|
||||
hmp_handle_error(mon, &err);
|
||||
}
|
||||
+
|
||||
+void hmp_info_sev(Monitor *mon, const QDict *qdict)
|
||||
+{
|
||||
+ SevInfo *info;
|
||||
+
|
||||
+ info = qmp_query_sev(NULL);
|
||||
+ monitor_printf(mon, "sev support: ");
|
||||
+ monitor_printf(mon, "%s\n", info->enabled ? "enabled" : "disabled");
|
||||
+
|
||||
+ if (info->enabled) {
|
||||
+ monitor_printf(mon, "state: %s\n", info->state);
|
||||
+ monitor_printf(mon, "policy: 0x%x\n", info->policy);
|
||||
+ monitor_printf(mon, "build id: %u\n", info->build_id);
|
||||
+ monitor_printf(mon, "api version: %u.%u\n",
|
||||
+ info->api_major, info->api_minor);
|
||||
+ }
|
||||
+
|
||||
+ qapi_free_SevInfo(info);
|
||||
+}
|
||||
diff --git a/hmp.h b/hmp.h
|
||||
index a6f56b1f29..153f106be8 100644
|
||||
--- a/hmp.h
|
||||
+++ b/hmp.h
|
||||
@@ -147,5 +147,6 @@ void hmp_info_ramblock(Monitor *mon, const QDict *qdict);
|
||||
void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_memory_size_summary(Monitor *mon, const QDict *qdict);
|
||||
+void hmp_info_sev(Monitor *mon, const QDict *qdict);
|
||||
|
||||
#endif
|
189
0060-sev-add-command-to-create-launch-me.patch
Normal file
189
0060-sev-add-command-to-create-launch-me.patch
Normal file
@ -0,0 +1,189 @@
|
||||
From 5abfa90f247fb546167b2f3a8d201f10707cca30 Mon Sep 17 00:00:00 2001
|
||||
From: Brijesh Singh <brijesh.singh@amd.com>
|
||||
Date: Tue, 6 Feb 2018 19:08:09 -0600
|
||||
Subject: [PATCH] sev: add command to create launch memory encryption context
|
||||
|
||||
The KVM_SEV_LAUNCH_START command creates a new VM encryption key (VEK).
|
||||
The encryption key created with the command will be used for encrypting
|
||||
the bootstrap images (such as guest bios).
|
||||
|
||||
Cc: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Cc: kvm@vger.kernel.org
|
||||
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
|
||||
[BR: FATE#322124]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
accel/kvm/sev.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
accel/kvm/trace-events | 2 +
|
||||
include/sysemu/sev.h | 10 +++++
|
||||
3 files changed, 111 insertions(+)
|
||||
|
||||
diff --git a/accel/kvm/sev.c b/accel/kvm/sev.c
|
||||
index 2c4bbba3c3..2ecc6a1d1a 100644
|
||||
--- a/accel/kvm/sev.c
|
||||
+++ b/accel/kvm/sev.c
|
||||
@@ -29,6 +29,17 @@ static int sev_fd;
|
||||
|
||||
#define SEV_FW_MAX_ERROR 0x17
|
||||
|
||||
+static SevGuestState current_sev_guest_state = SEV_STATE_UNINIT;
|
||||
+
|
||||
+static const char *const sev_state_str[] = {
|
||||
+ "uninit",
|
||||
+ "lupdate",
|
||||
+ "secret",
|
||||
+ "running",
|
||||
+ "supdate",
|
||||
+ "rupdate",
|
||||
+};
|
||||
+
|
||||
static const char *const sev_fw_errlist[] = {
|
||||
"",
|
||||
"Platform state is invalid",
|
||||
@@ -86,6 +97,16 @@ fw_error_to_str(int code)
|
||||
return sev_fw_errlist[code];
|
||||
}
|
||||
|
||||
+static void
|
||||
+sev_set_guest_state(SevGuestState new_state)
|
||||
+{
|
||||
+ assert(new_state < SEV_STATE_MAX);
|
||||
+
|
||||
+ trace_kvm_sev_change_state(sev_state_str[current_sev_guest_state],
|
||||
+ sev_state_str[new_state]);
|
||||
+ current_sev_guest_state = new_state;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
sev_ram_block_added(RAMBlockNotifier *n, void *host, size_t size)
|
||||
{
|
||||
@@ -337,6 +358,7 @@ sev_get_me_mask(void)
|
||||
void
|
||||
sev_get_current_state(char **state)
|
||||
{
|
||||
+ *state = g_strdup(sev_state_str[current_sev_guest_state]);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -355,6 +377,76 @@ sev_get_policy(uint32_t *policy)
|
||||
{
|
||||
}
|
||||
|
||||
+static int
|
||||
+sev_read_file_base64(const char *filename, guchar **data, gsize *len)
|
||||
+{
|
||||
+ gsize sz;
|
||||
+ gchar *base64;
|
||||
+ GError *error = NULL;
|
||||
+
|
||||
+ if (!g_file_get_contents(filename, &base64, &sz, &error)) {
|
||||
+ error_report("failed to read '%s' (%s)", filename, error->message);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ *data = g_base64_decode(base64, len);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+sev_launch_start(SEVState *s)
|
||||
+{
|
||||
+ gsize sz;
|
||||
+ int ret = 1;
|
||||
+ int fw_error;
|
||||
+ QSevGuestInfo *sev = s->sev_info;
|
||||
+ struct kvm_sev_launch_start *start;
|
||||
+ guchar *session = NULL, *dh_cert = NULL;
|
||||
+
|
||||
+ start = g_malloc0(sizeof(*start));
|
||||
+ if (!start) {
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ start->handle = object_property_get_int(OBJECT(sev), "handle",
|
||||
+ &error_abort);
|
||||
+ start->policy = object_property_get_int(OBJECT(sev), "policy",
|
||||
+ &error_abort);
|
||||
+ if (sev->session_file) {
|
||||
+ if (sev_read_file_base64(sev->session_file, &session, &sz) < 0) {
|
||||
+ return 1;
|
||||
+ }
|
||||
+ start->session_uaddr = (unsigned long)session;
|
||||
+ start->session_len = sz;
|
||||
+ }
|
||||
+
|
||||
+ if (sev->dh_cert_file) {
|
||||
+ if (sev_read_file_base64(sev->dh_cert_file, &dh_cert, &sz) < 0) {
|
||||
+ return 1;
|
||||
+ }
|
||||
+ start->dh_uaddr = (unsigned long)dh_cert;
|
||||
+ start->dh_len = sz;
|
||||
+ }
|
||||
+
|
||||
+ trace_kvm_sev_launch_start(start->policy, session, dh_cert);
|
||||
+ ret = sev_ioctl(KVM_SEV_LAUNCH_START, start, &fw_error);
|
||||
+ if (ret < 0) {
|
||||
+ error_report("%s: LAUNCH_START ret=%d fw_error=%d '%s'",
|
||||
+ __func__, ret, fw_error, fw_error_to_str(fw_error));
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ object_property_set_int(OBJECT(sev), start->handle, "handle",
|
||||
+ &error_abort);
|
||||
+ sev_set_guest_state(SEV_STATE_LUPDATE);
|
||||
+
|
||||
+ g_free(start);
|
||||
+ g_free(session);
|
||||
+ g_free(dh_cert);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
void *
|
||||
sev_guest_init(const char *id)
|
||||
{
|
||||
@@ -398,6 +490,13 @@ sev_guest_init(const char *id)
|
||||
goto err;
|
||||
}
|
||||
|
||||
+ ret = sev_launch_start(s);
|
||||
+ if (ret) {
|
||||
+ error_report("%s: failed to create encryption context", __func__);
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
sev_active = true;
|
||||
ram_block_notifier_add(&sev_ram_notifier);
|
||||
|
||||
diff --git a/accel/kvm/trace-events b/accel/kvm/trace-events
|
||||
index 364c84bd7a..5d993ca08e 100644
|
||||
--- a/accel/kvm/trace-events
|
||||
+++ b/accel/kvm/trace-events
|
||||
@@ -17,3 +17,5 @@ kvm_irqchip_release_virq(int virq) "virq %d"
|
||||
kvm_sev_init(void) ""
|
||||
kvm_memcrypt_register_region(void *addr, size_t len) "addr %p len 0x%lu"
|
||||
kvm_memcrypt_unregister_region(void *addr, size_t len) "addr %p len 0x%lu"
|
||||
+kvm_sev_change_state(const char *old, const char *new) "%s -> %s"
|
||||
+kvm_sev_launch_start(int policy, void *session, void *pdh) "policy 0x%x session %p pdh %p"
|
||||
diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h
|
||||
index 121e7e4aa4..08014a9c94 100644
|
||||
--- a/include/sysemu/sev.h
|
||||
+++ b/include/sysemu/sev.h
|
||||
@@ -58,6 +58,16 @@ struct QSevGuestInfoClass {
|
||||
ObjectClass parent_class;
|
||||
};
|
||||
|
||||
+typedef enum {
|
||||
+ SEV_STATE_UNINIT = 0,
|
||||
+ SEV_STATE_LUPDATE,
|
||||
+ SEV_STATE_SECRET,
|
||||
+ SEV_STATE_RUNNING,
|
||||
+ SEV_STATE_SUPDATE,
|
||||
+ SEV_STATE_RUPDATE,
|
||||
+ SEV_STATE_MAX
|
||||
+} SevGuestState;
|
||||
+
|
||||
struct SEVState {
|
||||
QSevGuestInfo *sev_info;
|
||||
};
|
126
0061-sev-add-command-to-encrypt-guest-me.patch
Normal file
126
0061-sev-add-command-to-encrypt-guest-me.patch
Normal file
@ -0,0 +1,126 @@
|
||||
From bcbe925e0f93234b0f0f6ecf4e5b8d400a46a691 Mon Sep 17 00:00:00 2001
|
||||
From: Brijesh Singh <brijesh.singh@amd.com>
|
||||
Date: Tue, 6 Feb 2018 19:08:10 -0600
|
||||
Subject: [PATCH] sev: add command to encrypt guest memory region
|
||||
|
||||
The KVM_SEV_LAUNCH_UPDATE_DATA command is used to encrypt a guest memory
|
||||
region using the VM Encryption Key created using LAUNCH_START.
|
||||
|
||||
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
|
||||
[BR: FATE#322124]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
accel/kvm/kvm-all.c | 2 ++
|
||||
accel/kvm/sev.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
accel/kvm/trace-events | 1 +
|
||||
include/sysemu/sev.h | 1 +
|
||||
4 files changed, 53 insertions(+)
|
||||
|
||||
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
|
||||
index f1fb826f06..37f7c442dc 100644
|
||||
--- a/accel/kvm/kvm-all.c
|
||||
+++ b/accel/kvm/kvm-all.c
|
||||
@@ -1675,6 +1675,8 @@ static int kvm_init(MachineState *ms)
|
||||
if (!kvm_state->memcrypt_handle) {
|
||||
goto err;
|
||||
}
|
||||
+
|
||||
+ kvm_state->memcrypt_encrypt_data = sev_encrypt_data;
|
||||
}
|
||||
|
||||
ret = kvm_arch_init(ms, s);
|
||||
diff --git a/accel/kvm/sev.c b/accel/kvm/sev.c
|
||||
index 2ecc6a1d1a..4414bda255 100644
|
||||
--- a/accel/kvm/sev.c
|
||||
+++ b/accel/kvm/sev.c
|
||||
@@ -97,6 +97,12 @@ fw_error_to_str(int code)
|
||||
return sev_fw_errlist[code];
|
||||
}
|
||||
|
||||
+static bool
|
||||
+sev_check_state(SevGuestState state)
|
||||
+{
|
||||
+ return current_sev_guest_state == state ? true : false;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
sev_set_guest_state(SevGuestState new_state)
|
||||
{
|
||||
@@ -447,6 +453,36 @@ sev_launch_start(SEVState *s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int
|
||||
+sev_launch_update_data(uint8_t *addr, uint64_t len)
|
||||
+{
|
||||
+ int ret, fw_error;
|
||||
+ struct kvm_sev_launch_update_data *update;
|
||||
+
|
||||
+ if (addr == NULL || len <= 0) {
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ update = g_malloc0(sizeof(*update));
|
||||
+ if (!update) {
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ update->uaddr = (__u64)addr;
|
||||
+ update->len = len;
|
||||
+ trace_kvm_sev_launch_update_data(addr, len);
|
||||
+ ret = sev_ioctl(KVM_SEV_LAUNCH_UPDATE_DATA, update, &fw_error);
|
||||
+ if (ret) {
|
||||
+ error_report("%s: LAUNCH_UPDATE ret=%d fw_error=%d '%s'",
|
||||
+ __func__, ret, fw_error, fw_error_to_str(fw_error));
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+err:
|
||||
+ g_free(update);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
void *
|
||||
sev_guest_init(const char *id)
|
||||
{
|
||||
@@ -506,6 +542,19 @@ err:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+int
|
||||
+sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len)
|
||||
+{
|
||||
+ assert(handle);
|
||||
+
|
||||
+ /* if SEV is in update state then encrypt the data else do nothing */
|
||||
+ if (sev_check_state(SEV_STATE_LUPDATE)) {
|
||||
+ return sev_launch_update_data(ptr, len);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
sev_register_types(void)
|
||||
{
|
||||
diff --git a/accel/kvm/trace-events b/accel/kvm/trace-events
|
||||
index 5d993ca08e..bd92f868b7 100644
|
||||
--- a/accel/kvm/trace-events
|
||||
+++ b/accel/kvm/trace-events
|
||||
@@ -19,3 +19,4 @@ kvm_memcrypt_register_region(void *addr, size_t len) "addr %p len 0x%lu"
|
||||
kvm_memcrypt_unregister_region(void *addr, size_t len) "addr %p len 0x%lu"
|
||||
kvm_sev_change_state(const char *old, const char *new) "%s -> %s"
|
||||
kvm_sev_launch_start(int policy, void *session, void *pdh) "policy 0x%x session %p pdh %p"
|
||||
+kvm_sev_launch_update_data(void *addr, uint64_t len) "addr %p len 0x%" PRIu64
|
||||
diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h
|
||||
index 08014a9c94..f7af1a00c5 100644
|
||||
--- a/include/sysemu/sev.h
|
||||
+++ b/include/sysemu/sev.h
|
||||
@@ -75,6 +75,7 @@ struct SEVState {
|
||||
typedef struct SEVState SEVState;
|
||||
|
||||
void *sev_guest_init(const char *id);
|
||||
+int sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len);
|
||||
|
||||
#endif
|
||||
|
49
0062-target-i386-encrypt-bios-rom.patch
Normal file
49
0062-target-i386-encrypt-bios-rom.patch
Normal file
@ -0,0 +1,49 @@
|
||||
From 6301b846ebcf3ff2afb0cefbb480447383dc2814 Mon Sep 17 00:00:00 2001
|
||||
From: Brijesh Singh <brijesh.singh@amd.com>
|
||||
Date: Tue, 6 Feb 2018 19:08:10 -0600
|
||||
Subject: [PATCH] target/i386: encrypt bios rom
|
||||
|
||||
SEV requires that guest bios must be encrypted before booting the guest.
|
||||
|
||||
Cc: "Michael S. Tsirkin" <mst@redhat.com>
|
||||
Cc: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Cc: Richard Henderson <rth@twiddle.net>
|
||||
Cc: Eduardo Habkost <ehabkost@redhat.com>
|
||||
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
|
||||
[BR: FATE#322124]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
hw/i386/pc_sysfw.c | 13 +++++++++++++
|
||||
1 file changed, 13 insertions(+)
|
||||
|
||||
diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c
|
||||
index 6b183747fc..8ddbbf74d3 100644
|
||||
--- a/hw/i386/pc_sysfw.c
|
||||
+++ b/hw/i386/pc_sysfw.c
|
||||
@@ -112,6 +112,8 @@ static void pc_system_flash_init(MemoryRegion *rom_memory)
|
||||
pflash_t *system_flash;
|
||||
MemoryRegion *flash_mem;
|
||||
char name[64];
|
||||
+ void *flash_ptr;
|
||||
+ int ret, flash_size;
|
||||
|
||||
sector_bits = 12;
|
||||
sector_size = 1 << sector_bits;
|
||||
@@ -168,6 +170,17 @@ static void pc_system_flash_init(MemoryRegion *rom_memory)
|
||||
if (unit == 0) {
|
||||
flash_mem = pflash_cfi01_get_memory(system_flash);
|
||||
pc_isa_bios_init(rom_memory, flash_mem, size);
|
||||
+
|
||||
+ /* Encrypt the pflash boot ROM */
|
||||
+ if (kvm_memcrypt_enabled()) {
|
||||
+ flash_ptr = memory_region_get_ram_ptr(flash_mem);
|
||||
+ flash_size = memory_region_size(flash_mem);
|
||||
+ ret = kvm_memcrypt_encrypt_data(flash_ptr, flash_size);
|
||||
+ if (ret) {
|
||||
+ error_report("failed to encrypt pflash rom");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
169
0063-sev-add-support-to-LAUNCH_MEASURE-c.patch
Normal file
169
0063-sev-add-support-to-LAUNCH_MEASURE-c.patch
Normal file
@ -0,0 +1,169 @@
|
||||
From 8593c38925a2c54bceb27e16f1ad9f02789afbf4 Mon Sep 17 00:00:00 2001
|
||||
From: Brijesh Singh <brijesh.singh@amd.com>
|
||||
Date: Tue, 6 Feb 2018 19:08:10 -0600
|
||||
Subject: [PATCH] sev: add support to LAUNCH_MEASURE command
|
||||
|
||||
During machine creation we encrypted the guest bios image, the
|
||||
LAUNCH_MEASURE command can be used to retrieve the measurement of
|
||||
the encrypted memory region. This measurement is a signature of
|
||||
the memory contents that can be sent to the guest owner as an
|
||||
attestation that the memory was encrypted correctly by the firmware.
|
||||
VM management tools like libvirt can query the measurement using
|
||||
query-launch-measure QMP command.
|
||||
|
||||
Cc: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Cc: kvm@vger.kernel.org
|
||||
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
|
||||
[BR: FATE#322124]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
accel/kvm/sev.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
accel/kvm/trace-events | 1 +
|
||||
accel/stubs/kvm-stub.c | 5 ++++
|
||||
include/sysemu/sev.h | 2 ++
|
||||
4 files changed, 75 insertions(+)
|
||||
|
||||
diff --git a/accel/kvm/sev.c b/accel/kvm/sev.c
|
||||
index 4414bda255..8d99c6cda4 100644
|
||||
--- a/accel/kvm/sev.c
|
||||
+++ b/accel/kvm/sev.c
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "sysemu/sev.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "trace.h"
|
||||
+#include "qapi-event.h"
|
||||
|
||||
#define DEFAULT_GUEST_POLICY 0x1 /* disable debug */
|
||||
#define DEFAULT_SEV_DEVICE "/dev/sev"
|
||||
@@ -26,6 +27,7 @@
|
||||
static uint64_t me_mask;
|
||||
static bool sev_active;
|
||||
static int sev_fd;
|
||||
+static SEVState *sev_state;
|
||||
|
||||
#define SEV_FW_MAX_ERROR 0x17
|
||||
|
||||
@@ -483,6 +485,68 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static void
|
||||
+sev_launch_get_measure(Notifier *notifier, void *unused)
|
||||
+{
|
||||
+ int ret, error;
|
||||
+ guchar *data;
|
||||
+ SEVState *s = sev_state;
|
||||
+ struct kvm_sev_launch_measure *measurement;
|
||||
+
|
||||
+ if (!sev_check_state(SEV_STATE_LUPDATE)) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ measurement = g_malloc0(sizeof(*measurement));
|
||||
+ if (!measurement) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* query the measurement blob length */
|
||||
+ ret = sev_ioctl(KVM_SEV_LAUNCH_MEASURE, measurement, &error);
|
||||
+ if (!measurement->len) {
|
||||
+ error_report("%s: LAUNCH_MEASURE ret=%d fw_error=%d '%s'",
|
||||
+ __func__, ret, error, fw_error_to_str(errno));
|
||||
+ goto free_measurement;
|
||||
+ }
|
||||
+
|
||||
+ data = g_malloc(measurement->len);
|
||||
+ if (s->measurement) {
|
||||
+ goto free_data;
|
||||
+ }
|
||||
+
|
||||
+ measurement->uaddr = (unsigned long)data;
|
||||
+
|
||||
+ /* get the measurement blob */
|
||||
+ ret = sev_ioctl(KVM_SEV_LAUNCH_MEASURE, measurement, &error);
|
||||
+ if (ret) {
|
||||
+ error_report("%s: LAUNCH_MEASURE ret=%d fw_error=%d '%s'",
|
||||
+ __func__, ret, error, fw_error_to_str(errno));
|
||||
+ goto free_data;
|
||||
+ }
|
||||
+
|
||||
+ sev_set_guest_state(SEV_STATE_SECRET);
|
||||
+
|
||||
+ /* encode the measurement value and emit the event */
|
||||
+ s->measurement = g_base64_encode(data, measurement->len);
|
||||
+ trace_kvm_sev_launch_measurement(s->measurement);
|
||||
+
|
||||
+free_data:
|
||||
+ g_free(data);
|
||||
+free_measurement:
|
||||
+ g_free(measurement);
|
||||
+}
|
||||
+
|
||||
+char *
|
||||
+sev_get_launch_measurement(void)
|
||||
+{
|
||||
+ return g_strdup(sev_state->measurement);
|
||||
+}
|
||||
+
|
||||
+static Notifier sev_machine_done_notify = {
|
||||
+ .notify = sev_launch_get_measure,
|
||||
+};
|
||||
+
|
||||
void *
|
||||
sev_guest_init(const char *id)
|
||||
{
|
||||
@@ -535,6 +599,9 @@ sev_guest_init(const char *id)
|
||||
|
||||
sev_active = true;
|
||||
ram_block_notifier_add(&sev_ram_notifier);
|
||||
+ qemu_add_machine_init_done_notifier(&sev_machine_done_notify);
|
||||
+
|
||||
+ sev_state = s;
|
||||
|
||||
return s;
|
||||
err:
|
||||
diff --git a/accel/kvm/trace-events b/accel/kvm/trace-events
|
||||
index bd92f868b7..19742bf9dd 100644
|
||||
--- a/accel/kvm/trace-events
|
||||
+++ b/accel/kvm/trace-events
|
||||
@@ -20,3 +20,4 @@ kvm_memcrypt_unregister_region(void *addr, size_t len) "addr %p len 0x%lu"
|
||||
kvm_sev_change_state(const char *old, const char *new) "%s -> %s"
|
||||
kvm_sev_launch_start(int policy, void *session, void *pdh) "policy 0x%x session %p pdh %p"
|
||||
kvm_sev_launch_update_data(void *addr, uint64_t len) "addr %p len 0x%" PRIu64
|
||||
+kvm_sev_launch_measurement(const char *value) "data %s"
|
||||
diff --git a/accel/stubs/kvm-stub.c b/accel/stubs/kvm-stub.c
|
||||
index e7d579e3e5..d0f1aa6d6f 100644
|
||||
--- a/accel/stubs/kvm-stub.c
|
||||
+++ b/accel/stubs/kvm-stub.c
|
||||
@@ -133,6 +133,11 @@ void sev_get_policy(uint32_t *policy)
|
||||
{
|
||||
}
|
||||
|
||||
+char *sev_get_launch_measurement(void)
|
||||
+{
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
bool kvm_memcrypt_enabled(void)
|
||||
{
|
||||
return false;
|
||||
diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h
|
||||
index f7af1a00c5..c173ad33f8 100644
|
||||
--- a/include/sysemu/sev.h
|
||||
+++ b/include/sysemu/sev.h
|
||||
@@ -30,6 +30,7 @@ extern uint64_t sev_get_me_mask(void);
|
||||
extern void sev_get_current_state(char **state);
|
||||
extern void sev_get_fw_version(uint8_t *major, uint8_t *minor, uint8_t *build);
|
||||
extern void sev_get_policy(uint32_t *policy);
|
||||
+extern char *sev_get_launch_measurement(void);
|
||||
|
||||
typedef struct QSevGuestInfo QSevGuestInfo;
|
||||
typedef struct QSevGuestInfoClass QSevGuestInfoClass;
|
||||
@@ -70,6 +71,7 @@ typedef enum {
|
||||
|
||||
struct SEVState {
|
||||
QSevGuestInfo *sev_info;
|
||||
+ gchar *measurement;
|
||||
};
|
||||
|
||||
typedef struct SEVState SEVState;
|
74
0064-sev-Finalize-the-SEV-guest-launch-f.patch
Normal file
74
0064-sev-Finalize-the-SEV-guest-launch-f.patch
Normal file
@ -0,0 +1,74 @@
|
||||
From 5f926f58bd02e7c42d7840a653cc33d83c90a5af Mon Sep 17 00:00:00 2001
|
||||
From: Brijesh Singh <brijesh.singh@amd.com>
|
||||
Date: Tue, 6 Feb 2018 19:08:10 -0600
|
||||
Subject: [PATCH] sev: Finalize the SEV guest launch flow
|
||||
|
||||
SEV launch flow requires us to issue LAUNCH_FINISH command before guest
|
||||
is ready to run.
|
||||
|
||||
Cc: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Cc: kvm@vger.kernel.org
|
||||
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
|
||||
[BR: FATE#322124]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
accel/kvm/sev.c | 29 +++++++++++++++++++++++++++++
|
||||
accel/kvm/trace-events | 1 +
|
||||
2 files changed, 30 insertions(+)
|
||||
|
||||
diff --git a/accel/kvm/sev.c b/accel/kvm/sev.c
|
||||
index 8d99c6cda4..e422f43caa 100644
|
||||
--- a/accel/kvm/sev.c
|
||||
+++ b/accel/kvm/sev.c
|
||||
@@ -547,6 +547,34 @@ static Notifier sev_machine_done_notify = {
|
||||
.notify = sev_launch_get_measure,
|
||||
};
|
||||
|
||||
+static void
|
||||
+sev_launch_finish(SEVState *s)
|
||||
+{
|
||||
+ int ret, error;
|
||||
+
|
||||
+ trace_kvm_sev_launch_finish();
|
||||
+ ret = sev_ioctl(KVM_SEV_LAUNCH_FINISH, 0, &error);
|
||||
+ if (ret) {
|
||||
+ error_report("%s: LAUNCH_FINISH ret=%d fw_error=%d '%s'",
|
||||
+ __func__, ret, error, fw_error_to_str(error));
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ sev_set_guest_state(SEV_STATE_RUNNING);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+sev_vm_state_change(void *opaque, int running, RunState state)
|
||||
+{
|
||||
+ SEVState *s = opaque;
|
||||
+
|
||||
+ if (running) {
|
||||
+ if (!sev_check_state(SEV_STATE_RUNNING)) {
|
||||
+ sev_launch_finish(s);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void *
|
||||
sev_guest_init(const char *id)
|
||||
{
|
||||
@@ -600,6 +628,7 @@ sev_guest_init(const char *id)
|
||||
sev_active = true;
|
||||
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, s);
|
||||
|
||||
sev_state = s;
|
||||
|
||||
diff --git a/accel/kvm/trace-events b/accel/kvm/trace-events
|
||||
index 19742bf9dd..e810d75ea1 100644
|
||||
--- a/accel/kvm/trace-events
|
||||
+++ b/accel/kvm/trace-events
|
||||
@@ -21,3 +21,4 @@ kvm_sev_change_state(const char *old, const char *new) "%s -> %s"
|
||||
kvm_sev_launch_start(int policy, void *session, void *pdh) "policy 0x%x session %p pdh %p"
|
||||
kvm_sev_launch_update_data(void *addr, uint64_t len) "addr %p len 0x%" PRIu64
|
||||
kvm_sev_launch_measurement(const char *value) "data %s"
|
||||
+kvm_sev_launch_finish(void) ""
|
58
0065-hw-i386-set-ram_debug_ops-when-memo.patch
Normal file
58
0065-hw-i386-set-ram_debug_ops-when-memo.patch
Normal file
@ -0,0 +1,58 @@
|
||||
From 730e2bc55583c1ae7ba0aff4b26975f51c2442cd Mon Sep 17 00:00:00 2001
|
||||
From: Brijesh Singh <brijesh.singh@amd.com>
|
||||
Date: Tue, 6 Feb 2018 19:08:10 -0600
|
||||
Subject: [PATCH] hw: i386: set ram_debug_ops when memory encryption is enabled
|
||||
|
||||
When memory encryption is enabled, the guest RAM and boot flash ROM will
|
||||
contain the encrypted data. By setting the debug ops allow us to invoke
|
||||
encryption APIs when accessing the memory for the debug purposes.
|
||||
|
||||
Cc: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Cc: Richard Henderson <rth@twiddle.net>
|
||||
Cc: Eduardo Habkost <ehabkost@redhat.com>
|
||||
Cc: "Michael S. Tsirkin" <mst@redhat.com>
|
||||
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
|
||||
[BR: FATE#322124]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
hw/i386/pc.c | 9 +++++++++
|
||||
hw/i386/pc_sysfw.c | 6 ++++++
|
||||
2 files changed, 15 insertions(+)
|
||||
|
||||
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
|
||||
index e7faf92143..c9c91e150b 100644
|
||||
--- a/hw/i386/pc.c
|
||||
+++ b/hw/i386/pc.c
|
||||
@@ -1355,6 +1355,15 @@ void pc_memory_init(PCMachineState *pcms,
|
||||
e820_add_entry(0x100000000ULL, pcms->above_4g_mem_size, E820_RAM);
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * When memory encryption is enabled, the guest RAM will be encrypted with
|
||||
+ * a guest unique key. Set the debug ops so that any debug access to the
|
||||
+ * guest RAM will go through the memory encryption APIs.
|
||||
+ */
|
||||
+ if (kvm_memcrypt_enabled()) {
|
||||
+ kvm_memcrypt_set_debug_ops(ram);
|
||||
+ }
|
||||
+
|
||||
if (!pcmc->has_reserved_memory &&
|
||||
(machine->ram_slots ||
|
||||
(machine->maxram_size > machine->ram_size))) {
|
||||
diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c
|
||||
index 8ddbbf74d3..3d149b1c9f 100644
|
||||
--- a/hw/i386/pc_sysfw.c
|
||||
+++ b/hw/i386/pc_sysfw.c
|
||||
@@ -180,6 +180,12 @@ static void pc_system_flash_init(MemoryRegion *rom_memory)
|
||||
error_report("failed to encrypt pflash rom");
|
||||
exit(1);
|
||||
}
|
||||
+
|
||||
+ /*
|
||||
+ * The pflash ROM is encrypted, set the debug ops so that any
|
||||
+ * debug accesses will use memory encryption APIs.
|
||||
+ */
|
||||
+ kvm_memcrypt_set_debug_ops(flash_mem);
|
||||
}
|
||||
}
|
||||
}
|
156
0066-sev-add-debug-encrypt-and-decrypt-c.patch
Normal file
156
0066-sev-add-debug-encrypt-and-decrypt-c.patch
Normal file
@ -0,0 +1,156 @@
|
||||
From ed8f2531e1b008cedfaca01980641c2432693fb3 Mon Sep 17 00:00:00 2001
|
||||
From: Brijesh Singh <brijesh.singh@amd.com>
|
||||
Date: Tue, 6 Feb 2018 19:08:11 -0600
|
||||
Subject: [PATCH] sev: add debug encrypt and decrypt commands
|
||||
|
||||
KVM_SEV_DBG_DECRYPT and KVM_SEV_DBG_ENCRYPT commands are used for
|
||||
decrypting and encrypting guest memory region. The command works only if
|
||||
the guest policy allows the debugging.
|
||||
|
||||
Cc: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Cc: kvm@vger.kernel.org
|
||||
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
|
||||
[BR: FATE#322124]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
accel/kvm/kvm-all.c | 1 +
|
||||
accel/kvm/sev.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
accel/kvm/trace-events | 1 +
|
||||
include/sysemu/sev.h | 1 +
|
||||
4 files changed, 75 insertions(+)
|
||||
|
||||
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
|
||||
index 37f7c442dc..7d3b7b4107 100644
|
||||
--- a/accel/kvm/kvm-all.c
|
||||
+++ b/accel/kvm/kvm-all.c
|
||||
@@ -1677,6 +1677,7 @@ static int kvm_init(MachineState *ms)
|
||||
}
|
||||
|
||||
kvm_state->memcrypt_encrypt_data = sev_encrypt_data;
|
||||
+ kvm_state->memcrypt_debug_ops = sev_set_debug_ops;
|
||||
}
|
||||
|
||||
ret = kvm_arch_init(ms, s);
|
||||
diff --git a/accel/kvm/sev.c b/accel/kvm/sev.c
|
||||
index e422f43caa..7b57575e2f 100644
|
||||
--- a/accel/kvm/sev.c
|
||||
+++ b/accel/kvm/sev.c
|
||||
@@ -23,11 +23,13 @@
|
||||
|
||||
#define DEFAULT_GUEST_POLICY 0x1 /* disable debug */
|
||||
#define DEFAULT_SEV_DEVICE "/dev/sev"
|
||||
+#define GUEST_POLICY_DBG_BIT 0x1
|
||||
|
||||
static uint64_t me_mask;
|
||||
static bool sev_active;
|
||||
static int sev_fd;
|
||||
static SEVState *sev_state;
|
||||
+static MemoryRegionRAMReadWriteOps sev_ops;
|
||||
|
||||
#define SEV_FW_MAX_ERROR 0x17
|
||||
|
||||
@@ -575,6 +577,51 @@ sev_vm_state_change(void *opaque, int running, RunState state)
|
||||
}
|
||||
}
|
||||
|
||||
+static int
|
||||
+sev_dbg_enc_dec(uint8_t *dst, const uint8_t *src, uint32_t len, bool write)
|
||||
+{
|
||||
+ int ret, error;
|
||||
+ struct kvm_sev_dbg *dbg;
|
||||
+
|
||||
+ dbg = g_malloc0(sizeof(*dbg));
|
||||
+ if (!dbg) {
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ dbg->src_uaddr = (unsigned long)src;
|
||||
+ dbg->dst_uaddr = (unsigned long)dst;
|
||||
+ dbg->len = len;
|
||||
+
|
||||
+ trace_kvm_sev_debug(write ? "encrypt" : "decrypt", src, dst, len);
|
||||
+ ret = sev_ioctl(write ? KVM_SEV_DBG_ENCRYPT : KVM_SEV_DBG_DECRYPT,
|
||||
+ dbg, &error);
|
||||
+ if (ret) {
|
||||
+ error_report("%s (%s) %#llx->%#llx+%#x ret=%d fw_error=%d '%s'",
|
||||
+ __func__, write ? "write" : "read", dbg->src_uaddr,
|
||||
+ dbg->dst_uaddr, dbg->len, ret, error,
|
||||
+ fw_error_to_str(error));
|
||||
+ }
|
||||
+
|
||||
+ g_free(dbg);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+sev_mem_read(uint8_t *dst, const uint8_t *src, uint32_t len, MemTxAttrs attrs)
|
||||
+{
|
||||
+ assert(attrs.debug);
|
||||
+
|
||||
+ return sev_dbg_enc_dec(dst, src, len, false);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+sev_mem_write(uint8_t *dst, const uint8_t *src, uint32_t len, MemTxAttrs attrs)
|
||||
+{
|
||||
+ assert(attrs.debug);
|
||||
+
|
||||
+ return sev_dbg_enc_dec(dst, src, len, true);
|
||||
+}
|
||||
+
|
||||
void *
|
||||
sev_guest_init(const char *id)
|
||||
{
|
||||
@@ -651,6 +698,31 @@ sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+void
|
||||
+sev_set_debug_ops(void *handle, MemoryRegion *mr)
|
||||
+{
|
||||
+ int policy;
|
||||
+ SEVState *s = (SEVState *)handle;
|
||||
+
|
||||
+ policy = object_property_get_int(OBJECT(s->sev_info),
|
||||
+ "policy", &error_abort);
|
||||
+
|
||||
+ /*
|
||||
+ * Check if guest policy supports debugging
|
||||
+ * Bit 0 :
|
||||
+ * 0 - debug allowed
|
||||
+ * 1 - debug is not allowed
|
||||
+ */
|
||||
+ if (policy & GUEST_POLICY_DBG_BIT) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ sev_ops.read = sev_mem_read;
|
||||
+ sev_ops.write = sev_mem_write;
|
||||
+
|
||||
+ memory_region_set_ram_debug_ops(mr, &sev_ops);
|
||||
+}
|
||||
+
|
||||
static void
|
||||
sev_register_types(void)
|
||||
{
|
||||
diff --git a/accel/kvm/trace-events b/accel/kvm/trace-events
|
||||
index e810d75ea1..de6a12c51e 100644
|
||||
--- a/accel/kvm/trace-events
|
||||
+++ b/accel/kvm/trace-events
|
||||
@@ -22,3 +22,4 @@ kvm_sev_launch_start(int policy, void *session, void *pdh) "policy 0x%x session
|
||||
kvm_sev_launch_update_data(void *addr, uint64_t len) "addr %p len 0x%" PRIu64
|
||||
kvm_sev_launch_measurement(const char *value) "data %s"
|
||||
kvm_sev_launch_finish(void) ""
|
||||
+kvm_sev_debug(const char *op, const uint8_t *src, uint8_t *dst, int len) "(%s) src %p dst %p len %d"
|
||||
diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h
|
||||
index c173ad33f8..186ebca0f9 100644
|
||||
--- a/include/sysemu/sev.h
|
||||
+++ b/include/sysemu/sev.h
|
||||
@@ -78,6 +78,7 @@ typedef struct SEVState SEVState;
|
||||
|
||||
void *sev_guest_init(const char *id);
|
||||
int sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len);
|
||||
+void sev_set_debug_ops(void *handle, MemoryRegion *mr);
|
||||
|
||||
#endif
|
||||
|
361
0067-target-i386-clear-C-bit-when-walkin.patch
Normal file
361
0067-target-i386-clear-C-bit-when-walkin.patch
Normal file
@ -0,0 +1,361 @@
|
||||
From 5be49d786b9d9a39cd2bae56032a6f92a59de93a Mon Sep 17 00:00:00 2001
|
||||
From: Brijesh Singh <brijesh.singh@amd.com>
|
||||
Date: Tue, 6 Feb 2018 19:08:11 -0600
|
||||
Subject: [PATCH] target/i386: clear C-bit when walking SEV guest page table
|
||||
|
||||
In SEV-enabled guest the pte entry will have C-bit set, we need to
|
||||
clear the C-bit when walking the page table.
|
||||
|
||||
Cc: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Cc: Richard Henderson <rth@twiddle.net>
|
||||
Cc: Eduardo Habkost <ehabkost@redhat.com>
|
||||
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
|
||||
[BR: FATE#322124]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
target/i386/helper.c | 31 +++++++++++++----------
|
||||
target/i386/monitor.c | 69 +++++++++++++++++++++++++++++++++------------------
|
||||
2 files changed, 63 insertions(+), 37 deletions(-)
|
||||
|
||||
diff --git a/target/i386/helper.c b/target/i386/helper.c
|
||||
index 5dc9e8839b..999154e21e 100644
|
||||
--- a/target/i386/helper.c
|
||||
+++ b/target/i386/helper.c
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "cpu.h"
|
||||
#include "exec/exec-all.h"
|
||||
#include "sysemu/kvm.h"
|
||||
+#include "sysemu/sev.h"
|
||||
#include "kvm_i386.h"
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
#include "sysemu/sysemu.h"
|
||||
@@ -732,6 +733,9 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||
int32_t a20_mask;
|
||||
uint32_t page_offset;
|
||||
int page_size;
|
||||
+ uint64_t me_mask;
|
||||
+
|
||||
+ me_mask = sev_get_me_mask();
|
||||
|
||||
a20_mask = x86_get_a20_mask(env);
|
||||
if (!(env->cr[0] & CR0_PG_MASK)) {
|
||||
@@ -755,25 +759,25 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||
}
|
||||
|
||||
if (la57) {
|
||||
- pml5e_addr = ((env->cr[3] & ~0xfff) +
|
||||
+ pml5e_addr = ((env->cr[3] & ~0xfff & me_mask) +
|
||||
(((addr >> 48) & 0x1ff) << 3)) & a20_mask;
|
||||
- pml5e = ldq_phys_debug(cs, pml5e_addr);
|
||||
+ pml5e = ldq_phys_debug(cs, pml5e_addr) & me_mask;
|
||||
if (!(pml5e & PG_PRESENT_MASK)) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
- pml5e = env->cr[3];
|
||||
+ pml5e = env->cr[3] & me_mask;
|
||||
}
|
||||
|
||||
pml4e_addr = ((pml5e & PG_ADDRESS_MASK) +
|
||||
(((addr >> 39) & 0x1ff) << 3)) & a20_mask;
|
||||
- pml4e = ldq_phys_debug(cs, pml4e_addr);
|
||||
+ pml4e = ldq_phys_debug(cs, pml4e_addr) & me_mask;
|
||||
if (!(pml4e & PG_PRESENT_MASK)) {
|
||||
return -1;
|
||||
}
|
||||
pdpe_addr = ((pml4e & PG_ADDRESS_MASK) +
|
||||
(((addr >> 30) & 0x1ff) << 3)) & a20_mask;
|
||||
- pdpe = x86_ldq_phys(cs, pdpe_addr);
|
||||
+ pdpe = ldq_phys_debug(cs, pdpe_addr) & me_mask;
|
||||
if (!(pdpe & PG_PRESENT_MASK)) {
|
||||
return -1;
|
||||
}
|
||||
@@ -786,16 +790,16 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
- pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
|
||||
- a20_mask;
|
||||
- pdpe = ldq_phys_debug(cs, pdpe_addr);
|
||||
+ pdpe_addr = ((env->cr[3] & ~0x1f & me_mask) + ((addr >> 27) & 0x18))
|
||||
+ & a20_mask;
|
||||
+ pdpe = ldq_phys_debug(cs, pdpe_addr) & me_mask;
|
||||
if (!(pdpe & PG_PRESENT_MASK))
|
||||
return -1;
|
||||
}
|
||||
|
||||
pde_addr = ((pdpe & PG_ADDRESS_MASK) +
|
||||
(((addr >> 21) & 0x1ff) << 3)) & a20_mask;
|
||||
- pde = ldq_phys_debug(cs, pde_addr);
|
||||
+ pde = ldq_phys_debug(cs, pde_addr) & me_mask;
|
||||
if (!(pde & PG_PRESENT_MASK)) {
|
||||
return -1;
|
||||
}
|
||||
@@ -808,7 +812,7 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||
pte_addr = ((pde & PG_ADDRESS_MASK) +
|
||||
(((addr >> 12) & 0x1ff) << 3)) & a20_mask;
|
||||
page_size = 4096;
|
||||
- pte = ldq_phys_debug(cs, pte_addr);
|
||||
+ pte = ldq_phys_debug(cs, pte_addr) & me_mask;
|
||||
}
|
||||
if (!(pte & PG_PRESENT_MASK)) {
|
||||
return -1;
|
||||
@@ -817,8 +821,9 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||
uint32_t pde;
|
||||
|
||||
/* page directory entry */
|
||||
- pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & a20_mask;
|
||||
- pde = ldl_phys_debug(cs, pde_addr);
|
||||
+ pde_addr = ((env->cr[3] & ~0xfff & me_mask) + ((addr >> 20) & 0xffc))
|
||||
+ & a20_mask;
|
||||
+ pde = ldl_phys_debug(cs, pde_addr) & me_mask;
|
||||
if (!(pde & PG_PRESENT_MASK))
|
||||
return -1;
|
||||
if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
|
||||
@@ -827,7 +832,7 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||
} else {
|
||||
/* page directory entry */
|
||||
pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & a20_mask;
|
||||
- pte = ldl_phys_debug(cs, pte_addr);
|
||||
+ pte = ldl_phys_debug(cs, pte_addr) & me_mask;
|
||||
if (!(pte & PG_PRESENT_MASK)) {
|
||||
return -1;
|
||||
}
|
||||
diff --git a/target/i386/monitor.c b/target/i386/monitor.c
|
||||
index 63f7125ba8..44ae31d13b 100644
|
||||
--- a/target/i386/monitor.c
|
||||
+++ b/target/i386/monitor.c
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "monitor/hmp-target.h"
|
||||
#include "hw/i386/pc.h"
|
||||
#include "sysemu/kvm.h"
|
||||
+#include "sysemu/sev.h"
|
||||
#include "hmp.h"
|
||||
|
||||
|
||||
@@ -93,16 +94,20 @@ static void tlb_info_pae32(Monitor *mon, CPUArchState *env)
|
||||
unsigned int l1, l2, l3;
|
||||
uint64_t pdpe, pde, pte;
|
||||
uint64_t pdp_addr, pd_addr, pt_addr;
|
||||
+ uint64_t me_mask;
|
||||
+
|
||||
+ me_mask = sev_get_me_mask();
|
||||
|
||||
pdp_addr = env->cr[3] & ~0x1f;
|
||||
+ pdp_addr &= me_mask;
|
||||
for (l1 = 0; l1 < 4; l1++) {
|
||||
cpu_physical_memory_read_debug(pdp_addr + l1 * 8, &pdpe, 8);
|
||||
- pdpe = le64_to_cpu(pdpe);
|
||||
+ pdpe = le64_to_cpu(pdpe & me_mask);
|
||||
if (pdpe & PG_PRESENT_MASK) {
|
||||
pd_addr = pdpe & 0x3fffffffff000ULL;
|
||||
for (l2 = 0; l2 < 512; l2++) {
|
||||
cpu_physical_memory_read_debug(pd_addr + l2 * 8, &pde, 8);
|
||||
- pde = le64_to_cpu(pde);
|
||||
+ pde = le64_to_cpu(pde & me_mask);
|
||||
if (pde & PG_PRESENT_MASK) {
|
||||
if (pde & PG_PSE_MASK) {
|
||||
/* 2M pages with PAE, CR4.PSE is ignored */
|
||||
@@ -113,7 +118,7 @@ static void tlb_info_pae32(Monitor *mon, CPUArchState *env)
|
||||
for (l3 = 0; l3 < 512; l3++) {
|
||||
cpu_physical_memory_read_debug(pt_addr + l3 * 8,
|
||||
&pte, 8);
|
||||
- pte = le64_to_cpu(pte);
|
||||
+ pte = le64_to_cpu(pte & me_mask);
|
||||
if (pte & PG_PRESENT_MASK) {
|
||||
print_pte(mon, env, (l1 << 30) + (l2 << 21)
|
||||
+ (l3 << 12),
|
||||
@@ -135,10 +140,13 @@ static void tlb_info_la48(Monitor *mon, CPUArchState *env,
|
||||
uint64_t l1, l2, l3, l4;
|
||||
uint64_t pml4e, pdpe, pde, pte;
|
||||
uint64_t pdp_addr, pd_addr, pt_addr;
|
||||
+ uint64_t me_mask;
|
||||
+
|
||||
+ me_mask = sev_get_me_mask();
|
||||
|
||||
for (l1 = 0; l1 < 512; l1++) {
|
||||
cpu_physical_memory_read_debug(pml4_addr + l1 * 8, &pml4e, 8);
|
||||
- pml4e = le64_to_cpu(pml4e);
|
||||
+ pml4e = le64_to_cpu(pml4e & me_mask);
|
||||
if (!(pml4e & PG_PRESENT_MASK)) {
|
||||
continue;
|
||||
}
|
||||
@@ -146,7 +154,7 @@ static void tlb_info_la48(Monitor *mon, CPUArchState *env,
|
||||
pdp_addr = pml4e & 0x3fffffffff000ULL;
|
||||
for (l2 = 0; l2 < 512; l2++) {
|
||||
cpu_physical_memory_read_debug(pdp_addr + l2 * 8, &pdpe, 8);
|
||||
- pdpe = le64_to_cpu(pdpe);
|
||||
+ pdpe = le64_to_cpu(pdpe & me_mask);
|
||||
if (!(pdpe & PG_PRESENT_MASK)) {
|
||||
continue;
|
||||
}
|
||||
@@ -161,7 +169,7 @@ static void tlb_info_la48(Monitor *mon, CPUArchState *env,
|
||||
pd_addr = pdpe & 0x3fffffffff000ULL;
|
||||
for (l3 = 0; l3 < 512; l3++) {
|
||||
cpu_physical_memory_read_debug(pd_addr + l3 * 8, &pde, 8);
|
||||
- pde = le64_to_cpu(pde);
|
||||
+ pde = le64_to_cpu(pde & me_mask);
|
||||
if (!(pde & PG_PRESENT_MASK)) {
|
||||
continue;
|
||||
}
|
||||
@@ -176,7 +184,7 @@ static void tlb_info_la48(Monitor *mon, CPUArchState *env,
|
||||
pt_addr = pde & 0x3fffffffff000ULL;
|
||||
for (l4 = 0; l4 < 512; l4++) {
|
||||
cpu_physical_memory_read_debug(pt_addr + l4 * 8, &pte, 8);
|
||||
- pte = le64_to_cpu(pte);
|
||||
+ pte = le64_to_cpu(pte & me_mask);
|
||||
if (pte & PG_PRESENT_MASK) {
|
||||
print_pte(mon, env, (l0 << 48) + (l1 << 39) +
|
||||
(l2 << 30) + (l3 << 21) + (l4 << 12),
|
||||
@@ -193,11 +201,14 @@ static void tlb_info_la57(Monitor *mon, CPUArchState *env)
|
||||
uint64_t l0;
|
||||
uint64_t pml5e;
|
||||
uint64_t pml5_addr;
|
||||
+ uint64_t me_mask;
|
||||
|
||||
- pml5_addr = env->cr[3] & 0x3fffffffff000ULL;
|
||||
+ me_mask = sev_get_me_mask();
|
||||
+
|
||||
+ pml5_addr = env->cr[3] & 0x3fffffffff000ULL & me_mask;
|
||||
for (l0 = 0; l0 < 512; l0++) {
|
||||
cpu_physical_memory_read_debug(pml5_addr + l0 * 8, &pml5e, 8);
|
||||
- pml5e = le64_to_cpu(pml5e);
|
||||
+ pml5e = le64_to_cpu(pml5e & me_mask);
|
||||
if (pml5e & PG_PRESENT_MASK) {
|
||||
tlb_info_la48(mon, env, l0, pml5e & 0x3fffffffff000ULL);
|
||||
}
|
||||
@@ -225,7 +236,8 @@ void hmp_info_tlb(Monitor *mon, const QDict *qdict)
|
||||
if (env->cr[4] & CR4_LA57_MASK) {
|
||||
tlb_info_la57(mon, env);
|
||||
} else {
|
||||
- tlb_info_la48(mon, env, 0, env->cr[3] & 0x3fffffffff000ULL);
|
||||
+ tlb_info_la48(mon, env, 0, env->cr[3] & 0x3fffffffff000ULL &
|
||||
+ sev_get_me_mask());
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
@@ -309,19 +321,22 @@ static void mem_info_pae32(Monitor *mon, CPUArchState *env)
|
||||
uint64_t pdpe, pde, pte;
|
||||
uint64_t pdp_addr, pd_addr, pt_addr;
|
||||
hwaddr start, end;
|
||||
+ uint64_t me_mask;
|
||||
|
||||
- pdp_addr = env->cr[3] & ~0x1f;
|
||||
+ me_mask = sev_get_me_mask();
|
||||
+
|
||||
+ pdp_addr = env->cr[3] & ~0x1f & me_mask;
|
||||
last_prot = 0;
|
||||
start = -1;
|
||||
for (l1 = 0; l1 < 4; l1++) {
|
||||
cpu_physical_memory_read_debug(pdp_addr + l1 * 8, &pdpe, 8);
|
||||
- pdpe = le64_to_cpu(pdpe);
|
||||
+ pdpe = le64_to_cpu(pdpe & me_mask);
|
||||
end = l1 << 30;
|
||||
if (pdpe & PG_PRESENT_MASK) {
|
||||
pd_addr = pdpe & 0x3fffffffff000ULL;
|
||||
for (l2 = 0; l2 < 512; l2++) {
|
||||
cpu_physical_memory_read_debug(pd_addr + l2 * 8, &pde, 8);
|
||||
- pde = le64_to_cpu(pde);
|
||||
+ pde = le64_to_cpu(pde & me_mask);
|
||||
end = (l1 << 30) + (l2 << 21);
|
||||
if (pde & PG_PRESENT_MASK) {
|
||||
if (pde & PG_PSE_MASK) {
|
||||
@@ -333,7 +348,7 @@ static void mem_info_pae32(Monitor *mon, CPUArchState *env)
|
||||
for (l3 = 0; l3 < 512; l3++) {
|
||||
cpu_physical_memory_read_debug(pt_addr + l3 * 8,
|
||||
&pte, 8);
|
||||
- pte = le64_to_cpu(pte);
|
||||
+ pte = le64_to_cpu(pte & me_mask);
|
||||
end = (l1 << 30) + (l2 << 21) + (l3 << 12);
|
||||
if (pte & PG_PRESENT_MASK) {
|
||||
prot = pte & pde & (PG_USER_MASK | PG_RW_MASK |
|
||||
@@ -366,19 +381,22 @@ static void mem_info_la48(Monitor *mon, CPUArchState *env)
|
||||
uint64_t l1, l2, l3, l4;
|
||||
uint64_t pml4e, pdpe, pde, pte;
|
||||
uint64_t pml4_addr, pdp_addr, pd_addr, pt_addr, start, end;
|
||||
+ uint64_t me_mask;
|
||||
+
|
||||
+ me_mask = sev_get_me_mask();
|
||||
|
||||
- pml4_addr = env->cr[3] & 0x3fffffffff000ULL;
|
||||
+ pml4_addr = env->cr[3] & 0x3fffffffff000ULL & me_mask;
|
||||
last_prot = 0;
|
||||
start = -1;
|
||||
for (l1 = 0; l1 < 512; l1++) {
|
||||
cpu_physical_memory_read_debug(pml4_addr + l1 * 8, &pml4e, 8);
|
||||
- pml4e = le64_to_cpu(pml4e);
|
||||
+ pml4e = le64_to_cpu(pml4e & me_mask);
|
||||
end = l1 << 39;
|
||||
if (pml4e & PG_PRESENT_MASK) {
|
||||
pdp_addr = pml4e & 0x3fffffffff000ULL;
|
||||
for (l2 = 0; l2 < 512; l2++) {
|
||||
cpu_physical_memory_read_debug(pdp_addr + l2 * 8, &pdpe, 8);
|
||||
- pdpe = le64_to_cpu(pdpe);
|
||||
+ pdpe = le64_to_cpu(pdpe & me_mask);
|
||||
end = (l1 << 39) + (l2 << 30);
|
||||
if (pdpe & PG_PRESENT_MASK) {
|
||||
if (pdpe & PG_PSE_MASK) {
|
||||
@@ -391,7 +409,7 @@ static void mem_info_la48(Monitor *mon, CPUArchState *env)
|
||||
for (l3 = 0; l3 < 512; l3++) {
|
||||
cpu_physical_memory_read_debug(pd_addr + l3 * 8,
|
||||
&pde, 8);
|
||||
- pde = le64_to_cpu(pde);
|
||||
+ pde = le64_to_cpu(pde & me_mask);
|
||||
end = (l1 << 39) + (l2 << 30) + (l3 << 21);
|
||||
if (pde & PG_PRESENT_MASK) {
|
||||
if (pde & PG_PSE_MASK) {
|
||||
@@ -405,7 +423,7 @@ static void mem_info_la48(Monitor *mon, CPUArchState *env)
|
||||
cpu_physical_memory_read_debug(pt_addr
|
||||
+ l4 * 8,
|
||||
&pte, 8);
|
||||
- pte = le64_to_cpu(pte);
|
||||
+ pte = le64_to_cpu(pte & me_mask);
|
||||
end = (l1 << 39) + (l2 << 30) +
|
||||
(l3 << 21) + (l4 << 12);
|
||||
if (pte & PG_PRESENT_MASK) {
|
||||
@@ -444,13 +462,16 @@ static void mem_info_la57(Monitor *mon, CPUArchState *env)
|
||||
uint64_t l0, l1, l2, l3, l4;
|
||||
uint64_t pml5e, pml4e, pdpe, pde, pte;
|
||||
uint64_t pml5_addr, pml4_addr, pdp_addr, pd_addr, pt_addr, start, end;
|
||||
+ uint64_t me_mask;
|
||||
+
|
||||
+ me_mask = sev_get_me_mask();
|
||||
|
||||
- pml5_addr = env->cr[3] & 0x3fffffffff000ULL;
|
||||
+ pml5_addr = env->cr[3] & 0x3fffffffff000ULL & me_mask;
|
||||
last_prot = 0;
|
||||
start = -1;
|
||||
for (l0 = 0; l0 < 512; l0++) {
|
||||
cpu_physical_memory_read_debug(pml5_addr + l0 * 8, &pml5e, 8);
|
||||
- pml5e = le64_to_cpu(pml5e);
|
||||
+ pml5e = le64_to_cpu(pml5e & me_mask);
|
||||
end = l0 << 48;
|
||||
if (!(pml5e & PG_PRESENT_MASK)) {
|
||||
prot = 0;
|
||||
@@ -461,7 +482,7 @@ static void mem_info_la57(Monitor *mon, CPUArchState *env)
|
||||
pml4_addr = pml5e & 0x3fffffffff000ULL;
|
||||
for (l1 = 0; l1 < 512; l1++) {
|
||||
cpu_physical_memory_read_debug(pml4_addr + l1 * 8, &pml4e, 8);
|
||||
- pml4e = le64_to_cpu(pml4e);
|
||||
+ pml4e = le64_to_cpu(pml4e & me_mask);
|
||||
end = (l0 << 48) + (l1 << 39);
|
||||
if (!(pml4e & PG_PRESENT_MASK)) {
|
||||
prot = 0;
|
||||
@@ -472,7 +493,7 @@ static void mem_info_la57(Monitor *mon, CPUArchState *env)
|
||||
pdp_addr = pml4e & 0x3fffffffff000ULL;
|
||||
for (l2 = 0; l2 < 512; l2++) {
|
||||
cpu_physical_memory_read_debug(pdp_addr + l2 * 8, &pdpe, 8);
|
||||
- pdpe = le64_to_cpu(pdpe);
|
||||
+ pdpe = le64_to_cpu(pdpe & me_mask);
|
||||
end = (l0 << 48) + (l1 << 39) + (l2 << 30);
|
||||
if (pdpe & PG_PRESENT_MASK) {
|
||||
prot = 0;
|
||||
@@ -491,7 +512,7 @@ static void mem_info_la57(Monitor *mon, CPUArchState *env)
|
||||
pd_addr = pdpe & 0x3fffffffff000ULL;
|
||||
for (l3 = 0; l3 < 512; l3++) {
|
||||
cpu_physical_memory_read_debug(pd_addr + l3 * 8, &pde, 8);
|
||||
- pde = le64_to_cpu(pde);
|
||||
+ pde = le64_to_cpu(pde & me_mask);
|
||||
end = (l0 << 48) + (l1 << 39) + (l2 << 30) + (l3 << 21);
|
||||
if (pde & PG_PRESENT_MASK) {
|
||||
prot = 0;
|
166
0068-include-add-psp-sev.h-header-file.patch
Normal file
166
0068-include-add-psp-sev.h-header-file.patch
Normal file
@ -0,0 +1,166 @@
|
||||
From 94e76aa9e24ad99ae746fa717ab4c721160128c1 Mon Sep 17 00:00:00 2001
|
||||
From: Brijesh Singh <brijesh.singh@amd.com>
|
||||
Date: Tue, 6 Feb 2018 19:08:11 -0600
|
||||
Subject: [PATCH] include: add psp-sev.h header file
|
||||
|
||||
The header file provide the ioctl command and structure to communicate
|
||||
with /dev/sev device.
|
||||
|
||||
Cc: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Cc: kvm@vger.kernel.org
|
||||
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
|
||||
[BR: FATE#322124]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
linux-headers/linux/psp-sev.h | 142 ++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 142 insertions(+)
|
||||
create mode 100644 linux-headers/linux/psp-sev.h
|
||||
|
||||
diff --git a/linux-headers/linux/psp-sev.h b/linux-headers/linux/psp-sev.h
|
||||
new file mode 100644
|
||||
index 0000000000..33e247471a
|
||||
--- /dev/null
|
||||
+++ b/linux-headers/linux/psp-sev.h
|
||||
@@ -0,0 +1,142 @@
|
||||
+/*
|
||||
+ * Userspace interface for AMD Secure Encrypted Virtualization (SEV)
|
||||
+ * platform management commands.
|
||||
+ *
|
||||
+ * Copyright (C) 2016-2017 Advanced Micro Devices, Inc.
|
||||
+ *
|
||||
+ * Author: Brijesh Singh <brijesh.singh@amd.com>
|
||||
+ *
|
||||
+ * SEV spec 0.14 is available at:
|
||||
+ * http://support.amd.com/TechDocs/55766_SEV-KM%20API_Specification.pdf
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ */
|
||||
+
|
||||
+#ifndef __PSP_SEV_USER_H__
|
||||
+#define __PSP_SEV_USER_H__
|
||||
+
|
||||
+#include <linux/types.h>
|
||||
+
|
||||
+/**
|
||||
+ * SEV platform commands
|
||||
+ */
|
||||
+enum {
|
||||
+ SEV_FACTORY_RESET = 0,
|
||||
+ SEV_PLATFORM_STATUS,
|
||||
+ SEV_PEK_GEN,
|
||||
+ SEV_PEK_CSR,
|
||||
+ SEV_PDH_GEN,
|
||||
+ SEV_PDH_CERT_EXPORT,
|
||||
+ SEV_PEK_CERT_IMPORT,
|
||||
+
|
||||
+ SEV_MAX,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * SEV Firmware status code
|
||||
+ */
|
||||
+typedef enum {
|
||||
+ SEV_RET_SUCCESS = 0,
|
||||
+ SEV_RET_INVALID_PLATFORM_STATE,
|
||||
+ SEV_RET_INVALID_GUEST_STATE,
|
||||
+ SEV_RET_INAVLID_CONFIG,
|
||||
+ SEV_RET_INVALID_LEN,
|
||||
+ SEV_RET_ALREADY_OWNED,
|
||||
+ SEV_RET_INVALID_CERTIFICATE,
|
||||
+ SEV_RET_POLICY_FAILURE,
|
||||
+ SEV_RET_INACTIVE,
|
||||
+ SEV_RET_INVALID_ADDRESS,
|
||||
+ SEV_RET_BAD_SIGNATURE,
|
||||
+ SEV_RET_BAD_MEASUREMENT,
|
||||
+ SEV_RET_ASID_OWNED,
|
||||
+ SEV_RET_INVALID_ASID,
|
||||
+ SEV_RET_WBINVD_REQUIRED,
|
||||
+ SEV_RET_DFFLUSH_REQUIRED,
|
||||
+ SEV_RET_INVALID_GUEST,
|
||||
+ SEV_RET_INVALID_COMMAND,
|
||||
+ SEV_RET_ACTIVE,
|
||||
+ SEV_RET_HWSEV_RET_PLATFORM,
|
||||
+ SEV_RET_HWSEV_RET_UNSAFE,
|
||||
+ SEV_RET_UNSUPPORTED,
|
||||
+ SEV_RET_MAX,
|
||||
+} sev_ret_code;
|
||||
+
|
||||
+/**
|
||||
+ * struct sev_user_data_status - PLATFORM_STATUS command parameters
|
||||
+ *
|
||||
+ * @major: major API version
|
||||
+ * @minor: minor API version
|
||||
+ * @state: platform state
|
||||
+ * @flags: platform config flags
|
||||
+ * @build: firmware build id for API version
|
||||
+ * @guest_count: number of active guests
|
||||
+ */
|
||||
+struct sev_user_data_status {
|
||||
+ __u8 api_major; /* Out */
|
||||
+ __u8 api_minor; /* Out */
|
||||
+ __u8 state; /* Out */
|
||||
+ __u32 flags; /* Out */
|
||||
+ __u8 build; /* Out */
|
||||
+ __u32 guest_count; /* Out */
|
||||
+} __attribute__((packed));
|
||||
+
|
||||
+/**
|
||||
+ * struct sev_user_data_pek_csr - PEK_CSR command parameters
|
||||
+ *
|
||||
+ * @address: PEK certificate chain
|
||||
+ * @length: length of certificate
|
||||
+ */
|
||||
+struct sev_user_data_pek_csr {
|
||||
+ __u64 address; /* In */
|
||||
+ __u32 length; /* In/Out */
|
||||
+} __attribute__((packed));
|
||||
+
|
||||
+/**
|
||||
+ * struct sev_user_data_cert_import - PEK_CERT_IMPORT command parameters
|
||||
+ *
|
||||
+ * @pek_address: PEK certificate chain
|
||||
+ * @pek_len: length of PEK certificate
|
||||
+ * @oca_address: OCA certificate chain
|
||||
+ * @oca_len: length of OCA certificate
|
||||
+ */
|
||||
+struct sev_user_data_pek_cert_import {
|
||||
+ __u64 pek_cert_address; /* In */
|
||||
+ __u32 pek_cert_len; /* In */
|
||||
+ __u64 oca_cert_address; /* In */
|
||||
+ __u32 oca_cert_len; /* In */
|
||||
+} __attribute__((packed));
|
||||
+
|
||||
+/**
|
||||
+ * struct sev_user_data_pdh_cert_export - PDH_CERT_EXPORT command parameters
|
||||
+ *
|
||||
+ * @pdh_address: PDH certificate address
|
||||
+ * @pdh_len: length of PDH certificate
|
||||
+ * @cert_chain_address: PDH certificate chain
|
||||
+ * @cert_chain_len: length of PDH certificate chain
|
||||
+ */
|
||||
+struct sev_user_data_pdh_cert_export {
|
||||
+ __u64 pdh_cert_address; /* In */
|
||||
+ __u32 pdh_cert_len; /* In/Out */
|
||||
+ __u64 cert_chain_address; /* In */
|
||||
+ __u32 cert_chain_len; /* In/Out */
|
||||
+} __attribute__((packed));
|
||||
+
|
||||
+/**
|
||||
+ * struct sev_issue_cmd - SEV ioctl parameters
|
||||
+ *
|
||||
+ * @cmd: SEV commands to execute
|
||||
+ * @opaque: pointer to the command structure
|
||||
+ * @error: SEV FW return code on failure
|
||||
+ */
|
||||
+struct sev_issue_cmd {
|
||||
+ __u32 cmd; /* In */
|
||||
+ __u64 data; /* In */
|
||||
+ __u32 error; /* Out */
|
||||
+} __attribute__((packed));
|
||||
+
|
||||
+#define SEV_IOC_TYPE 'S'
|
||||
+#define SEV_ISSUE_CMD _IOWR(SEV_IOC_TYPE, 0x0, struct sev_issue_cmd)
|
||||
+
|
||||
+#endif /* __PSP_USER_SEV_H */
|
74
0069-sev-add-support-to-query-PLATFORM_S.patch
Normal file
74
0069-sev-add-support-to-query-PLATFORM_S.patch
Normal file
@ -0,0 +1,74 @@
|
||||
From 8798ba8f4a4ba43cf7a34960ed70b32cbe69a4f6 Mon Sep 17 00:00:00 2001
|
||||
From: Brijesh Singh <brijesh.singh@amd.com>
|
||||
Date: Tue, 6 Feb 2018 19:08:11 -0600
|
||||
Subject: [PATCH] sev: add support to query PLATFORM_STATUS command
|
||||
|
||||
The command is used to query the SEV API version and build id.
|
||||
|
||||
Cc: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Cc: kvm@vger.kernel.org
|
||||
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
|
||||
[BR: FATE#322124]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
accel/kvm/sev.c | 33 +++++++++++++++++++++++++++++++++
|
||||
1 file changed, 33 insertions(+)
|
||||
|
||||
diff --git a/accel/kvm/sev.c b/accel/kvm/sev.c
|
||||
index 7b57575e2f..186834364e 100644
|
||||
--- a/accel/kvm/sev.c
|
||||
+++ b/accel/kvm/sev.c
|
||||
@@ -21,6 +21,9 @@
|
||||
#include "trace.h"
|
||||
#include "qapi-event.h"
|
||||
|
||||
+#include <sys/ioctl.h>
|
||||
+#include <linux/psp-sev.h>
|
||||
+
|
||||
#define DEFAULT_GUEST_POLICY 0x1 /* disable debug */
|
||||
#define DEFAULT_SEV_DEVICE "/dev/sev"
|
||||
#define GUEST_POLICY_DBG_BIT 0x1
|
||||
@@ -91,6 +94,22 @@ sev_ioctl(int cmd, void *data, int *error)
|
||||
return r;
|
||||
}
|
||||
|
||||
+static int
|
||||
+sev_platform_ioctl(int cmd, void *data, int *error)
|
||||
+{
|
||||
+ int r;
|
||||
+ struct sev_issue_cmd arg;
|
||||
+
|
||||
+ arg.cmd = cmd;
|
||||
+ arg.data = (unsigned long)data;
|
||||
+ r = ioctl(sev_fd, SEV_ISSUE_CMD, &arg);
|
||||
+ if (error) {
|
||||
+ *error = arg.error;
|
||||
+ }
|
||||
+
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
static const char *
|
||||
fw_error_to_str(int code)
|
||||
{
|
||||
@@ -380,6 +399,20 @@ sev_enabled(void)
|
||||
void
|
||||
sev_get_fw_version(uint8_t *major, uint8_t *minor, uint8_t *build)
|
||||
{
|
||||
+ struct sev_user_data_status status = {};
|
||||
+ int r, err;
|
||||
+
|
||||
+ r = sev_platform_ioctl(SEV_PLATFORM_STATUS, &status, &err);
|
||||
+ if (r) {
|
||||
+ error_report("%s: failed to get platform status ret=%d"
|
||||
+ "fw_error='%d: %s'", __func__, r, err,
|
||||
+ fw_error_to_str(err));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ *major = status.api_major;
|
||||
+ *minor = status.api_minor;
|
||||
+ *build = status.build;
|
||||
}
|
||||
|
||||
void
|
40
0070-sev-add-support-to-KVM_SEV_GUEST_ST.patch
Normal file
40
0070-sev-add-support-to-KVM_SEV_GUEST_ST.patch
Normal file
@ -0,0 +1,40 @@
|
||||
From 0139a4366095226b25d4f3f819fc0b0c260ce46b Mon Sep 17 00:00:00 2001
|
||||
From: Brijesh Singh <brijesh.singh@amd.com>
|
||||
Date: Tue, 6 Feb 2018 19:08:11 -0600
|
||||
Subject: [PATCH] sev: add support to KVM_SEV_GUEST_STATUS
|
||||
|
||||
The command is used to query the current SEV guest status. We use this
|
||||
command to query the guest policy for QMP query-sev command.
|
||||
|
||||
Cc: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Cc: kvm@vger.kernel.org
|
||||
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
|
||||
[BR: FATE#322124]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
accel/kvm/sev.c | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
diff --git a/accel/kvm/sev.c b/accel/kvm/sev.c
|
||||
index 186834364e..b149f4ae64 100644
|
||||
--- a/accel/kvm/sev.c
|
||||
+++ b/accel/kvm/sev.c
|
||||
@@ -418,6 +418,18 @@ sev_get_fw_version(uint8_t *major, uint8_t *minor, uint8_t *build)
|
||||
void
|
||||
sev_get_policy(uint32_t *policy)
|
||||
{
|
||||
+ struct kvm_sev_guest_status status = {};
|
||||
+ int r, err;
|
||||
+
|
||||
+ r = sev_ioctl(KVM_SEV_GUEST_STATUS, &status, &err);
|
||||
+ if (r) {
|
||||
+ error_report("%s: failed to get platform status ret=%d "
|
||||
+ "fw_error='%d: %s'", __func__, r, err,
|
||||
+ fw_error_to_str(err));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ *policy = status.policy;
|
||||
}
|
||||
|
||||
static int
|
83
0071-qmp-add-query-sev-launch-measure-co.patch
Normal file
83
0071-qmp-add-query-sev-launch-measure-co.patch
Normal file
@ -0,0 +1,83 @@
|
||||
From 49a869039c960dbc02e6bbee9d0f0d0ce39003d5 Mon Sep 17 00:00:00 2001
|
||||
From: Brijesh Singh <brijesh.singh@amd.com>
|
||||
Date: Tue, 6 Feb 2018 19:08:11 -0600
|
||||
Subject: [PATCH] qmp: add query-sev-launch-measure command
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The command can be used by libvirt to retrieve the measurement of SEV guest.
|
||||
This measurement is a signature of the memory contents that was encrypted
|
||||
through the LAUNCH_UPDATE_DATA.
|
||||
|
||||
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
|
||||
Cc: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
|
||||
Cc: Markus Armbruster <armbru@redhat.com>
|
||||
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
|
||||
[BR: FATE#322124]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
qapi-schema.json | 30 ++++++++++++++++++++++++++++++
|
||||
qmp.c | 14 ++++++++++++++
|
||||
2 files changed, 44 insertions(+)
|
||||
|
||||
diff --git a/qapi-schema.json b/qapi-schema.json
|
||||
index 40c2de3026..8ab8e74956 100644
|
||||
--- a/qapi-schema.json
|
||||
+++ b/qapi-schema.json
|
||||
@@ -3247,3 +3247,33 @@
|
||||
#
|
||||
##
|
||||
{ 'command': 'query-sev', 'returns': 'SevInfo' }
|
||||
+
|
||||
+##
|
||||
+# @SevLaunchMeasureInfo:
|
||||
+#
|
||||
+# SEV Guest Launch measurement information
|
||||
+#
|
||||
+# @data: the measurement value encoded in base64
|
||||
+#
|
||||
+# Since: 2.12
|
||||
+#
|
||||
+# Notes: If measurement is not available then a null measurement is returned.
|
||||
+##
|
||||
+{ 'struct': 'SevLaunchMeasureInfo', 'data': {'data': 'str'} }
|
||||
+
|
||||
+##
|
||||
+# @query-sev-launch-measure:
|
||||
+#
|
||||
+# Query the SEV guest launch information.
|
||||
+#
|
||||
+# Returns: The @SevLaunchMeasureInfo for the guest
|
||||
+#
|
||||
+# Since: 2.12
|
||||
+#
|
||||
+# Example:
|
||||
+#
|
||||
+# -> { "execute": "query-sev-launch-measure" }
|
||||
+# <- { "return": { "data": "4l8LXeNlSPUDlXPJG5966/8%YZ" } }
|
||||
+#
|
||||
+##
|
||||
+{ 'command': 'query-sev-launch-measure', 'returns': 'SevLaunchMeasureInfo' }
|
||||
diff --git a/qmp.c b/qmp.c
|
||||
index 4cd01ea666..d9ec4bf18e 100644
|
||||
--- a/qmp.c
|
||||
+++ b/qmp.c
|
||||
@@ -738,3 +738,17 @@ SevInfo *qmp_query_sev(Error **errp)
|
||||
|
||||
return info;
|
||||
}
|
||||
+
|
||||
+SevLaunchMeasureInfo *qmp_query_sev_launch_measure(Error **errp)
|
||||
+{
|
||||
+ SevLaunchMeasureInfo *info = NULL;
|
||||
+
|
||||
+ if (sev_enabled()) {
|
||||
+ info = g_malloc0(sizeof(*info));
|
||||
+ info->data = sev_get_launch_measurement();
|
||||
+ } else {
|
||||
+ error_setg(errp, "SEV is not enabled");
|
||||
+ }
|
||||
+
|
||||
+ return info;
|
||||
+}
|
45
0072-sev-Fix-build-for-non-x86-hosts.patch
Normal file
45
0072-sev-Fix-build-for-non-x86-hosts.patch
Normal file
@ -0,0 +1,45 @@
|
||||
From 5c1a357744cfd2917705907bc3d50efd1184b7d9 Mon Sep 17 00:00:00 2001
|
||||
From: Bruce Rogers <brogers@suse.com>
|
||||
Date: Wed, 7 Feb 2018 14:01:55 -0700
|
||||
Subject: [PATCH] sev: Fix build for non-x86 hosts
|
||||
|
||||
I imagine the upstream code will still change in a way to not
|
||||
require this work around, but for now this works.
|
||||
Also bypass the test for query-sev-launch-measure qmp command test,
|
||||
since it causes the qemu-testsuite package to fail to build.
|
||||
|
||||
[BR: FATE#322124]
|
||||
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||||
---
|
||||
accel/kvm/sev.c | 4 ++++
|
||||
tests/qmp-test.c | 1 +
|
||||
2 files changed, 5 insertions(+)
|
||||
|
||||
diff --git a/accel/kvm/sev.c b/accel/kvm/sev.c
|
||||
index b149f4ae64..0e48d1f249 100644
|
||||
--- a/accel/kvm/sev.c
|
||||
+++ b/accel/kvm/sev.c
|
||||
@@ -322,7 +322,11 @@ sev_get_host_cbitpos(void)
|
||||
{
|
||||
uint32_t ebx;
|
||||
|
||||
+#ifdef TARGET_X86_64
|
||||
host_cpuid(0x8000001F, 0, NULL, &ebx, NULL, NULL);
|
||||
+#else
|
||||
+ ebx = 0;
|
||||
+#endif
|
||||
|
||||
return ebx & 0x3f;
|
||||
}
|
||||
diff --git a/tests/qmp-test.c b/tests/qmp-test.c
|
||||
index c5a5c10b41..2b2d9b2a4a 100644
|
||||
--- a/tests/qmp-test.c
|
||||
+++ b/tests/qmp-test.c
|
||||
@@ -200,6 +200,7 @@ static bool query_is_blacklisted(const char *cmd)
|
||||
"query-gic-capabilities", /* arm */
|
||||
/* Success depends on target-specific build configuration: */
|
||||
"query-pci", /* CONFIG_PCI */
|
||||
+ "query-sev-launch-measure", /* not fully cooked yet */
|
||||
NULL
|
||||
};
|
||||
int i;
|
@ -1,3 +1,41 @@
|
||||
-------------------------------------------------------------------
|
||||
Thu Feb 8 18:30:53 UTC 2018 - brogers@suse.com
|
||||
|
||||
- Patch queue updated from git://github.com/openSUSE/qemu.git opensuse-2.11
|
||||
* Patches added:
|
||||
0046-memattrs-add-debug-attribute.patch
|
||||
0047-exec-add-ram_debug_ops-support.patch
|
||||
0048-exec-add-debug-version-of-physical-.patch
|
||||
0049-monitor-i386-use-debug-APIs-when-ac.patch
|
||||
0050-target-i386-add-memory-encryption-f.patch
|
||||
0051-machine-add-memory-encryption-prope.patch
|
||||
0052-kvm-update-kvm.h-to-include-memory-.patch
|
||||
0053-docs-add-AMD-Secure-Encrypted-Virtu.patch
|
||||
0054-accel-add-Secure-Encrypted-Virtuliz.patch
|
||||
0055-sev-add-command-to-initialize-the-m.patch
|
||||
0056-sev-register-the-guest-memory-range.patch
|
||||
0057-kvm-introduce-memory-encryption-API.patch
|
||||
0058-qmp-add-query-sev-command.patch
|
||||
0059-hmp-add-info-sev-command.patch
|
||||
0060-sev-add-command-to-create-launch-me.patch
|
||||
0061-sev-add-command-to-encrypt-guest-me.patch
|
||||
0062-target-i386-encrypt-bios-rom.patch
|
||||
0063-sev-add-support-to-LAUNCH_MEASURE-c.patch
|
||||
0064-sev-Finalize-the-SEV-guest-launch-f.patch
|
||||
0065-hw-i386-set-ram_debug_ops-when-memo.patch
|
||||
0066-sev-add-debug-encrypt-and-decrypt-c.patch
|
||||
0067-target-i386-clear-C-bit-when-walkin.patch
|
||||
0068-include-add-psp-sev.h-header-file.patch
|
||||
0069-sev-add-support-to-query-PLATFORM_S.patch
|
||||
0070-sev-add-support-to-KVM_SEV_GUEST_ST.patch
|
||||
0071-qmp-add-query-sev-launch-measure-co.patch
|
||||
0072-sev-Fix-build-for-non-x86-hosts.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Feb 8 15:26:00 UTC 2018 - brogers@suse.com
|
||||
|
||||
- Update python3 related patches now that they are upstream
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon Jan 29 21:51:20 UTC 2018 - brogers@suse.com
|
||||
|
||||
|
@ -71,6 +71,33 @@ Patch0042: 0042-configure-allow-use-of-python-3.patch
|
||||
Patch0043: 0043-input-add-missing-JIS-keys-to-virti.patch
|
||||
Patch0044: 0044-Make-installed-scripts-explicitly-p.patch
|
||||
Patch0045: 0045-pc-fail-memory-hot-plug-unplug-with.patch
|
||||
Patch0046: 0046-memattrs-add-debug-attribute.patch
|
||||
Patch0047: 0047-exec-add-ram_debug_ops-support.patch
|
||||
Patch0048: 0048-exec-add-debug-version-of-physical-.patch
|
||||
Patch0049: 0049-monitor-i386-use-debug-APIs-when-ac.patch
|
||||
Patch0050: 0050-target-i386-add-memory-encryption-f.patch
|
||||
Patch0051: 0051-machine-add-memory-encryption-prope.patch
|
||||
Patch0052: 0052-kvm-update-kvm.h-to-include-memory-.patch
|
||||
Patch0053: 0053-docs-add-AMD-Secure-Encrypted-Virtu.patch
|
||||
Patch0054: 0054-accel-add-Secure-Encrypted-Virtuliz.patch
|
||||
Patch0055: 0055-sev-add-command-to-initialize-the-m.patch
|
||||
Patch0056: 0056-sev-register-the-guest-memory-range.patch
|
||||
Patch0057: 0057-kvm-introduce-memory-encryption-API.patch
|
||||
Patch0058: 0058-qmp-add-query-sev-command.patch
|
||||
Patch0059: 0059-hmp-add-info-sev-command.patch
|
||||
Patch0060: 0060-sev-add-command-to-create-launch-me.patch
|
||||
Patch0061: 0061-sev-add-command-to-encrypt-guest-me.patch
|
||||
Patch0062: 0062-target-i386-encrypt-bios-rom.patch
|
||||
Patch0063: 0063-sev-add-support-to-LAUNCH_MEASURE-c.patch
|
||||
Patch0064: 0064-sev-Finalize-the-SEV-guest-launch-f.patch
|
||||
Patch0065: 0065-hw-i386-set-ram_debug_ops-when-memo.patch
|
||||
Patch0066: 0066-sev-add-debug-encrypt-and-decrypt-c.patch
|
||||
Patch0067: 0067-target-i386-clear-C-bit-when-walkin.patch
|
||||
Patch0068: 0068-include-add-psp-sev.h-header-file.patch
|
||||
Patch0069: 0069-sev-add-support-to-query-PLATFORM_S.patch
|
||||
Patch0070: 0070-sev-add-support-to-KVM_SEV_GUEST_ST.patch
|
||||
Patch0071: 0071-qmp-add-query-sev-launch-measure-co.patch
|
||||
Patch0072: 0072-sev-Fix-build-for-non-x86-hosts.patch
|
||||
# Please do not add QEMU patches manually here.
|
||||
# Run update_git.sh to regenerate this queue.
|
||||
Source400: update_git.sh
|
||||
@ -145,6 +172,33 @@ syscall layer occurs on the native hardware and operating system.
|
||||
%patch0043 -p1
|
||||
%patch0044 -p1
|
||||
%patch0045 -p1
|
||||
%patch0046 -p1
|
||||
%patch0047 -p1
|
||||
%patch0048 -p1
|
||||
%patch0049 -p1
|
||||
%patch0050 -p1
|
||||
%patch0051 -p1
|
||||
%patch0052 -p1
|
||||
%patch0053 -p1
|
||||
%patch0054 -p1
|
||||
%patch0055 -p1
|
||||
%patch0056 -p1
|
||||
%patch0057 -p1
|
||||
%patch0058 -p1
|
||||
%patch0059 -p1
|
||||
%patch0060 -p1
|
||||
%patch0061 -p1
|
||||
%patch0062 -p1
|
||||
%patch0063 -p1
|
||||
%patch0064 -p1
|
||||
%patch0065 -p1
|
||||
%patch0066 -p1
|
||||
%patch0067 -p1
|
||||
%patch0068 -p1
|
||||
%patch0069 -p1
|
||||
%patch0070 -p1
|
||||
%patch0071 -p1
|
||||
%patch0072 -p1
|
||||
|
||||
%build
|
||||
./configure \
|
||||
|
@ -1,3 +1,42 @@
|
||||
-------------------------------------------------------------------
|
||||
Thu Feb 8 18:29:30 UTC 2018 - brogers@suse.com
|
||||
|
||||
- Add AMD SEV (Secure Encrypted Virtualization) support by taking
|
||||
the v7 series of the patches posted to qemu ml. (fate#322124)
|
||||
0046-memattrs-add-debug-attribute.patch
|
||||
0047-exec-add-ram_debug_ops-support.patch
|
||||
0048-exec-add-debug-version-of-physical-.patch
|
||||
0049-monitor-i386-use-debug-APIs-when-ac.patch
|
||||
0050-target-i386-add-memory-encryption-f.patch
|
||||
0051-machine-add-memory-encryption-prope.patch
|
||||
0052-kvm-update-kvm.h-to-include-memory-.patch
|
||||
0053-docs-add-AMD-Secure-Encrypted-Virtu.patch
|
||||
0054-accel-add-Secure-Encrypted-Virtuliz.patch
|
||||
0055-sev-add-command-to-initialize-the-m.patch
|
||||
0056-sev-register-the-guest-memory-range.patch
|
||||
0057-kvm-introduce-memory-encryption-API.patch
|
||||
0058-qmp-add-query-sev-command.patch
|
||||
0059-hmp-add-info-sev-command.patch
|
||||
0060-sev-add-command-to-create-launch-me.patch
|
||||
0061-sev-add-command-to-encrypt-guest-me.patch
|
||||
0062-target-i386-encrypt-bios-rom.patch
|
||||
0063-sev-add-support-to-LAUNCH_MEASURE-c.patch
|
||||
0064-sev-Finalize-the-SEV-guest-launch-f.patch
|
||||
0065-hw-i386-set-ram_debug_ops-when-memo.patch
|
||||
0066-sev-add-debug-encrypt-and-decrypt-c.patch
|
||||
0067-target-i386-clear-C-bit-when-walkin.patch
|
||||
0068-include-add-psp-sev.h-header-file.patch
|
||||
0069-sev-add-support-to-query-PLATFORM_S.patch
|
||||
0070-sev-add-support-to-KVM_SEV_GUEST_ST.patch
|
||||
0071-qmp-add-query-sev-launch-measure-co.patch
|
||||
0072-sev-Fix-build-for-non-x86-hosts.patch
|
||||
- Patch queue updated from git://github.com/openSUSE/qemu.git opensuse-2.11
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Feb 8 15:24:44 UTC 2018 - brogers@suse.com
|
||||
|
||||
- Update python3 related patches now that they are upstream
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Feb 8 00:12:14 UTC 2018 - jfehlig@suse.com
|
||||
|
||||
|
@ -175,6 +175,33 @@ Patch0042: 0042-configure-allow-use-of-python-3.patch
|
||||
Patch0043: 0043-input-add-missing-JIS-keys-to-virti.patch
|
||||
Patch0044: 0044-Make-installed-scripts-explicitly-p.patch
|
||||
Patch0045: 0045-pc-fail-memory-hot-plug-unplug-with.patch
|
||||
Patch0046: 0046-memattrs-add-debug-attribute.patch
|
||||
Patch0047: 0047-exec-add-ram_debug_ops-support.patch
|
||||
Patch0048: 0048-exec-add-debug-version-of-physical-.patch
|
||||
Patch0049: 0049-monitor-i386-use-debug-APIs-when-ac.patch
|
||||
Patch0050: 0050-target-i386-add-memory-encryption-f.patch
|
||||
Patch0051: 0051-machine-add-memory-encryption-prope.patch
|
||||
Patch0052: 0052-kvm-update-kvm.h-to-include-memory-.patch
|
||||
Patch0053: 0053-docs-add-AMD-Secure-Encrypted-Virtu.patch
|
||||
Patch0054: 0054-accel-add-Secure-Encrypted-Virtuliz.patch
|
||||
Patch0055: 0055-sev-add-command-to-initialize-the-m.patch
|
||||
Patch0056: 0056-sev-register-the-guest-memory-range.patch
|
||||
Patch0057: 0057-kvm-introduce-memory-encryption-API.patch
|
||||
Patch0058: 0058-qmp-add-query-sev-command.patch
|
||||
Patch0059: 0059-hmp-add-info-sev-command.patch
|
||||
Patch0060: 0060-sev-add-command-to-create-launch-me.patch
|
||||
Patch0061: 0061-sev-add-command-to-encrypt-guest-me.patch
|
||||
Patch0062: 0062-target-i386-encrypt-bios-rom.patch
|
||||
Patch0063: 0063-sev-add-support-to-LAUNCH_MEASURE-c.patch
|
||||
Patch0064: 0064-sev-Finalize-the-SEV-guest-launch-f.patch
|
||||
Patch0065: 0065-hw-i386-set-ram_debug_ops-when-memo.patch
|
||||
Patch0066: 0066-sev-add-debug-encrypt-and-decrypt-c.patch
|
||||
Patch0067: 0067-target-i386-clear-C-bit-when-walkin.patch
|
||||
Patch0068: 0068-include-add-psp-sev.h-header-file.patch
|
||||
Patch0069: 0069-sev-add-support-to-query-PLATFORM_S.patch
|
||||
Patch0070: 0070-sev-add-support-to-KVM_SEV_GUEST_ST.patch
|
||||
Patch0071: 0071-qmp-add-query-sev-launch-measure-co.patch
|
||||
Patch0072: 0072-sev-Fix-build-for-non-x86-hosts.patch
|
||||
# Please do not add QEMU patches manually here.
|
||||
# Run update_git.sh to regenerate this queue.
|
||||
|
||||
@ -816,6 +843,33 @@ This package provides a service file for starting and stopping KSM.
|
||||
%patch0043 -p1
|
||||
%patch0044 -p1
|
||||
%patch0045 -p1
|
||||
%patch0046 -p1
|
||||
%patch0047 -p1
|
||||
%patch0048 -p1
|
||||
%patch0049 -p1
|
||||
%patch0050 -p1
|
||||
%patch0051 -p1
|
||||
%patch0052 -p1
|
||||
%patch0053 -p1
|
||||
%patch0054 -p1
|
||||
%patch0055 -p1
|
||||
%patch0056 -p1
|
||||
%patch0057 -p1
|
||||
%patch0058 -p1
|
||||
%patch0059 -p1
|
||||
%patch0060 -p1
|
||||
%patch0061 -p1
|
||||
%patch0062 -p1
|
||||
%patch0063 -p1
|
||||
%patch0064 -p1
|
||||
%patch0065 -p1
|
||||
%patch0066 -p1
|
||||
%patch0067 -p1
|
||||
%patch0068 -p1
|
||||
%patch0069 -p1
|
||||
%patch0070 -p1
|
||||
%patch0071 -p1
|
||||
%patch0072 -p1
|
||||
|
||||
%if 0%{?suse_version} > 1320
|
||||
%patch1000 -p1
|
||||
|
39
qemu.changes
39
qemu.changes
@ -1,3 +1,42 @@
|
||||
-------------------------------------------------------------------
|
||||
Thu Feb 8 18:29:30 UTC 2018 - brogers@suse.com
|
||||
|
||||
- Add AMD SEV (Secure Encrypted Virtualization) support by taking
|
||||
the v7 series of the patches posted to qemu ml. (fate#322124)
|
||||
0046-memattrs-add-debug-attribute.patch
|
||||
0047-exec-add-ram_debug_ops-support.patch
|
||||
0048-exec-add-debug-version-of-physical-.patch
|
||||
0049-monitor-i386-use-debug-APIs-when-ac.patch
|
||||
0050-target-i386-add-memory-encryption-f.patch
|
||||
0051-machine-add-memory-encryption-prope.patch
|
||||
0052-kvm-update-kvm.h-to-include-memory-.patch
|
||||
0053-docs-add-AMD-Secure-Encrypted-Virtu.patch
|
||||
0054-accel-add-Secure-Encrypted-Virtuliz.patch
|
||||
0055-sev-add-command-to-initialize-the-m.patch
|
||||
0056-sev-register-the-guest-memory-range.patch
|
||||
0057-kvm-introduce-memory-encryption-API.patch
|
||||
0058-qmp-add-query-sev-command.patch
|
||||
0059-hmp-add-info-sev-command.patch
|
||||
0060-sev-add-command-to-create-launch-me.patch
|
||||
0061-sev-add-command-to-encrypt-guest-me.patch
|
||||
0062-target-i386-encrypt-bios-rom.patch
|
||||
0063-sev-add-support-to-LAUNCH_MEASURE-c.patch
|
||||
0064-sev-Finalize-the-SEV-guest-launch-f.patch
|
||||
0065-hw-i386-set-ram_debug_ops-when-memo.patch
|
||||
0066-sev-add-debug-encrypt-and-decrypt-c.patch
|
||||
0067-target-i386-clear-C-bit-when-walkin.patch
|
||||
0068-include-add-psp-sev.h-header-file.patch
|
||||
0069-sev-add-support-to-query-PLATFORM_S.patch
|
||||
0070-sev-add-support-to-KVM_SEV_GUEST_ST.patch
|
||||
0071-qmp-add-query-sev-launch-measure-co.patch
|
||||
0072-sev-Fix-build-for-non-x86-hosts.patch
|
||||
- Patch queue updated from git://github.com/openSUSE/qemu.git opensuse-2.11
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Feb 8 15:24:44 UTC 2018 - brogers@suse.com
|
||||
|
||||
- Update python3 related patches now that they are upstream
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Feb 8 00:12:14 UTC 2018 - jfehlig@suse.com
|
||||
|
||||
|
54
qemu.spec
54
qemu.spec
@ -175,6 +175,33 @@ Patch0042: 0042-configure-allow-use-of-python-3.patch
|
||||
Patch0043: 0043-input-add-missing-JIS-keys-to-virti.patch
|
||||
Patch0044: 0044-Make-installed-scripts-explicitly-p.patch
|
||||
Patch0045: 0045-pc-fail-memory-hot-plug-unplug-with.patch
|
||||
Patch0046: 0046-memattrs-add-debug-attribute.patch
|
||||
Patch0047: 0047-exec-add-ram_debug_ops-support.patch
|
||||
Patch0048: 0048-exec-add-debug-version-of-physical-.patch
|
||||
Patch0049: 0049-monitor-i386-use-debug-APIs-when-ac.patch
|
||||
Patch0050: 0050-target-i386-add-memory-encryption-f.patch
|
||||
Patch0051: 0051-machine-add-memory-encryption-prope.patch
|
||||
Patch0052: 0052-kvm-update-kvm.h-to-include-memory-.patch
|
||||
Patch0053: 0053-docs-add-AMD-Secure-Encrypted-Virtu.patch
|
||||
Patch0054: 0054-accel-add-Secure-Encrypted-Virtuliz.patch
|
||||
Patch0055: 0055-sev-add-command-to-initialize-the-m.patch
|
||||
Patch0056: 0056-sev-register-the-guest-memory-range.patch
|
||||
Patch0057: 0057-kvm-introduce-memory-encryption-API.patch
|
||||
Patch0058: 0058-qmp-add-query-sev-command.patch
|
||||
Patch0059: 0059-hmp-add-info-sev-command.patch
|
||||
Patch0060: 0060-sev-add-command-to-create-launch-me.patch
|
||||
Patch0061: 0061-sev-add-command-to-encrypt-guest-me.patch
|
||||
Patch0062: 0062-target-i386-encrypt-bios-rom.patch
|
||||
Patch0063: 0063-sev-add-support-to-LAUNCH_MEASURE-c.patch
|
||||
Patch0064: 0064-sev-Finalize-the-SEV-guest-launch-f.patch
|
||||
Patch0065: 0065-hw-i386-set-ram_debug_ops-when-memo.patch
|
||||
Patch0066: 0066-sev-add-debug-encrypt-and-decrypt-c.patch
|
||||
Patch0067: 0067-target-i386-clear-C-bit-when-walkin.patch
|
||||
Patch0068: 0068-include-add-psp-sev.h-header-file.patch
|
||||
Patch0069: 0069-sev-add-support-to-query-PLATFORM_S.patch
|
||||
Patch0070: 0070-sev-add-support-to-KVM_SEV_GUEST_ST.patch
|
||||
Patch0071: 0071-qmp-add-query-sev-launch-measure-co.patch
|
||||
Patch0072: 0072-sev-Fix-build-for-non-x86-hosts.patch
|
||||
# Please do not add QEMU patches manually here.
|
||||
# Run update_git.sh to regenerate this queue.
|
||||
|
||||
@ -816,6 +843,33 @@ This package provides a service file for starting and stopping KSM.
|
||||
%patch0043 -p1
|
||||
%patch0044 -p1
|
||||
%patch0045 -p1
|
||||
%patch0046 -p1
|
||||
%patch0047 -p1
|
||||
%patch0048 -p1
|
||||
%patch0049 -p1
|
||||
%patch0050 -p1
|
||||
%patch0051 -p1
|
||||
%patch0052 -p1
|
||||
%patch0053 -p1
|
||||
%patch0054 -p1
|
||||
%patch0055 -p1
|
||||
%patch0056 -p1
|
||||
%patch0057 -p1
|
||||
%patch0058 -p1
|
||||
%patch0059 -p1
|
||||
%patch0060 -p1
|
||||
%patch0061 -p1
|
||||
%patch0062 -p1
|
||||
%patch0063 -p1
|
||||
%patch0064 -p1
|
||||
%patch0065 -p1
|
||||
%patch0066 -p1
|
||||
%patch0067 -p1
|
||||
%patch0068 -p1
|
||||
%patch0069 -p1
|
||||
%patch0070 -p1
|
||||
%patch0071 -p1
|
||||
%patch0072 -p1
|
||||
|
||||
%if 0%{?suse_version} > 1320
|
||||
%patch1000 -p1
|
||||
|
Loading…
Reference in New Issue
Block a user