mirror of
https://github.com/flatcar/scripts.git
synced 2025-08-16 09:26:58 +02:00
sys-kernel/coreos-sources: backport kernel patches that fix memory coherence on Hyper-V
This is v3 of the patchset from here: https://lore.kernel.org/lkml/1648138492-2191-1-git-send-email-mikelley@microsoft.com/T/#u There was a slight merge conflict because hv_map_memory/hv_unmap_memory don't exist in 5.15.
This commit is contained in:
parent
9847794b4f
commit
e498f55aaf
@ -37,4 +37,6 @@ UNIPATCH_LIST="
|
||||
${PATCH_DIR}/z0003-PCI-hv-Make-the-code-arch-neutral-by-adding-arch-spe.patch \
|
||||
${PATCH_DIR}/z0004-PCI-hv-Add-arm64-Hyper-V-vPCI-support.patch \
|
||||
${PATCH_DIR}/z0005-Revert-PCI-MSI-Mask-MSI-X-vectors-only-on-success.patch \
|
||||
${PATCH_DIR}/z0006-Drivers-hv-vmbus-Propagate-VMbus-coherence-to-each-V.patch \
|
||||
${PATCH_DIR}/z0007-PCI-hv-Propagate-coherence-from-VMbus-device-to-PCI-.patch \
|
||||
"
|
||||
|
@ -0,0 +1,126 @@
|
||||
From b1b77cc3614b1f39a270d203c77d79834e9e91f3 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Kelley <mikelley@microsoft.com>
|
||||
Date: Thu, 24 Mar 2022 09:14:51 -0700
|
||||
Subject: [PATCH 1/2] Drivers: hv: vmbus: Propagate VMbus coherence to each
|
||||
VMbus device
|
||||
|
||||
VMbus synthetic devices are not represented in the ACPI DSDT -- only
|
||||
the top level VMbus device is represented. As a result, on ARM64
|
||||
coherence information in the _CCA method is not specified for
|
||||
synthetic devices, so they default to not hardware coherent.
|
||||
Drivers for some of these synthetic devices have been recently
|
||||
updated to use the standard DMA APIs, and they are incurring extra
|
||||
overhead of unneeded software coherence management.
|
||||
|
||||
Fix this by propagating coherence information from the VMbus node
|
||||
in ACPI to the individual synthetic devices. There's no effect on
|
||||
x86/x64 where devices are always hardware coherent.
|
||||
|
||||
Signed-off-by: Michael Kelley <mikelley@microsoft.com>
|
||||
Acked-by: Robin Murphy <robin.murphy@arm.com>
|
||||
---
|
||||
drivers/hv/hv_common.c | 11 +++++++++++
|
||||
drivers/hv/vmbus_drv.c | 31 +++++++++++++++++++++++++++++++
|
||||
include/asm-generic/mshyperv.h | 1 +
|
||||
3 files changed, 43 insertions(+)
|
||||
|
||||
diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
|
||||
index c0d9048a4112..196cedd5f37c 100644
|
||||
--- a/drivers/hv/hv_common.c
|
||||
+++ b/drivers/hv/hv_common.c
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <linux/panic_notifier.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/slab.h>
|
||||
+#include <linux/dma-map-ops.h>
|
||||
#include <asm/hyperv-tlfs.h>
|
||||
#include <asm/mshyperv.h>
|
||||
|
||||
@@ -216,6 +217,16 @@ bool hv_query_ext_cap(u64 cap_query)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hv_query_ext_cap);
|
||||
|
||||
+void hv_setup_dma_ops(struct device *dev, bool coherent)
|
||||
+{
|
||||
+ /*
|
||||
+ * Hyper-V does not offer a vIOMMU in the guest
|
||||
+ * VM, so pass 0/NULL for the IOMMU settings
|
||||
+ */
|
||||
+ arch_setup_dma_ops(dev, 0, 0, NULL, coherent);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(hv_setup_dma_ops);
|
||||
+
|
||||
bool hv_is_hibernation_supported(void)
|
||||
{
|
||||
return !hv_root_partition && acpi_sleep_state_supported(ACPI_STATE_S4);
|
||||
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
|
||||
index 44bd0b6ff505..fdbd5531405e 100644
|
||||
--- a/drivers/hv/vmbus_drv.c
|
||||
+++ b/drivers/hv/vmbus_drv.c
|
||||
@@ -919,6 +919,21 @@ static int vmbus_probe(struct device *child_device)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * vmbus_dma_configure -- Configure DMA coherence for VMbus device
|
||||
+ */
|
||||
+static int vmbus_dma_configure(struct device *child_device)
|
||||
+{
|
||||
+ /*
|
||||
+ * On ARM64, propagate the DMA coherence setting from the top level
|
||||
+ * VMbus ACPI device to the child VMbus device being added here.
|
||||
+ * On x86/x64 coherence is assumed and these calls have no effect.
|
||||
+ */
|
||||
+ hv_setup_dma_ops(child_device,
|
||||
+ device_get_dma_attr(&hv_acpi_dev->dev) == DEV_DMA_COHERENT);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* vmbus_remove - Remove a vmbus device
|
||||
*/
|
||||
@@ -1039,6 +1054,7 @@ static struct bus_type hv_bus = {
|
||||
.remove = vmbus_remove,
|
||||
.probe = vmbus_probe,
|
||||
.uevent = vmbus_uevent,
|
||||
+ .dma_configure = vmbus_dma_configure,
|
||||
.dev_groups = vmbus_dev_groups,
|
||||
.drv_groups = vmbus_drv_groups,
|
||||
.bus_groups = vmbus_bus_groups,
|
||||
@@ -2424,6 +2440,21 @@ static int vmbus_acpi_add(struct acpi_device *device)
|
||||
|
||||
hv_acpi_dev = device;
|
||||
|
||||
+ /*
|
||||
+ * Older versions of Hyper-V for ARM64 fail to include the _CCA
|
||||
+ * method on the top level VMbus device in the DSDT. But devices
|
||||
+ * are hardware coherent in all current Hyper-V use cases, so fix
|
||||
+ * up the ACPI device to behave as if _CCA is present and indicates
|
||||
+ * hardware coherence.
|
||||
+ */
|
||||
+ ACPI_COMPANION_SET(&device->dev, device);
|
||||
+ if (IS_ENABLED(CONFIG_ACPI_CCA_REQUIRED) &&
|
||||
+ device_get_dma_attr(&device->dev) == DEV_DMA_NOT_SUPPORTED) {
|
||||
+ pr_info("No ACPI _CCA found; assuming coherent device I/O\n");
|
||||
+ device->flags.cca_seen = true;
|
||||
+ device->flags.coherent_dma = true;
|
||||
+ }
|
||||
+
|
||||
result = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
|
||||
vmbus_walk_resources, NULL);
|
||||
|
||||
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
|
||||
index d3eae6cdbacb..807f1b524af2 100644
|
||||
--- a/include/asm-generic/mshyperv.h
|
||||
+++ b/include/asm-generic/mshyperv.h
|
||||
@@ -256,6 +256,7 @@ enum hv_isolation_type hv_get_isolation_type(void);
|
||||
bool hv_is_isolation_supported(void);
|
||||
void hyperv_cleanup(void);
|
||||
bool hv_query_ext_cap(u64 cap_query);
|
||||
+void hv_setup_dma_ops(struct device *dev, bool coherent);
|
||||
#else /* CONFIG_HYPERV */
|
||||
static inline bool hv_is_hyperv_initialized(void) { return false; }
|
||||
static inline bool hv_is_hibernation_supported(void) { return false; }
|
||||
--
|
||||
2.32.0
|
||||
|
@ -0,0 +1,48 @@
|
||||
From 9b38850d8ff2bbc6df27d394c825f92d846a6dd9 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Kelley <mikelley@microsoft.com>
|
||||
Date: Thu, 24 Mar 2022 09:14:52 -0700
|
||||
Subject: [PATCH 2/2] PCI: hv: Propagate coherence from VMbus device to PCI
|
||||
device
|
||||
|
||||
PCI pass-thru devices in a Hyper-V VM are represented as a VMBus
|
||||
device and as a PCI device. The coherence of the VMbus device is
|
||||
set based on the VMbus node in ACPI, but the PCI device has no
|
||||
ACPI node and defaults to not hardware coherent. This results
|
||||
in extra software coherence management overhead on ARM64 when
|
||||
devices are hardware coherent.
|
||||
|
||||
Fix this by setting up the PCI host bus so that normal
|
||||
PCI mechanisms will propagate the coherence of the VMbus
|
||||
device to the PCI device. There's no effect on x86/x64 where
|
||||
devices are always hardware coherent.
|
||||
|
||||
Signed-off-by: Michael Kelley <mikelley@microsoft.com>
|
||||
Acked-by: Boqun Feng <boqun.feng@gmail.com>
|
||||
Acked-by: Robin Murphy <robin.murphy@arm.com>
|
||||
---
|
||||
drivers/pci/controller/pci-hyperv.c | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
|
||||
index ddbbdadc8490..95806cb1e4d8 100644
|
||||
--- a/drivers/pci/controller/pci-hyperv.c
|
||||
+++ b/drivers/pci/controller/pci-hyperv.c
|
||||
@@ -3404,6 +3404,15 @@ static int hv_pci_probe(struct hv_device *hdev,
|
||||
hbus->bridge->domain_nr = dom;
|
||||
#ifdef CONFIG_X86
|
||||
hbus->sysdata.domain = dom;
|
||||
+#elif defined(CONFIG_ARM64)
|
||||
+ /*
|
||||
+ * Set the PCI bus parent to be the corresponding VMbus
|
||||
+ * device. Then the VMbus device will be assigned as the
|
||||
+ * ACPI companion in pcibios_root_bridge_prepare() and
|
||||
+ * pci_dma_configure() will propagate device coherence
|
||||
+ * information to devices created on the bus.
|
||||
+ */
|
||||
+ hbus->sysdata.parent = hdev->device.parent;
|
||||
#endif
|
||||
|
||||
hbus->hdev = hdev;
|
||||
--
|
||||
2.32.0
|
||||
|
Loading…
Reference in New Issue
Block a user