From 49812da5a8c0e5ec147598c5227875ea6a79f1ceef21e6b0030f67696301fcaf Mon Sep 17 00:00:00 2001 From: Bruce Rogers Date: Thu, 8 Feb 2018 19:55:31 +0000 Subject: [PATCH] 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 --- ...-string-input-visitor-Fix-uint64-par.patch | 4 +- ...-test-string-input-visitor-Add-int-t.patch | 20 +- ...-qapi-use-items-values-intead-of-ite.patch | 11 +- ...-qapi-Use-OrderedDict-from-standard-.patch | 9 +- ...-qapi-adapt-to-moved-location-of-Str.patch | 9 +- ...-qapi-Adapt-to-moved-location-of-mak.patch | 10 +- ...-qapi-remove-q-arg-to-diff-when-comp.patch | 10 +- ...-qapi-ensure-stable-sort-ordering-wh.patch | 9 +- ...-qapi-force-a-UTF-8-locale-for-runni.patch | 26 +- ...-scripts-ensure-signrom-treats-data-.patch | 9 +- 0042-configure-allow-use-of-python-3.patch | 10 +- ...-input-add-missing-JIS-keys-to-virti.patch | 13 +- ...-Make-installed-scripts-explicitly-p.patch | 6 +- ...-pc-fail-memory-hot-plug-unplug-with.patch | 2 +- 0046-memattrs-add-debug-attribute.patch | 39 ++ 0047-exec-add-ram_debug_ops-support.patch | 230 ++++++++++ ...-exec-add-debug-version-of-physical-.patch | 107 +++++ ...-monitor-i386-use-debug-APIs-when-ac.patch | 368 ++++++++++++++++ ...-target-i386-add-memory-encryption-f.patch | 137 ++++++ ...-machine-add-memory-encryption-prope.patch | 86 ++++ ...-kvm-update-kvm.h-to-include-memory-.patch | 118 +++++ ...-docs-add-AMD-Secure-Encrypted-Virtu.patch | 115 +++++ ...-accel-add-Secure-Encrypted-Virtuliz.patch | 403 ++++++++++++++++++ ...-sev-add-command-to-initialize-the-m.patch | 349 +++++++++++++++ ...-sev-register-the-guest-memory-range.patch | 94 ++++ ...-kvm-introduce-memory-encryption-API.patch | 129 ++++++ 0058-qmp-add-query-sev-command.patch | 108 +++++ 0059-hmp-add-info-sev-command.patch | 86 ++++ ...-sev-add-command-to-create-launch-me.patch | 189 ++++++++ ...-sev-add-command-to-encrypt-guest-me.patch | 126 ++++++ 0062-target-i386-encrypt-bios-rom.patch | 49 +++ ...-sev-add-support-to-LAUNCH_MEASURE-c.patch | 169 ++++++++ ...-sev-Finalize-the-SEV-guest-launch-f.patch | 74 ++++ ...-hw-i386-set-ram_debug_ops-when-memo.patch | 58 +++ ...-sev-add-debug-encrypt-and-decrypt-c.patch | 156 +++++++ ...-target-i386-clear-C-bit-when-walkin.patch | 361 ++++++++++++++++ 0068-include-add-psp-sev.h-header-file.patch | 166 ++++++++ ...-sev-add-support-to-query-PLATFORM_S.patch | 74 ++++ ...-sev-add-support-to-KVM_SEV_GUEST_ST.patch | 40 ++ ...-qmp-add-query-sev-launch-measure-co.patch | 83 ++++ 0072-sev-Fix-build-for-non-x86-hosts.patch | 45 ++ qemu-linux-user.changes | 38 ++ qemu-linux-user.spec | 54 +++ qemu-testsuite.changes | 39 ++ qemu-testsuite.spec | 54 +++ qemu.changes | 39 ++ qemu.spec | 54 +++ 47 files changed, 4344 insertions(+), 41 deletions(-) create mode 100644 0046-memattrs-add-debug-attribute.patch create mode 100644 0047-exec-add-ram_debug_ops-support.patch create mode 100644 0048-exec-add-debug-version-of-physical-.patch create mode 100644 0049-monitor-i386-use-debug-APIs-when-ac.patch create mode 100644 0050-target-i386-add-memory-encryption-f.patch create mode 100644 0051-machine-add-memory-encryption-prope.patch create mode 100644 0052-kvm-update-kvm.h-to-include-memory-.patch create mode 100644 0053-docs-add-AMD-Secure-Encrypted-Virtu.patch create mode 100644 0054-accel-add-Secure-Encrypted-Virtuliz.patch create mode 100644 0055-sev-add-command-to-initialize-the-m.patch create mode 100644 0056-sev-register-the-guest-memory-range.patch create mode 100644 0057-kvm-introduce-memory-encryption-API.patch create mode 100644 0058-qmp-add-query-sev-command.patch create mode 100644 0059-hmp-add-info-sev-command.patch create mode 100644 0060-sev-add-command-to-create-launch-me.patch create mode 100644 0061-sev-add-command-to-encrypt-guest-me.patch create mode 100644 0062-target-i386-encrypt-bios-rom.patch create mode 100644 0063-sev-add-support-to-LAUNCH_MEASURE-c.patch create mode 100644 0064-sev-Finalize-the-SEV-guest-launch-f.patch create mode 100644 0065-hw-i386-set-ram_debug_ops-when-memo.patch create mode 100644 0066-sev-add-debug-encrypt-and-decrypt-c.patch create mode 100644 0067-target-i386-clear-C-bit-when-walkin.patch create mode 100644 0068-include-add-psp-sev.h-header-file.patch create mode 100644 0069-sev-add-support-to-query-PLATFORM_S.patch create mode 100644 0070-sev-add-support-to-KVM_SEV_GUEST_ST.patch create mode 100644 0071-qmp-add-query-sev-launch-measure-co.patch create mode 100644 0072-sev-Fix-build-for-non-x86-hosts.patch diff --git a/0027-string-input-visitor-Fix-uint64-par.patch b/0027-string-input-visitor-Fix-uint64-par.patch index a5c1cef..f9f7f55 100644 --- a/0027-string-input-visitor-Fix-uint64-par.patch +++ b/0027-string-input-visitor-Fix-uint64-par.patch @@ -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; diff --git a/0028-test-string-input-visitor-Add-int-t.patch b/0028-test-string-input-visitor-Add-int-t.patch index 2c5c2e2..3e5466b 100644 --- a/0028-test-string-input-visitor-Add-int-t.patch +++ b/0028-test-string-input-visitor-Add-int-t.patch @@ -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); diff --git a/0034-qapi-use-items-values-intead-of-ite.patch b/0034-qapi-use-items-values-intead-of-ite.patch index 71cf84b..8e58ad1 100644 --- a/0034-qapi-use-items-values-intead-of-ite.patch +++ b/0034-qapi-use-items-values-intead-of-ite.patch @@ -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" -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é Signed-off-by: Daniel P. Berrange +Message-Id: <20180116134217.8725-3-berrange@redhat.com> +Signed-off-by: Eduardo Habkost +(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 --- scripts/qapi.py | 24 ++++++++++++------------ scripts/qapi2texi.py | 11 ++++++----- diff --git a/0035-qapi-Use-OrderedDict-from-standard-.patch b/0035-qapi-Use-OrderedDict-from-standard-.patch index 9bb0f3f..b79bf38 100644 --- a/0035-qapi-Use-OrderedDict-from-standard-.patch +++ b/0035-qapi-Use-OrderedDict-from-standard-.patch @@ -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" -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é Signed-off-by: Daniel P. Berrange +Message-Id: <20180116134217.8725-4-berrange@redhat.com> +Signed-off-by: Eduardo Habkost +(cherry picked from commit 38710a8994911d98acbe183a39ec3a53638de510) +[BR: BSC#1077564] +Signed-off-by: Bruce Rogers --- scripts/qapi.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/0036-qapi-adapt-to-moved-location-of-Str.patch b/0036-qapi-adapt-to-moved-location-of-Str.patch index c59a4dd..236b837 100644 --- a/0036-qapi-adapt-to-moved-location-of-Str.patch +++ b/0036-qapi-adapt-to-moved-location-of-Str.patch @@ -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" -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é Signed-off-by: Daniel P. Berrange +Message-Id: <20180116134217.8725-5-berrange@redhat.com> +Signed-off-by: Eduardo Habkost +(cherry picked from commit 5f90af8e6b34f9e6b60eb05a15707a95a0febbde) +[BR: BSC#1077564] +Signed-off-by: Bruce Rogers --- scripts/qapi.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/0037-qapi-Adapt-to-moved-location-of-mak.patch b/0037-qapi-Adapt-to-moved-location-of-mak.patch index 21a39b6..baa1eb7 100644 --- a/0037-qapi-Adapt-to-moved-location-of-mak.patch +++ b/0037-qapi-Adapt-to-moved-location-of-mak.patch @@ -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" -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 Signed-off-by: Daniel P. Berrange +Message-Id: <20180116134217.8725-6-berrange@redhat.com> +Signed-off-by: Eduardo Habkost +(cherry picked from commit 52c4272c6c916a53cde65b997e1a4e891c14dcef) +[BR: BSC#1077564] +Signed-off-by: Bruce Rogers --- scripts/qapi.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/0038-qapi-remove-q-arg-to-diff-when-comp.patch b/0038-qapi-remove-q-arg-to-diff-when-comp.patch index 7b2e4f2..1365a19 100644 --- a/0038-qapi-remove-q-arg-to-diff-when-comp.patch +++ b/0038-qapi-remove-q-arg-to-diff-when-comp.patch @@ -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" -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 Signed-off-by: Daniel P. Berrange +Message-Id: <20180116134217.8725-7-berrange@redhat.com> +Signed-off-by: Eduardo Habkost +(cherry picked from commit 46ec4fcea95204a8e5bab9295cbfaa3606d78dc9) +[BR: BSC#1077564] +Signed-off-by: Bruce Rogers --- tests/Makefile.include | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/0039-qapi-ensure-stable-sort-ordering-wh.patch b/0039-qapi-ensure-stable-sort-ordering-wh.patch index 84181a8..22da18d 100644 --- a/0039-qapi-ensure-stable-sort-ordering-wh.patch +++ b/0039-qapi-ensure-stable-sort-ordering-wh.patch @@ -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" -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é Signed-off-by: Daniel P. Berrange +Message-Id: <20180116134217.8725-8-berrange@redhat.com> +Signed-off-by: Eduardo Habkost +(cherry picked from commit f7a5376d4b667cf6c83c1d640e32d22456d7b5ee) +[BR: BSC#1077564] +Signed-off-by: Bruce Rogers --- scripts/qapi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/0040-qapi-force-a-UTF-8-locale-for-runni.patch b/0040-qapi-force-a-UTF-8-locale-for-runni.patch index 4d1af7b..04b55e7 100644 --- a/0040-qapi-force-a-UTF-8-locale-for-runni.patch +++ b/0040-qapi-force-a-UTF-8-locale-for-runni.patch @@ -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" -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 +Message-Id: <20180116134217.8725-9-berrange@redhat.com> +Reviewed-by: Eric Blake +Signed-off-by: Eduardo Habkost +(cherry picked from commit d4e5ec877ca698a87dabe68814c6f93668f50c60) +[BR: BSC#1077564] +Signed-off-by: Bruce Rogers --- 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: diff --git a/0041-scripts-ensure-signrom-treats-data-.patch b/0041-scripts-ensure-signrom-treats-data-.patch index ca7c817..a05e904 100644 --- a/0041-scripts-ensure-signrom-treats-data-.patch +++ b/0041-scripts-ensure-signrom-treats-data-.patch @@ -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" -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é Signed-off-by: Daniel P. Berrange +Message-Id: <20180116134217.8725-10-berrange@redhat.com> +Signed-off-by: Eduardo Habkost +(cherry picked from commit 31d8f92e646f7d4cfbb4ffab440ab41a3c838fd3) +[BR: BSC#1077564] +Signed-off-by: Bruce Rogers --- scripts/signrom.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/0042-configure-allow-use-of-python-3.patch b/0042-configure-allow-use-of-python-3.patch index 16b8fee..614ac0b 100644 --- a/0042-configure-allow-use-of-python-3.patch +++ b/0042-configure-allow-use-of-python-3.patch @@ -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" -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 +Message-Id: <20180116134217.8725-11-berrange@redhat.com> +Reviewed-by: Eric Blake +Signed-off-by: Eduardo Habkost +(cherry picked from commit c21965a0c8b979c306e927f158257e5b0fa3a1f9) +[BR: BSC#1077564] +Signed-off-by: Bruce Rogers --- configure | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/0043-input-add-missing-JIS-keys-to-virti.patch b/0043-input-add-missing-JIS-keys-to-virti.patch index 07e7229..f3d3b94 100644 --- a/0043-input-add-missing-JIS-keys-to-virti.patch +++ b/0043-input-add-missing-JIS-keys-to-virti.patch @@ -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 -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 +Message-Id: <20180116134217.8725-12-berrange@redhat.com> +Reviewed-by: Eric Blake +Signed-off-by: Eduardo Habkost +(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 --- hw/input/virtio-input-hid.c | 7 +++++++ qapi/ui.json | 5 ++++- diff --git a/0044-Make-installed-scripts-explicitly-p.patch b/0044-Make-installed-scripts-explicitly-p.patch index 892586f..6e67250 100644 --- a/0044-Make-installed-scripts-explicitly-p.patch +++ b/0044-Make-installed-scripts-explicitly-p.patch @@ -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 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 --- scripts/analyze-migration.py | 2 +- diff --git a/0045-pc-fail-memory-hot-plug-unplug-with.patch b/0045-pc-fail-memory-hot-plug-unplug-with.patch index f019d3b..60d7def 100644 --- a/0045-pc-fail-memory-hot-plug-unplug-with.patch +++ b/0045-pc-fail-memory-hot-plug-unplug-with.patch @@ -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 Date: Fri, 22 Dec 2017 09:51:20 +0800 Subject: [PATCH] pc: fail memory hot-plug/unplug with -no-acpi and Q35 machine diff --git a/0046-memattrs-add-debug-attribute.patch b/0046-memattrs-add-debug-attribute.patch new file mode 100644 index 0000000..676afc9 --- /dev/null +++ b/0046-memattrs-add-debug-attribute.patch @@ -0,0 +1,39 @@ +From 8e76b032dc33ce4330da6ec73c10113cdc172b25 Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +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 +Cc: Peter Maydell +Cc: Edgar E. Iglesias" +Cc: Richard Henderson +Cc: Paolo Bonzini +Reviewed-by: Edgar E. Iglesias" +Signed-off-by: Brijesh Singh +[BR: FATE#322124] +Signed-off-by: Bruce Rogers +--- + 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, diff --git a/0047-exec-add-ram_debug_ops-support.patch b/0047-exec-add-ram_debug_ops-support.patch new file mode 100644 index 0000000..efe343a --- /dev/null +++ b/0047-exec-add-ram_debug_ops-support.patch @@ -0,0 +1,230 @@ +From faf4862946a9e236e8e4fb956adad2dc11577fe0 Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +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 +Cc: Peter Crosthwaite +Cc: Richard Henderson +Signed-off-by: Brijesh Singh +[BR: FATE#322124] +Signed-off-by: Bruce Rogers +--- + 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. diff --git a/0048-exec-add-debug-version-of-physical-.patch b/0048-exec-add-debug-version-of-physical-.patch new file mode 100644 index 0000000..935a42b --- /dev/null +++ b/0048-exec-add-debug-version-of-physical-.patch @@ -0,0 +1,107 @@ +From 8c55cf176a4b6d6411e8b1e6385ff6a78b0e55f2 Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +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 +Cc: Peter Crosthwaite +Cc: Richard Henderson +Signed-off-by: Brijesh Singh +Reviewed-by: Paolo Bonzini +[BR: FATE#322124] +Signed-off-by: Bruce Rogers +--- + 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) + { diff --git a/0049-monitor-i386-use-debug-APIs-when-ac.patch b/0049-monitor-i386-use-debug-APIs-when-ac.patch new file mode 100644 index 0000000..cf8d367 --- /dev/null +++ b/0049-monitor-i386-use-debug-APIs-when-ac.patch @@ -0,0 +1,368 @@ +From 5a0c3e3ff1a772c572b810851e04e0deb2930367 Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +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 +Cc: Peter Crosthwaite +Cc: Richard Henderson +Cc: "Dr. David Alan Gilbert" +Cc: Markus Armbruster +Cc: Eduardo Habkost +Signed-off-by: Brijesh Singh +[BR: FATE#322124] +Signed-off-by: Bruce Rogers +--- + 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); diff --git a/0050-target-i386-add-memory-encryption-f.patch b/0050-target-i386-add-memory-encryption-f.patch new file mode 100644 index 0000000..2e3e0a5 --- /dev/null +++ b/0050-target-i386-add-memory-encryption-f.patch @@ -0,0 +1,137 @@ +From 7fee871608f1ab458151d03712fb0b89cf5c5668 Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +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 +Cc: Richard Henderson +Cc: Eduardo Habkost +Signed-off-by: Brijesh Singh +[BR: FATE#322124] +Signed-off-by: Bruce Rogers +--- + 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) + diff --git a/0051-machine-add-memory-encryption-prope.patch b/0051-machine-add-memory-encryption-prope.patch new file mode 100644 index 0000000..ec7ad76 --- /dev/null +++ b/0051-machine-add-memory-encryption-prope.patch @@ -0,0 +1,86 @@ +From 80b31eed583af21eee2e2f152d2c24e6aa13b2b7 Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +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 +Cc: Eduardo Habkost +Cc: Marcel Apfelbaum +Cc: Stefan Hajnoczi +Signed-off-by: Brijesh Singh +[BR: FATE#322124] +Signed-off-by: Bruce Rogers +--- + 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 + diff --git a/0052-kvm-update-kvm.h-to-include-memory-.patch b/0052-kvm-update-kvm.h-to-include-memory-.patch new file mode 100644 index 0000000..108dbc7 --- /dev/null +++ b/0052-kvm-update-kvm.h-to-include-memory-.patch @@ -0,0 +1,118 @@ +From fd981d8bae5ef3b9056845add32a0830356b3b7f Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +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 +Cc: Cornelia Huck +Cc: Paolo Bonzini +Signed-off-by: Brijesh Singh +[BR: FATE#322124] +Signed-off-by: Bruce Rogers +--- + 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) diff --git a/0053-docs-add-AMD-Secure-Encrypted-Virtu.patch b/0053-docs-add-AMD-Secure-Encrypted-Virtu.patch new file mode 100644 index 0000000..12bf04c --- /dev/null +++ b/0053-docs-add-AMD-Secure-Encrypted-Virtu.patch @@ -0,0 +1,115 @@ +From e31dff17694578d6f14f94fce81f446827502318 Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +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 +Signed-off-by: Brijesh Singh +[BR: FATE#322124] +Signed-off-by: Bruce Rogers +--- + 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 diff --git a/0054-accel-add-Secure-Encrypted-Virtuliz.patch b/0054-accel-add-Secure-Encrypted-Virtuliz.patch new file mode 100644 index 0000000..aedc426 --- /dev/null +++ b/0054-accel-add-Secure-Encrypted-Virtuliz.patch @@ -0,0 +1,403 @@ +From 725b55269e39ee0c64daf556b019d1eb70940b21 Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +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 +Signed-off-by: Brijesh Singh +[BR: FATE#322124] +Signed-off-by: Bruce Rogers +--- + 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 ++ * ++ * 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=,session-file= ++ + 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 ++ * ++ * 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=$( +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 +Signed-off-by: Brijesh Singh +[BR: FATE#322124] +Signed-off-by: Bruce Rogers +--- + 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 ++ + #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 + diff --git a/0056-sev-register-the-guest-memory-range.patch b/0056-sev-register-the-guest-memory-range.patch new file mode 100644 index 0000000..29b9323 --- /dev/null +++ b/0056-sev-register-the-guest-memory-range.patch @@ -0,0 +1,94 @@ +From 127890da09ac0ebb4945f52b0e23e582d93fc698 Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +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 +Signed-off-by: Brijesh Singh +[BR: FATE#322124] +Signed-off-by: Bruce Rogers +--- + 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" diff --git a/0057-kvm-introduce-memory-encryption-API.patch b/0057-kvm-introduce-memory-encryption-API.patch new file mode 100644 index 0000000..901d6b8 --- /dev/null +++ b/0057-kvm-introduce-memory-encryption-API.patch @@ -0,0 +1,129 @@ +From f2a1359c865cf33fc5960e1b9e6912827075f567 Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +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 +Cc: kvm@vger.kernel.org +Signed-off-by: Brijesh Singh +[BR: FATE#322124] +Signed-off-by: Bruce Rogers +--- + 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" + diff --git a/0058-qmp-add-query-sev-command.patch b/0058-qmp-add-query-sev-command.patch new file mode 100644 index 0000000..e9364c4 --- /dev/null +++ b/0058-qmp-add-query-sev-command.patch @@ -0,0 +1,108 @@ +From 839e76e0c43407cff82395ee6d4e3eb94fd07fa3 Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +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é" +Cc: "Dr. David Alan Gilbert" +Cc: Markus Armbruster +Signed-off-by: Brijesh Singh +[BR: FATE#322124] +Signed-off-by: Bruce Rogers +--- + 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; ++} diff --git a/0059-hmp-add-info-sev-command.patch b/0059-hmp-add-info-sev-command.patch new file mode 100644 index 0000000..9d94716 --- /dev/null +++ b/0059-hmp-add-info-sev-command.patch @@ -0,0 +1,86 @@ +From d363eb37dad9acacbcd688f8275c16334ca69fbe Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +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é" +Cc: "Dr. David Alan Gilbert" +Cc: Markus Armbruster +Signed-off-by: Brijesh Singh +[BR: FATE#322124] +Signed-off-by: Bruce Rogers +--- + 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 diff --git a/0060-sev-add-command-to-create-launch-me.patch b/0060-sev-add-command-to-create-launch-me.patch new file mode 100644 index 0000000..04f59d7 --- /dev/null +++ b/0060-sev-add-command-to-create-launch-me.patch @@ -0,0 +1,189 @@ +From 5abfa90f247fb546167b2f3a8d201f10707cca30 Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +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 +Cc: kvm@vger.kernel.org +Signed-off-by: Brijesh Singh +[BR: FATE#322124] +Signed-off-by: Bruce Rogers +--- + 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; + }; diff --git a/0061-sev-add-command-to-encrypt-guest-me.patch b/0061-sev-add-command-to-encrypt-guest-me.patch new file mode 100644 index 0000000..d855f98 --- /dev/null +++ b/0061-sev-add-command-to-encrypt-guest-me.patch @@ -0,0 +1,126 @@ +From bcbe925e0f93234b0f0f6ecf4e5b8d400a46a691 Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +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 +[BR: FATE#322124] +Signed-off-by: Bruce Rogers +--- + 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 + diff --git a/0062-target-i386-encrypt-bios-rom.patch b/0062-target-i386-encrypt-bios-rom.patch new file mode 100644 index 0000000..b71c877 --- /dev/null +++ b/0062-target-i386-encrypt-bios-rom.patch @@ -0,0 +1,49 @@ +From 6301b846ebcf3ff2afb0cefbb480447383dc2814 Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +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" +Cc: Paolo Bonzini +Cc: Richard Henderson +Cc: Eduardo Habkost +Signed-off-by: Brijesh Singh +[BR: FATE#322124] +Signed-off-by: Bruce Rogers +--- + 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); ++ } ++ } + } + } + } diff --git a/0063-sev-add-support-to-LAUNCH_MEASURE-c.patch b/0063-sev-add-support-to-LAUNCH_MEASURE-c.patch new file mode 100644 index 0000000..8909fc8 --- /dev/null +++ b/0063-sev-add-support-to-LAUNCH_MEASURE-c.patch @@ -0,0 +1,169 @@ +From 8593c38925a2c54bceb27e16f1ad9f02789afbf4 Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +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 +Cc: kvm@vger.kernel.org +Signed-off-by: Brijesh Singh +[BR: FATE#322124] +Signed-off-by: Bruce Rogers +--- + 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; diff --git a/0064-sev-Finalize-the-SEV-guest-launch-f.patch b/0064-sev-Finalize-the-SEV-guest-launch-f.patch new file mode 100644 index 0000000..f731f7a --- /dev/null +++ b/0064-sev-Finalize-the-SEV-guest-launch-f.patch @@ -0,0 +1,74 @@ +From 5f926f58bd02e7c42d7840a653cc33d83c90a5af Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +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 +Cc: kvm@vger.kernel.org +Signed-off-by: Brijesh Singh +[BR: FATE#322124] +Signed-off-by: Bruce Rogers +--- + 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) "" diff --git a/0065-hw-i386-set-ram_debug_ops-when-memo.patch b/0065-hw-i386-set-ram_debug_ops-when-memo.patch new file mode 100644 index 0000000..6fc43e2 --- /dev/null +++ b/0065-hw-i386-set-ram_debug_ops-when-memo.patch @@ -0,0 +1,58 @@ +From 730e2bc55583c1ae7ba0aff4b26975f51c2442cd Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +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 +Cc: Richard Henderson +Cc: Eduardo Habkost +Cc: "Michael S. Tsirkin" +Signed-off-by: Brijesh Singh +[BR: FATE#322124] +Signed-off-by: Bruce Rogers +--- + 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); + } + } + } diff --git a/0066-sev-add-debug-encrypt-and-decrypt-c.patch b/0066-sev-add-debug-encrypt-and-decrypt-c.patch new file mode 100644 index 0000000..246aed0 --- /dev/null +++ b/0066-sev-add-debug-encrypt-and-decrypt-c.patch @@ -0,0 +1,156 @@ +From ed8f2531e1b008cedfaca01980641c2432693fb3 Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +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 +Cc: kvm@vger.kernel.org +Signed-off-by: Brijesh Singh +[BR: FATE#322124] +Signed-off-by: Bruce Rogers +--- + 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 + diff --git a/0067-target-i386-clear-C-bit-when-walkin.patch b/0067-target-i386-clear-C-bit-when-walkin.patch new file mode 100644 index 0000000..336cb92 --- /dev/null +++ b/0067-target-i386-clear-C-bit-when-walkin.patch @@ -0,0 +1,361 @@ +From 5be49d786b9d9a39cd2bae56032a6f92a59de93a Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +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 +Cc: Richard Henderson +Cc: Eduardo Habkost +Signed-off-by: Brijesh Singh +[BR: FATE#322124] +Signed-off-by: Bruce Rogers +--- + 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; diff --git a/0068-include-add-psp-sev.h-header-file.patch b/0068-include-add-psp-sev.h-header-file.patch new file mode 100644 index 0000000..fdf5007 --- /dev/null +++ b/0068-include-add-psp-sev.h-header-file.patch @@ -0,0 +1,166 @@ +From 94e76aa9e24ad99ae746fa717ab4c721160128c1 Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +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 +Cc: kvm@vger.kernel.org +Signed-off-by: Brijesh Singh +[BR: FATE#322124] +Signed-off-by: Bruce Rogers +--- + 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 ++ * ++ * 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 ++ ++/** ++ * 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 */ diff --git a/0069-sev-add-support-to-query-PLATFORM_S.patch b/0069-sev-add-support-to-query-PLATFORM_S.patch new file mode 100644 index 0000000..a0e1f14 --- /dev/null +++ b/0069-sev-add-support-to-query-PLATFORM_S.patch @@ -0,0 +1,74 @@ +From 8798ba8f4a4ba43cf7a34960ed70b32cbe69a4f6 Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +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 +Cc: kvm@vger.kernel.org +Signed-off-by: Brijesh Singh +[BR: FATE#322124] +Signed-off-by: Bruce Rogers +--- + 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 ++#include ++ + #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 diff --git a/0070-sev-add-support-to-KVM_SEV_GUEST_ST.patch b/0070-sev-add-support-to-KVM_SEV_GUEST_ST.patch new file mode 100644 index 0000000..cf4624a --- /dev/null +++ b/0070-sev-add-support-to-KVM_SEV_GUEST_ST.patch @@ -0,0 +1,40 @@ +From 0139a4366095226b25d4f3f819fc0b0c260ce46b Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +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 +Cc: kvm@vger.kernel.org +Signed-off-by: Brijesh Singh +[BR: FATE#322124] +Signed-off-by: Bruce Rogers +--- + 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 diff --git a/0071-qmp-add-query-sev-launch-measure-co.patch b/0071-qmp-add-query-sev-launch-measure-co.patch new file mode 100644 index 0000000..76c4e6c --- /dev/null +++ b/0071-qmp-add-query-sev-launch-measure-co.patch @@ -0,0 +1,83 @@ +From 49a869039c960dbc02e6bbee9d0f0d0ce39003d5 Mon Sep 17 00:00:00 2001 +From: Brijesh Singh +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é" +Cc: "Dr. David Alan Gilbert" +Cc: Markus Armbruster +Signed-off-by: Brijesh Singh +[BR: FATE#322124] +Signed-off-by: Bruce Rogers +--- + 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; ++} diff --git a/0072-sev-Fix-build-for-non-x86-hosts.patch b/0072-sev-Fix-build-for-non-x86-hosts.patch new file mode 100644 index 0000000..2ac8e4e --- /dev/null +++ b/0072-sev-Fix-build-for-non-x86-hosts.patch @@ -0,0 +1,45 @@ +From 5c1a357744cfd2917705907bc3d50efd1184b7d9 Mon Sep 17 00:00:00 2001 +From: Bruce Rogers +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 +--- + 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; diff --git a/qemu-linux-user.changes b/qemu-linux-user.changes index fdf745b..665d2e7 100644 --- a/qemu-linux-user.changes +++ b/qemu-linux-user.changes @@ -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 diff --git a/qemu-linux-user.spec b/qemu-linux-user.spec index a044fdc..168e0ea 100644 --- a/qemu-linux-user.spec +++ b/qemu-linux-user.spec @@ -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 \ diff --git a/qemu-testsuite.changes b/qemu-testsuite.changes index a21c493..2d90e62 100644 --- a/qemu-testsuite.changes +++ b/qemu-testsuite.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 diff --git a/qemu-testsuite.spec b/qemu-testsuite.spec index cf83741..b1d1650 100644 --- a/qemu-testsuite.spec +++ b/qemu-testsuite.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 diff --git a/qemu.changes b/qemu.changes index a21c493..2d90e62 100644 --- a/qemu.changes +++ b/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 diff --git a/qemu.spec b/qemu.spec index 5992dcc..8746996 100644 --- a/qemu.spec +++ b/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