mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-15 12:54:27 +00:00
Hyper-V: vmbus: implementat bus_get_dma_tag in vmbus
In ARM64 Hyper-V UFS filesystem is getting corruption and those corruptions are consistently happening just after hitting a page boundary. It is unable to correctly read disk blocks into buffers that are not aligned to 512-byte boundaries. It happens because storvsc needs physically contiguous memory which may not be the case when bus_dma needs to create a bounce buffer. This can happen when the destination is not cache-line aligned. Hyper-V VMs have VMbus synthetic devices and PCI pass-thru devices that are added dynamically via the VMbus protocol and are not represented in the ACPI DSDT. Only the top level VMbus node exists in the DSDT. As such, on ARM64 these devices don't pick up coherence information and default to not hardware coherent. PR: 267654, 272666 Reviewed by: andrew, whu Tested by: lwhsu MFC after: 3 days Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D41728
This commit is contained in:
parent
9c30461dd2
commit
e7a9817b8d
|
@ -137,6 +137,7 @@ static void vmbus_intr_teardown(struct vmbus_softc *);
|
|||
static int vmbus_doattach(struct vmbus_softc *);
|
||||
static void vmbus_event_proc_dummy(struct vmbus_softc *,
|
||||
int);
|
||||
static bus_dma_tag_t vmbus_get_dma_tag(device_t parent, device_t child);
|
||||
static struct vmbus_softc *vmbus_sc;
|
||||
|
||||
SYSCTL_NODE(_hw, OID_AUTO, vmbus, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL,
|
||||
|
@ -183,6 +184,7 @@ static device_method_t vmbus_methods[] = {
|
|||
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
|
||||
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
|
||||
DEVMETHOD(bus_get_cpus, bus_generic_get_cpus),
|
||||
DEVMETHOD(bus_get_dma_tag, vmbus_get_dma_tag),
|
||||
|
||||
/* pcib interface */
|
||||
DEVMETHOD(pcib_alloc_msi, vmbus_alloc_msi),
|
||||
|
@ -219,6 +221,13 @@ vmbus_get_softc(void)
|
|||
return vmbus_sc;
|
||||
}
|
||||
|
||||
static bus_dma_tag_t
|
||||
vmbus_get_dma_tag(device_t dev, device_t child)
|
||||
{
|
||||
struct vmbus_softc *sc = vmbus_get_softc();
|
||||
return (sc->dmat);
|
||||
}
|
||||
|
||||
void
|
||||
vmbus_msghc_reset(struct vmbus_msghc *mh, size_t dsize)
|
||||
{
|
||||
|
@ -1382,6 +1391,9 @@ vmbus_doattach(struct vmbus_softc *sc)
|
|||
struct sysctl_oid_list *child;
|
||||
struct sysctl_ctx_list *ctx;
|
||||
int ret;
|
||||
device_t dev_res;
|
||||
ACPI_HANDLE handle;
|
||||
unsigned int coherent;
|
||||
|
||||
if (sc->vmbus_flags & VMBUS_FLAG_ATTACHED)
|
||||
return (0);
|
||||
|
@ -1402,6 +1414,27 @@ vmbus_doattach(struct vmbus_softc *sc)
|
|||
sizeof(struct vmbus_channel *) * VMBUS_CHAN_MAX, M_DEVBUF,
|
||||
M_WAITOK | M_ZERO);
|
||||
|
||||
/* Coherency attribute */
|
||||
dev_res = devclass_get_device(devclass_find("vmbus_res"), 0);
|
||||
handle = acpi_get_handle(dev_res);
|
||||
|
||||
if (ACPI_FAILURE(acpi_GetInteger(handle, "_CCA", &coherent)))
|
||||
coherent = 0;
|
||||
if (bootverbose)
|
||||
device_printf(sc->vmbus_dev, "Bus is%s cache-coherent\n",
|
||||
coherent ? "" : " not");
|
||||
|
||||
bus_dma_tag_create(bus_get_dma_tag(sc->vmbus_dev),
|
||||
1, 0,
|
||||
BUS_SPACE_MAXADDR,
|
||||
BUS_SPACE_MAXADDR,
|
||||
NULL, NULL,
|
||||
BUS_SPACE_MAXSIZE,
|
||||
BUS_SPACE_UNRESTRICTED,
|
||||
BUS_SPACE_MAXSIZE,
|
||||
coherent ? BUS_DMA_COHERENT : 0,
|
||||
NULL, NULL,
|
||||
&sc->dmat);
|
||||
/*
|
||||
* Create context for "post message" Hypercalls
|
||||
*/
|
||||
|
|
|
@ -129,6 +129,7 @@ struct vmbus_softc {
|
|||
void *icookie;
|
||||
int vector;
|
||||
#endif
|
||||
bus_dma_tag_t dmat;
|
||||
};
|
||||
|
||||
#define VMBUS_FLAG_ATTACHED 0x0001 /* vmbus was attached */
|
||||
|
|
Loading…
Reference in a new issue