linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/12] Drivers: hv: Add PCI pass-thru support to Hyper-V Confidential VMs
@ 2022-11-11  6:21 Michael Kelley
  2022-11-11  6:21 ` [PATCH v2 01/12] x86/ioremap: Fix page aligned size calculation in __ioremap_caller() Michael Kelley
                   ` (12 more replies)
  0 siblings, 13 replies; 27+ messages in thread
From: Michael Kelley @ 2022-11-11  6:21 UTC (permalink / raw)
  To: hpa, kys, haiyangz, wei.liu, decui, luto, peterz, davem,
	edumazet, kuba, pabeni, lpieralisi, robh, kw, bhelgaas, arnd,
	hch, m.szyprowski, robin.murphy, thomas.lendacky, brijesh.singh,
	tglx, mingo, bp, dave.hansen, Tianyu.Lan, kirill.shutemov,
	sathyanarayanan.kuppuswamy, ak, isaku.yamahata, dan.j.williams,
	jane.chu, seanjc, tony.luck, x86, linux-kernel, linux-hyperv,
	netdev, linux-pci, linux-arch, iommu
  Cc: mikelley

This patch series adds support for PCI pass-thru devices to Hyper-V
Confidential VMs (also called "Isolation VMs"). But in preparation, it
first changes how private (encrypted) vs. shared (decrypted) memory is
handled in Hyper-V SEV-SNP guest VMs. The new approach builds on the
confidential computing (coco) mechanisms introduced in the 5.19 kernel
for TDX support and significantly reduces the amount of Hyper-V specific
code. Furthermore, with this new approach a proposed RFC patch set for
generic DMA layer functionality[1] is no longer necessary.

Background
==========
Hyper-V guests on AMD SEV-SNP hardware have the option of using the
"virtual Top Of Memory" (vTOM) feature specified by the SEV-SNP
architecture. With vTOM, shared vs. private memory accesses are
controlled by splitting the guest physical address space into two
halves.  vTOM is the dividing line where the uppermost bit of the
physical address space is set; e.g., with 47 bits of guest physical
address space, vTOM is 0x40000000000 (bit 46 is set).  Guest phyiscal
memory is accessible at two parallel physical addresses -- one below
vTOM and one above vTOM.  Accesses below vTOM are private (encrypted)
while accesses above vTOM are shared (decrypted). In this sense, vTOM
is like the GPA.SHARED bit in Intel TDX.

In Hyper-V's use of vTOM, the normal guest OS runs at VMPL2, while
a Hyper-V provided "paravisor" runs at VMPL0 in the guest VM. (VMPL is
Virtual Machine Privilege Level. See AMD's SEV-SNP spec for more
details.) The paravisor provides emulation for various system devices
like the I/O APIC as part of the guest VM.  Accesses to such devices
made by the normal guest OS trap to the paravisor and are emulated in
the guest VM context instead of in the Hyper-V host. This emulation is
invisible to the normal guest OS, but with the quirk that memory mapped
I/O accesses to these devices must be treated as private, not shared as
would be the case for other device accesses.

Support for Hyper-V guests using vTOM was added to the Linux kernel
in two patch sets[2][3]. This support treats the vTOM bit as part of
the physical address.  For accessing shared (decrypted) memory, the core
approach is to create a second kernel virtual mapping that maps to
parallel physical addresses above vTOM, while leaving the original
mapping unchanged.  Most of the code for creating that second virtual
mapping is confined to Hyper-V specific areas, but there are are also
changes to generic swiotlb code.

Changes in this patch set
=========================
In preparation for supporting PCI pass-thru devices, this patch set
changes the core approach for handling vTOM. In the new approach,
the vTOM bit is treated as a protection flag, and not as part of
the physical address. This new approach is like the approach for
the GPA.SHARED bit in Intel TDX.  Furthermore, there's no need to
create a second kernel virtual mapping.  When memory is changed
between private and shared using set_memory_decrypted() and
set_memory_encrypted(), the PTEs for the existing kernel mapping
are changed to add or remove the vTOM bit just as with TDX. The
hypercalls to change the memory status on the host side are made
using the existing callback mechanism. Everything just works, with
a minor tweak to map the I/O APIC to use private accesses as mentioned
above.

With the new handling of vTOM in place, existing Hyper-V code that
creates the second kernel virtual mapping still works, but it is now
redundant as the original kernel virtual mapping (as updated) maps
to the same physical address. To simplify things going forward, this
patch set removes the code that creates the second kernel virtual
mapping. And since a second kernel virtual mapping is no longer
needed, changes to the DMA layer proposed as an RFC[1] are no
longer needed.

Finally, to support PCI pass-thru in a Confidential VM, Hyper-V
requires that all accesses to PCI config space be emulated using
a hypercall.  This patch set adds functions to invoke those
hypercalls and uses them in the config space access functions
in the Hyper-V PCI driver. Lastly, the Hyper-V PCI driver is
marked as allowed to be used in a Confidential VM.  The Hyper-V
PCI driver has been hardened against a malicious Hyper-V in a
previous patch set.[4]

Patch Organization
==================
Patch 1 fixes a bug in __ioremap_caller() that affects the
existing Hyper-V code after the change to treat the vTOM bit as
a protection flag. Fixing the bug allows the old code to continue
to run until later patches in the series remove or update it.
This sequencing avoids the need to enable the new approach and
remove the old code in a single large patch.

Patch 2 handles the I/O APIC quirk by defining a new CC_ATTR enum
member that is set only when running on Hyper-V.

Patch 3 does some simple reordering of code to facilitate Patch 5.

Patch 4 tweaks calls to vmap_pfn() in the old Hyper-V code that
are deleted in later patches in the series. Like Patch 1, this
patch helps avoid the need to enable the new approach and remove
the old code in a single large patch.

Patch 5 enables the new approach to handling vTOM for Hyper-V
guest VMs.

Patches 6 thru 9 remove existing code for creating a second
kernel virtual mapping.

Patch 10 updates existing code so that it no longer assumes that
the vTOM bit is part of the physical address.

Patch 11 adds the new hypercalls for accessing MMIO Config Space.

Patch 12 updates the PCI Hyper-V driver to use the new hypercalls
and enables the PCI Hyper-V driver to be used in a Confidential VM.

[1] https://lore.kernel.org/lkml/20220706195027.76026-1-parri.andrea@gmail.com/
[2] https://lore.kernel.org/all/20211025122116.264793-1-ltykernel@gmail.com/
[3] https://lore.kernel.org/all/20211213071407.314309-1-ltykernel@gmail.com/
[4] https://lore.kernel.org/all/20220511223207.3386-1-parri.andrea@gmail.com/

---

Changes in v2:
* Patch 11: Include more detail in the error message if an MMIO
  hypercall fails. [Bjorn Helgaas]

* Patch 12: Restore removed memory barriers. It seems like these
  barriers should not be needed because of the spin_unlock() calls,
  but commit bdd74440d9e8 indicates that they are. This patch series
  will leave the barriers unchanged; whether they are really needed
  can be sorted out separately. [Boqun Feng]


Michael Kelley (12):
  x86/ioremap: Fix page aligned size calculation in __ioremap_caller()
  x86/ioapic: Gate decrypted mapping on cc_platform_has() attribute
  x86/hyperv: Reorder code in prep for subsequent patch
  Drivers: hv: Explicitly request decrypted in vmap_pfn() calls
  x86/hyperv: Change vTOM handling to use standard coco mechanisms
  swiotlb: Remove bounce buffer remapping for Hyper-V
  Drivers: hv: vmbus: Remove second mapping of VMBus monitor pages
  Drivers: hv: vmbus: Remove second way of mapping ring buffers
  hv_netvsc: Remove second mapping of send and recv buffers
  Drivers: hv: Don't remap addresses that are above shared_gpa_boundary
  PCI: hv: Add hypercalls to read/write MMIO space
  PCI: hv: Enable PCI pass-thru devices in Confidential VMs

 arch/x86/coco/core.c                |  10 +-
 arch/x86/hyperv/hv_init.c           |   7 +-
 arch/x86/hyperv/ivm.c               | 121 +++++++++----------
 arch/x86/include/asm/hyperv-tlfs.h  |   3 +
 arch/x86/include/asm/mshyperv.h     |   8 +-
 arch/x86/kernel/apic/io_apic.c      |   3 +-
 arch/x86/kernel/cpu/mshyperv.c      |  22 ++--
 arch/x86/mm/ioremap.c               |   2 +-
 arch/x86/mm/pat/set_memory.c        |   6 +-
 drivers/hv/Kconfig                  |   1 -
 drivers/hv/channel_mgmt.c           |   2 +-
 drivers/hv/connection.c             | 113 +++++-------------
 drivers/hv/hv.c                     |  23 ++--
 drivers/hv/hv_common.c              |  11 --
 drivers/hv/hyperv_vmbus.h           |   2 -
 drivers/hv/ring_buffer.c            |  62 ++++------
 drivers/net/hyperv/hyperv_net.h     |   2 -
 drivers/net/hyperv/netvsc.c         |  48 +-------
 drivers/pci/controller/pci-hyperv.c | 232 ++++++++++++++++++++++++++----------
 include/asm-generic/hyperv-tlfs.h   |  22 ++++
 include/asm-generic/mshyperv.h      |   2 -
 include/linux/cc_platform.h         |  13 ++
 include/linux/swiotlb.h             |   2 -
 kernel/dma/swiotlb.c                |  45 +------
 24 files changed, 358 insertions(+), 404 deletions(-)

-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v2 01/12] x86/ioremap: Fix page aligned size calculation in __ioremap_caller()
  2022-11-11  6:21 [PATCH v2 00/12] Drivers: hv: Add PCI pass-thru support to Hyper-V Confidential VMs Michael Kelley
@ 2022-11-11  6:21 ` Michael Kelley
  2022-11-12  0:11   ` Dave Hansen
  2022-11-14 16:40   ` Dave Hansen
  2022-11-11  6:21 ` [PATCH v2 02/12] x86/ioapic: Gate decrypted mapping on cc_platform_has() attribute Michael Kelley
                   ` (11 subsequent siblings)
  12 siblings, 2 replies; 27+ messages in thread
From: Michael Kelley @ 2022-11-11  6:21 UTC (permalink / raw)
  To: hpa, kys, haiyangz, wei.liu, decui, luto, peterz, davem,
	edumazet, kuba, pabeni, lpieralisi, robh, kw, bhelgaas, arnd,
	hch, m.szyprowski, robin.murphy, thomas.lendacky, brijesh.singh,
	tglx, mingo, bp, dave.hansen, Tianyu.Lan, kirill.shutemov,
	sathyanarayanan.kuppuswamy, ak, isaku.yamahata, dan.j.williams,
	jane.chu, seanjc, tony.luck, x86, linux-kernel, linux-hyperv,
	netdev, linux-pci, linux-arch, iommu
  Cc: mikelley

If applying the PHYSICAL_PAGE_MASK to the phys_addr argument causes
upper bits to be masked out, the re-calculation of size to account for
page alignment is incorrect because the same bits are not masked out
in last_addr.

Fix this by masking the page aligned last_addr as well.

Signed-off-by: Michael Kelley <mikelley@microsoft.com>
---
 arch/x86/mm/ioremap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index 78c5bc6..0343de4 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -218,7 +218,7 @@ static void __ioremap_check_mem(resource_size_t addr, unsigned long size,
 	 */
 	offset = phys_addr & ~PAGE_MASK;
 	phys_addr &= PHYSICAL_PAGE_MASK;
-	size = PAGE_ALIGN(last_addr+1) - phys_addr;
+	size = (PAGE_ALIGN(last_addr+1) & PHYSICAL_PAGE_MASK) - phys_addr;
 
 	retval = memtype_reserve(phys_addr, (u64)phys_addr + size,
 						pcm, &new_pcm);
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 02/12] x86/ioapic: Gate decrypted mapping on cc_platform_has() attribute
  2022-11-11  6:21 [PATCH v2 00/12] Drivers: hv: Add PCI pass-thru support to Hyper-V Confidential VMs Michael Kelley
  2022-11-11  6:21 ` [PATCH v2 01/12] x86/ioremap: Fix page aligned size calculation in __ioremap_caller() Michael Kelley
@ 2022-11-11  6:21 ` Michael Kelley
  2022-11-12  0:21   ` Dave Hansen
  2022-11-11  6:21 ` [PATCH v2 03/12] x86/hyperv: Reorder code in prep for subsequent patch Michael Kelley
                   ` (10 subsequent siblings)
  12 siblings, 1 reply; 27+ messages in thread
From: Michael Kelley @ 2022-11-11  6:21 UTC (permalink / raw)
  To: hpa, kys, haiyangz, wei.liu, decui, luto, peterz, davem,
	edumazet, kuba, pabeni, lpieralisi, robh, kw, bhelgaas, arnd,
	hch, m.szyprowski, robin.murphy, thomas.lendacky, brijesh.singh,
	tglx, mingo, bp, dave.hansen, Tianyu.Lan, kirill.shutemov,
	sathyanarayanan.kuppuswamy, ak, isaku.yamahata, dan.j.williams,
	jane.chu, seanjc, tony.luck, x86, linux-kernel, linux-hyperv,
	netdev, linux-pci, linux-arch, iommu
  Cc: mikelley

Current code always maps the IOAPIC as shared (decrypted) in a
confidential VM. But Hyper-V guest VMs on AMD SEV-SNP with vTOM
enabled use a paravisor running in VMPL0 to emulate the IOAPIC.
In such a case, the IOAPIC must be accessed as private (encrypted).

Fix this by gating the IOAPIC decrypted mapping on a new
cc_platform_has() attribute that a subsequent patch in the series
will set only for Hyper-V guests. The new attribute is named
somewhat generically because similar paravisor emulation cases
may arise in the future.

Signed-off-by: Michael Kelley <mikelley@microsoft.com>
Reviewed-by: Wei Liu <wei.liu@kernel.org>
---
 arch/x86/kernel/apic/io_apic.c |  3 ++-
 include/linux/cc_platform.h    | 13 +++++++++++++
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index a868b76..d2c1bf7 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -2686,7 +2686,8 @@ static void io_apic_set_fixmap(enum fixed_addresses idx, phys_addr_t phys)
 	 * Ensure fixmaps for IOAPIC MMIO respect memory encryption pgprot
 	 * bits, just like normal ioremap():
 	 */
-	flags = pgprot_decrypted(flags);
+	if (!cc_platform_has(CC_ATTR_HAS_PARAVISOR))
+		flags = pgprot_decrypted(flags);
 
 	__set_fixmap(idx, phys, flags);
 }
diff --git a/include/linux/cc_platform.h b/include/linux/cc_platform.h
index cb0d6cd..b6c4a79 100644
--- a/include/linux/cc_platform.h
+++ b/include/linux/cc_platform.h
@@ -90,6 +90,19 @@ enum cc_attr {
 	 * Examples include TDX Guest.
 	 */
 	CC_ATTR_HOTPLUG_DISABLED,
+
+	/**
+	 * @CC_ATTR_HAS_PARAVISOR: Guest VM is running with a paravisor
+	 *
+	 * The platform/OS is running as a guest/virtual machine with
+	 * a paravisor in VMPL0. Having a paravisor affects things
+	 * like whether the I/O APIC is emulated and operates in the
+	 * encrypted or decrypted portion of the guest physical address
+	 * space.
+	 *
+	 * Examples include Hyper-V SEV-SNP guests using vTOM.
+	 */
+	CC_ATTR_HAS_PARAVISOR,
 };
 
 #ifdef CONFIG_ARCH_HAS_CC_PLATFORM
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 03/12] x86/hyperv: Reorder code in prep for subsequent patch
  2022-11-11  6:21 [PATCH v2 00/12] Drivers: hv: Add PCI pass-thru support to Hyper-V Confidential VMs Michael Kelley
  2022-11-11  6:21 ` [PATCH v2 01/12] x86/ioremap: Fix page aligned size calculation in __ioremap_caller() Michael Kelley
  2022-11-11  6:21 ` [PATCH v2 02/12] x86/ioapic: Gate decrypted mapping on cc_platform_has() attribute Michael Kelley
@ 2022-11-11  6:21 ` Michael Kelley
  2022-11-11  6:21 ` [PATCH v2 04/12] Drivers: hv: Explicitly request decrypted in vmap_pfn() calls Michael Kelley
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 27+ messages in thread
From: Michael Kelley @ 2022-11-11  6:21 UTC (permalink / raw)
  To: hpa, kys, haiyangz, wei.liu, decui, luto, peterz, davem,
	edumazet, kuba, pabeni, lpieralisi, robh, kw, bhelgaas, arnd,
	hch, m.szyprowski, robin.murphy, thomas.lendacky, brijesh.singh,
	tglx, mingo, bp, dave.hansen, Tianyu.Lan, kirill.shutemov,
	sathyanarayanan.kuppuswamy, ak, isaku.yamahata, dan.j.williams,
	jane.chu, seanjc, tony.luck, x86, linux-kernel, linux-hyperv,
	netdev, linux-pci, linux-arch, iommu
  Cc: mikelley

Reorder some code as preparation for a subsequent patch.  No
functional change.

Signed-off-by: Michael Kelley <mikelley@microsoft.com>
Reviewed-by: Tianyu Lan <Tianyu.Lan@microsoft.com>
---
 arch/x86/hyperv/ivm.c | 68 +++++++++++++++++++++++++--------------------------
 1 file changed, 34 insertions(+), 34 deletions(-)

diff --git a/arch/x86/hyperv/ivm.c b/arch/x86/hyperv/ivm.c
index 1dbcbd9..f33c67e 100644
--- a/arch/x86/hyperv/ivm.c
+++ b/arch/x86/hyperv/ivm.c
@@ -235,40 +235,6 @@ void hv_ghcb_msr_read(u64 msr, u64 *value)
 EXPORT_SYMBOL_GPL(hv_ghcb_msr_read);
 #endif
 
