Re: [PATCH RFC v3 00/49] Add AMD Secure Nested Paging (SEV-SNP) support

2024-04-18 Thread Ani Sinha



> On 20 Mar 2024, at 14:08, Michael Roth  wrote:
> 
> These patches implement SEV-SNP base support along with CPUID enforcement
> support for QEMU, and are also available at:
> 
>  https://github.com/amdese/qemu/commits/snp-v3-rfc
> 
> they are based on top of the following patchset from Paolo:
> 
>  "[PATCH 0/7] target/i386: VM type infrastructure and KVM_SEV_INIT2 support"
>  https://lists.gnu.org/archive/html/qemu-devel/2024-03/msg04663.html

Can you please also CC me on future revisions of this patchset? 

Thanks!


> 
> 
> Patch Layout
> 
> 
> 01-05: Various changes needed to handle new header files in kvm-next tree
>   and some hacks to get a functional header sync in place for building
>   this series.
> 06-18: These are patches directly plucked from Xiaoyao's TDX v5 patchset[1]
>   that implement common dependencies between SNP/TDX like base
>   guest_memfd, KVM_EXIT_MEMORY_FAULT handling (with a small FIXUP), and
>   mechanisms to disable SMM. We would've also needed some of the basic
>   infrastructure for handling specifying VM types for KVM_CREATE, but
>   much of that is now part of the sevinit2 series this patchset is based
>   on. Ideally all these patches, once stable, could be maintained in a
>   common tree so that future SNP/TDX patchsets can be more easily
>   iterated on/reviewed.
> 19-20: Patches introduced by this series that are  possible candidate for a
>   common tree.
>   shared/private pages when things like VFIO are in use.
> 21-32: Introduction of sev-snp-guest object and various configuration
>   requirements for SNP.
> 33-36: Handling for various KVM_EXIT_VMGEXIT events that are handled in
>   userspace.
> 37-49: Support for creating a cryptographic "launch" context and populating
>   various OVMF metadata pages, BIOS regions, and vCPU/VMSA pages with
>   the initial encrypted/measured/validated launch data prior to
>   launching the SNP guest.
> 
> 
> Testing
> ---
> 
> This series has been tested against the following host kernel tree, which
> is a snapshot of the latest WIP SNP hypervisor tree at the time of this
> posting. It will likely not be kept up to date afterward, so please keep an
> eye upstream or official AMDESE github if you are looking for the latest
> some time after this posting:
> 
>  https://github.com/mdroth/linux/commits/snp-host-v12-wip40/
> 
> A patched OVMF is also needed due to upstream KVM no longer supporting MMIO
> ranges that are mapped as private. It is recommended you build the AmdSevX64
> variant as it provides the kernel-hashing support present in this series:
> 
>  https://github.com/mdroth/edk2/commits/apic-mmio-fix1c/
> 
> A basic command-line invocation for SNP would be:
> 
> qemu-system-x86_64 -smp 32,maxcpus=255 -cpu EPYC-Milan-v2
>  -machine q35,confidential-guest-support=sev0,memory-backend=ram1
>  -object memory-backend-memfd,id=ram1,size=4G,share=true,reserve=false
>  -object sev-snp-guest,id=sev0,cbitpos=51,reduced-phys-bits=1,id-auth=
>  -bios /home/mroth/ovmf/OVMF_CODE-upstream-20240228-apicfix-1c-AmdSevX64.fd
> 
> With kernel-hashing and certificate data supplied:
> 
> qemu-system-x86_64 -smp 32,maxcpus=255 -cpu EPYC-Milan-v2
>  -machine q35,confidential-guest-support=sev0,memory-backend=ram1
>  -object memory-backend-memfd,id=ram1,size=4G,share=true,reserve=false
>  -object 
> sev-snp-guest,id=sev0,cbitpos=51,reduced-phys-bits=1,id-auth=,certs-path=/home/mroth/cert.blob,kernel-hashes=on
>  -bios /home/mroth/ovmf/OVMF_CODE-upstream-20240228-apicfix-1c-AmdSevX64.fd
>  -kernel /boot/vmlinuz-6.8.0-snp-host-v12-wip40+
>  -initrd /boot/initrd.img-6.8.0-snp-host-v12-wip40+
>  -append "root=UUID=d72a6d1c-06cf-4b79-af43-f1bac4f620f9 ro 
> console=ttyS0,115200n8"
> 
> Any comments/feedback would be very much appreciated.
> 
> [1] https://github.com/amdese/linux
>https://github.com/amdese/amdsev/tree/snp-latest
> 
> Changes since rfc2:
> 
> - reworked on top of guest_memfd support
> - added handling for various KVM_EXIT_VMGEXIT events
> - various changes/considerations for PCI passthrough support
> - general bugfixes/hardening/cleanups
> - qapi cmdline doc fixes/rework (Dov, Markus)
> - switch to qbase64_decode, more error-checking for cmdline opts (Dov)
> - unset id_block_en for 0 input (Dov)
> - use error_setg in snp init (Dov)
> - report more info in trace_kvm_sev_init (Dov)
> - rework bounds-checking for kvm_cpuid_info, rework existing checks for 
> readability, add additional checks (Dov)
> - fixups for validated_ranges handling (Dov)
> - rename 'policy' field to 'snp-policy' in query-sev when sev-type is SNP
> 
> Changes since rfc1:
> 
> - rebased onto latest master
> - drop SNP config file in favor of a new 'sev-snp-guest' object where all
>   SNP-related params are passed as strings/integers via command-line
> - report specific error if BIOS reports invalid address/len for
>   reserved/pre-validated regions (Connor)
> - use Range helpers 

