Skip to content

Commit bb1ac2c

Browse files
kelleymhallenpais
authored andcommitted
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 <[email protected]>
1 parent 94d924e commit bb1ac2c

File tree

3 files changed

+35
-0
lines changed

3 files changed

+35
-0
lines changed

drivers/hv/hv_common.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <linux/panic_notifier.h>
2121
#include <linux/ptrace.h>
2222
#include <linux/slab.h>
23+
#include <linux/dma-map-ops.h>
2324
#include <asm/hyperv-tlfs.h>
2425
#include <asm/mshyperv.h>
2526

@@ -216,6 +217,16 @@ bool hv_query_ext_cap(u64 cap_query)
216217
}
217218
EXPORT_SYMBOL_GPL(hv_query_ext_cap);
218219

220+
void hv_setup_dma_ops(struct device *dev, bool coherent)
221+
{
222+
/*
223+
* Hyper-V does not offer a vIOMMU in the guest
224+
* VM, so pass 0/NULL for the IOMMU settings
225+
*/
226+
arch_setup_dma_ops(dev, 0, 0, NULL, coherent);
227+
}
228+
EXPORT_SYMBOL_GPL(hv_setup_dma_ops);
229+
219230
bool hv_is_hibernation_supported(void)
220231
{
221232
return !hv_root_partition && acpi_sleep_state_supported(ACPI_STATE_S4);

drivers/hv/vmbus_drv.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -904,6 +904,14 @@ static int vmbus_probe(struct device *child_device)
904904
struct hv_device *dev = device_to_hv_device(child_device);
905905
const struct hv_vmbus_device_id *dev_id;
906906

907+
/*
908+
* On ARM64, propagate the DMA coherence setting from the top level
909+
* VMbus ACPI device to the child VMbus device being added here.
910+
* On x86/x64 coherence is assumed and these calls have no effect.
911+
*/
912+
hv_setup_dma_ops(child_device,
913+
device_get_dma_attr(&hv_acpi_dev->dev) == DEV_DMA_COHERENT);
914+
907915
dev_id = hv_vmbus_get_id(drv, dev);
908916
if (drv->probe) {
909917
ret = drv->probe(dev, dev_id);
@@ -2430,6 +2438,21 @@ static int vmbus_acpi_add(struct acpi_device *device)
24302438

24312439
hv_acpi_dev = device;
24322440

2441+
/*
2442+
* Older versions of Hyper-V for ARM64 fail to include the _CCA
2443+
* method on the top level VMbus device in the DSDT. But devices
2444+
* are hardware coherent in all current Hyper-V use cases, so fix
2445+
* up the ACPI device to behave as if _CCA is present and indicates
2446+
* hardware coherence.
2447+
*/
2448+
ACPI_COMPANION_SET(&device->dev, device);
2449+
if (IS_ENABLED(CONFIG_ACPI_CCA_REQUIRED) &&
2450+
device_get_dma_attr(&device->dev) == DEV_DMA_NOT_SUPPORTED) {
2451+
pr_info("No ACPI _CCA found; assuming coherent device I/O\n");
2452+
device->flags.cca_seen = true;
2453+
device->flags.coherent_dma = true;
2454+
}
2455+
24332456
result = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
24342457
vmbus_walk_resources, NULL);
24352458

include/asm-generic/mshyperv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ enum hv_isolation_type hv_get_isolation_type(void);
256256
bool hv_is_isolation_supported(void);
257257
void hyperv_cleanup(void);
258258
bool hv_query_ext_cap(u64 cap_query);
259+
void hv_setup_dma_ops(struct device *dev, bool coherent);
259260
#else /* CONFIG_HYPERV */
260261
static inline bool hv_is_hyperv_initialized(void) { return false; }
261262
static inline bool hv_is_hibernation_supported(void) { return false; }

0 commit comments

Comments
 (0)