-enum hv_isolation_type hv_get_isolation_type(void)
-{
-	if (!(ms_hyperv.priv_high & HV_ISOLATION))
-		return HV_ISOLATION_TYPE_NONE;
-	return FIELD_GET(HV_ISOLATION_TYPE, ms_hyperv.isolation_config_b);
-}
-EXPORT_SYMBOL_GPL(hv_get_isolation_type);
-
-/*
- * hv_is_isolation_supported - Check system runs in the Hyper-V
- * isolation VM.
- */
-bool hv_is_isolation_supported(void)
-{
-	if (!cpu_feature_enabled(X86_FEATURE_HYPERVISOR))
-		return false;
-
-	if (!hypervisor_is_type(X86_HYPER_MS_HYPERV))
-		return false;
-
-	return hv_get_isolation_type() != HV_ISOLATION_TYPE_NONE;
-}
-
-DEFINE_STATIC_KEY_FALSE(isolation_type_snp);
-
-/*
- * hv_isolation_type_snp - Check system runs in the AMD SEV-SNP based
- * isolation VM.
- */
-bool hv_isolation_type_snp(void)
-{
-	return static_branch_unlikely(&isolation_type_snp);
-}
-
 /*
  * hv_mark_gpa_visibility - Set pages visible to host via hvcall.
  *
@@ -387,3 +353,37 @@ void hv_unmap_memory(void *addr)
 {
 	vunmap(addr);
 }
+
+enum hv_isolation_type hv_get_isolation_type(void)
+{
+	if (!(ms_hyperv.priv_high & HV_ISOLATION))
+		return HV_ISOLATION_TYPE_NONE;
+	return FIELD_GET(HV_ISOLATION_TYPE, ms_hyperv.isolation_config_b);
+}
+EXPORT_SYMBOL_GPL(hv_get_isolation_type);
+
+/*
+ * hv_is_isolation_supported - Check system runs in the Hyper-V
+ * isolation VM.
+ */
+bool hv_is_isolation_supported(void)
+{
+	if (!cpu_feature_enabled(X86_FEATURE_HYPERVISOR))
+		return false;
+
+	if (!hypervisor_is_type(X86_HYPER_MS_HYPERV))
+		return false;
+
+	return hv_get_isolation_type() != HV_ISOLATION_TYPE_NONE;
+}
+
+DEFINE_STATIC_KEY_FALSE(isolation_type_snp);
+
+/*
+ * hv_isolation_type_snp - Check system runs in the AMD SEV-SNP based
+ * isolation VM.
+ */
+bool hv_isolation_type_snp(void)
+{
+	return static_branch_unlikely(&isolation_type_snp);
+}
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 04/12] Drivers: hv: Explicitly request decrypted in vmap_pfn() calls
  2022-11-11  6:21 [PATCH v2 00/12] Drivers: hv: Add PCI pass-thru support to Hyper-V Confidential VMs Michael Kelley
                   ` (2 preceding siblings ...)
  2022-11-11  6:21 ` [PATCH v2 03/12] x86/hyperv: Reorder code in prep for subsequent patch Michael Kelley
@ 2022-11-11  6:21 ` Michael Kelley
  2022-11-11  6:21 ` [PATCH v2 05/12] x86/hyperv: Change vTOM handling to use standard coco mechanisms Michael Kelley
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 27+ messages in thread
From: Michael Kelley @ 2022-11-11  6:21 UTC (permalink / raw)
  To: hpa, kys, haiyangz, wei.liu, decui, luto, peterz, davem,
	edumazet, kuba, pabeni, lpieralisi, robh, kw, bhelgaas, arnd,
	hch, m.szyprowski, robin.murphy, thomas.lendacky, brijesh.singh,
	tglx, mingo, bp, dave.hansen, Tianyu.Lan, kirill.shutemov,
	sathyanarayanan.kuppuswamy, ak, isaku.yamahata, dan.j.williams,
	jane.chu, seanjc, tony.luck, x86, linux-kernel, linux-hyperv,
	netdev, linux-pci, linux-arch, iommu
  Cc: mikelley

In preparation for a subsequent patch, update vmap_pfn() calls to
explicitly request that the mapping be for decrypted access to
the memory.  There's no change in functionality since the PFNs
passed to vmap_pfn() are above the shared_gpa_boundary, implicitly
producing a decrypted mapping. But explicitly requesting decrypted
allows the code to work before and after a subsequent patch
that will cause vmap_pfn() to mask the PFNs to being below the
shared_gpa_boundary. While another subsesquent patch removes the
vmap_pfn() calls entirely, this temporary tweak avoids the need
for a large patch that makes all the changes at once.

Signed-off-by: Michael Kelley <mikelley@microsoft.com>
Reviewed-by: Tianyu Lan <Tianyu.Lan@microsoft.com>
---
 arch/x86/hyperv/ivm.c    | 2 +-
 drivers/hv/ring_buffer.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/hyperv/ivm.c b/arch/x86/hyperv/ivm.c
index f33c67e..e8be4c2 100644
--- a/arch/x86/hyperv/ivm.c
+++ b/arch/x86/hyperv/ivm.c
@@ -343,7 +343,7 @@ void *hv_map_memory(void *addr, unsigned long size)
 		pfns[i] = vmalloc_to_pfn(addr + i * PAGE_SIZE) +
 			(ms_hyperv.shared_gpa_boundary >> PAGE_SHIFT);
 
-	vaddr = vmap_pfn(pfns, size / PAGE_SIZE, PAGE_KERNEL_IO);
+	vaddr = vmap_pfn(pfns, size / PAGE_SIZE, pgprot_decrypted(PAGE_KERNEL_NOENC));
 	kfree(pfns);
 
 	return vaddr;
diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
index 59a4aa8..b4a91b1 100644
--- a/drivers/hv/ring_buffer.c
+++ b/drivers/hv/ring_buffer.c
@@ -211,7 +211,7 @@ int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info,
 
 		ring_info->ring_buffer = (struct hv_ring_buffer *)
 			vmap_pfn(pfns_wraparound, page_cnt * 2 - 1,
-				 PAGE_KERNEL);
+				 pgprot_decrypted(PAGE_KERNEL_NOENC));
 		kfree(pfns_wraparound);
 
 		if (!ring_info->ring_buffer)
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 05/12] x86/hyperv: Change vTOM handling to use standard coco mechanisms
  2022-11-11  6:21 [PATCH v2 00/12] Drivers: hv: Add PCI pass-thru support to Hyper-V Confidential VMs Michael Kelley
                   ` (3 preceding siblings ...)
  2022-11-11  6:21 ` [PATCH v2 04/12] Drivers: hv: Explicitly request decrypted in vmap_pfn() calls Michael Kelley
@ 2022-11-11  6:21 ` Michael Kelley
  2022-11-11 18:49   ` Tom Lendacky
  2022-11-11  6:21 ` [PATCH v2 06/12] swiotlb: Remove bounce buffer remapping for Hyper-V Michael Kelley
                   ` (7 subsequent siblings)
  12 siblings, 1 reply; 27+ messages in thread
From: Michael Kelley @ 2022-11-11  6:21 UTC (permalink / raw)
  To: hpa, kys, haiyangz, wei.liu, decui, luto, peterz, davem,
	edumazet, kuba, pabeni, lpieralisi, robh, kw, bhelgaas, arnd,
	hch, m.szyprowski, robin.murphy, thomas.lendacky, brijesh.singh,
	tglx, mingo, bp, dave.hansen, Tianyu.Lan, kirill.shutemov,
	sathyanarayanan.kuppuswamy, ak, isaku.yamahata, dan.j.williams,
	jane.chu, seanjc, tony.luck, x86, linux-kernel, linux-hyperv,
	netdev, linux-pci, linux-arch, iommu
  Cc: mikelley

Hyper-V guests on AMD SEV-SNP hardware have the option of using the
"virtual Top Of Memory" (vTOM) feature specified by the SEV-SNP
architecture. With vTOM, shared vs. private memory accesses are
controlled by splitting the guest physical address space into two
halves.  vTOM is the dividing line where the uppermost bit of the
physical address space is set; e.g., with 47 bits of guest physical
address space, vTOM is 0x40000000000 (bit 46 is set).  Guest phyiscal
memory is accessible at two parallel physical addresses -- one below
vTOM and one above vTOM.  Accesses below vTOM are private (encrypted)
while accesses above vTOM are shared (decrypted). In this sense, vTOM
is like the GPA.SHARED bit in Intel TDX.

Support for Hyper-V guests using vTOM was added to the Linux kernel in
two patch sets[1][2]. This support treats the vTOM bit as part of
the physical address. For accessing shared (decrypted) memory, these
patch sets create a second kernel virtual mapping that maps to physical
addresses above vTOM.

A better approach is to treat the vTOM bit as a protection flag, not
as part of the physical address. This new approach is like the approach
for the GPA.SHARED bit in Intel TDX. Rather than creating a second kernel
virtual mapping, the existing mapping is updated using recently added
coco mechanisms.  When memory is changed between private and shared using
set_memory_decrypted() and set_memory_encrypted(), the PTEs for the
existing kernel mapping are changed to add or remove the vTOM bit
in the guest physical address, just as with TDX. The hypercalls to
change the memory status on the host side are made using the existing
callback mechanism. Everything just works, with a minor tweak to map
the I/O APIC to use private accesses.

To accomplish the switch in approach, the following must be done in
in this single patch:

* Update Hyper-V initialization to set the cc _mask based on vTOM
  and do other coco initialization.

* Update physical_mask so the vTOM bit is no longer treated as part
  of the physical address

* Update cc_mkenc() and cc_mkdec() to be active for Hyper-V guests.
  This makes the vTOM bit part of the protection flags.

* Code already exists to make hypercalls to inform Hyper-V about pages
  changing between shared and private.  Update this code to run as a
  callback from __set_memory_enc_pgtable().

* Remove the Hyper-V special case from __set_memory_enc_dec(), and
  make the normal case active for Hyper-V VMs, which have
  CC_ATTR_GUEST_MEM_ENCRYPT, but not CC_ATTR_MEM_ENCRYPT.

[1] https://lore.kernel.org/all/20211025122116.264793-1-ltykernel@gmail.com/
[2] https://lore.kernel.org/all/20211213071407.314309-1-ltykernel@gmail.com/

Signed-off-by: Michael Kelley <mikelley@microsoft.com>
Reviewed-by: Tianyu Lan <Tianyu.Lan@microsoft.com>
---
 arch/x86/coco/core.c            | 10 ++++++++-
 arch/x86/hyperv/ivm.c           | 45 +++++++++++++++++++++++++++++++----------
 arch/x86/include/asm/mshyperv.h |  8 ++------
 arch/x86/kernel/cpu/mshyperv.c  | 15 +++++++-------
 arch/x86/mm/pat/set_memory.c    |  6 ++----
 5 files changed, 54 insertions(+), 30 deletions(-)

diff --git a/arch/x86/coco/core.c b/arch/x86/coco/core.c
index 49b44f8..de4e83e 100644
--- a/arch/x86/coco/core.c
+++ b/arch/x86/coco/core.c
@@ -78,7 +78,13 @@ static bool amd_cc_platform_has(enum cc_attr attr)
 
 static bool hyperv_cc_platform_has(enum cc_attr attr)
 {
-	return attr == CC_ATTR_GUEST_MEM_ENCRYPT;
+	switch (attr) {
+	case CC_ATTR_GUEST_MEM_ENCRYPT:
+	case CC_ATTR_HAS_PARAVISOR:
+		return true;
+	default:
+		return false;
+	}
 }
 
 bool cc_platform_has(enum cc_attr attr)
