From e498f55aafb172382f2882baae2479810c789b10 Mon Sep 17 00:00:00 2001 From: Jeremi Piotrowski Date: Thu, 24 Mar 2022 10:15:08 +0000 Subject: [PATCH] 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. --- .../coreos-sources-5.15.32.ebuild | 2 + ...-Propagate-VMbus-coherence-to-each-V.patch | 126 ++++++++++++++++++ ...-coherence-from-VMbus-device-to-PCI-.patch | 48 +++++++ 3 files changed, 176 insertions(+) create mode 100644 sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-sources/files/5.15/z0006-Drivers-hv-vmbus-Propagate-VMbus-coherence-to-each-V.patch create mode 100644 sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-sources/files/5.15/z0007-PCI-hv-Propagate-coherence-from-VMbus-device-to-PCI-.patch diff --git a/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-sources/coreos-sources-5.15.32.ebuild b/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-sources/coreos-sources-5.15.32.ebuild index 96ac1b4ca4..b7be8550ea 100644 --- a/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-sources/coreos-sources-5.15.32.ebuild +++ b/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-sources/coreos-sources-5.15.32.ebuild @@ -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 \ " diff --git a/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-sources/files/5.15/z0006-Drivers-hv-vmbus-Propagate-VMbus-coherence-to-each-V.patch b/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-sources/files/5.15/z0006-Drivers-hv-vmbus-Propagate-VMbus-coherence-to-each-V.patch new file mode 100644 index 0000000000..25c5d8d108 --- /dev/null +++ b/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-sources/files/5.15/z0006-Drivers-hv-vmbus-Propagate-VMbus-coherence-to-each-V.patch @@ -0,0 +1,126 @@ +From b1b77cc3614b1f39a270d203c77d79834e9e91f3 Mon Sep 17 00:00:00 2001 +From: Michael Kelley +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 +Acked-by: Robin Murphy +--- + 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 + #include + #include ++#include + #include + #include + +@@ -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 + diff --git a/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-sources/files/5.15/z0007-PCI-hv-Propagate-coherence-from-VMbus-device-to-PCI-.patch b/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-sources/files/5.15/z0007-PCI-hv-Propagate-coherence-from-VMbus-device-to-PCI-.patch new file mode 100644 index 0000000000..6184cee196 --- /dev/null +++ b/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-sources/files/5.15/z0007-PCI-hv-Propagate-coherence-from-VMbus-device-to-PCI-.patch @@ -0,0 +1,48 @@ +From 9b38850d8ff2bbc6df27d394c825f92d846a6dd9 Mon Sep 17 00:00:00 2001 +From: Michael Kelley +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 +Acked-by: Boqun Feng +Acked-by: Robin Murphy +--- + 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 +