Re: [PATCH RFC v3 00/49] Add AMD Secure Nested Paging (SEV-SNP) support

2024-03-21 Thread Michael Roth
On Wed, Mar 20, 2024 at 03:38:56AM -0500, Michael Roth wrote:
> 
> Testing
> ---
> 
> This series has been tested against the following host kernel tree, which
> is a snapshot of the latest WIP SNP hypervisor tree at the time of this
> posting. It will likely not be kept up to date afterward, so please keep an
> eye upstream or official AMDESE github if you are looking for the latest
> some time after this posting:
> 
>   https://github.com/mdroth/linux/commits/snp-host-v12-wip40/

I just noticed I had a necessary local change that wasn't included in the
initial push of this branch. I've updated the branch now, but just wanted
to post a heads-up in case anyone was having issues.

-Mike



Re: [PATCH RFC v3 00/49] Add AMD Secure Nested Paging (SEV-SNP) support

2024-03-20 Thread Xiaoyao Li

On 3/21/2024 1:08 AM, Paolo Bonzini wrote:

On Wed, Mar 20, 2024 at 10:59 AM Paolo Bonzini  wrote:

I will now focus on reviewing patches 6-20.  This way we can prepare a
common tree for SEV_INIT2/SNP/TDX, for both vendors to build upon.


Ok, the attachment is the delta that I have. The only major change is
requiring discard (thus effectively blocking VFIO support for
SEV-SNP/TDX, at least for now).

I will push it shortly to the same sevinit2 branch, and will post the
patches sometime soon.