@@ -108,6 +114,7 @@ u64 cc_mkenc(u64 val)
 	switch (vendor) {
 	case CC_VENDOR_AMD:
 		return val | cc_mask;
+	case CC_VENDOR_HYPERV:
 	case CC_VENDOR_INTEL:
 		return val & ~cc_mask;
 	default:
@@ -121,6 +128,7 @@ u64 cc_mkdec(u64 val)
 	switch (vendor) {
 	case CC_VENDOR_AMD:
 		return val & ~cc_mask;
+	case CC_VENDOR_HYPERV:
 	case CC_VENDOR_INTEL:
 		return val | cc_mask;
 	default:
diff --git a/arch/x86/hyperv/ivm.c b/arch/x86/hyperv/ivm.c
index e8be4c2..29ccbe8 100644
--- a/arch/x86/hyperv/ivm.c
+++ b/arch/x86/hyperv/ivm.c
@@ -13,6 +13,7 @@
 #include <asm/svm.h>
 #include <asm/sev.h>
 #include <asm/io.h>
+#include <asm/coco.h>
 #include <asm/mshyperv.h>
 #include <asm/hypervisor.h>
 
@@ -233,7 +234,6 @@ void hv_ghcb_msr_read(u64 msr, u64 *value)
 	local_irq_restore(flags);
 }
 EXPORT_SYMBOL_GPL(hv_ghcb_msr_read);
-#endif
 
 /*
  * hv_mark_gpa_visibility - Set pages visible to host via hvcall.
@@ -286,27 +286,25 @@ static int hv_mark_gpa_visibility(u16 count, const u64 pfn[],
 }
 
 /*
- * hv_set_mem_host_visibility - Set specified memory visible to host.
+ * hv_vtom_set_host_visibility - Set specified memory visible to host.
  *
  * In Isolation VM, all guest memory is encrypted from host and guest
  * needs to set memory visible to host via hvcall before sharing memory
  * with host. This function works as wrap of hv_mark_gpa_visibility()
  * with memory base and size.
  */
-int hv_set_mem_host_visibility(unsigned long kbuffer, int pagecount, bool visible)
+static bool hv_vtom_set_host_visibility(unsigned long kbuffer, int pagecount, bool enc)
 {
-	enum hv_mem_host_visibility visibility = visible ?
-			VMBUS_PAGE_VISIBLE_READ_WRITE : VMBUS_PAGE_NOT_VISIBLE;
+	enum hv_mem_host_visibility visibility = enc ?
+			VMBUS_PAGE_NOT_VISIBLE : VMBUS_PAGE_VISIBLE_READ_WRITE;
 	u64 *pfn_array;
 	int ret = 0;
+	bool result = true;
 	int i, pfn;
 
-	if (!hv_is_isolation_supported() || !hv_hypercall_pg)
-		return 0;
-
 	pfn_array = kmalloc(HV_HYP_PAGE_SIZE, GFP_KERNEL);
 	if (!pfn_array)
-		return -ENOMEM;
+		return false;
 
 	for (i = 0, pfn = 0; i < pagecount; i++) {
 		pfn_array[pfn] = virt_to_hvpfn((void *)kbuffer + i * HV_HYP_PAGE_SIZE);
@@ -315,17 +313,42 @@ int hv_set_mem_host_visibility(unsigned long kbuffer, int pagecount, bool visibl
 		if (pfn == HV_MAX_MODIFY_GPA_REP_COUNT || i == pagecount - 1) {
 			ret = hv_mark_gpa_visibility(pfn, pfn_array,
 						     visibility);
-			if (ret)
+			if (ret) {
+				result = false;
 				goto err_free_pfn_array;
+			}
 			pfn = 0;
 		}
 	}
 
  err_free_pfn_array:
 	kfree(pfn_array);
-	return ret;
+	return result;
+}
+
+static bool hv_vtom_tlb_flush_required(bool private)
+{
+	return true;
 }
 
+static bool hv_vtom_cache_flush_required(void)
+{
+	return false;
+}
+
+void __init hv_vtom_init(void)
+{
+	cc_set_vendor(CC_VENDOR_HYPERV);
+	cc_set_mask(ms_hyperv.shared_gpa_boundary);
+	physical_mask &= ms_hyperv.shared_gpa_boundary - 1;
+
+	x86_platform.guest.enc_cache_flush_required = hv_vtom_cache_flush_required;
+	x86_platform.guest.enc_tlb_flush_required = hv_vtom_tlb_flush_required;
+	x86_platform.guest.enc_status_change_finish = hv_vtom_set_host_visibility;
+}
+
+#endif /* CONFIG_AMD_MEM_ENCRYPT */
+
 /*
  * hv_map_memory - map memory to extra space in the AMD SEV-SNP Isolation VM.
  */
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 61f0c20..59b3310 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -174,18 +174,19 @@ static inline void hv_apic_init(void) {}
 int hv_map_ioapic_interrupt(int ioapic_id, bool level, int vcpu, int vector,
 		struct hv_interrupt_entry *entry);
 int hv_unmap_ioapic_interrupt(int ioapic_id, struct hv_interrupt_entry *entry);
-int hv_set_mem_host_visibility(unsigned long addr, int numpages, bool visible);
 
 #ifdef CONFIG_AMD_MEM_ENCRYPT
 void hv_ghcb_msr_write(u64 msr, u64 value);
 void hv_ghcb_msr_read(u64 msr, u64 *value);
 bool hv_ghcb_negotiate_protocol(void);
 void hv_ghcb_terminate(unsigned int set, unsigned int reason);
+void hv_vtom_init(void);
 #else
 static inline void hv_ghcb_msr_write(u64 msr, u64 value) {}
 static inline void hv_ghcb_msr_read(u64 msr, u64 *value) {}
 static inline bool hv_ghcb_negotiate_protocol(void) { return false; }
 static inline void hv_ghcb_terminate(unsigned int set, unsigned int reason) {}
+static inline void hv_vtom_init(void) {}
 #endif
 
 extern bool hv_isolation_type_snp(void);
@@ -241,11 +242,6 @@ static inline int hyperv_flush_guest_mapping_range(u64 as,
 }
 static inline void hv_set_register(unsigned int reg, u64 value) { }
 static inline u64 hv_get_register(unsigned int reg) { return 0; }
-static inline int hv_set_mem_host_visibility(unsigned long addr, int numpages,
-					     bool visible)
-{
-	return -1;
-}
 #endif /* CONFIG_HYPERV */
 
 
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 8316139..b080795 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -33,7 +33,6 @@
 #include <asm/nmi.h>
 #include <clocksource/hyperv_timer.h>
 #include <asm/numa.h>
-#include <asm/coco.h>
 
 /* Is Linux running as the root partition? */
 bool hv_root_partition;
@@ -325,8 +324,10 @@ static void __init ms_hyperv_init_platform(void)
 	if (ms_hyperv.priv_high & HV_ISOLATION) {
 		ms_hyperv.isolation_config_a = cpuid_eax(HYPERV_CPUID_ISOLATION_CONFIG);
 		ms_hyperv.isolation_config_b = cpuid_ebx(HYPERV_CPUID_ISOLATION_CONFIG);
-		ms_hyperv.shared_gpa_boundary =
-			BIT_ULL(ms_hyperv.shared_gpa_boundary_bits);
+
+		if (ms_hyperv.shared_gpa_boundary_active)
+			ms_hyperv.shared_gpa_boundary =
+				BIT_ULL(ms_hyperv.shared_gpa_boundary_bits);
 
 		pr_info("Hyper-V: Isolation Config: Group A 0x%x, Group B 0x%x\n",
 			ms_hyperv.isolation_config_a, ms_hyperv.isolation_config_b);
@@ -337,11 +338,6 @@ static void __init ms_hyperv_init_platform(void)
 			swiotlb_unencrypted_base = ms_hyperv.shared_gpa_boundary;
 #endif
 		}
-		/* Isolation VMs are unenlightened SEV-based VMs, thus this check: */
-		if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT)) {
-			if (hv_get_isolation_type() != HV_ISOLATION_TYPE_NONE)
-				cc_set_vendor(CC_VENDOR_HYPERV);
-		}
 	}
 
 	if (hv_max_functions_eax >= HYPERV_CPUID_NESTED_FEATURES) {
@@ -410,6 +406,9 @@ static void __init ms_hyperv_init_platform(void)
 	i8253_clear_counter_on_shutdown = false;
 
 #if IS_ENABLED(CONFIG_HYPERV)
+	if ((hv_get_isolation_type() == HV_ISOLATION_TYPE_VBS) ||
+	    (hv_get_isolation_type() == HV_ISOLATION_TYPE_SNP))
+		hv_vtom_init();
 	/*
 	 * Setup the hook to get control post apic initialization.
 	 */
diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
index 06eb8910..024fbf4 100644
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -2126,10 +2126,8 @@ static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
 
 static int __set_memory_enc_dec(unsigned long addr, int numpages, bool enc)
 {
-	if (hv_is_isolation_supported())
-		return hv_set_mem_host_visibility(addr, numpages, !enc);
-
-	if (cc_platform_has(CC_ATTR_MEM_ENCRYPT))
+	if (cc_platform_has(CC_ATTR_MEM_ENCRYPT) ||
+	    cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
 		return __set_memory_enc_pgtable(addr, numpages, enc);
 
 	return 0;
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 06/12] swiotlb: Remove bounce buffer remapping for Hyper-V
  2022-11-11  6:21 [PATCH v2 00/12] Drivers: hv: Add PCI pass-thru support to Hyper-V Confidential VMs Michael Kelley
                   ` (4 preceding siblings ...)
  2022-11-11  6:21 ` [PATCH v2 05/12] x86/hyperv: Change vTOM handling to use standard coco mechanisms Michael Kelley
@ 2022-11-11  6:21 ` Michael Kelley
  2022-11-11  6:21 ` [PATCH v2 07/12] Drivers: hv: vmbus: Remove second mapping of VMBus monitor pages Michael Kelley
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 27+ messages in thread
From: Michael Kelley @ 2022-11-11  6:21 UTC (permalink / raw)
  To: hpa, kys, haiyangz, wei.liu, decui, luto, peterz, davem,
	edumazet, kuba, pabeni, lpieralisi, robh, kw, bhelgaas, arnd,
	hch, m.szyprowski, robin.murphy, thomas.lendacky, brijesh.singh,
	tglx, mingo, bp, dave.hansen, Tianyu.Lan, kirill.shutemov,
	sathyanarayanan.kuppuswamy, ak, isaku.yamahata, dan.j.williams,
	jane.chu, seanjc, tony.luck, x86, linux-kernel, linux-hyperv,
	netdev, linux-pci, linux-arch, iommu
  Cc: mikelley

With changes to how Hyper-V guest VMs flip memory between private
(encrypted) and shared (decrypted), creating a second kernel virtual
mapping for shared memory is no longer necessary. Everything needed
for the transition to shared is handled by set_memory_decrypted().

As such, remove swiotlb_unencrypted_base and the associated
code.

Signed-off-by: Michael Kelley <mikelley@microsoft.com>
Acked-by: Christoph Hellwig <hch@lst.de>
---
 arch/x86/kernel/cpu/mshyperv.c |  7 +------
 include/linux/swiotlb.h        |  2 --
 kernel/dma/swiotlb.c           | 45 +-----------------------------------------
 3 files changed, 2 insertions(+), 52 deletions(-)

diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index b080795..c87e411 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -18,7 +18,6 @@
 #include <linux/kexec.h>
 #include <linux/i8253.h>
 #include <linux/random.h>
-#include <linux/swiotlb.h>
 #include <asm/processor.h>
 #include <asm/hypervisor.h>
 #include <asm/hyperv-tlfs.h>
@@ -332,12 +331,8 @@ static void __init ms_hyperv_init_platform(void)
 		pr_info("Hyper-V: Isolation Config: Group A 0x%x, Group B 0x%x\n",
 			ms_hyperv.isolation_config_a, ms_hyperv.isolation_config_b);
 
-		if (hv_get_isolation_type() == HV_ISOLATION_TYPE_SNP) {
+		if (hv_get_isolation_type() == HV_ISOLATION_TYPE_SNP)
 			static_branch_enable(&isolation_type_snp);
-#ifdef CONFIG_SWIOTLB
-			swiotlb_unencrypted_base = ms_hyperv.shared_gpa_boundary;
-#endif
-		}
 	}
 
 	if (hv_max_functions_eax >= HYPERV_CPUID_NESTED_FEATURES) {
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
index 35bc4e2..13d7075 100644
--- a/include/linux/swiotlb.h
+++ b/include/linux/swiotlb.h
@@ -185,6 +185,4 @@ static inline bool is_swiotlb_for_alloc(struct device *dev)
 }
 #endif /* CONFIG_DMA_RESTRICTED_POOL */
 
-extern phys_addr_t swiotlb_unencrypted_base;
-
 #endif /* __LINUX_SWIOTLB_H */
diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
index a34c38b..d3d6be0 100644
--- a/kernel/dma/swiotlb.c
+++ b/kernel/dma/swiotlb.c
@@ -73,8 +73,6 @@ struct io_tlb_slot {
 
 struct io_tlb_mem io_tlb_default_mem;
 
-phys_addr_t swiotlb_unencrypted_base;
-
 static unsigned long default_nslabs = IO_TLB_DEFAULT_SIZE >> IO_TLB_SHIFT;
 static unsigned long default_nareas;
 
@@ -210,34 +208,6 @@ static inline unsigned long nr_slots(u64 val)
 }
 
 /*
- * Remap swioltb memory in the unencrypted physical address space
- * when swiotlb_unencrypted_base is set. (e.g. for Hyper-V AMD SEV-SNP
- * Isolation VMs).
- */
-#ifdef CONFIG_HAS_IOMEM
-static void *swiotlb_mem_remap(struct io_tlb_mem *mem, unsigned long bytes)
-{
-	void *vaddr = NULL;
-
-	if (swiotlb_unencrypted_base) {
-		phys_addr_t paddr = mem->start + swiotlb_unencrypted_base;
-
-		vaddr = memremap(paddr, bytes, MEMREMAP_WB);
-		if (!vaddr)
-			pr_err("Failed to map the unencrypted memory %pa size %lx.\n",
-			       &paddr, bytes);
-	}
-
-	return vaddr;
-}
-#else
-static void *swiotlb_mem_remap(struct io_tlb_mem *mem, unsigned long bytes)
-{
-	return NULL;
-}
-#endif
-
-/*
  * Early SWIOTLB allocation may be too early to allow an architecture to
  * perform the desired operations.  This function allows the architecture to
  * call SWIOTLB when the operations are possible.  It needs to be called
@@ -246,18 +216,12 @@ static void *swiotlb_mem_remap(struct io_tlb_mem *mem, unsigned long bytes)
 void __init swiotlb_update_mem_attributes(void)
 {
 	struct io_tlb_mem *mem = &io_tlb_default_mem;
-	void *vaddr;
 	unsigned long bytes;
 
 	if (!mem->nslabs || mem->late_alloc)
 		return;
-	vaddr = phys_to_virt(mem->start);
 	bytes = PAGE_ALIGN(mem->nslabs << IO_TLB_SHIFT);
-	set_memory_decrypted((unsigned long)vaddr, bytes >> PAGE_SHIFT);
-
-	mem->vaddr = swiotlb_mem_remap(mem, bytes);
-	if (!mem->vaddr)
-		mem->vaddr = vaddr;
+	set_memory_decrypted((unsigned long)mem->vaddr, bytes >> PAGE_SHIFT);
 }
 
 static void swiotlb_init_io_tlb_mem(struct io_tlb_mem *mem, phys_addr_t start,
@@ -288,13 +252,6 @@ static void swiotlb_init_io_tlb_mem(struct io_tlb_mem *mem, phys_addr_t start,
 		mem->slots[i].alloc_size = 0;
 	}
 
-	/*
-	 * If swiotlb_unencrypted_base is set, the bounce buffer memory will
-	 * be remapped and cleared in swiotlb_update_mem_attributes.
-	 */
-	if (swiotlb_unencrypted_base)
-		return;
-
 	memset(vaddr, 0, bytes);
 	mem->vaddr = vaddr;
 	return;
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 07/12] Drivers: hv: vmbus: Remove second mapping of VMBus monitor pages
  2022-11-11  6:21 [PATCH v2 00/12] Drivers: hv: Add PCI pass-thru support to Hyper-V Confidential VMs Michael Kelley
                   ` (5 preceding siblings ...)
  2022-11-11  6:21 ` [PATCH v2 06/12] swiotlb: Remove bounce buffer remapping for Hyper-V Michael Kelley
@ 2022-11-11  6:21 ` Michael Kelley
  2022-11-11  6:21 ` [PATCH v2 08/12] Drivers: hv: vmbus: Remove second way of mapping ring buffers Michael Kelley
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 27+ messages in thread
From: Michael Kelley @ 2022-11-11  6:21 UTC (permalink / raw)
  To: hpa, kys, haiyangz, wei.liu, decui, luto, peterz, davem,
	edumazet, kuba, pabeni, lpieralisi, robh, kw, bhelgaas, arnd,
	hch, m.szyprowski, robin.murphy, thomas.lendacky, brijesh.singh,
	tglx, mingo, bp, dave.hansen, Tianyu.Lan, kirill.shutemov,
	sathyanarayanan.kuppuswamy, ak, isaku.yamahata, dan.j.williams,
	jane.chu, seanjc, tony.luck, x86, linux-kernel, linux-hyperv,
	netdev, linux-pci, linux-arch, iommu
  Cc: mikelley

With changes to how Hyper-V guest VMs flip memory between private
(encrypted) and shared (decrypted), creating a second kernel virtual
mapping for shared memory is no longer necessary.  Everything needed
for the transition to shared is handled by set_memory_decrypted().

As such, remove the code to create and manage the second
mapping for VMBus monitor pages. Because set_memory_decrypted()
and set_memory_encrypted() are no-ops in normal VMs, it's
not even necessary to test for being in a Confidential VM
(a.k.a., "Isolation VM").

Signed-off-by: Michael Kelley <mikelley@microsoft.com>
Reviewed-by: Tianyu Lan <Tianyu.Lan@microsoft.com>
---
 drivers/hv/connection.c   | 113 ++++++++++++----------------------------------
 drivers/hv/hyperv_vmbus.h |   2 -
 2 files changed, 28 insertions(+), 87 deletions(-)

diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index 9dc27e5..e473b69 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -104,8 +104,14 @@ int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, u32 version)
 		vmbus_connection.msg_conn_id = VMBUS_MESSAGE_CONNECTION_ID;
 	}
 
-	msg->monitor_page1 = vmbus_connection.monitor_pages_pa[0];
-	msg->monitor_page2 = vmbus_connection.monitor_pages_pa[1];
+	/*
+	 * shared_gpa_boundary is zero in non-SNP VMs, so it's safe to always
+	 * do the add
+	 */
+	msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages[0]) +
+				ms_hyperv.shared_gpa_boundary;
+	msg->monitor_page2 = virt_to_phys(vmbus_connection.monitor_pages[1]) +
+				ms_hyperv.shared_gpa_boundary;
 
 	msg->target_vcpu = hv_cpu_number_to_vp_number(VMBUS_CONNECT_CPU);
 
@@ -219,72 +225,27 @@ int vmbus_connect(void)
 	 * Setup the monitor notification facility. The 1st page for
 	 * parent->child and the 2nd page for child->parent
 	 */
-	vmbus_connection.monitor_pages[0] = (void *)hv_alloc_hyperv_zeroed_page();
-	vmbus_connection.monitor_pages[1] = (void *)hv_alloc_hyperv_zeroed_page();
+	vmbus_connection.monitor_pages[0] = (void *)hv_alloc_hyperv_page();
+	vmbus_connection.monitor_pages[1] = (void *)hv_alloc_hyperv_page();
 	if ((vmbus_connection.monitor_pages[0] == NULL) ||
 	    (vmbus_connection.monitor_pages[1] == NULL)) {
 		ret = -ENOMEM;
 		goto cleanup;
 	}
 
-	vmbus_connection.monitor_pages_original[0]
-		= vmbus_connection.monitor_pages[0];
-	vmbus_connection.monitor_pages_original[1]
-		= vmbus_connection.monitor_pages[1];
-	vmbus_connection.monitor_pages_pa[0]
-		= virt_to_phys(vmbus_connection.monitor_pages[0]);
-	vmbus_connection.monitor_pages_pa[1]
-		= virt_to_phys(vmbus_connection.monitor_pages[1]);
-
-	if (hv_is_isolation_supported()) {
-		ret = set_memory_decrypted((unsigned long)
-					   vmbus_connection.monitor_pages[0],
-					   1);
-		ret |= set_memory_decrypted((unsigned long)
-					    vmbus_connection.monitor_pages[1],
-					    1);
-		if (ret)
-			goto cleanup;
-
-		/*
-		 * Isolation VM with AMD SNP needs to access monitor page via
-		 * address space above shared gpa boundary.
-		 */
-		if (hv_isolation_type_snp()) {
-			vmbus_connection.monitor_pages_pa[0] +=
-				ms_hyperv.shared_gpa_boundary;
-			vmbus_connection.monitor_pages_pa[1] +=
-				ms_hyperv.shared_gpa_boundary;
-
-			vmbus_connection.monitor_pages[0]
-				= memremap(vmbus_connection.monitor_pages_pa[0],
-					   HV_HYP_PAGE_SIZE,
-					   MEMREMAP_WB);
-			if (!vmbus_connection.monitor_pages[0]) {
-				ret = -ENOMEM;
-				goto cleanup;
-			}
-
-			vmbus_connection.monitor_pages[1]
-				= memremap(vmbus_connection.monitor_pages_pa[1],
-					   HV_HYP_PAGE_SIZE,
-					   MEMREMAP_WB);
-			if (!vmbus_connection.monitor_pages[1]) {
-				ret = -ENOMEM;
-				goto cleanup;
-			}
-		}
-
-		/*
-		 * Set memory host visibility hvcall smears memory
-		 * and so zero monitor pages here.
-		 */
-		memset(vmbus_connection.monitor_pages[0], 0x00,
-		       HV_HYP_PAGE_SIZE);
-		memset(vmbus_connection.monitor_pages[1], 0x00,
-		       HV_HYP_PAGE_SIZE);
+	ret = set_memory_decrypted((unsigned long)
+				vmbus_connection.monitor_pages[0], 1);
+	ret |= set_memory_decrypted((unsigned long)
+				vmbus_connection.monitor_pages[1], 1);
+	if (ret)
+		goto cleanup;
 
-	}
+	/*
+	 * Set_memory_decrypted() will change the memory contents if
+	 * decryption occurs, so zero monitor pages here.
+	 */
+	memset(vmbus_connection.monitor_pages[0], 0x00, HV_HYP_PAGE_SIZE);
+	memset(vmbus_connection.monitor_pages[1], 0x00, HV_HYP_PAGE_SIZE);
 
 	msginfo = kzalloc(sizeof(*msginfo) +
 			  sizeof(struct vmbus_channel_initiate_contact),
@@ -376,31 +337,13 @@ void vmbus_disconnect(void)
 		vmbus_connection.int_page = NULL;
 	}
 
-	if (hv_is_isolation_supported()) {
-		/*
-		 * memunmap() checks input address is ioremap address or not
-		 * inside. It doesn't unmap any thing in the non-SNP CVM and
-		 * so not check CVM type here.
-		 */
-		memunmap(vmbus_connection.monitor_pages[0]);
-		memunmap(vmbus_connection.monitor_pages[1]);
-
-		set_memory_encrypted((unsigned long)
-			vmbus_connection.monitor_pages_original[0],
-			1);
-		set_memory_encrypted((unsigned long)
-			vmbus_connection.monitor_pages_original[1],
-			1);
-	}
+	set_memory_encrypted((unsigned long)vmbus_connection.monitor_pages[0], 1);
+	set_memory_encrypted((unsigned long)vmbus_connection.monitor_pages[1], 1);
 
-	hv_free_hyperv_page((unsigned long)
-		vmbus_connection.monitor_pages_original[0]);
-	hv_free_hyperv_page((unsigned long)
-		vmbus_connection.monitor_pages_original[1]);
-	vmbus_connection.monitor_pages_original[0] =
-		vmbus_connection.monitor_pages[0] = NULL;
-	vmbus_connection.monitor_pages_original[1] =
-		vmbus_connection.monitor_pages[1] = NULL;
+	hv_free_hyperv_page((unsigned long)vmbus_connection.monitor_pages[0]);
+	hv_free_hyperv_page((unsigned long)vmbus_connection.monitor_pages[1]);
+	vmbus_connection.monitor_pages[0] = NULL;
+	vmbus_connection.monitor_pages[1] = NULL;
 }
 
 /*
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index dc673ed..167ac51 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -241,8 +241,6 @@ struct vmbus_connection {
 	 * is child->parent notification
 	 */
 	struct hv_monitor_page *monitor_pages[2];
-	void *monitor_pages_original[2];
-	phys_addr_t monitor_pages_pa[2];
 	struct list_head chn_msg_list;
 	spinlock_t channelmsg_lock;
 
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 08/12] Drivers: hv: vmbus: Remove second way of mapping ring buffers
  2022-11-11  6:21 [PATCH v2 00/12] Drivers: hv: Add PCI pass-thru support to Hyper-V Confidential VMs Michael Kelley
                   ` (6 preceding siblings ...)
  2022-11-11  6:21 ` [PATCH v2 07/12] Drivers: hv: vmbus: Remove second mapping of VMBus monitor pages Michael Kelley
@ 2022-11-11  6:21 ` Michael Kelley
  2022-11-11  6:21 ` [PATCH v2 09/12] hv_netvsc: Remove second mapping of send and recv buffers Michael Kelley
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 27+ messages in thread
From: Michael Kelley @ 2022-11-11  6:21 UTC (permalink / raw)
  To: hpa, kys, haiyangz, wei.liu, decui, luto, peterz, davem,
	edumazet, kuba, pabeni, lpieralisi, robh, kw, bhelgaas, arnd,
	hch, m.szyprowski, robin.murphy, thomas.lendacky, brijesh.singh,
	tglx, mingo, bp, dave.hansen, Tianyu.Lan, kirill.shutemov,
	sathyanarayanan.kuppuswamy, ak, isaku.yamahata, dan.j.williams,
	jane.chu, seanjc, tony.luck, x86, linux-kernel, linux-hyperv,
	netdev, linux-pci, linux-arch, iommu
  Cc: mikelley

With changes to how Hyper-V guest VMs flip memory between private
(encrypted) and shared (decrypted), it's no longer necessary to
have separate code paths for mapping VMBus ring buffers for
for normal VMs and for Confidential VMs.

As such, remove the code path that uses vmap_pfn(), and set
the protection flags argument to vmap() to account for the
difference between normal and Confidential VMs.

Signed-off-by: Michael Kelley <mikelley@microsoft.com>
Reviewed-by: Tianyu Lan <Tianyu.Lan@microsoft.com>
---
 drivers/hv/ring_buffer.c | 62 ++++++++++++++++--------------------------------
 1 file changed, 20 insertions(+), 42 deletions(-)

diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
index b4a91b1..20a0631 100644
--- a/drivers/hv/ring_buffer.c
+++ b/drivers/hv/ring_buffer.c
@@ -186,8 +186,6 @@ int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info,
 		       struct page *pages, u32 page_cnt, u32 max_pkt_size)
 {
 	struct page **pages_wraparound;
-	unsigned long *pfns_wraparound;
-	u64 pfn;
 	int i;
 
 	BUILD_BUG_ON((sizeof(struct hv_ring_buffer) != PAGE_SIZE));
@@ -196,50 +194,30 @@ int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info,
 	 * First page holds struct hv_ring_buffer, do wraparound mapping for
 	 * the rest.
 	 */
-	if (hv_isolation_type_snp()) {
-		pfn = page_to_pfn(pages) +
-			PFN_DOWN(ms_hyperv.shared_gpa_boundary);
+	pages_wraparound = kcalloc(page_cnt * 2 - 1,
+				   sizeof(struct page *),
+				   GFP_KERNEL);
+	if (!pages_wraparound)
+		return -ENOMEM;
 
-		pfns_wraparound = kcalloc(page_cnt * 2 - 1,
-			sizeof(unsigned long), GFP_KERNEL);
-		if (!pfns_wraparound)
-			return -ENOMEM;
-
-		pfns_wraparound[0] = pfn;
-		for (i = 0; i < 2 * (page_cnt - 1); i++)
-			pfns_wraparound[i + 1] = pfn + i % (page_cnt - 1) + 1;
-
-		ring_info->ring_buffer = (struct hv_ring_buffer *)
-			vmap_pfn(pfns_wraparound, page_cnt * 2 - 1,
-				 pgprot_decrypted(PAGE_KERNEL_NOENC));
-		kfree(pfns_wraparound);
-
-		if (!ring_info->ring_buffer)
-			return -ENOMEM;
-
-		/* Zero ring buffer after setting memory host visibility. */
-		memset(ring_info->ring_buffer, 0x00, PAGE_SIZE * page_cnt);
-	} else {
-		pages_wraparound = kcalloc(page_cnt * 2 - 1,
-					   sizeof(struct page *),
-					   GFP_KERNEL);
-		if (!pages_wraparound)
-			return -ENOMEM;
-
-		pages_wraparound[0] = pages;
-		for (i = 0; i < 2 * (page_cnt - 1); i++)
-			pages_wraparound[i + 1] =
-				&pages[i % (page_cnt - 1) + 1];
+	pages_wraparound[0] = pages;
+	for (i = 0; i < 2 * (page_cnt - 1); i++)
+		pages_wraparound[i + 1] =
+			&pages[i % (page_cnt - 1) + 1];
 
-		ring_info->ring_buffer = (struct hv_ring_buffer *)
-			vmap(pages_wraparound, page_cnt * 2 - 1, VM_MAP,
-				PAGE_KERNEL);
+	ring_info->ring_buffer = (struct hv_ring_buffer *)
+		vmap(pages_wraparound, page_cnt * 2 - 1, VM_MAP,
+			pgprot_decrypted(PAGE_KERNEL_NOENC));
 
-		kfree(pages_wraparound);
-		if (!ring_info->ring_buffer)
-			return -ENOMEM;
-	}
+	kfree(pages_wraparound);
+	if (!ring_info->ring_buffer)
+		return -ENOMEM;
 
+	/*
+	 * Ensure the header page is zero'ed since
+	 * encryption status may have changed.
+	 */
+	memset(ring_info->ring_buffer, 0, HV_HYP_PAGE_SIZE);
 
 	ring_info->ring_buffer->read_index =
 		ring_info->ring_buffer->write_index = 0;
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 09/12] hv_netvsc: Remove second mapping of send and recv buffers
  2022-11-11  6:21 [PATCH v2 00/12] Drivers: hv: Add PCI pass-thru support to Hyper-V Confidential VMs Michael Kelley
                   ` (7 preceding siblings ...)
  2022-11-11  6:21 ` [PATCH v2 08/12] Drivers: hv: vmbus: Remove second way of mapping ring buffers Michael Kelley
@ 2022-11-11  6:21 ` Michael Kelley
  2022-11-11  6:21 ` [PATCH v2 10/12] Drivers: hv: Don't remap addresses that are above shared_gpa_boundary Michael Kelley
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 27+ messages in thread
From: Michael Kelley @ 2022-11-11  6:21 UTC (permalink / raw)
  To: hpa, kys, haiyangz, wei.liu, decui, luto, peterz, davem,
	edumazet, kuba, pabeni, lpieralisi, robh, kw, bhelgaas, arnd,
	hch, m.szyprowski, robin.murphy, thomas.lendacky, brijesh.singh,
	tglx, mingo, bp, dave.hansen, Tianyu.Lan, kirill.shutemov,
	sathyanarayanan.kuppuswamy, ak, isaku.yamahata, dan.j.williams,
	jane.chu, seanjc, tony.luck, x86, linux-kernel, linux-hyperv,
	netdev, linux-pci, linux-arch, iommu
  Cc: mikelley

With changes to how Hyper-V guest VMs flip memory between private
(encrypted) and shared (decrypted), creating a second kernel virtual
mapping for shared memory is no longer necessary.  Everything needed
for the transition to shared is handled by set_memory_decrypted().

As such, remove the code to create and manage the second
mapping for the pre-allocated send and recv buffers.  This mapping
is the last user of hv_map_memory()/hv_unmap_memory(), so delete
these functions as well.  Finally, hv_map_memory() is the last
user of vmap_pfn() in Hyper-V guest code, so remove the Kconfig
selection of VMAP_PFN.

Signed-off-by: Michael Kelley <mikelley@microsoft.com>
Reviewed-by: Tianyu Lan <Tianyu.Lan@microsoft.com>
---
 arch/x86/hyperv/ivm.c           | 28 ------------------------
 drivers/hv/Kconfig              |  1 -
 drivers/hv/hv_common.c          | 11 ----------
 drivers/net/hyperv/hyperv_net.h |  2 --
 drivers/net/hyperv/netvsc.c     | 48 ++---------------------------------------
 include/asm-generic/mshyperv.h  |  2 --
 6 files changed, 2 insertions(+), 90 deletions(-)

diff --git a/arch/x86/hyperv/ivm.c b/arch/x86/hyperv/ivm.c
index 29ccbe8..5e4b8b0 100644
--- a/arch/x86/hyperv/ivm.c
+++ b/arch/x86/hyperv/ivm.c
@@ -349,34 +349,6 @@ void __init hv_vtom_init(void)
 
 #endif /* CONFIG_AMD_MEM_ENCRYPT */
 
-/*
- * hv_map_memory - map memory to extra space in the AMD SEV-SNP Isolation VM.
- */
-void *hv_map_memory(void *addr, unsigned long size)
-{
-	unsigned long *pfns = kcalloc(size / PAGE_SIZE,
-				      sizeof(unsigned long), GFP_KERNEL);
-	void *vaddr;
-	int i;
-
-	if (!pfns)
-		return NULL;
-
-	for (i = 0; i < size / PAGE_SIZE; i++)
-		pfns[i] = vmalloc_to_pfn(addr + i * PAGE_SIZE) +
-			(ms_hyperv.shared_gpa_boundary >> PAGE_SHIFT);
-
-	vaddr = vmap_pfn(pfns, size / PAGE_SIZE, pgprot_decrypted(PAGE_KERNEL_NOENC));
-	kfree(pfns);
-
-	return vaddr;
-}
-
-void hv_unmap_memory(void *addr)
-{
-	vunmap(addr);
-}
-
 enum hv_isolation_type hv_get_isolation_type(void)
 {
 	if (!(ms_hyperv.priv_high & HV_ISOLATION))
diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
index 0747a8f..9a074cb 100644
--- a/drivers/hv/Kconfig
+++ b/drivers/hv/Kconfig
@@ -8,7 +8,6 @@ config HYPERV
 		|| (ARM64 && !CPU_BIG_ENDIAN))
 	select PARAVIRT
 	select X86_HV_CALLBACK_VECTOR if X86
-	select VMAP_PFN
 	help
 	  Select this option to run Linux as a Hyper-V client operating
 	  system.
diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index ae68298..566735f 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -308,14 +308,3 @@ u64 __weak hv_ghcb_hypercall(u64 control, void *input, void *output, u32 input_s
 	return HV_STATUS_INVALID_PARAMETER;
 }
 EXPORT_SYMBOL_GPL(hv_ghcb_hypercall);