Xiaoyao, you can use that branch too (it's on
https://gitlab.com/bonzini/qemu) as the basis for your TDX work.


Sure, it's really a good news for us.

BTW, there are some minor comments on guest_memfd patches of my v5 
post[*]. Could you please resolve them it your branch?


[*] 
https://lore.kernel.org/qemu-devel/20240229063726.610065-1-xiaoyao...@intel.com/



Paolo





Re: [PATCH RFC v3 00/49] Add AMD Secure Nested Paging (SEV-SNP) support

2024-03-20 Thread Paolo Bonzini
On Wed, Mar 20, 2024 at 10:59 AM Paolo Bonzini  wrote:
> I will now focus on reviewing patches 6-20.  This way we can prepare a
> common tree for SEV_INIT2/SNP/TDX, for both vendors to build upon.

Ok, the attachment is the delta that I have. The only major change is
requiring discard (thus effectively blocking VFIO support for
SEV-SNP/TDX, at least for now).

I will push it shortly to the same sevinit2 branch, and will post the
patches sometime soon.

Xiaoyao, you can use that branch too (it's on
https://gitlab.com/bonzini/qemu) as the basis for your TDX work.

Paolo
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index bf0ae0c8adb..428468950d9 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -285,19 +285,8 @@ static int kvm_set_user_memory_region(KVMMemoryListener *kml, KVMSlot *slot, boo
 {
 KVMState *s = kvm_state;
 struct kvm_userspace_memory_region2 mem;
-static int cap_user_memory2 = -1;
 int ret;
 
-if (cap_user_memory2 == -1) {
-cap_user_memory2 = kvm_check_extension(s, KVM_CAP_USER_MEMORY2);
-}
-
-if (!cap_user_memory2 && slot->guest_memfd >= 0) {
-error_report("%s, KVM doesn't support KVM_CAP_USER_MEMORY2,"
- " which is required by guest memfd!", __func__);
-exit(1);
-}
-
 mem.slot = slot->slot | (kml->as_id << 16);
 mem.guest_phys_addr = slot->start_addr;
 mem.userspace_addr = (unsigned long)slot->ram;
@@ -310,7 +299,7 @@ static int kvm_set_user_memory_region(KVMMemoryListener *kml, KVMSlot *slot, boo
  * value. This is needed based on KVM commit 75d61fbc. */
 mem.memory_size = 0;
 
-if (cap_user_memory2) {
+if (kvm_guest_memfd_supported) {
 ret = kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION2, );
 } else {
 ret = kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, );
@@ -320,7 +309,7 @@ static int kvm_set_user_memory_region(KVMMemoryListener *kml, KVMSlot *slot, boo
 }
 }
 mem.memory_size = slot->memory_size;
-if (cap_user_memory2) {
+if (kvm_guest_memfd_supported) {
 ret = kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION2, );
 } else {
 ret = kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, );
@@ -332,7 +321,7 @@ err:
   mem.userspace_addr, mem.guest_memfd,
   mem.guest_memfd_offset, ret);
 if (ret < 0) {
-if (cap_user_memory2) {
+if (kvm_guest_memfd_supported) {
 error_report("%s: KVM_SET_USER_MEMORY_REGION2 failed, slot=%d,"
 " start=0x%" PRIx64 ", size=0x%" PRIx64 ","
 " flags=0x%" PRIx32 ", guest_memfd=%" PRId32 ","
@@ -502,6 +491,7 @@ static int kvm_mem_flags(MemoryRegion *mr)
 flags |= KVM_MEM_READONLY;
 }
 if (memory_region_has_guest_memfd(mr)) {
+assert(kvm_guest_memfd_supported);
 flags |= KVM_MEM_GUEST_MEMFD;
 }
 return flags;
@@ -1310,18 +1300,7 @@ static int kvm_set_memory_attributes(hwaddr start, hwaddr size, uint64_t attr)
 struct kvm_memory_attributes attrs;
 int r;
 
-if (kvm_supported_memory_attributes == 0) {
-error_report("No memory attribute supported by KVM\n");
-return -EINVAL;
-}
-
-if ((attr & kvm_supported_memory_attributes) != attr) {
-error_report("memory attribute 0x%lx not supported by KVM,"
- " supported bits are 0x%lx\n",
- attr, kvm_supported_memory_attributes);
-return -EINVAL;
-}
-
+assert((attr & kvm_supported_memory_attributes) == attr);
 attrs.attributes = attr;
 attrs.address = start;
 attrs.size = size;
@@ -2488,11 +2467,14 @@ static int kvm_init(MachineState *ms)
 }
 s->as = g_new0(struct KVMAs, s->nr_as);
 
-kvm_guest_memfd_supported = kvm_check_extension(s, KVM_CAP_GUEST_MEMFD);
-
 ret = kvm_check_extension(s, KVM_CAP_MEMORY_ATTRIBUTES);
 kvm_supported_memory_attributes = ret > 0 ? ret : 0;
 
+kvm_guest_memfd_supported =
+kvm_check_extension(s, KVM_CAP_GUEST_MEMFD) &&
+kvm_check_extension(s, KVM_CAP_USER_MEMORY2) &&
+(kvm_supported_memory_attributes & KVM_MEMORY_ATTRIBUTE_PRIVATE);
+
 if (object_property_find(OBJECT(current_machine), "kvm-type")) {
 g_autofree char *kvm_type = object_property_get_str(OBJECT(current_machine),
 "kvm-type",
@@ -2962,14 +2944,10 @@ int kvm_convert_memory(hwaddr start, hwaddr size, bool to_private)
 */
 return 0;
 } else {
-ret = ram_block_discard_is_disabled()
-  ? ram_block_discard_range(rb, offset, size)
-  : 0;
+ret = ram_block_discard_range(rb, offset, size);
 }
 } else {
-ret = ram_block_discard_is_disabled()
-  ? ram_block_discard_guest_memfd_range(rb, offset, 

Re: [PATCH RFC v3 00/49] Add AMD Secure Nested Paging (SEV-SNP) support

2024-03-20 Thread Paolo Bonzini

On 3/20/24 09:38, Michael Roth wrote:

These patches implement SEV-SNP base support along with CPUID enforcement
support for QEMU, and are also available at:

   https://github.com/amdese/qemu/commits/snp-v3-rfc

they are based on top of the following patchset from Paolo:

   "[PATCH 0/7] target/i386: VM type infrastructure and KVM_SEV_INIT2 support"
   https://lists.gnu.org/archive/html/qemu-devel/2024-03/msg04663.html


Patch Layout


01-05: Various changes needed to handle new header files in kvm-next tree
and some hacks to get a functional header sync in place for building
this series.
06-18: These are patches directly plucked from Xiaoyao's TDX v5 patchset[1]
that implement common dependencies between SNP/TDX like base
guest_memfd, KVM_EXIT_MEMORY_FAULT handling (with a small FIXUP), and
mechanisms to disable SMM. We would've also needed some of the basic
infrastructure for handling specifying VM types for KVM_CREATE, but
much of that is now part of the sevinit2 series this patchset is based
on. Ideally all these patches, once stable, could be maintained in a
common tree so that future SNP/TDX patchsets can be more easily
iterated on/reviewed.
19-20: Patches introduced by this series that are  possible candidate for a
common tree.
shared/private pages when things like VFIO are in use.
21-32: Introduction of sev-snp-guest object and various configuration
requirements for SNP.
33-36: Handling for various KVM_EXIT_VMGEXIT events that are handled in
userspace.
37-49: Support for creating a cryptographic "launch" context and populating
various OVMF metadata pages, BIOS regions, and vCPU/VMSA pages with
the initial encrypted/measured/validated launch data prior to
launching the SNP guest.


I reviewed the non-SEV bits of patches 21-46 and it looks nicely 
self-contained.  That's pretty much expected but still good news.


I didn't look closely at the SEV-SNP code for obvious reasons (it's only 
been one hour :)), except for the object-oriented aesthetics which I 
have remarked upon.  However, they seem to be in good shape.


I will now focus on reviewing patches 6-20.  This way we can prepare a 
common tree for SEV_INIT2/SNP/TDX, for both vendors to build upon.


Thanks for posting this, and thanks to the Intel people too for the 
previous work on the guest_memfd parts!


Paolo




[PATCH RFC v3 00/49] Add AMD Secure Nested Paging (SEV-SNP) support

2024-03-20 Thread Michael Roth
These patches implement SEV-SNP base support along with CPUID enforcement
support for QEMU, and are also available at:

  https://github.com/amdese/qemu/commits/snp-v3-rfc

they are based on top of the following patchset from Paolo:

  "[PATCH 0/7] target/i386: VM type infrastructure and KVM_SEV_INIT2 support"
  https://lists.gnu.org/archive/html/qemu-devel/2024-03/msg04663.html


Patch Layout


01-05: Various changes needed to handle new header files in kvm-next tree
   and some hacks to get a functional header sync in place for building
   this series.
06-18: These are patches directly plucked from Xiaoyao's TDX v5 patchset[1]
   that implement common dependencies between SNP/TDX like base
   guest_memfd, KVM_EXIT_MEMORY_FAULT handling (with a small FIXUP), and
   mechanisms to disable SMM. We would've also needed some of the basic
   infrastructure for handling specifying VM types for KVM_CREATE, but
   much of that is now part of the sevinit2 series this patchset is based
   on. Ideally all these patches, once stable, could be maintained in a
   common tree so that future SNP/TDX patchsets can be more easily
   iterated on/reviewed.
19-20: Patches introduced by this series that are  possible candidate for a
   common tree.
   shared/private pages when things like VFIO are in use.
21-32: Introduction of sev-snp-guest object and various configuration
   requirements for SNP.
33-36: Handling for various KVM_EXIT_VMGEXIT events that are handled in
   userspace.
37-49: Support for creating a cryptographic "launch" context and populating
   various OVMF metadata pages, BIOS regions, and vCPU/VMSA pages with
   the initial encrypted/measured/validated launch data prior to
   launching the SNP guest.


Testing
---

This series has been tested against the following host kernel tree, which
is a snapshot of the latest WIP SNP hypervisor tree at the time of this
posting. It will likely not be kept up to date afterward, so please keep an
eye upstream or official AMDESE github if you are looking for the latest
some time after this posting:

  https://github.com/mdroth/linux/commits/snp-host-v12-wip40/

A patched OVMF is also needed due to upstream KVM no longer supporting MMIO
ranges that are mapped as private. It is recommended you build the AmdSevX64
variant as it provides the kernel-hashing support present in this series:

  https://github.com/mdroth/edk2/commits/apic-mmio-fix1c/

A basic command-line invocation for SNP would be:

 qemu-system-x86_64 -smp 32,maxcpus=255 -cpu EPYC-Milan-v2
  -machine q35,confidential-guest-support=sev0,memory-backend=ram1
  -object memory-backend-memfd,id=ram1,size=4G,share=true,reserve=false
  -object sev-snp-guest,id=sev0,cbitpos=51,reduced-phys-bits=1,id-auth=
  -bios /home/mroth/ovmf/OVMF_CODE-upstream-20240228-apicfix-1c-AmdSevX64.fd

With kernel-hashing and certificate data supplied:

 qemu-system-x86_64 -smp 32,maxcpus=255 -cpu EPYC-Milan-v2
  -machine q35,confidential-guest-support=sev0,memory-backend=ram1
  -object memory-backend-memfd,id=ram1,size=4G,share=true,reserve=false
  -object 
sev-snp-guest,id=sev0,cbitpos=51,reduced-phys-bits=1,id-auth=,certs-path=/home/mroth/cert.blob,kernel-hashes=on
  -bios /home/mroth/ovmf/OVMF_CODE-upstream-20240228-apicfix-1c-AmdSevX64.fd
  -kernel /boot/vmlinuz-6.8.0-snp-host-v12-wip40+
  -initrd /boot/initrd.img-6.8.0-snp-host-v12-wip40+
  -append "root=UUID=d72a6d1c-06cf-4b79-af43-f1bac4f620f9 ro 
console=ttyS0,115200n8"

Any comments/feedback would be very much appreciated.

[1] https://github.com/amdese/linux
https://github.com/amdese/amdsev/tree/snp-latest

Changes since rfc2:

- reworked on top of guest_memfd support
- added handling for various KVM_EXIT_VMGEXIT events
- various changes/considerations for PCI passthrough support
- general bugfixes/hardening/cleanups
- qapi cmdline doc fixes/rework (Dov, Markus)
- switch to qbase64_decode, more error-checking for cmdline opts (Dov)
- unset id_block_en for 0 input (Dov)
- use error_setg in snp init (Dov)
- report more info in trace_kvm_sev_init (Dov)
- rework bounds-checking for kvm_cpuid_info, rework existing checks for 
readability, add additional checks (Dov)
- fixups for validated_ranges handling (Dov)
- rename 'policy' field to 'snp-policy' in query-sev when sev-type is SNP

Changes since rfc1:

 - rebased onto latest master
 - drop SNP config file in favor of a new 'sev-snp-guest' object where all
   SNP-related params are passed as strings/integers via command-line
 - report specific error if BIOS reports invalid address/len for
   reserved/pre-validated regions (Connor)
 - use Range helpers for handling validated region overlaps (Dave)
 - simplify error handling in sev_snp_launch_start, and report the correct
   return code when handling LAUNCH_START failures (Dov)
 - add SEV-SNP bit to CPUID 0x801f when SNP enabled
 - updated query-sev to handle differences between SEV and SEV-SNP
 -