-
-void __weak *hv_map_memory(void *addr, unsigned long size)
-{
-	return NULL;
-}
-EXPORT_SYMBOL_GPL(hv_map_memory);
-
-void __weak hv_unmap_memory(void *addr)
-{
-}
-EXPORT_SYMBOL_GPL(hv_unmap_memory);
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index dd5919e..33d51e3 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -1139,7 +1139,6 @@ struct netvsc_device {
 
 	/* Receive buffer allocated by us but manages by NetVSP */
 	void *recv_buf;
-	void *recv_original_buf;
 	u32 recv_buf_size; /* allocated bytes */
 	struct vmbus_gpadl recv_buf_gpadl_handle;
 	u32 recv_section_cnt;
@@ -1148,7 +1147,6 @@ struct netvsc_device {
 
 	/* Send buffer allocated by us */
 	void *send_buf;
-	void *send_original_buf;
 	u32 send_buf_size;
 	struct vmbus_gpadl send_buf_gpadl_handle;
 	u32 send_section_cnt;
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 9352dad..661bbe6 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -154,17 +154,8 @@ static void free_netvsc_device(struct rcu_head *head)
 	int i;
 
 	kfree(nvdev->extension);
-
-	if (nvdev->recv_original_buf)
-		vfree(nvdev->recv_original_buf);
-	else
-		vfree(nvdev->recv_buf);
-
-	if (nvdev->send_original_buf)
-		vfree(nvdev->send_original_buf);
-	else
-		vfree(nvdev->send_buf);
-
+	vfree(nvdev->recv_buf);
+	vfree(nvdev->send_buf);
 	bitmap_free(nvdev->send_section_map);
 
 	for (i = 0; i < VRSS_CHANNEL_MAX; i++) {
@@ -347,7 +338,6 @@ static int netvsc_init_buf(struct hv_device *device,
 	struct nvsp_message *init_packet;
 	unsigned int buf_size;
 	int i, ret = 0;
-	void *vaddr;
 
 	/* Get receive buffer area. */
 	buf_size = device_info->recv_sections * device_info->recv_section_size;
@@ -383,17 +373,6 @@ static int netvsc_init_buf(struct hv_device *device,
 		goto cleanup;
 	}
 
-	if (hv_isolation_type_snp()) {
-		vaddr = hv_map_memory(net_device->recv_buf, buf_size);
-		if (!vaddr) {
-			ret = -ENOMEM;
-			goto cleanup;
-		}
-
-		net_device->recv_original_buf = net_device->recv_buf;
-		net_device->recv_buf = vaddr;
-	}
-
 	/* Notify the NetVsp of the gpadl handle */
 	init_packet = &net_device->channel_init_pkt;
 	memset(init_packet, 0, sizeof(struct nvsp_message));
@@ -497,17 +476,6 @@ static int netvsc_init_buf(struct hv_device *device,
 		goto cleanup;
 	}
 
-	if (hv_isolation_type_snp()) {
-		vaddr = hv_map_memory(net_device->send_buf, buf_size);
-		if (!vaddr) {
-			ret = -ENOMEM;
-			goto cleanup;
-		}
-
-		net_device->send_original_buf = net_device->send_buf;
-		net_device->send_buf = vaddr;
-	}
-
 	/* Notify the NetVsp of the gpadl handle */
 	init_packet = &net_device->channel_init_pkt;
 	memset(init_packet, 0, sizeof(struct nvsp_message));
@@ -762,12 +730,6 @@ void netvsc_device_remove(struct hv_device *device)
 		netvsc_teardown_send_gpadl(device, net_device, ndev);
 	}
 
-	if (net_device->recv_original_buf)
-		hv_unmap_memory(net_device->recv_buf);
-
-	if (net_device->send_original_buf)
-		hv_unmap_memory(net_device->send_buf);
-
 	/* Release all resources */
 	free_netvsc_device_rcu(net_device);
 }
@@ -1831,12 +1793,6 @@ struct netvsc_device *netvsc_device_add(struct hv_device *device,
 	netif_napi_del(&net_device->chan_table[0].napi);
 
 cleanup2:
-	if (net_device->recv_original_buf)
-		hv_unmap_memory(net_device->recv_buf);
-
-	if (net_device->send_original_buf)
-		hv_unmap_memory(net_device->send_buf);
-
 	free_netvsc_device(&net_device->rcu);
 
 	return ERR_PTR(ret);
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index bfb9eb9..6fabc4a 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -267,8 +267,6 @@ static inline int cpumask_to_vpset_noself(struct hv_vpset *vpset,
 void hyperv_cleanup(void);
 bool hv_query_ext_cap(u64 cap_query);
 void hv_setup_dma_ops(struct device *dev, bool coherent);
-void *hv_map_memory(void *addr, unsigned long size);
-void hv_unmap_memory(void *addr);
 #else /* CONFIG_HYPERV */
 static inline bool hv_is_hyperv_initialized(void) { return false; }
 static inline bool hv_is_hibernation_supported(void) { return false; }
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 10/12] Drivers: hv: Don't remap addresses that are above shared_gpa_boundary
  2022-11-11  6:21 [PATCH v2 00/12] Drivers: hv: Add PCI pass-thru support to Hyper-V Confidential VMs Michael Kelley
                   ` (8 preceding siblings ...)
  2022-11-11  6:21 ` [PATCH v2 09/12] hv_netvsc: Remove second mapping of send and recv buffers Michael Kelley
@ 2022-11-11  6:21 ` Michael Kelley
  2022-11-11  6:21 ` [PATCH v2 11/12] PCI: hv: Add hypercalls to read/write MMIO space Michael Kelley
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 27+ messages in thread
From: Michael Kelley @ 2022-11-11  6:21 UTC (permalink / raw)
  To: hpa, kys, haiyangz, wei.liu, decui, luto, peterz, davem,
	edumazet, kuba, pabeni, lpieralisi, robh, kw, bhelgaas, arnd,
	hch, m.szyprowski, robin.murphy, thomas.lendacky, brijesh.singh,
	tglx, mingo, bp, dave.hansen, Tianyu.Lan, kirill.shutemov,
	sathyanarayanan.kuppuswamy, ak, isaku.yamahata, dan.j.williams,
	jane.chu, seanjc, tony.luck, x86, linux-kernel, linux-hyperv,
	netdev, linux-pci, linux-arch, iommu
  Cc: mikelley

With the vTOM bit now treated as a protection flag and not part of
the physical address, avoid remapping physical addresses with vTOM set
since technically such addresses aren't valid.  Use ioremap_cache()
instead of memremap() to ensure that the mapping provides decrypted
access, which will correctly set the vTOM bit as a protection flag.

While this change is not required for correctness with the current
implementation of memremap(), for general code hygiene it's better to
not depend on the mapping functions doing something reasonable with
a physical address that is out-of-range.

While here, fix typos in two error messages.

Signed-off-by: Michael Kelley <mikelley@microsoft.com>
Reviewed-by: Tianyu Lan <Tianyu.Lan@microsoft.com>
---
 arch/x86/hyperv/hv_init.c |  7 +++++--
 drivers/hv/hv.c           | 23 +++++++++++++----------
 2 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index f49bc3e..7f46e12 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -64,7 +64,10 @@ static int hyperv_init_ghcb(void)
 	 * memory boundary and map it here.
 	 */
 	rdmsrl(MSR_AMD64_SEV_ES_GHCB, ghcb_gpa);
-	ghcb_va = memremap(ghcb_gpa, HV_HYP_PAGE_SIZE, MEMREMAP_WB);
+
+	/* Mask out vTOM bit. ioremap_cache() maps decrypted */
+	ghcb_gpa &= ~ms_hyperv.shared_gpa_boundary;
+	ghcb_va = (void *)ioremap_cache(ghcb_gpa, HV_HYP_PAGE_SIZE);
 	if (!ghcb_va)
 		return -ENOMEM;
 
@@ -220,7 +223,7 @@ static int hv_cpu_die(unsigned int cpu)
 	if (hv_ghcb_pg) {
 		ghcb_va = (void **)this_cpu_ptr(hv_ghcb_pg);
 		if (*ghcb_va)
-			memunmap(*ghcb_va);
+			iounmap(*ghcb_va);
 		*ghcb_va = NULL;
 	}
 
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 4d6480d..410e6c4 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -217,11 +217,13 @@ void hv_synic_enable_regs(unsigned int cpu)
 	simp.simp_enabled = 1;
 
 	if (hv_isolation_type_snp()) {
+		/* Mask out vTOM bit. ioremap_cache() maps decrypted */
+		u64 base = (simp.base_simp_gpa << HV_HYP_PAGE_SHIFT) &
+				~ms_hyperv.shared_gpa_boundary;
 		hv_cpu->synic_message_page
-			= memremap(simp.base_simp_gpa << HV_HYP_PAGE_SHIFT,
-				   HV_HYP_PAGE_SIZE, MEMREMAP_WB);
+			= (void *)ioremap_cache(base, HV_HYP_PAGE_SIZE);
 		if (!hv_cpu->synic_message_page)
-			pr_err("Fail to map syinc message page.\n");
+			pr_err("Fail to map synic message page.\n");
 	} else {
 		simp.base_simp_gpa = virt_to_phys(hv_cpu->synic_message_page)
 			>> HV_HYP_PAGE_SHIFT;
@@ -234,12 +236,13 @@ void hv_synic_enable_regs(unsigned int cpu)
 	siefp.siefp_enabled = 1;
 
 	if (hv_isolation_type_snp()) {
-		hv_cpu->synic_event_page =
-			memremap(siefp.base_siefp_gpa << HV_HYP_PAGE_SHIFT,
-				 HV_HYP_PAGE_SIZE, MEMREMAP_WB);
-
+		/* Mask out vTOM bit. ioremap_cache() maps decrypted */
+		u64 base = (siefp.base_siefp_gpa << HV_HYP_PAGE_SHIFT) &
+				~ms_hyperv.shared_gpa_boundary;
+		hv_cpu->synic_event_page
+			= (void *)ioremap_cache(base, HV_HYP_PAGE_SIZE);
 		if (!hv_cpu->synic_event_page)
-			pr_err("Fail to map syinc event page.\n");
+			pr_err("Fail to map synic event page.\n");
 	} else {
 		siefp.base_siefp_gpa = virt_to_phys(hv_cpu->synic_event_page)
 			>> HV_HYP_PAGE_SHIFT;
@@ -316,7 +319,7 @@ void hv_synic_disable_regs(unsigned int cpu)
 	 */
 	simp.simp_enabled = 0;
 	if (hv_isolation_type_snp())
-		memunmap(hv_cpu->synic_message_page);
+		iounmap(hv_cpu->synic_message_page);
 	else
 		simp.base_simp_gpa = 0;
 
@@ -326,7 +329,7 @@ void hv_synic_disable_regs(unsigned int cpu)
 	siefp.siefp_enabled = 0;
 
 	if (hv_isolation_type_snp())
-		memunmap(hv_cpu->synic_event_page);
+		iounmap(hv_cpu->synic_event_page);
 	else
 		siefp.base_siefp_gpa = 0;
 
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 11/12] PCI: hv: Add hypercalls to read/write MMIO space
  2022-11-11  6:21 [PATCH v2 00/12] Drivers: hv: Add PCI pass-thru support to Hyper-V Confidential VMs Michael Kelley
                   ` (9 preceding siblings ...)
  2022-11-11  6:21 ` [PATCH v2 10/12] Drivers: hv: Don't remap addresses that are above shared_gpa_boundary Michael Kelley
@ 2022-11-11  6:21 ` Michael Kelley
  2022-11-11  6:21 ` [PATCH v2 12/12] PCI: hv: Enable PCI pass-thru devices in Confidential VMs Michael Kelley
  2022-11-11 16:44 ` [PATCH v2 00/12] Drivers: hv: Add PCI pass-thru support to Hyper-V " Wei Liu
  12 siblings, 0 replies; 27+ messages in thread
From: Michael Kelley @ 2022-11-11  6:21 UTC (permalink / raw)
  To: hpa, kys, haiyangz, wei.liu, decui, luto, peterz, davem,
	edumazet, kuba, pabeni, lpieralisi, robh, kw, bhelgaas, arnd,
	hch, m.szyprowski, robin.murphy, thomas.lendacky, brijesh.singh,
	tglx, mingo, bp, dave.hansen, Tianyu.Lan, kirill.shutemov,
	sathyanarayanan.kuppuswamy, ak, isaku.yamahata, dan.j.williams,
	jane.chu, seanjc, tony.luck, x86, linux-kernel, linux-hyperv,
	netdev, linux-pci, linux-arch, iommu
  Cc: mikelley

To support PCI pass-thru devices in Confidential VMs, Hyper-V
has added hypercalls to read and write MMIO space. Add the
appropriate definitions to hyperv-tlfs.h and implement
functions to make the hypercalls. These functions are used
in a subsequent patch.

Co-developed-by: Dexuan Cui <decui@microsoft.com>
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Signed-off-by: Michael Kelley <mikelley@microsoft.com>
---
 arch/x86/include/asm/hyperv-tlfs.h  |  3 ++
 drivers/pci/controller/pci-hyperv.c | 64 +++++++++++++++++++++++++++++++++++++
 include/asm-generic/hyperv-tlfs.h   | 22 +++++++++++++
 3 files changed, 89 insertions(+)

diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h
index 3089ec3..f769b9d 100644
--- a/arch/x86/include/asm/hyperv-tlfs.h
+++ b/arch/x86/include/asm/hyperv-tlfs.h
@@ -117,6 +117,9 @@
 /* Recommend using enlightened VMCS */
 #define HV_X64_ENLIGHTENED_VMCS_RECOMMENDED		BIT(14)
 
+/* Use hypercalls for MMIO config space access */
+#define HV_X64_USE_MMIO_HYPERCALLS			BIT(21)
+
 /*
  * CPU management features identification.
  * These are HYPERV_CPUID_CPU_MANAGEMENT_FEATURES.EAX bits.
diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
index ba64284..09b40a1 100644
--- a/drivers/pci/controller/pci-hyperv.c
+++ b/drivers/pci/controller/pci-hyperv.c
@@ -1054,6 +1054,70 @@ static int wslot_to_devfn(u32 wslot)
 	return PCI_DEVFN(slot_no.bits.dev, slot_no.bits.func);
 }
 
+static void hv_pci_read_mmio(struct device *dev, phys_addr_t gpa, int size, u32 *val)
+{
+	struct hv_mmio_read_input *in;
+	struct hv_mmio_read_output *out;
+	u64 ret;
+
+	/*
+	 * Must be called with interrupts disabled so it is safe
+	 * to use the per-cpu input argument page.  Use it for
+	 * both input and output.
+	 */
+	in = *this_cpu_ptr(hyperv_pcpu_input_arg);
+	out = *this_cpu_ptr(hyperv_pcpu_input_arg) + sizeof(*in);
+	in->gpa = gpa;
+	in->size = size;
+
+	ret = hv_do_hypercall(HVCALL_MMIO_READ, in, out);
+	if (hv_result_success(ret)) {
+		switch (size) {
+		case 1:
+			*val = *(u8 *)(out->data);
+			break;
+		case 2:
+			*val = *(u16 *)(out->data);
+			break;
+		default:
+			*val = *(u32 *)(out->data);
+			break;
+		}
+	} else
+		dev_err(dev, "MMIO read hypercall error %llx addr %llx size %d\n",
+				ret, gpa, size);
+}
+
+static void hv_pci_write_mmio(struct device *dev, phys_addr_t gpa, int size, u32 val)
+{
+	struct hv_mmio_write_input *in;
+	u64 ret;
+
+	/*
+	 * Must be called with interrupts disabled so it is safe
+	 * to use the per-cpu input argument memory.
+	 */
+	in = *this_cpu_ptr(hyperv_pcpu_input_arg);
+	in->gpa = gpa;
+	in->size = size;
+	switch (size) {
+	case 1:
+		*(u8 *)(in->data) = val;
+		break;
+	case 2:
+		*(u16 *)(in->data) = val;
+		break;
+	default:
+		*(u32 *)(in->data) = val;
+		break;
+	}
+
+	ret = hv_do_hypercall(HVCALL_MMIO_WRITE, in, NULL);
+	if (!hv_result_success(ret))
+		dev_err(dev, "MMIO write hypercall error %llx addr %llx size %d\n",
+				ret, gpa, size);
+}
+
 /*
  * PCI Configuration Space for these root PCI buses is implemented as a pair
  * of pages in memory-mapped I/O space.  Writing to the first page chooses
diff --git a/include/asm-generic/hyperv-tlfs.h b/include/asm-generic/hyperv-tlfs.h
index b17c6ee..fcab07b 100644
--- a/include/asm-generic/hyperv-tlfs.h
+++ b/include/asm-generic/hyperv-tlfs.h
@@ -168,6 +168,8 @@ struct ms_hyperv_tsc_page {
 #define HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_SPACE 0x00af
 #define HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_LIST 0x00b0
 #define HVCALL_MODIFY_SPARSE_GPA_PAGE_HOST_VISIBILITY 0x00db
+#define HVCALL_MMIO_READ			0x0106
+#define HVCALL_MMIO_WRITE			0x0107
 
 /* Extended hypercalls */
 #define HV_EXT_CALL_QUERY_CAPABILITIES		0x8001
@@ -790,4 +792,24 @@ struct hv_memory_hint {
 	union hv_gpa_page_range ranges[];
 } __packed;
 
+/* Data structures for HVCALL_MMIO_READ and HVCALL_MMIO_WRITE */
+#define HV_HYPERCALL_MMIO_MAX_DATA_LENGTH 64
+
+struct hv_mmio_read_input {
+	u64 gpa;
+	u32 size;
+	u32 reserved;
+} __packed;
+
+struct hv_mmio_read_output {
+	u8 data[HV_HYPERCALL_MMIO_MAX_DATA_LENGTH];
+} __packed;
+
+struct hv_mmio_write_input {
+	u64 gpa;
+	u32 size;
+	u32 reserved;
+	u8 data[HV_HYPERCALL_MMIO_MAX_DATA_LENGTH];
+} __packed;
+
 #endif
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 12/12] PCI: hv: Enable PCI pass-thru devices in Confidential VMs
  2022-11-11  6:21 [PATCH v2 00/12] Drivers: hv: Add PCI pass-thru support to Hyper-V Confidential VMs Michael Kelley
                   ` (10 preceding siblings ...)
  2022-11-11  6:21 ` [PATCH v2 11/12] PCI: hv: Add hypercalls to read/write MMIO space Michael Kelley
@ 2022-11-11  6:21 ` Michael Kelley
  2022-11-11 16:44 ` [PATCH v2 00/12] Drivers: hv: Add PCI pass-thru support to Hyper-V " Wei Liu
  12 siblings, 0 replies; 27+ messages in thread
From: Michael Kelley @ 2022-11-11  6:21 UTC (permalink / raw)
  To: hpa, kys, haiyangz, wei.liu, decui, luto, peterz, davem,
	edumazet, kuba, pabeni, lpieralisi, robh, kw, bhelgaas, arnd,
	hch, m.szyprowski, robin.murphy, thomas.lendacky, brijesh.singh,
	tglx, mingo, bp, dave.hansen, Tianyu.Lan, kirill.shutemov,
	sathyanarayanan.kuppuswamy, ak, isaku.yamahata, dan.j.williams,
	jane.chu, seanjc, tony.luck, x86, linux-kernel, linux-hyperv,
	netdev, linux-pci, linux-arch, iommu
  Cc: mikelley

For PCI pass-thru devices in a Confidential VM, Hyper-V requires
that PCI config space be accessed via hypercalls.  In normal VMs,
config space accesses are trapped to the Hyper-V host and emulated.
But in a confidential VM, the host can't access guest memory to
decode the instruction for emulation, so an explicit hypercall must
be used.

Update the PCI config space access functions to use the hypercalls
when such use is indicated by Hyper-V flags.  Also, set the flag to
allow the Hyper-V PCI driver to be loaded and used in a Confidential
VM (a.k.a., "Isolation VM").  The driver has previously been hardened
against a malicious Hyper-V host[1].

[1] https://lore.kernel.org/all/20220511223207.3386-2-parri.andrea@gmail.com/

Co-developed-by: Dexuan Cui <decui@microsoft.com>
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Signed-off-by: Michael Kelley <mikelley@microsoft.com>
Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
---
 drivers/hv/channel_mgmt.c           |   2 +-
 drivers/pci/controller/pci-hyperv.c | 168 ++++++++++++++++++++++--------------
 2 files changed, 105 insertions(+), 65 deletions(-)

diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index 5b12040..c0f9ac2 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -67,7 +67,7 @@
 	{ .dev_type = HV_PCIE,
 	  HV_PCIE_GUID,
 	  .perf_device = false,
-	  .allowed_in_isolated = false,
+	  .allowed_in_isolated = true,
 	},
 
 	/* Synthetic Frame Buffer */
diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
index 09b40a1..6ce83e4 100644
--- a/drivers/pci/controller/pci-hyperv.c
+++ b/drivers/pci/controller/pci-hyperv.c
@@ -514,6 +514,7 @@ struct hv_pcibus_device {
 
 	/* Highest slot of child device with resources allocated */
 	int wslot_res_allocated;
+	bool use_calls; /* Use hypercalls to access mmio cfg space */
 
 	/* hypercall arg, must not cross page boundary */
 	struct hv_retarget_device_interrupt retarget_msi_interrupt_params;
@@ -1136,8 +1137,10 @@ static void hv_pci_write_mmio(struct device *dev, phys_addr_t gpa, int size, u32
 static void _hv_pcifront_read_config(struct hv_pci_dev *hpdev, int where,
 				     int size, u32 *val)
 {
+	struct hv_pcibus_device *hbus = hpdev->hbus;
+	struct device *dev = &hbus->hdev->device;
+	int offset = where + CFG_PAGE_OFFSET;
 	unsigned long flags;
-	void __iomem *addr = hpdev->hbus->cfg_addr + CFG_PAGE_OFFSET + where;
 
 	/*
 	 * If the attempt is to read the IDs or the ROM BAR, simulate that.
@@ -1165,56 +1168,79 @@ static void _hv_pcifront_read_config(struct hv_pci_dev *hpdev, int where,
 		 */
 		*val = 0;
 	} else if (where + size <= CFG_PAGE_SIZE) {
-		spin_lock_irqsave(&hpdev->hbus->config_lock, flags);
-		/* Choose the function to be read. (See comment above) */
-		writel(hpdev->desc.win_slot.slot, hpdev->hbus->cfg_addr);
-		/* Make sure the function was chosen before we start reading. */
-		mb();
-		/* Read from that function's config space. */
-		switch (size) {
-		case 1:
-			*val = readb(addr);
-			break;
-		case 2:
-			*val = readw(addr);
-			break;
-		default:
-			*val = readl(addr);
-			break;
+
+		spin_lock_irqsave(&hbus->config_lock, flags);
+		if (hbus->use_calls) {
+			phys_addr_t addr = hbus->mem_config->start + offset;
+
+			hv_pci_write_mmio(dev, hbus->mem_config->start, 4,
+						hpdev->desc.win_slot.slot);
+			hv_pci_read_mmio(dev, addr, size, val);
+		} else {
+			void __iomem *addr = hbus->cfg_addr + offset;
+
+			/* Choose the function to be read. (See comment above) */
+			writel(hpdev->desc.win_slot.slot, hbus->cfg_addr);
+			/* Make sure the function was chosen before reading. */
+			mb();
+			/* Read from that function's config space. */
+			switch (size) {
+			case 1:
+				*val = readb(addr);
+				break;
+			case 2:
+				*val = readw(addr);
+				break;
+			default:
+				*val = readl(addr);
+				break;
+			}
+			/*
+			 * Make sure the read was done before we release the
+			 * spinlock allowing consecutive reads/writes.
+			 */
+			mb();
 		}
-		/*
-		 * Make sure the read was done before we release the spinlock
-		 * allowing consecutive reads/writes.
-		 */
-		mb();
-		spin_unlock_irqrestore(&hpdev->hbus->config_lock, flags);
+		spin_unlock_irqrestore(&hbus->config_lock, flags);
 	} else {
-		dev_err(&hpdev->hbus->hdev->device,
-			"Attempt to read beyond a function's config space.\n");
+		dev_err(dev, "Attempt to read beyond a function's config space.\n");
 	}
 }
 
 static u16 hv_pcifront_get_vendor_id(struct hv_pci_dev *hpdev)
 {
+	struct hv_pcibus_device *hbus = hpdev->hbus;
+	struct device *dev = &hbus->hdev->device;
+	u32 val;
 	u16 ret;
 	unsigned long flags;
-	void __iomem *addr = hpdev->hbus->cfg_addr + CFG_PAGE_OFFSET +
-			     PCI_VENDOR_ID;
 
-	spin_lock_irqsave(&hpdev->hbus->config_lock, flags);
+	spin_lock_irqsave(&hbus->config_lock, flags);
 
-	/* Choose the function to be read. (See comment above) */
-	writel(hpdev->desc.win_slot.slot, hpdev->hbus->cfg_addr);
-	/* Make sure the function was chosen before we start reading. */
-	mb();
-	/* Read from that function's config space. */
-	ret = readw(addr);
-	/*
-	 * mb() is not required here, because the spin_unlock_irqrestore()
-	 * is a barrier.
-	 */
+	if (hbus->use_calls) {
+		phys_addr_t addr = hbus->mem_config->start +
+					 CFG_PAGE_OFFSET + PCI_VENDOR_ID;
+
+		hv_pci_write_mmio(dev, hbus->mem_config->start, 4,
+					hpdev->desc.win_slot.slot);
+		hv_pci_read_mmio(dev, addr, 2, &val);
+		ret = val;  /* Truncates to 16 bits */
+	} else {
+		void __iomem *addr = hbus->cfg_addr + CFG_PAGE_OFFSET +
+					     PCI_VENDOR_ID;
+		/* Choose the function to be read. (See comment above) */
+		writel(hpdev->desc.win_slot.slot, hbus->cfg_addr);
+		/* Make sure the function was chosen before we start reading. */
+		mb();
+		/* Read from that function's config space. */
+		ret = readw(addr);
+		/*
+		 * mb() is not required here, because the
+		 * spin_unlock_irqrestore() is a barrier.
+		 */
+	}
 
-	spin_unlock_irqrestore(&hpdev->hbus->config_lock, flags);
+	spin_unlock_irqrestore(&hbus->config_lock, flags);
 
 	return ret;
 }
@@ -1229,39 +1255,51 @@ static u16 hv_pcifront_get_vendor_id(struct hv_pci_dev *hpdev)
 static void _hv_pcifront_write_config(struct hv_pci_dev *hpdev, int where,
 				      int size, u32 val)
 {
+	struct hv_pcibus_device *hbus = hpdev->hbus;
+	struct device *dev = &hbus->hdev->device;
+	int offset = where + CFG_PAGE_OFFSET;
 	unsigned long flags;
-	void __iomem *addr = hpdev->hbus->cfg_addr + CFG_PAGE_OFFSET + where;
 
 	if (where >= PCI_SUBSYSTEM_VENDOR_ID &&
 	    where + size <= PCI_CAPABILITY_LIST) {
 		/* SSIDs and ROM BARs are read-only */
 	} else if (where >= PCI_COMMAND && where + size <= CFG_PAGE_SIZE) {
-		spin_lock_irqsave(&hpdev->hbus->config_lock, flags);
-		/* Choose the function to be written. (See comment above) */
-		writel(hpdev->desc.win_slot.slot, hpdev->hbus->cfg_addr);
-		/* Make sure the function was chosen before we start writing. */
-		wmb();
-		/* Write to that function's config space. */
-		switch (size) {
-		case 1:
-			writeb(val, addr);
-			break;
-		case 2:
-			writew(val, addr);
-			break;
-		default:
-			writel(val, addr);
-			break;
+		spin_lock_irqsave(&hbus->config_lock, flags);
+
+		if (hbus->use_calls) {
+			phys_addr_t addr = hbus->mem_config->start + offset;
+
+			hv_pci_write_mmio(dev, hbus->mem_config->start, 4,
+						hpdev->desc.win_slot.slot);
+			hv_pci_write_mmio(dev, addr, size, val);
+		} else {
+			void __iomem *addr = hbus->cfg_addr + offset;
+
+			/* Choose the function to write. (See comment above) */
+			writel(hpdev->desc.win_slot.slot, hbus->cfg_addr);
+			/* Make sure the function was chosen before writing. */
+			wmb();
+			/* Write to that function's config space. */
+			switch (size) {
+			case 1:
+				writeb(val, addr);
+				break;
+			case 2:
+				writew(val, addr);
+				break;
+			default:
+				writel(val, addr);
+				break;
+			}
+			/*
+			 * Make sure the write was done before we release the
+			 * spinlock allowing consecutive reads/writes.
+			 */
+			mb();
 		}
-		/*
-		 * Make sure the write was done before we release the spinlock
-		 * allowing consecutive reads/writes.
-		 */
-		mb();
-		spin_unlock_irqrestore(&hpdev->hbus->config_lock, flags);
+		spin_unlock_irqrestore(&hbus->config_lock, flags);
 	} else {
-		dev_err(&hpdev->hbus->hdev->device,
-			"Attempt to write beyond a function's config space.\n");
+		dev_err(dev, "Attempt to write beyond a function's config space.\n");
 	}
 }
 
@@ -3580,6 +3618,7 @@ static int hv_pci_probe(struct hv_device *hdev,
 	hbus->bridge->domain_nr = dom;
 #ifdef CONFIG_X86
 	hbus->sysdata.domain = dom;
+	hbus->use_calls = !!(ms_hyperv.hints & HV_X64_USE_MMIO_HYPERCALLS);
 #elif defined(CONFIG_ARM64)
 	/*
 	 * Set the PCI bus parent to be the corresponding VMbus
@@ -3589,6 +3628,7 @@ static int hv_pci_probe(struct hv_device *hdev,
 	 * information to devices created on the bus.
 	 */
 	hbus->sysdata.parent = hdev->device.parent;
+	hbus->use_calls = false;
 #endif
 
 	hbus->hdev = hdev;
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH v2 00/12] Drivers: hv: Add PCI pass-thru support to Hyper-V Confidential VMs
  2022-11-11  6:21 [PATCH v2 00/12] Drivers: hv: Add PCI pass-thru support to Hyper-V Confidential VMs Michael Kelley
                   ` (11 preceding siblings ...)
  2022-11-11  6:21 ` [PATCH v2 12/12] PCI: hv: Enable PCI pass-thru devices in Confidential VMs Michael Kelley
@ 2022-11-11 16:44 ` Wei Liu
  12 siblings, 0 replies; 27+ messages in thread
From: Wei Liu @ 2022-11-11 16:44 UTC (permalink / raw)
  To: Michael Kelley
  Cc: hpa, kys, haiyangz, wei.liu, decui, luto, peterz, davem,
	edumazet, kuba, pabeni, lpieralisi, robh, kw, bhelgaas, arnd,
	hch, m.szyprowski, robin.murphy, thomas.lendacky, brijesh.singh,
	tglx, mingo, bp, dave.hansen, Tianyu.Lan, kirill.shutemov,
	sathyanarayanan.kuppuswamy, ak, isaku.yamahata, dan.j.williams,
	jane.chu, seanjc, tony.luck, x86, linux-kernel, linux-hyperv,
	netdev, linux-pci, linux-arch, iommu

On Thu, Nov 10, 2022 at 10:21:29PM -0800, Michael Kelley wrote:
[...]
> Patch Organization
> ==================
> Patch 1 fixes a bug in __ioremap_caller() that affects the
> existing Hyper-V code after the change to treat the vTOM bit as
> a protection flag. Fixing the bug allows the old code to continue
> to run until later patches in the series remove or update it.
> This sequencing avoids the need to enable the new approach and
> remove the old code in a single large patch.
> 
> Patch 2 handles the I/O APIC quirk by defining a new CC_ATTR enum
> member that is set only when running on Hyper-V.

I'm waiting for x86 maintainers acks on these two patches before merging
this series.

Thanks,
Wei.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v2 05/12] x86/hyperv: Change vTOM handling to use standard coco mechanisms
  2022-11-11  6:21 ` [PATCH v2 05/12] x86/hyperv: Change vTOM handling to use standard coco mechanisms Michael Kelley
@ 2022-11-11 18:49   ` Tom Lendacky
  2022-11-13 16:01     ` Michael Kelley (LINUX)
  0 siblings, 1 reply; 27+ messages in thread
From: Tom Lendacky @ 2022-11-11 18:49 UTC (permalink / raw)
  To: Michael Kelley, hpa, kys, haiyangz, wei.liu, decui, luto, peterz,
	davem, edumazet, kuba, pabeni, lpieralisi, robh, kw, bhelgaas,
	arnd, hch, m.szyprowski, robin.murphy, brijesh.singh, tglx,
	mingo, bp, dave.hansen, Tianyu.Lan, kirill.shutemov,
	sathyanarayanan.kuppuswamy, ak, isaku.yamahata, dan.j.williams,
	jane.chu, seanjc, tony.luck, x86, linux-kernel, linux-hyperv,
	netdev, linux-pci, linux-arch, iommu

On 11/11/22 00:21, Michael Kelley wrote:
> Hyper-V guests on AMD SEV-SNP hardware have the option of using the
> "virtual Top Of Memory" (vTOM) feature specified by the SEV-SNP
> architecture. With vTOM, shared vs. private memory accesses are
> controlled by splitting the guest physical address space into two
> halves.  vTOM is the dividing line where the uppermost bit of the
> physical address space is set; e.g., with 47 bits of guest physical
> address space, vTOM is 0x40000000000 (bit 46 is set).  Guest phyiscal
> memory is accessible at two parallel physical addresses -- one below
> vTOM and one above vTOM.  Accesses below vTOM are private (encrypted)
> while accesses above vTOM are shared (decrypted). In this sense, vTOM
> is like the GPA.SHARED bit in Intel TDX.
> 
> Support for Hyper-V guests using vTOM was added to the Linux kernel in
> two patch sets[1][2]. This support treats the vTOM bit as part of
> the physical address. For accessing shared (decrypted) memory, these
> patch sets create a second kernel virtual mapping that maps to physical
> addresses above vTOM.
> 
> A better approach is to treat the vTOM bit as a protection flag, not
> as part of the physical address. This new approach is like the approach
> for the GPA.SHARED bit in Intel TDX. Rather than creating a second kernel
> virtual mapping, the existing mapping is updated using recently added
> coco mechanisms.  When memory is changed between private and shared using
> set_memory_decrypted() and set_memory_encrypted(), the PTEs for the
> existing kernel mapping are changed to add or remove the vTOM bit
> in the guest physical address, just as with TDX. The hypercalls to
> change the memory status on the host side are made using the existing
> callback mechanism. Everything just works, with a minor tweak to map
> the I/O APIC to use private accesses.
> 
> To accomplish the switch in approach, the following must be done in
> in this single patch:
> 
> * Update Hyper-V initialization to set the cc _mask based on vTOM
>    and do other coco initialization.
> 
> * Update physical_mask so the vTOM bit is no longer treated as part
>    of the physical address
> 
> * Update cc_mkenc() and cc_mkdec() to be active for Hyper-V guests.
>    This makes the vTOM bit part of the protection flags.
> 
> * Code already exists to make hypercalls to inform Hyper-V about pages
>    changing between shared and private.  Update this code to run as a
>    callback from __set_memory_enc_pgtable().
> 
> * Remove the Hyper-V special case from __set_memory_enc_dec(), and
>    make the normal case active for Hyper-V VMs, which have
>    CC_ATTR_GUEST_MEM_ENCRYPT, but not CC_ATTR_MEM_ENCRYPT.
> 
> [1] https://lore.kernel.org/all/20211025122116.264793-1-ltykernel@gmail.com/
> [2] https://lore.kernel.org/all/20211213071407.314309-1-ltykernel@gmail.com/
> 
> Signed-off-by: Michael Kelley <mikelley@microsoft.com>
> Reviewed-by: Tianyu Lan <Tianyu.Lan@microsoft.com>
> ---
>   arch/x86/coco/core.c            | 10 ++++++++-
>   arch/x86/hyperv/ivm.c           | 45 +++++++++++++++++++++++++++++++----------
>   arch/x86/include/asm/mshyperv.h |  8 ++------
>   arch/x86/kernel/cpu/mshyperv.c  | 15 +++++++-------
>   arch/x86/mm/pat/set_memory.c    |  6 ++----
>   5 files changed, 54 insertions(+), 30 deletions(-)
> 


> diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
> index 06eb8910..024fbf4 100644
> --- a/arch/x86/mm/pat/set_memory.c
> +++ b/arch/x86/mm/pat/set_memory.c
> @@ -2126,10 +2126,8 @@ static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
>   
>   static int __set_memory_enc_dec(unsigned long addr, int numpages, bool enc)
>   {
> -	if (hv_is_isolation_supported())
> -		return hv_set_mem_host_visibility(addr, numpages, !enc);
> -
> -	if (cc_platform_has(CC_ATTR_MEM_ENCRYPT))
> +	if (cc_platform_has(CC_ATTR_MEM_ENCRYPT) ||
> +	    cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))

This seems kind of strange since CC_ATTR_MEM_ENCRYPT is supposed to mean 
either HOST or GUEST memory encryption, but then you check for GUEST 
memory encryption directly. Can your cc_platform_has() support be setup to 
handle the CC_ATTR_MEM_ENCRYPT attribute in some way?

Thanks,
Tom

>   		return __set_memory_enc_pgtable(addr, numpages, enc);
>   
>   	return 0;

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v2 01/12] x86/ioremap: Fix page aligned size calculation in __ioremap_caller()
  2022-11-11  6:21 ` [PATCH v2 01/12] x86/ioremap: Fix page aligned size calculation in __ioremap_caller() Michael Kelley
@ 2022-11-12  0:11   ` Dave Hansen
  2022-11-12  4:31     ` Michael Kelley (LINUX)
  2022-11-14 16:40   ` Dave Hansen
  1 sibling, 1 reply; 27+ messages in thread
From: Dave Hansen @ 2022-11-12  0:11 UTC (permalink / raw)
  To: Michael Kelley, hpa, kys, haiyangz, wei.liu, decui, luto, peterz,
	davem, edumazet, kuba, pabeni, lpieralisi, robh, kw, bhelgaas,
	arnd, hch, m.szyprowski, robin.murphy, thomas.lendacky,
	brijesh.singh, tglx, mingo, bp, dave.hansen, Tianyu.Lan,
	kirill.shutemov, sathyanarayanan.kuppuswamy, ak, isaku.yamahata,
	dan.j.williams, jane.chu, seanjc, tony.luck, x86, linux-kernel,
	linux-hyperv, netdev, linux-pci, linux-arch, iommu

On 11/10/22 22:21, Michael Kelley wrote:
> If applying the PHYSICAL_PAGE_MASK to the phys_addr argument causes
> upper bits to be masked out, the re-calculation of size to account for
> page alignment is incorrect because the same bits are not masked out
> in last_addr.
> 
> Fix this by masking the page aligned last_addr as well.

This makes sense at first glance.

How did you notice this?  What is the impact to users?  Did the bug
actually cause you some trouble or was it by inspection?  Do you have a
sense of how many folks might be impacted?  Any thoughts on how it
lasted for 14+ years?

For the functionality of the mapping, I guess 'size' doesn't really
matter because even a 1-byte 'size' will map a page.  The other fallout
would be from memtype_reserve() reserving too little.  But, that's
unlikely to matter for small mappings because even though:

	ioremap(0x1800, 0x800);

would end up just reserving 0x1000->0x1800, it still wouldn't allow

	ioremap(0x1000, 0x800);

to succeed because *both* of them would end up trying to reserve the
beginning of the page.  Basically, the first caller effectively reserves
the whole page and any second user will fail.

So the other place it would matter would be for mappings that span two
pages, say:

	ioremap(0x1fff, 0x2)

But I guess those aren't very common.  Most large ioremap() callers seem
to already have base and size page-aligned.

Anyway, sorry to make so much of a big deal about a one-liner.  But,
these decade-old bugs really make me wonder how they stuck around for so
long.

I'd be curious if you thought about this too while putting together this
fox.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v2 02/12] x86/ioapic: Gate decrypted mapping on cc_platform_has() attribute
  2022-11-11  6:21 ` [PATCH v2 02/12] x86/ioapic: Gate decrypted mapping on cc_platform_has() attribute Michael Kelley
@ 2022-11-12  0:21   ` Dave Hansen
  2022-11-12  4:48     ` Michael Kelley (LINUX)
  0 siblings, 1 reply; 27+ messages in thread
From: Dave Hansen @ 2022-11-12  0:21 UTC (permalink / raw)
  To: Michael Kelley, hpa, kys, haiyangz, wei.liu, decui, luto, peterz,
	davem, edumazet, kuba, pabeni, lpieralisi, robh, kw, bhelgaas,
	arnd, hch, m.szyprowski, robin.murphy, thomas.lendacky,
	brijesh.singh, tglx, mingo, bp, dave.hansen, Tianyu.Lan,
	kirill.shutemov, sathyanarayanan.kuppuswamy, ak, isaku.yamahata,
	dan.j.williams, jane.chu, seanjc, tony.luck, x86, linux-kernel,
	linux-hyperv, netdev, linux-pci, linux-arch, iommu

On 11/10/22 22:21, Michael Kelley wrote:
>  	 * Ensure fixmaps for IOAPIC MMIO respect memory encryption pgprot
>  	 * bits, just like normal ioremap():
>  	 */
> -	flags = pgprot_decrypted(flags);
> +	if (!cc_platform_has(CC_ATTR_HAS_PARAVISOR))
> +		flags = pgprot_decrypted(flags);

This begs the question whether *all* paravisors will want to avoid a
decrypted ioapic mapping.  Is this _fundamental_ to paravisors, or it is
an implementation detail of this _individual_ paravisor?

^ permalink raw reply	[flat|nested] 27+ messages in thread

* RE: [PATCH v2 01/12] x86/ioremap: Fix page aligned size calculation in __ioremap_caller()
  2022-11-12  0:11   ` Dave Hansen
@ 2022-11-12  4:31     ` Michael Kelley (LINUX)
  0 siblings, 0 replies; 27+ messages in thread
From: Michael Kelley (LINUX) @ 2022-11-12  4:31 UTC (permalink / raw)
  To: Dave Hansen, hpa, KY Srinivasan, Haiyang Zhang, wei.liu,
	Dexuan Cui, luto, peterz, davem, edumazet, kuba, pabeni,
	lpieralisi, robh, kw, bhelgaas, arnd, hch, m.szyprowski,
	robin.murphy, thomas.lendacky, brijesh.singh, tglx, mingo, bp,
	dave.hansen, Tianyu Lan, kirill.shutemov,
	sathyanarayanan.kuppuswamy, ak, isaku.yamahata, Williams, Dan J,
	jane.chu, seanjc, tony.luck, x86, linux-kernel, linux-hyperv,
	netdev, linux-pci, linux-arch, iommu

From: Dave Hansen <dave.hansen@intel.com> Sent: Friday, November 11, 2022 4:12 PM
> 
> On 11/10/22 22:21, Michael Kelley wrote:
> > If applying the PHYSICAL_PAGE_MASK to the phys_addr argument causes
> > upper bits to be masked out, the re-calculation of size to account for
> > page alignment is incorrect because the same bits are not masked out
> > in last_addr.
> >
> > Fix this by masking the page aligned last_addr as well.
> 
> This makes sense at first glance.
> 
> How did you notice this?  What is the impact to users?  Did the bug
> actually cause you some trouble or was it by inspection?  Do you have a
> sense of how many folks might be impacted?  Any thoughts on how it
> lasted for 14+ years?
> 
> For the functionality of the mapping, I guess 'size' doesn't really
> matter because even a 1-byte 'size' will map a page.  The other fallout
> would be from memtype_reserve() reserving too little.  But, that's
> unlikely to matter for small mappings because even though:
> 
> 	ioremap(0x1800, 0x800);
> 
> would end up just reserving 0x1000->0x1800, it still wouldn't allow
> 
> 	ioremap(0x1000, 0x800);
> 
> to succeed because *both* of them would end up trying to reserve the
> beginning of the page.  Basically, the first caller effectively reserves
> the whole page and any second user will fail.
> 
> So the other place it would matter would be for mappings that span two
> pages, say:
> 
> 	ioremap(0x1fff, 0x2)
> 
> But I guess those aren't very common.  Most large ioremap() callers seem
> to already have base and size page-aligned.
> 
> Anyway, sorry to make so much of a big deal about a one-liner.  But,
> these decade-old bugs really make me wonder how they stuck around for so
> long.
> 
> I'd be curious if you thought about this too while putting together this
> fox.

The bug only manifests if the phys_addr input argument exceeds
PHYSICAL_PAGE_MASK, which is the global variable physical_mask, which is
the size of the machine's or VM's physical address space. That's the only case
in which masking with PHYSICAL_PAGE_MASK changes anything.   So I don't
see that your examples fit the situation.  In the case where the masking does
clear some high order bits, the "size" calculation yields a huge number which
then quickly causes an error.

With that understanding, I'd guess that over the last 14 years, the bug has
never manifested, or if it did, it was due to something badly broken in the
caller.  It's not clear why masking with PHYSICAL_PAGE_MASK is there in the
first place, other than as a "safety check" on the phys_addr input argument
that wasn't done quite correctly.

I hit the issue because this patch series does a *transition* in how the AMD
SNP "vTOM" bit is handled.  vTOM is bit 46 in a 47-bit physical address space --
i.e., it's the high order bit.  Current code treats the vTOM bit as part of the
physical address, and current code passes addresses with vTOM set into
__ioremap_caller() and everything works.   But Patch 5 of this patch series
changes the underlying global variable physical_mask to remove bit 46,
similar to what tdx_early_init() does.  At that point, passing __ioremap_caller()
a phys_addr with the vTOM bit set causes the bug and a failure.  With the
fix, Patch 5 in this series causes __ioremap_caller() to mask out the vTOM bit,
which is what I want, at least temporarily.

Later patches in the series change things so that we no longer pass a
phys_addr to __ioremap_caller() that has the vTOM bit set.  After those
later patches, this fix to __ioremap_caller() isn't needed.  But I wanted to
avoid cramming all the vTOM-related changes into a single huge patch.
Having __ioremap_caller() correctly handle a phys_addr that exceeds
physical_mask instead of blowing up let's this patch series sequence things
into reasonable size chunks.  And given that the __ioremap_caller() code is
wrong regardless, fixing it seemed like a reasonable overall solution.

Michael

^ permalink raw reply	[flat|nested] 27+ messages in thread

* RE: [PATCH v2 02/12] x86/ioapic: Gate decrypted mapping on cc_platform_has() attribute
  2022-11-12  0:21   ` Dave Hansen
@ 2022-11-12  4:48     ` Michael Kelley (LINUX)
  2022-11-14 16:23       ` Dave Hansen
  0 siblings, 1 reply; 27+ messages in thread
From: Michael Kelley (LINUX) @ 2022-11-12  4:48 UTC (permalink / raw)
  To: Dave Hansen, hpa, KY Srinivasan, Haiyang Zhang, wei.liu,
	Dexuan Cui, luto, peterz, davem, edumazet, kuba, pabeni,
	lpieralisi, robh, kw, bhelgaas, arnd, hch, m.szyprowski,
	robin.murphy, thomas.lendacky, brijesh.singh, tglx, mingo, bp,
	dave.hansen, Tianyu Lan, kirill.shutemov,
	sathyanarayanan.kuppuswamy, ak, isaku.yamahata, Williams, Dan J,
	jane.chu, seanjc, tony.luck, x86, linux-kernel, linux-hyperv,
	netdev, linux-pci, linux-arch, iommu

From: Dave Hansen <dave.hansen@intel.com> Sent: Friday, November 11, 2022 4:22 PM
> 
> On 11/10/22 22:21, Michael Kelley wrote:
> >  	 * Ensure fixmaps for IOAPIC MMIO respect memory encryption pgprot
> >  	 * bits, just like normal ioremap():
> >  	 */
> > -	flags = pgprot_decrypted(flags);
> > +	if (!cc_platform_has(CC_ATTR_HAS_PARAVISOR))
> > +		flags = pgprot_decrypted(flags);
> 
> This begs the question whether *all* paravisors will want to avoid a
> decrypted ioapic mapping.  Is this _fundamental_ to paravisors, or it is
> an implementation detail of this _individual_ paravisor?

Hard to say.  The paravisor that Hyper-V provides for use with the vTOM
option in a SEV SNP VM is the only paravisor I've seen.  At least as defined
by Hyper-V and AMD SNP Virtual Machine Privilege Levels (VMPLs), the
paravisor resides within the VM trust boundary.  Anything that a paravisor
emulates would be in the "private" (i.e., encrypted) memory so it can be
accessed by both the guest OS and the paravisor.  But nothing fundamental
says that IOAPIC emulation *must* be done in the paravisor.

I originally though about naming this attribute HAS_EMULATED_IOAPIC, but
that felt a bit narrow as other emulated hardware might need similar treatment
in the future, at least with the Hyper-V and AMD SEV SNP vTOM paravisor.

Net, we currently have N=1 for paravisors, and we won't know what the more
generalized case looks like until N >= 2.  If/when that happens, additional logic
might be needed here, and the name of this attribute might need adjustment
to support broader usage.  But if there's consensus on a different name now,
or on the narrower HAS_EMULATED_IOAPIC name, it doesn’t really matter
to me.

Michael

^ permalink raw reply	[flat|nested] 27+ messages in thread

* RE: [PATCH v2 05/12] x86/hyperv: Change vTOM handling to use standard coco mechanisms
  2022-11-11 18:49   ` Tom Lendacky
@ 2022-11-13 16:01     ` Michael Kelley (LINUX)
  2022-11-16 16:38       ` Tom Lendacky
  0 siblings, 1 reply; 27+ messages in thread
From: Michael Kelley (LINUX) @ 2022-11-13 16:01 UTC (permalink / raw)
  To: Tom Lendacky, hpa, KY Srinivasan, Haiyang Zhang, wei.liu,
	Dexuan Cui, luto, peterz, davem, edumazet, kuba, pabeni,
	lpieralisi, robh, kw, bhelgaas, arnd, hch, m.szyprowski,
	robin.murphy, brijesh.singh, tglx, mingo, bp, dave.hansen,
	Tianyu Lan, kirill.shutemov, sathyanarayanan.kuppuswamy, ak,
	isaku.yamahata, Williams, Dan J, jane.chu, seanjc, tony.luck,
	x86, linux-kernel, linux-hyperv, netdev, linux-pci, linux-arch,
	iommu

From: Tom Lendacky <thomas.lendacky@amd.com> Sent: Friday, November 11, 2022 10:50 AM
> 
> On 11/11/22 00:21, Michael Kelley wrote:

[snip]

> > diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
> > index 06eb8910..024fbf4 100644
> > --- a/arch/x86/mm/pat/set_memory.c
> > +++ b/arch/x86/mm/pat/set_memory.c
> > @@ -2126,10 +2126,8 @@ static int __set_memory_enc_pgtable(unsigned long
> addr, int numpages, bool enc)
> >
> >   static int __set_memory_enc_dec(unsigned long addr, int numpages, bool enc)
> >   {
> > -	if (hv_is_isolation_supported())
> > -		return hv_set_mem_host_visibility(addr, numpages, !enc);
> > -
> > -	if (cc_platform_has(CC_ATTR_MEM_ENCRYPT))
> > +	if (cc_platform_has(CC_ATTR_MEM_ENCRYPT) ||
> > +	    cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
> 
> This seems kind of strange since CC_ATTR_MEM_ENCRYPT is supposed to mean
> either HOST or GUEST memory encryption, but then you check for GUEST
> memory encryption directly. Can your cc_platform_has() support be setup to
> handle the CC_ATTR_MEM_ENCRYPT attribute in some way?
> 
> Thanks,
> Tom

Current upstream code for Hyper-V guests with vTOM enables only
CC_ATTR_GUEST_MEM_ENCRYPT.  I had been wary of also enabling
CC_ATTR_MEM_ENCRYPT because that would enable other code paths that
Might not be right for the vTOM case.  But looking at it more closely, enabling
CC_ATTR_MEM_ENCRYPT may work.

There are two problems with Hyper-V vTOM enabling CC_ATTR_MEM_ENCRYPT,
but both are fixable:

1) The call to mem_encrypt_init() happens a little bit too soon.  Hyper-V is fully
initialized and hypercalls become possible after start_kernel() calls late_time_init().
mem_encrypt_init() needs to happen after the call to late_time_init() so that
marking the swiotlb memory as decrypted can make the hypercalls to sync the
page state change with the host.   Moving mem_encrypt_init() a few lines later in
start_kernel() works in my case, but I can't test all the cases that you probably
have.  This change also has the benefit of removing the call to
swiotlb_update_mem_attributes() at the end of hyperv_init(), which always
seemed like a hack.

2)  mem_encrypt_free_decrypted_mem() is mismatched with
sme_postprocess_startup() in its handling of bss decrypted memory.  The
decryption is done if sme_me_mask is non-zero, while the re-encryption is
done if CC_ATTR_MEM_ENCRYPT is true, and those conditions won't be
equivalent in a Hyper-V vTOM VM if we enable CC_ATTR_MEM_ENCRYPT
(sme_me_mask is always zero in a Hyper-V vTOM VM).  Changing
mem_encrypt_free_decrypted_mem() to do re-encryption only if sme_me_mask
is non-zero solves that problem.  Note that there doesn't seem to be a way for a
Hyper-V vTOM VM to have decrypted bss, since there's no way to sync the
page state change with the host that early in the boot process, but I don't think
there's a requirement for such, so all is good.

With the above two changes, Hyper-V vTOM VMs can enable
CC_ATTR_MEM_ENCRYPT.  The Hyper-V hack in __set_memory_enc_dec()
still goes away, and there's no change to the condition for invoking
__set_memory_enc_pgtable().

Thoughts?  Have I missed anything?  Overall, I'm persuaded that this is a better
approach and can submit a v3 patch series with these changes if you agree.

Michael

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v2 02/12] x86/ioapic: Gate decrypted mapping on cc_platform_has() attribute
  2022-11-12  4:48     ` Michael Kelley (LINUX)
@ 2022-11-14 16:23       ` Dave Hansen
  2022-11-14 16:54         ` Michael Kelley (LINUX)
  0 siblings, 1 reply; 27+ messages in thread
From: Dave Hansen @ 2022-11-14 16:23 UTC (permalink / raw)
  To: Michael Kelley (LINUX),
	hpa, KY Srinivasan, Haiyang Zhang, wei.liu, Dexuan Cui, luto,
	peterz, davem, edumazet, kuba, pabeni, lpieralisi, robh, kw,
	bhelgaas, arnd, hch, m.szyprowski, robin.murphy, thomas.lendacky,
	brijesh.singh, tglx, mingo, bp, dave.hansen, Tianyu Lan,
	kirill.shutemov, sathyanarayanan.kuppuswamy, ak, isaku.yamahata,
	Williams, Dan J, jane.chu, seanjc, tony.luck, x86, linux-kernel,
	linux-hyperv, netdev, linux-pci, linux-arch, iommu

On 11/11/22 20:48, Michael Kelley (LINUX) wrote:
> From: Dave Hansen <dave.hansen@intel.com> Sent: Friday, November 11, 2022 4:22 PM
>> On 11/10/22 22:21, Michael Kelley wrote:
>>>  	 * Ensure fixmaps for IOAPIC MMIO respect memory encryption pgprot
>>>  	 * bits, just like normal ioremap():
>>>  	 */
>>> -	flags = pgprot_decrypted(flags);
>>> +	if (!cc_platform_has(CC_ATTR_HAS_PARAVISOR))
>>> +		flags = pgprot_decrypted(flags);
>> This begs the question whether *all* paravisors will want to avoid a
>> decrypted ioapic mapping.  Is this _fundamental_ to paravisors, or it is
>> an implementation detail of this _individual_ paravisor?
> Hard to say.  The paravisor that Hyper-V provides for use with the vTOM
> option in a SEV SNP VM is the only paravisor I've seen.  At least as defined
> by Hyper-V and AMD SNP Virtual Machine Privilege Levels (VMPLs), the
> paravisor resides within the VM trust boundary.  Anything that a paravisor
> emulates would be in the "private" (i.e., encrypted) memory so it can be
> accessed by both the guest OS and the paravisor.  But nothing fundamental
> says that IOAPIC emulation *must* be done in the paravisor.

Please just make this check more specific.  Either make this a specific
Hyper-V+SVM check, or rename it HAS_EMULATED_IOAPIC, like you were
thinking.  If paravisors catch on and we end up with ten more of these
things across five different paravisors and see a pattern, *then* a
paravisor-specific one makes sense.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v2 01/12] x86/ioremap: Fix page aligned size calculation in __ioremap_caller()
  2022-11-11  6:21 ` [PATCH v2 01/12] x86/ioremap: Fix page aligned size calculation in __ioremap_caller() Michael Kelley
  2022-11-12  0:11   ` Dave Hansen
@ 2022-11-14 16:40   ` Dave Hansen
  2022-11-14 16:53     ` Michael Kelley (LINUX)
  1 sibling, 1 reply; 27+ messages in thread
From: Dave Hansen @ 2022-11-14 16:40 UTC (permalink / raw)
  To: Michael Kelley, hpa, kys, haiyangz, wei.liu, decui, luto, peterz,
	davem, edumazet, kuba, pabeni, lpieralisi, robh, kw, bhelgaas,
	arnd, hch, m.szyprowski, robin.murphy, thomas.lendacky,
	brijesh.singh, tglx, mingo, bp, dave.hansen, Tianyu.Lan,
	kirill.shutemov, sathyanarayanan.kuppuswamy, ak, isaku.yamahata,
	dan.j.williams, jane.chu, seanjc, tony.luck, x86, linux-kernel,
	linux-hyperv, netdev, linux-pci, linux-arch, iommu

On 11/10/22 22:21, Michael Kelley wrote:
> --- a/arch/x86/mm/ioremap.c
> +++ b/arch/x86/mm/ioremap.c
> @@ -218,7 +218,7 @@ static void __ioremap_check_mem(resource_size_t addr, unsigned long size,
>  	 */
>  	offset = phys_addr & ~PAGE_MASK;
>  	phys_addr &= PHYSICAL_PAGE_MASK;
> -	size = PAGE_ALIGN(last_addr+1) - phys_addr;
> +	size = (PAGE_ALIGN(last_addr+1) & PHYSICAL_PAGE_MASK) - phys_addr;

Michael, thanks for the explanation in your other reply.  First and
foremost, I *totally* missed the reason for this patch.  I was thinking
about issues that could pop up from the _lower_ bits being masked off.

Granted, your changelog _did_ say "upper bits", so shame on me.  But, it
would be great to put some more background in the changelog to make it a
bit harder for silly reviewers to miss such things.

I'd also like to propose something that I think is more straightforward:

        /*
         * Mappings have to be page-aligned
         */
        offset = phys_addr & ~PAGE_MASK;
        phys_addr &= PAGE_MASK;
        size = PAGE_ALIGN(last_addr+1) - phys_addr;

	/*
	 * Mask out any bits not parts of the actual physical
	 * address, like memory encryption bits.
	 */
	phys_addr &= PHYSICAL_PAGE_MASK;

Because, first of all, that "Mappings have to be page-aligned" thing is
(now) doing more than page-aligning things.  Second, the moment you mask
out the metadata bits, the 'size' calculation gets harder.  Doing it in
two phases (page alignment followed by metadata bit masking) breaks up
the two logical operations.



^ permalink raw reply	[flat|nested] 27+ messages in thread

* RE: [PATCH v2 01/12] x86/ioremap: Fix page aligned size calculation in __ioremap_caller()
  2022-11-14 16:40   ` Dave Hansen
@ 2022-11-14 16:53     ` Michael Kelley (LINUX)
  2022-11-14 16:57       ` Dave Hansen
  0 siblings, 1 reply; 27+ messages in thread
From: Michael Kelley (LINUX) @ 2022-11-14 16:53 UTC (permalink / raw)
  To: Dave Hansen, hpa, KY Srinivasan, Haiyang Zhang, wei.liu,
	Dexuan Cui, luto, peterz, davem, edumazet, kuba, pabeni,
	lpieralisi, robh, kw, bhelgaas, arnd, hch, m.szyprowski,
	robin.murphy, thomas.lendacky, brijesh.singh, tglx, mingo, bp,
	dave.hansen, Tianyu Lan, kirill.shutemov,
	sathyanarayanan.kuppuswamy, ak, isaku.yamahata, Williams, Dan J,
	jane.chu, seanjc, tony.luck, x86, linux-kernel, linux-hyperv,
	netdev, linux-pci, linux-arch, iommu

From: Dave Hansen <dave.hansen@intel.com> Sent: Monday, November 14, 2022 8:40 AM
> 
> On 11/10/22 22:21, Michael Kelley wrote:
> > --- a/arch/x86/mm/ioremap.c
> > +++ b/arch/x86/mm/ioremap.c
> > @@ -218,7 +218,7 @@ static void __ioremap_check_mem(resource_size_t addr,
> unsigned long size,
> >  	 */
> >  	offset = phys_addr & ~PAGE_MASK;
> >  	phys_addr &= PHYSICAL_PAGE_MASK;
> > -	size = PAGE_ALIGN(last_addr+1) - phys_addr;
> > +	size = (PAGE_ALIGN(last_addr+1) & PHYSICAL_PAGE_MASK) - phys_addr;
> 
> Michael, thanks for the explanation in your other reply.  First and
> foremost, I *totally* missed the reason for this patch.  I was thinking
> about issues that could pop up from the _lower_ bits being masked off.
> 
> Granted, your changelog _did_ say "upper bits", so shame on me.  But, it
> would be great to put some more background in the changelog to make it a
> bit harder for silly reviewers to miss such things.
> 
> I'd also like to propose something that I think is more straightforward:
> 
>         /*
>          * Mappings have to be page-aligned
>          */
>         offset = phys_addr & ~PAGE_MASK;
>         phys_addr &= PAGE_MASK;
>         size = PAGE_ALIGN(last_addr+1) - phys_addr;
> 
> 	/*
> 	 * Mask out any bits not parts of the actual physical
> 	 * address, like memory encryption bits.
> 	 */
> 	phys_addr &= PHYSICAL_PAGE_MASK;
> 
> Because, first of all, that "Mappings have to be page-aligned" thing is
> (now) doing more than page-aligning things.  Second, the moment you mask
> out the metadata bits, the 'size' calculation gets harder.  Doing it in
> two phases (page alignment followed by metadata bit masking) breaks up
> the two logical operations.
> 

Work for me.  Will do this in v3.

Michael


^ permalink raw reply	[flat|nested] 27+ messages in thread

* RE: [PATCH v2 02/12] x86/ioapic: Gate decrypted mapping on cc_platform_has() attribute
  2022-11-14 16:23       ` Dave Hansen
@ 2022-11-14 16:54         ` Michael Kelley (LINUX)
  0 siblings, 0 replies; 27+ messages in thread
From: Michael Kelley (LINUX) @ 2022-11-14 16:54 UTC (permalink / raw)
  To: Dave Hansen, hpa, KY Srinivasan, Haiyang Zhang, wei.liu,
	Dexuan Cui, luto, peterz, davem, edumazet, kuba, pabeni,
	lpieralisi, robh, kw, bhelgaas, arnd, hch, m.szyprowski,
	robin.murphy, thomas.lendacky, brijesh.singh, tglx, mingo, bp,
	dave.hansen, Tianyu Lan, kirill.shutemov,
	sathyanarayanan.kuppuswamy, ak, isaku.yamahata, Williams, Dan J,
	jane.chu, seanjc, tony.luck, x86, linux-kernel, linux-hyperv,
	netdev, linux-pci, linux-arch, iommu

From: Dave Hansen <dave.hansen@intel.com> Sent: Monday, November 14, 2022 8:23 AM
> 
> On 11/11/22 20:48, Michael Kelley (LINUX) wrote:
> > From: Dave Hansen <dave.hansen@intel.com> Sent: Friday, November 11, 2022 4:22
> PM
> >> On 11/10/22 22:21, Michael Kelley wrote:
> >>>  	 * Ensure fixmaps for IOAPIC MMIO respect memory encryption pgprot
> >>>  	 * bits, just like normal ioremap():
> >>>  	 */
> >>> -	flags = pgprot_decrypted(flags);
> >>> +	if (!cc_platform_has(CC_ATTR_HAS_PARAVISOR))
> >>> +		flags = pgprot_decrypted(flags);
> >> This begs the question whether *all* paravisors will want to avoid a
> >> decrypted ioapic mapping.  Is this _fundamental_ to paravisors, or it is
> >> an implementation detail of this _individual_ paravisor?
> > Hard to say.  The paravisor that Hyper-V provides for use with the vTOM
> > option in a SEV SNP VM is the only paravisor I've seen.  At least as defined
> > by Hyper-V and AMD SNP Virtual Machine Privilege Levels (VMPLs), the
> > paravisor resides within the VM trust boundary.  Anything that a paravisor
> > emulates would be in the "private" (i.e., encrypted) memory so it can be
> > accessed by both the guest OS and the paravisor.  But nothing fundamental
> > says that IOAPIC emulation *must* be done in the paravisor.
> 
> Please just make this check more specific.  Either make this a specific
> Hyper-V+SVM check, or rename it HAS_EMULATED_IOAPIC, like you were
> thinking.  If paravisors catch on and we end up with ten more of these
> things across five different paravisors and see a pattern, *then* a
> paravisor-specific one makes sense.

I'm good with that.  I'll use HAS_EMULATED_IOAPIC in v3.

Michael

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v2 01/12] x86/ioremap: Fix page aligned size calculation in __ioremap_caller()
  2022-11-14 16:53     ` Michael Kelley (LINUX)
@ 2022-11-14 16:57       ` Dave Hansen
  2022-11-14 17:25         ` Michael Kelley (LINUX)
  0 siblings, 1 reply; 27+ messages in thread
From: Dave Hansen @ 2022-11-14 16:57 UTC (permalink / raw)
  To: Michael Kelley (LINUX),
	hpa, KY Srinivasan, Haiyang Zhang, wei.liu, Dexuan Cui, luto,
	peterz, davem, edumazet, kuba, pabeni, lpieralisi, robh, kw,
	bhelgaas, arnd, hch, m.szyprowski, robin.murphy, thomas.lendacky,
	brijesh.singh, tglx, mingo, bp, dave.hansen, Tianyu Lan,
	kirill.shutemov, sathyanarayanan.kuppuswamy, ak, isaku.yamahata,
	Williams, Dan J, jane.chu, seanjc, tony.luck, x86, linux-kernel,
	linux-hyperv, netdev, linux-pci, linux-arch, iommu

On 11/14/22 08:53, Michael Kelley (LINUX) wrote:
>> Because, first of all, that "Mappings have to be page-aligned" thing is
>> (now) doing more than page-aligning things.  Second, the moment you mask
>> out the metadata bits, the 'size' calculation gets harder.  Doing it in
>> two phases (page alignment followed by metadata bit masking) breaks up
>> the two logical operations.
>>
> Work for me.  Will do this in v3.

Kirill also made a good point about TDX: it isn't affected by this
because it always passes *real* (no metadata bits set) physical
addresses in here.  Could you double check that you don't want to do the
same for your code?



^ permalink raw reply	[flat|nested] 27+ messages in thread

* RE: [PATCH v2 01/12] x86/ioremap: Fix page aligned size calculation in __ioremap_caller()
  2022-11-14 16:57       ` Dave Hansen
@ 2022-11-14 17:25         ` Michael Kelley (LINUX)
  0 siblings, 0 replies; 27+ messages in thread
From: Michael Kelley (LINUX) @ 2022-11-14 17:25 UTC (permalink / raw)
  To: Dave Hansen, hpa, KY Srinivasan, Haiyang Zhang, wei.liu,
	Dexuan Cui, luto, peterz, davem, edumazet, kuba, pabeni,
	lpieralisi, robh, kw, bhelgaas, arnd, hch, m.szyprowski,
	robin.murphy, thomas.lendacky, brijesh.singh, tglx, mingo, bp,
	dave.hansen, Tianyu Lan, kirill.shutemov,
	sathyanarayanan.kuppuswamy, ak, isaku.yamahata, Williams, Dan J,
	jane.chu, seanjc, tony.luck, x86, linux-kernel, linux-hyperv,
	netdev, linux-pci, linux-arch, iommu

From: Dave Hansen <dave.hansen@intel.com> Sent: Monday, November 14, 2022 8:58 AM
> 
> On 11/14/22 08:53, Michael Kelley (LINUX) wrote:
> >> Because, first of all, that "Mappings have to be page-aligned" thing is
> >> (now) doing more than page-aligning things.  Second, the moment you mask
> >> out the metadata bits, the 'size' calculation gets harder.  Doing it in
> >> two phases (page alignment followed by metadata bit masking) breaks up
> >> the two logical operations.
> >>
> > Work for me.  Will do this in v3.
> 
> Kirill also made a good point about TDX: it isn't affected by this
> because it always passes *real* (no metadata bits set) physical
> addresses in here.  Could you double check that you don't want to do the
> same for your code?
> 

Yes, we want to do the same for the Hyper-V vTOM code.   And when this
full patch set is applied, we're only passing in *real* physical addresses and
are not depending on __ioremap_caller() doing any masking.

But this patch set is executing a transition from current code, which passes
physical addresses with metadata bits set (i.e., the vTOM bit), to the new
approach, which does not.  There are several places in the current Hyper-V
vTOM code that need changes to make this transition.  These changes are
non-trivial, and I don't want to have to cram them all into one big patch.
By making this fix, the current code continues to work throughout this
patch series while the changes are incrementally made in multiple
individual patches.  But when it's all done, we won't be passing any
physical addresses with the vTOM bit set.

Note that current code works and doesn't hit the bug because the
global variable physical_mask includes the vTOM bit as part of the
physical address.  But Patch 5 of the series removes the vTOM bit
from physical_mask.  At that point, the current __ioremap_caller()
code breaks due to the bug.  By fixing the bug, the current Hyper-V
vTOM code continues to work until all the changes can be completed
(which is Patch 10 of the series).

Perhaps it's convoluted, but basically I'm trying to avoid having to merge
Patches 5 thru 10 into one big patch.  And since the current
__ioremap_caller() is wrong anyway, fixing it made everything smoother.

Michael


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v2 05/12] x86/hyperv: Change vTOM handling to use standard coco mechanisms
  2022-11-13 16:01     ` Michael Kelley (LINUX)
@ 2022-11-16 16:38       ` Tom Lendacky
  0 siblings, 0 replies; 27+ messages in thread
From: Tom Lendacky @ 2022-11-16 16:38 UTC (permalink / raw)
  To: Michael Kelley (LINUX),
	hpa, KY Srinivasan, Haiyang Zhang, wei.liu, Dexuan Cui, luto,
	peterz, davem, edumazet, kuba, pabeni, lpieralisi, robh, kw,
	bhelgaas, arnd, hch, m.szyprowski, robin.murphy, brijesh.singh,
	tglx, mingo, bp, dave.hansen, Tianyu Lan, kirill.shutemov,
	sathyanarayanan.kuppuswamy, ak, isaku.yamahata, Williams, Dan J,
	jane.chu, seanjc, tony.luck, x86, linux-kernel, linux-hyperv,
	netdev, linux-pci, linux-arch, iommu

On 11/13/22 10:01, Michael Kelley (LINUX) wrote:
> From: Tom Lendacky <thomas.lendacky@amd.com> Sent: Friday, November 11, 2022 10:50 AM
>>
>> On 11/11/22 00:21, Michael Kelley wrote:
> 
> [snip]
> 
>>> diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
>>> index 06eb8910..024fbf4 100644
>>> --- a/arch/x86/mm/pat/set_memory.c
>>> +++ b/arch/x86/mm/pat/set_memory.c
>>> @@ -2126,10 +2126,8 @@ static int __set_memory_enc_pgtable(unsigned long
>> addr, int numpages, bool enc)
>>>
>>>    static int __set_memory_enc_dec(unsigned long addr, int numpages, bool enc)
>>>    {
>>> -	if (hv_is_isolation_supported())
>>> -		return hv_set_mem_host_visibility(addr, numpages, !enc);
>>> -
>>> -	if (cc_platform_has(CC_ATTR_MEM_ENCRYPT))
>>> +	if (cc_platform_has(CC_ATTR_MEM_ENCRYPT) ||
>>> +	    cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
>>
>> This seems kind of strange since CC_ATTR_MEM_ENCRYPT is supposed to mean
>> either HOST or GUEST memory encryption, but then you check for GUEST
>> memory encryption directly. Can your cc_platform_has() support be setup to
>> handle the CC_ATTR_MEM_ENCRYPT attribute in some way?
>>
>> Thanks,
>> Tom
> 
> Current upstream code for Hyper-V guests with vTOM enables only
> CC_ATTR_GUEST_MEM_ENCRYPT.  I had been wary of also enabling
> CC_ATTR_MEM_ENCRYPT because that would enable other code paths that
> Might not be right for the vTOM case.  But looking at it more closely, enabling
> CC_ATTR_MEM_ENCRYPT may work.
> 
> There are two problems with Hyper-V vTOM enabling CC_ATTR_MEM_ENCRYPT,
> but both are fixable:
> 
> 1) The call to mem_encrypt_init() happens a little bit too soon.  Hyper-V is fully
> initialized and hypercalls become possible after start_kernel() calls late_time_init().
> mem_encrypt_init() needs to happen after the call to late_time_init() so that
> marking the swiotlb memory as decrypted can make the hypercalls to sync the
> page state change with the host.   Moving mem_encrypt_init() a few lines later in
> start_kernel() works in my case, but I can't test all the cases that you probably
> have.  This change also has the benefit of removing the call to
> swiotlb_update_mem_attributes() at the end of hyperv_init(), which always
> seemed like a hack.

It seems safe for SME/SEV since mem_encrypt_init() is only updating the 
SWIOTLB attributes at this point. I'll do some quick testing, but you 
might want to verify with TDX folks, too.

> 
> 2)  mem_encrypt_free_decrypted_mem() is mismatched with
> sme_postprocess_startup() in its handling of bss decrypted memory.  The
> decryption is done if sme_me_mask is non-zero, while the re-encryption is
> done if CC_ATTR_MEM_ENCRYPT is true, and those conditions won't be
> equivalent in a Hyper-V vTOM VM if we enable CC_ATTR_MEM_ENCRYPT
> (sme_me_mask is always zero in a Hyper-V vTOM VM).  Changing
> mem_encrypt_free_decrypted_mem() to do re-encryption only if sme_me_mask
> is non-zero solves that problem.  Note that there doesn't seem to be a way for a

Hmmm, yes, this was because of an issue using the cc_platform_has() call 
during identity mapped paging. I think matching them in this case would be 
best, e.g., changing mem_encrypt_free_decrypted_mem() to check for a 
non-zero sme_me_mask - along with a nice comment on why it is checking 
sme_me_mask.

Thanks,
Tom

> Hyper-V vTOM VM to have decrypted bss, since there's no way to sync the
> page state change with the host that early in the boot process, but I don't think
> there's a requirement for such, so all is good.
> 
> With the above two changes, Hyper-V vTOM VMs can enable
> CC_ATTR_MEM_ENCRYPT.  The Hyper-V hack in __set_memory_enc_dec()
> still goes away, and there's no change to the condition for invoking
> __set_memory_enc_pgtable().
> 
> Thoughts?  Have I missed anything?  Overall, I'm persuaded that this is a better
> approach and can submit a v3 patch series with these changes if you agree.
> 
> Michael

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2022-11-16 16:43 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-11  6:21 [PATCH v2 00/12] Drivers: hv: Add PCI pass-thru support to Hyper-V Confidential VMs Michael Kelley
2022-11-11  6:21 ` [PATCH v2 01/12] x86/ioremap: Fix page aligned size calculation in __ioremap_caller() Michael Kelley
2022-11-12  0:11   ` Dave Hansen
2022-11-12  4:31     ` Michael Kelley (LINUX)
2022-11-14 16:40   ` Dave Hansen
2022-11-14 16:53     ` Michael Kelley (LINUX)
2022-11-14 16:57       ` Dave Hansen
2022-11-14 17:25         ` Michael Kelley (LINUX)
2022-11-11  6:21 ` [PATCH v2 02/12] x86/ioapic: Gate decrypted mapping on cc_platform_has() attribute Michael Kelley
2022-11-12  0:21   ` Dave Hansen
2022-11-12  4:48     ` Michael Kelley (LINUX)
2022-11-14 16:23       ` Dave Hansen
2022-11-14 16:54         ` Michael Kelley (LINUX)
2022-11-11  6:21 ` [PATCH v2 03/12] x86/hyperv: Reorder code in prep for subsequent patch Michael Kelley
2022-11-11  6:21 ` [PATCH v2 04/12] Drivers: hv: Explicitly request decrypted in vmap_pfn() calls Michael Kelley
2022-11-11  6:21 ` [PATCH v2 05/12] x86/hyperv: Change vTOM handling to use standard coco mechanisms Michael Kelley
2022-11-11 18:49   ` Tom Lendacky
2022-11-13 16:01     ` Michael Kelley (LINUX)
2022-11-16 16:38       ` Tom Lendacky
2022-11-11  6:21 ` [PATCH v2 06/12] swiotlb: Remove bounce buffer remapping for Hyper-V Michael Kelley
2022-11-11  6:21 ` [PATCH v2 07/12] Drivers: hv: vmbus: Remove second mapping of VMBus monitor pages Michael Kelley
2022-11-11  6:21 ` [PATCH v2 08/12] Drivers: hv: vmbus: Remove second way of mapping ring buffers Michael Kelley
2022-11-11  6:21 ` [PATCH v2 09/12] hv_netvsc: Remove second mapping of send and recv buffers Michael Kelley
2022-11-11  6:21 ` [PATCH v2 10/12] Drivers: hv: Don't remap addresses that are above shared_gpa_boundary Michael Kelley
2022-11-11  6:21 ` [PATCH v2 11/12] PCI: hv: Add hypercalls to read/write MMIO space Michael Kelley
2022-11-11  6:21 ` [PATCH v2 12/12] PCI: hv: Enable PCI pass-thru devices in Confidential VMs Michael Kelley
2022-11-11 16:44 ` [PATCH v2 00/12] Drivers: hv: Add PCI pass-thru support to Hyper-V " Wei Liu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).