Switch to contigmalloc in the Hyper-V code
In the Hyper-V drivers we need to allocate buffers shared between the host and guest. This memory has been allocated with bus_dma, however it doesn't use this correctly, e.g. it is missing calls to bus_dmamap_sync. Along with this on arm64 we need this memory to be mapped with the correct memory type that bus_dma may not use. Switch to contigmalloc to allocate this memory as this will correctly allocate cacheable memory. Reviewed by: Souradeep Chakrabarti <schakrabarti@microsoft.com> Sponsored by: Arm Ltd Differential Revision: https://reviews.freebsd.org/D40227
This commit is contained in:
parent
657aec455f
commit
62f9bcf2b4
@ -41,9 +41,5 @@ struct hyperv_dma {
|
|||||||
|
|
||||||
void hyperv_dma_map_paddr(void *arg, bus_dma_segment_t *segs,
|
void hyperv_dma_map_paddr(void *arg, bus_dma_segment_t *segs,
|
||||||
int nseg, int error);
|
int nseg, int error);
|
||||||
void *hyperv_dmamem_alloc(bus_dma_tag_t parent_dtag,
|
|
||||||
bus_size_t alignment, bus_addr_t boundary, bus_size_t size,
|
|
||||||
struct hyperv_dma *dma, int flags);
|
|
||||||
void hyperv_dmamem_free(struct hyperv_dma *dma, void *ptr);
|
|
||||||
|
|
||||||
#endif /* !_HYPERV_BUSDMA_H_ */
|
#endif /* !_HYPERV_BUSDMA_H_ */
|
||||||
|
@ -43,6 +43,10 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
#include <sys/taskqueue.h>
|
#include <sys/taskqueue.h>
|
||||||
|
|
||||||
|
#include <vm/vm.h>
|
||||||
|
#include <vm/vm_extern.h>
|
||||||
|
#include <vm/pmap.h>
|
||||||
|
|
||||||
#include <net/ethernet.h>
|
#include <net/ethernet.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <net/if_var.h>
|
#include <net/if_var.h>
|
||||||
@ -52,7 +56,6 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <netinet/tcp_lro.h>
|
#include <netinet/tcp_lro.h>
|
||||||
|
|
||||||
#include <dev/hyperv/include/hyperv.h>
|
#include <dev/hyperv/include/hyperv.h>
|
||||||
#include <dev/hyperv/include/hyperv_busdma.h>
|
|
||||||
#include <dev/hyperv/include/vmbus.h>
|
#include <dev/hyperv/include/vmbus.h>
|
||||||
#include <dev/hyperv/include/vmbus_xact.h>
|
#include <dev/hyperv/include/vmbus_xact.h>
|
||||||
|
|
||||||
@ -166,7 +169,8 @@ hn_nvs_conn_rxbuf(struct hn_softc *sc)
|
|||||||
* just share this RXBUF.
|
* just share this RXBUF.
|
||||||
*/
|
*/
|
||||||
error = vmbus_chan_gpadl_connect(sc->hn_prichan,
|
error = vmbus_chan_gpadl_connect(sc->hn_prichan,
|
||||||
sc->hn_rxbuf_dma.hv_paddr, rxbuf_size, &sc->hn_rxbuf_gpadl);
|
pmap_kextract((vm_offset_t)sc->hn_rxbuf), rxbuf_size,
|
||||||
|
&sc->hn_rxbuf_gpadl);
|
||||||
if (error) {
|
if (error) {
|
||||||
if_printf(sc->hn_ifp, "rxbuf gpadl conn failed: %d\n",
|
if_printf(sc->hn_ifp, "rxbuf gpadl conn failed: %d\n",
|
||||||
error);
|
error);
|
||||||
@ -235,7 +239,8 @@ hn_nvs_conn_chim(struct hn_softc *sc)
|
|||||||
* Sub-channels just share this chimney sending buffer.
|
* Sub-channels just share this chimney sending buffer.
|
||||||
*/
|
*/
|
||||||
error = vmbus_chan_gpadl_connect(sc->hn_prichan,
|
error = vmbus_chan_gpadl_connect(sc->hn_prichan,
|
||||||
sc->hn_chim_dma.hv_paddr, HN_CHIM_SIZE, &sc->hn_chim_gpadl);
|
pmap_kextract((vm_offset_t)sc->hn_chim), HN_CHIM_SIZE,
|
||||||
|
&sc->hn_chim_gpadl);
|
||||||
if (error) {
|
if (error) {
|
||||||
if_printf(sc->hn_ifp, "chim gpadl conn failed: %d\n", error);
|
if_printf(sc->hn_ifp, "chim gpadl conn failed: %d\n", error);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
@ -50,7 +50,6 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <netinet/tcp_lro.h>
|
#include <netinet/tcp_lro.h>
|
||||||
|
|
||||||
#include <dev/hyperv/include/hyperv.h>
|
#include <dev/hyperv/include/hyperv.h>
|
||||||
#include <dev/hyperv/include/hyperv_busdma.h>
|
|
||||||
#include <dev/hyperv/include/vmbus.h>
|
#include <dev/hyperv/include/vmbus.h>
|
||||||
#include <dev/hyperv/include/vmbus_xact.h>
|
#include <dev/hyperv/include/vmbus_xact.h>
|
||||||
|
|
||||||
|
@ -85,6 +85,10 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/eventhandler.h>
|
#include <sys/eventhandler.h>
|
||||||
#include <sys/epoch.h>
|
#include <sys/epoch.h>
|
||||||
|
|
||||||
|
#include <vm/vm.h>
|
||||||
|
#include <vm/vm_extern.h>
|
||||||
|
#include <vm/pmap.h>
|
||||||
|
|
||||||
#include <machine/atomic.h>
|
#include <machine/atomic.h>
|
||||||
#include <machine/in_cksum.h>
|
#include <machine/in_cksum.h>
|
||||||
|
|
||||||
@ -4984,9 +4988,8 @@ hn_create_rx_data(struct hn_softc *sc, int ring_cnt)
|
|||||||
* - A large enough buffer is allocated, certain version of NVSes
|
* - A large enough buffer is allocated, certain version of NVSes
|
||||||
* may further limit the usable space.
|
* may further limit the usable space.
|
||||||
*/
|
*/
|
||||||
sc->hn_rxbuf = hyperv_dmamem_alloc(bus_get_dma_tag(dev),
|
sc->hn_rxbuf = contigmalloc(HN_RXBUF_SIZE, M_DEVBUF, M_WAITOK | M_ZERO,
|
||||||
PAGE_SIZE, 0, HN_RXBUF_SIZE, &sc->hn_rxbuf_dma,
|
0ul, ~0ul, PAGE_SIZE, 0);
|
||||||
BUS_DMA_WAITOK | BUS_DMA_ZERO);
|
|
||||||
if (sc->hn_rxbuf == NULL) {
|
if (sc->hn_rxbuf == NULL) {
|
||||||
device_printf(sc->hn_dev, "allocate rxbuf failed\n");
|
device_printf(sc->hn_dev, "allocate rxbuf failed\n");
|
||||||
return (ENOMEM);
|
return (ENOMEM);
|
||||||
@ -5016,9 +5019,8 @@ hn_create_rx_data(struct hn_softc *sc, int ring_cnt)
|
|||||||
for (i = 0; i < sc->hn_rx_ring_cnt; ++i) {
|
for (i = 0; i < sc->hn_rx_ring_cnt; ++i) {
|
||||||
struct hn_rx_ring *rxr = &sc->hn_rx_ring[i];
|
struct hn_rx_ring *rxr = &sc->hn_rx_ring[i];
|
||||||
|
|
||||||
rxr->hn_br = hyperv_dmamem_alloc(bus_get_dma_tag(dev),
|
rxr->hn_br = contigmalloc(HN_TXBR_SIZE + HN_RXBR_SIZE, M_DEVBUF,
|
||||||
PAGE_SIZE, 0, HN_TXBR_SIZE + HN_RXBR_SIZE,
|
M_WAITOK | M_ZERO, 0ul, ~0ul, PAGE_SIZE, 0);
|
||||||
&rxr->hn_br_dma, BUS_DMA_WAITOK);
|
|
||||||
if (rxr->hn_br == NULL) {
|
if (rxr->hn_br == NULL) {
|
||||||
device_printf(dev, "allocate bufring failed\n");
|
device_printf(dev, "allocate bufring failed\n");
|
||||||
return (ENOMEM);
|
return (ENOMEM);
|
||||||
@ -5171,7 +5173,7 @@ hn_destroy_rx_data(struct hn_softc *sc)
|
|||||||
|
|
||||||
if (sc->hn_rxbuf != NULL) {
|
if (sc->hn_rxbuf != NULL) {
|
||||||
if ((sc->hn_flags & HN_FLAG_RXBUF_REF) == 0)
|
if ((sc->hn_flags & HN_FLAG_RXBUF_REF) == 0)
|
||||||
hyperv_dmamem_free(&sc->hn_rxbuf_dma, sc->hn_rxbuf);
|
contigfree(sc->hn_rxbuf, HN_RXBUF_SIZE, M_DEVBUF);
|
||||||
else
|
else
|
||||||
device_printf(sc->hn_dev, "RXBUF is referenced\n");
|
device_printf(sc->hn_dev, "RXBUF is referenced\n");
|
||||||
sc->hn_rxbuf = NULL;
|
sc->hn_rxbuf = NULL;
|
||||||
@ -5186,7 +5188,8 @@ hn_destroy_rx_data(struct hn_softc *sc)
|
|||||||
if (rxr->hn_br == NULL)
|
if (rxr->hn_br == NULL)
|
||||||
continue;
|
continue;
|
||||||
if ((rxr->hn_rx_flags & HN_RX_FLAG_BR_REF) == 0) {
|
if ((rxr->hn_rx_flags & HN_RX_FLAG_BR_REF) == 0) {
|
||||||
hyperv_dmamem_free(&rxr->hn_br_dma, rxr->hn_br);
|
contigfree(rxr->hn_br, HN_TXBR_SIZE + HN_RXBR_SIZE,
|
||||||
|
M_DEVBUF);
|
||||||
} else {
|
} else {
|
||||||
device_printf(sc->hn_dev,
|
device_printf(sc->hn_dev,
|
||||||
"%dth channel bufring is referenced", i);
|
"%dth channel bufring is referenced", i);
|
||||||
@ -5491,9 +5494,8 @@ hn_create_tx_data(struct hn_softc *sc, int ring_cnt)
|
|||||||
*
|
*
|
||||||
* NOTE: It is shared by all channels.
|
* NOTE: It is shared by all channels.
|
||||||
*/
|
*/
|
||||||
sc->hn_chim = hyperv_dmamem_alloc(bus_get_dma_tag(sc->hn_dev),
|
sc->hn_chim = contigmalloc(HN_CHIM_SIZE, M_DEVBUF, M_WAITOK | M_ZERO,
|
||||||
PAGE_SIZE, 0, HN_CHIM_SIZE, &sc->hn_chim_dma,
|
0ul, ~0ul, PAGE_SIZE, 0);
|
||||||
BUS_DMA_WAITOK | BUS_DMA_ZERO);
|
|
||||||
if (sc->hn_chim == NULL) {
|
if (sc->hn_chim == NULL) {
|
||||||
device_printf(sc->hn_dev, "allocate txbuf failed\n");
|
device_printf(sc->hn_dev, "allocate txbuf failed\n");
|
||||||
return (ENOMEM);
|
return (ENOMEM);
|
||||||
@ -5689,7 +5691,7 @@ hn_destroy_tx_data(struct hn_softc *sc)
|
|||||||
|
|
||||||
if (sc->hn_chim != NULL) {
|
if (sc->hn_chim != NULL) {
|
||||||
if ((sc->hn_flags & HN_FLAG_CHIM_REF) == 0) {
|
if ((sc->hn_flags & HN_FLAG_CHIM_REF) == 0) {
|
||||||
hyperv_dmamem_free(&sc->hn_chim_dma, sc->hn_chim);
|
contigfree(sc->hn_chim, HN_CHIM_SIZE, M_DEVBUF);
|
||||||
} else {
|
} else {
|
||||||
device_printf(sc->hn_dev,
|
device_printf(sc->hn_dev,
|
||||||
"chimney sending buffer is referenced");
|
"chimney sending buffer is referenced");
|
||||||
@ -6263,7 +6265,7 @@ hn_chan_attach(struct hn_softc *sc, struct vmbus_channel *chan)
|
|||||||
* Open this channel
|
* Open this channel
|
||||||
*/
|
*/
|
||||||
cbr.cbr = rxr->hn_br;
|
cbr.cbr = rxr->hn_br;
|
||||||
cbr.cbr_paddr = rxr->hn_br_dma.hv_paddr;
|
cbr.cbr_paddr = pmap_kextract((vm_offset_t)rxr->hn_br);
|
||||||
cbr.cbr_txsz = HN_TXBR_SIZE;
|
cbr.cbr_txsz = HN_TXBR_SIZE;
|
||||||
cbr.cbr_rxsz = HN_RXBR_SIZE;
|
cbr.cbr_rxsz = HN_RXBR_SIZE;
|
||||||
error = vmbus_chan_open_br(chan, &cbr, NULL, 0, hn_chan_callback, rxr);
|
error = vmbus_chan_open_br(chan, &cbr, NULL, 0, hn_chan_callback, rxr);
|
||||||
|
@ -102,7 +102,6 @@ struct hn_rx_ring {
|
|||||||
struct sysctl_oid *hn_rx_sysctl_tree;
|
struct sysctl_oid *hn_rx_sysctl_tree;
|
||||||
|
|
||||||
void *hn_br; /* TX/RX bufring */
|
void *hn_br; /* TX/RX bufring */
|
||||||
struct hyperv_dma hn_br_dma;
|
|
||||||
|
|
||||||
struct vmbus_channel *hn_chan;
|
struct vmbus_channel *hn_chan;
|
||||||
} __aligned(CACHE_LINE_SIZE);
|
} __aligned(CACHE_LINE_SIZE);
|
||||||
@ -242,10 +241,8 @@ struct hn_softc {
|
|||||||
|
|
||||||
void *hn_rxbuf;
|
void *hn_rxbuf;
|
||||||
uint32_t hn_rxbuf_gpadl;
|
uint32_t hn_rxbuf_gpadl;
|
||||||
struct hyperv_dma hn_rxbuf_dma;
|
|
||||||
|
|
||||||
uint32_t hn_chim_gpadl;
|
uint32_t hn_chim_gpadl;
|
||||||
struct hyperv_dma hn_chim_dma;
|
|
||||||
|
|
||||||
uint32_t hn_rndis_rid;
|
uint32_t hn_rndis_rid;
|
||||||
uint32_t hn_ndis_ver;
|
uint32_t hn_ndis_ver;
|
||||||
|
@ -77,7 +77,6 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <dev/acpica/acpi_pcibvar.h>
|
#include <dev/acpica/acpi_pcibvar.h>
|
||||||
#endif
|
#endif
|
||||||
#include <dev/hyperv/include/hyperv.h>
|
#include <dev/hyperv/include/hyperv.h>
|
||||||
#include <dev/hyperv/include/hyperv_busdma.h>
|
|
||||||
#include <dev/hyperv/include/vmbus_xact.h>
|
#include <dev/hyperv/include/vmbus_xact.h>
|
||||||
#include <dev/hyperv/vmbus/vmbus_reg.h>
|
#include <dev/hyperv/vmbus/vmbus_reg.h>
|
||||||
#include <dev/hyperv/vmbus/vmbus_chanvar.h>
|
#include <dev/hyperv/vmbus/vmbus_chanvar.h>
|
||||||
|
@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/conf.h>
|
#include <sys/conf.h>
|
||||||
#include <sys/fcntl.h>
|
#include <sys/fcntl.h>
|
||||||
#include <sys/kernel.h>
|
#include <sys/kernel.h>
|
||||||
|
#include <sys/malloc.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
#include <sys/timetc.h>
|
#include <sys/timetc.h>
|
||||||
#include <sys/vdso.h>
|
#include <sys/vdso.h>
|
||||||
@ -41,6 +42,8 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <machine/specialreg.h>
|
#include <machine/specialreg.h>
|
||||||
|
|
||||||
#include <vm/vm.h>
|
#include <vm/vm.h>
|
||||||
|
#include <vm/vm_extern.h>
|
||||||
|
#include <vm/pmap.h>
|
||||||
|
|
||||||
#include <dev/hyperv/include/hyperv.h>
|
#include <dev/hyperv/include/hyperv.h>
|
||||||
#include <dev/hyperv/include/hyperv_busdma.h>
|
#include <dev/hyperv/include/hyperv_busdma.h>
|
||||||
@ -51,7 +54,6 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
struct hyperv_reftsc_ctx {
|
struct hyperv_reftsc_ctx {
|
||||||
struct hyperv_reftsc *tsc_ref;
|
struct hyperv_reftsc *tsc_ref;
|
||||||
struct hyperv_dma tsc_ref_dma;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint32_t hyperv_tsc_vdso_timehands(
|
static uint32_t hyperv_tsc_vdso_timehands(
|
||||||
@ -117,7 +119,7 @@ hyperv_tsc_mmap(struct cdev *dev __unused, vm_ooffset_t offset,
|
|||||||
if (offset != 0)
|
if (offset != 0)
|
||||||
return (EOPNOTSUPP);
|
return (EOPNOTSUPP);
|
||||||
|
|
||||||
*paddr = hyperv_ref_tsc.tsc_ref_dma.hv_paddr;
|
*paddr = pmap_kextract((vm_offset_t)hyperv_ref_tsc.tsc_ref);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,18 +210,17 @@ hyperv_tsc_tcinit(void *dummy __unused)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
hyperv_ref_tsc.tsc_ref = hyperv_dmamem_alloc(NULL, PAGE_SIZE, 0,
|
hyperv_ref_tsc.tsc_ref = contigmalloc(PAGE_SIZE, M_DEVBUF,
|
||||||
sizeof(struct hyperv_reftsc), &hyperv_ref_tsc.tsc_ref_dma,
|
M_WAITOK | M_ZERO, 0ul, ~0ul, PAGE_SIZE, 0);
|
||||||
BUS_DMA_WAITOK | BUS_DMA_ZERO);
|
|
||||||
if (hyperv_ref_tsc.tsc_ref == NULL) {
|
if (hyperv_ref_tsc.tsc_ref == NULL) {
|
||||||
printf("hyperv: reftsc page allocation failed\n");
|
printf("hyperv: reftsc page allocation failed\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
orig = rdmsr(MSR_HV_REFERENCE_TSC);
|
orig = rdmsr(MSR_HV_REFERENCE_TSC);
|
||||||
val = MSR_HV_REFTSC_ENABLE | (orig & MSR_HV_REFTSC_RSVD_MASK) |
|
val = (pmap_kextract((vm_offset_t)hyperv_ref_tsc.tsc_ref) >>
|
||||||
((hyperv_ref_tsc.tsc_ref_dma.hv_paddr >> PAGE_SHIFT) <<
|
PAGE_SHIFT) << MSR_HV_REFTSC_PGSHIFT;
|
||||||
MSR_HV_REFTSC_PGSHIFT);
|
val |= MSR_HV_REFTSC_ENABLE | (orig & MSR_HV_REFTSC_RSVD_MASK);
|
||||||
wrmsr(MSR_HV_REFERENCE_TSC, val);
|
wrmsr(MSR_HV_REFERENCE_TSC, val);
|
||||||
|
|
||||||
/* Register "enlightened" timecounter. */
|
/* Register "enlightened" timecounter. */
|
||||||
|
@ -49,50 +49,3 @@ hyperv_dma_map_paddr(void *arg, bus_dma_segment_t *segs, int nseg, int error)
|
|||||||
*paddr = segs->ds_addr;
|
*paddr = segs->ds_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
|
||||||
hyperv_dmamem_alloc(bus_dma_tag_t parent_dtag, bus_size_t alignment,
|
|
||||||
bus_addr_t boundary, bus_size_t size, struct hyperv_dma *dma, int flags)
|
|
||||||
{
|
|
||||||
void *ret;
|
|
||||||
int error;
|
|
||||||
|
|
||||||
error = bus_dma_tag_create(parent_dtag, /* parent */
|
|
||||||
alignment, /* alignment */
|
|
||||||
boundary, /* boundary */
|
|
||||||
BUS_SPACE_MAXADDR, /* lowaddr */
|
|
||||||
BUS_SPACE_MAXADDR, /* highaddr */
|
|
||||||
NULL, NULL, /* filter, filterarg */
|
|
||||||
size, /* maxsize */
|
|
||||||
1, /* nsegments */
|
|
||||||
size, /* maxsegsize */
|
|
||||||
0, /* flags */
|
|
||||||
NULL, /* lockfunc */
|
|
||||||
NULL, /* lockfuncarg */
|
|
||||||
&dma->hv_dtag);
|
|
||||||
if (error)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
error = bus_dmamem_alloc(dma->hv_dtag, &ret,
|
|
||||||
(flags & HYPERV_DMA_MASK) | BUS_DMA_COHERENT, &dma->hv_dmap);
|
|
||||||
if (error) {
|
|
||||||
bus_dma_tag_destroy(dma->hv_dtag);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = bus_dmamap_load(dma->hv_dtag, dma->hv_dmap, ret, size,
|
|
||||||
hyperv_dma_map_paddr, &dma->hv_paddr, BUS_DMA_NOWAIT);
|
|
||||||
if (error) {
|
|
||||||
bus_dmamem_free(dma->hv_dtag, ret, dma->hv_dmap);
|
|
||||||
bus_dma_tag_destroy(dma->hv_dtag);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
hyperv_dmamem_free(struct hyperv_dma *dma, void *ptr)
|
|
||||||
{
|
|
||||||
bus_dmamap_unload(dma->hv_dtag, dma->hv_dmap);
|
|
||||||
bus_dmamem_free(dma->hv_dtag, ptr, dma->hv_dmap);
|
|
||||||
bus_dma_tag_destroy(dma->hv_dtag);
|
|
||||||
}
|
|
||||||
|
@ -61,10 +61,12 @@
|
|||||||
#define MSR_HV_SIEFP_ENABLE 0x0001ULL
|
#define MSR_HV_SIEFP_ENABLE 0x0001ULL
|
||||||
#define MSR_HV_SIEFP_RSVD_MASK 0x0ffeULL
|
#define MSR_HV_SIEFP_RSVD_MASK 0x0ffeULL
|
||||||
#define MSR_HV_SIEFP_PGSHIFT 12
|
#define MSR_HV_SIEFP_PGSHIFT 12
|
||||||
|
#define MSR_HV_SIEFP_PGMASK (~0ULL << MSR_HV_SIEFP_PGSHIFT)
|
||||||
|
|
||||||
#define MSR_HV_SIMP_ENABLE 0x0001ULL
|
#define MSR_HV_SIMP_ENABLE 0x0001ULL
|
||||||
#define MSR_HV_SIMP_RSVD_MASK 0x0ffeULL
|
#define MSR_HV_SIMP_RSVD_MASK 0x0ffeULL
|
||||||
#define MSR_HV_SIMP_PGSHIFT 12
|
#define MSR_HV_SIMP_PGSHIFT 12
|
||||||
|
#define MSR_HV_SIMP_PGMASK (~0ULL << MSR_HV_SIMP_PGSHIFT)
|
||||||
|
|
||||||
#define MSR_HV_SINT_VECTOR_MASK 0x00ffULL
|
#define MSR_HV_SINT_VECTOR_MASK 0x00ffULL
|
||||||
#define MSR_HV_SINT_RSVD1_MASK 0xff00ULL
|
#define MSR_HV_SINT_RSVD1_MASK 0xff00ULL
|
||||||
|
@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/taskqueue.h>
|
#include <sys/taskqueue.h>
|
||||||
|
|
||||||
#include <vm/vm.h>
|
#include <vm/vm.h>
|
||||||
|
#include <vm/vm_extern.h>
|
||||||
#include <vm/vm_param.h>
|
#include <vm/vm_param.h>
|
||||||
#include <vm/pmap.h>
|
#include <vm/pmap.h>
|
||||||
|
|
||||||
@ -425,9 +426,9 @@ vmbus_connect(struct vmbus_softc *sc, uint32_t version)
|
|||||||
req = vmbus_msghc_dataptr(mh);
|
req = vmbus_msghc_dataptr(mh);
|
||||||
req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CONNECT;
|
req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CONNECT;
|
||||||
req->chm_ver = version;
|
req->chm_ver = version;
|
||||||
req->chm_evtflags = sc->vmbus_evtflags_dma.hv_paddr;
|
req->chm_evtflags = pmap_kextract((vm_offset_t)sc->vmbus_evtflags);
|
||||||
req->chm_mnf1 = sc->vmbus_mnf1_dma.hv_paddr;
|
req->chm_mnf1 = pmap_kextract((vm_offset_t)sc->vmbus_mnf1);
|
||||||
req->chm_mnf2 = sc->vmbus_mnf2_dma.hv_paddr;
|
req->chm_mnf2 = pmap_kextract((vm_offset_t)sc->vmbus_mnf2);
|
||||||
|
|
||||||
error = vmbus_msghc_exec(sc, mh);
|
error = vmbus_msghc_exec(sc, mh);
|
||||||
if (error) {
|
if (error) {
|
||||||
@ -744,17 +745,17 @@ vmbus_synic_setup(void *xsc)
|
|||||||
* Setup the SynIC message.
|
* Setup the SynIC message.
|
||||||
*/
|
*/
|
||||||
orig = RDMSR(MSR_HV_SIMP);
|
orig = RDMSR(MSR_HV_SIMP);
|
||||||
val = MSR_HV_SIMP_ENABLE | (orig & MSR_HV_SIMP_RSVD_MASK) |
|
val = pmap_kextract((vm_offset_t)VMBUS_PCPU_GET(sc, message, cpu)) &
|
||||||
((VMBUS_PCPU_GET(sc, message_dma.hv_paddr, cpu) >> PAGE_SHIFT)
|
MSR_HV_SIMP_PGMASK;
|
||||||
<< MSR_HV_SIMP_PGSHIFT);
|
val |= MSR_HV_SIMP_ENABLE | (orig & MSR_HV_SIMP_RSVD_MASK);
|
||||||
WRMSR(MSR_HV_SIMP, val);
|
WRMSR(MSR_HV_SIMP, val);
|
||||||
/*
|
/*
|
||||||
* Setup the SynIC event flags.
|
* Setup the SynIC event flags.
|
||||||
*/
|
*/
|
||||||
orig = RDMSR(MSR_HV_SIEFP);
|
orig = RDMSR(MSR_HV_SIEFP);
|
||||||
val = MSR_HV_SIEFP_ENABLE | (orig & MSR_HV_SIEFP_RSVD_MASK) |
|
val = pmap_kextract((vm_offset_t)VMBUS_PCPU_GET(sc, event_flags, cpu)) &
|
||||||
((VMBUS_PCPU_GET(sc, event_flags_dma.hv_paddr, cpu) >> PAGE_SHIFT)
|
MSR_HV_SIMP_PGMASK;
|
||||||
<< MSR_HV_SIEFP_PGSHIFT);
|
val |= MSR_HV_SIEFP_ENABLE | (orig & MSR_HV_SIEFP_RSVD_MASK);
|
||||||
WRMSR(MSR_HV_SIEFP, val);
|
WRMSR(MSR_HV_SIEFP, val);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -817,48 +818,43 @@ vmbus_synic_teardown(void *arg)
|
|||||||
static int
|
static int
|
||||||
vmbus_dma_alloc(struct vmbus_softc *sc)
|
vmbus_dma_alloc(struct vmbus_softc *sc)
|
||||||
{
|
{
|
||||||
bus_dma_tag_t parent_dtag;
|
|
||||||
uint8_t *evtflags;
|
uint8_t *evtflags;
|
||||||
int cpu;
|
int cpu;
|
||||||
|
|
||||||
parent_dtag = bus_get_dma_tag(sc->vmbus_dev);
|
|
||||||
CPU_FOREACH(cpu) {
|
CPU_FOREACH(cpu) {
|
||||||
void *ptr;
|
void *ptr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Per-cpu messages and event flags.
|
* Per-cpu messages and event flags.
|
||||||
*/
|
*/
|
||||||
ptr = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
|
ptr = contigmalloc(PAGE_SIZE, M_DEVBUF, M_WAITOK | M_ZERO,
|
||||||
PAGE_SIZE, VMBUS_PCPU_PTR(sc, message_dma, cpu),
|
0ul, ~0ul, PAGE_SIZE, 0);
|
||||||
BUS_DMA_WAITOK | BUS_DMA_ZERO);
|
|
||||||
if (ptr == NULL)
|
if (ptr == NULL)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
VMBUS_PCPU_GET(sc, message, cpu) = ptr;
|
VMBUS_PCPU_GET(sc, message, cpu) = ptr;
|
||||||
|
|
||||||
ptr = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
|
ptr = contigmalloc(PAGE_SIZE, M_DEVBUF, M_WAITOK | M_ZERO,
|
||||||
PAGE_SIZE, VMBUS_PCPU_PTR(sc, event_flags_dma, cpu),
|
0ul, ~0ul, PAGE_SIZE, 0);
|
||||||
BUS_DMA_WAITOK | BUS_DMA_ZERO);
|
|
||||||
if (ptr == NULL)
|
if (ptr == NULL)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
VMBUS_PCPU_GET(sc, event_flags, cpu) = ptr;
|
VMBUS_PCPU_GET(sc, event_flags, cpu) = ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
evtflags = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
|
evtflags = contigmalloc(PAGE_SIZE, M_DEVBUF, M_WAITOK | M_ZERO,
|
||||||
PAGE_SIZE, &sc->vmbus_evtflags_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO);
|
0ul, ~0ul, PAGE_SIZE, 0);
|
||||||
if (evtflags == NULL)
|
if (evtflags == NULL)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
sc->vmbus_rx_evtflags = (u_long *)evtflags;
|
sc->vmbus_rx_evtflags = (u_long *)evtflags;
|
||||||
sc->vmbus_tx_evtflags = (u_long *)(evtflags + (PAGE_SIZE / 2));
|
sc->vmbus_tx_evtflags = (u_long *)(evtflags + (PAGE_SIZE / 2));
|
||||||
sc->vmbus_evtflags = evtflags;
|
sc->vmbus_evtflags = evtflags;
|
||||||
|
|
||||||
sc->vmbus_mnf1 = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
|
sc->vmbus_mnf1 = contigmalloc(PAGE_SIZE, M_DEVBUF, M_WAITOK | M_ZERO,
|
||||||
PAGE_SIZE, &sc->vmbus_mnf1_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO);
|
0ul, ~0ul, PAGE_SIZE, 0);
|
||||||
if (sc->vmbus_mnf1 == NULL)
|
if (sc->vmbus_mnf1 == NULL)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
|
||||||
sc->vmbus_mnf2 = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
|
sc->vmbus_mnf2 = contigmalloc(sizeof(struct vmbus_mnf), M_DEVBUF,
|
||||||
sizeof(struct vmbus_mnf), &sc->vmbus_mnf2_dma,
|
M_WAITOK | M_ZERO, 0ul, ~0ul, PAGE_SIZE, 0);
|
||||||
BUS_DMA_WAITOK | BUS_DMA_ZERO);
|
|
||||||
if (sc->vmbus_mnf2 == NULL)
|
if (sc->vmbus_mnf2 == NULL)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
|
||||||
@ -871,31 +867,29 @@ vmbus_dma_free(struct vmbus_softc *sc)
|
|||||||
int cpu;
|
int cpu;
|
||||||
|
|
||||||
if (sc->vmbus_evtflags != NULL) {
|
if (sc->vmbus_evtflags != NULL) {
|
||||||
hyperv_dmamem_free(&sc->vmbus_evtflags_dma, sc->vmbus_evtflags);
|
contigfree(sc->vmbus_evtflags, PAGE_SIZE, M_DEVBUF);
|
||||||
sc->vmbus_evtflags = NULL;
|
sc->vmbus_evtflags = NULL;
|
||||||
sc->vmbus_rx_evtflags = NULL;
|
sc->vmbus_rx_evtflags = NULL;
|
||||||
sc->vmbus_tx_evtflags = NULL;
|
sc->vmbus_tx_evtflags = NULL;
|
||||||
}
|
}
|
||||||
if (sc->vmbus_mnf1 != NULL) {
|
if (sc->vmbus_mnf1 != NULL) {
|
||||||
hyperv_dmamem_free(&sc->vmbus_mnf1_dma, sc->vmbus_mnf1);
|
contigfree(sc->vmbus_mnf1, PAGE_SIZE, M_DEVBUF);
|
||||||
sc->vmbus_mnf1 = NULL;
|
sc->vmbus_mnf1 = NULL;
|
||||||
}
|
}
|
||||||
if (sc->vmbus_mnf2 != NULL) {
|
if (sc->vmbus_mnf2 != NULL) {
|
||||||
hyperv_dmamem_free(&sc->vmbus_mnf2_dma, sc->vmbus_mnf2);
|
contigfree(sc->vmbus_mnf2, sizeof(struct vmbus_mnf), M_DEVBUF);
|
||||||
sc->vmbus_mnf2 = NULL;
|
sc->vmbus_mnf2 = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
CPU_FOREACH(cpu) {
|
CPU_FOREACH(cpu) {
|
||||||
if (VMBUS_PCPU_GET(sc, message, cpu) != NULL) {
|
if (VMBUS_PCPU_GET(sc, message, cpu) != NULL) {
|
||||||
hyperv_dmamem_free(
|
contigfree(VMBUS_PCPU_GET(sc, message, cpu), PAGE_SIZE,
|
||||||
VMBUS_PCPU_PTR(sc, message_dma, cpu),
|
M_DEVBUF);
|
||||||
VMBUS_PCPU_GET(sc, message, cpu));
|
|
||||||
VMBUS_PCPU_GET(sc, message, cpu) = NULL;
|
VMBUS_PCPU_GET(sc, message, cpu) = NULL;
|
||||||
}
|
}
|
||||||
if (VMBUS_PCPU_GET(sc, event_flags, cpu) != NULL) {
|
if (VMBUS_PCPU_GET(sc, event_flags, cpu) != NULL) {
|
||||||
hyperv_dmamem_free(
|
contigfree(VMBUS_PCPU_GET(sc, event_flags, cpu),
|
||||||
VMBUS_PCPU_PTR(sc, event_flags_dma, cpu),
|
PAGE_SIZE, M_DEVBUF);
|
||||||
VMBUS_PCPU_GET(sc, event_flags, cpu));
|
|
||||||
VMBUS_PCPU_GET(sc, event_flags, cpu) = NULL;
|
VMBUS_PCPU_GET(sc, event_flags, cpu) = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,10 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <machine/atomic.h>
|
#include <machine/atomic.h>
|
||||||
#include <machine/stdarg.h>
|
#include <machine/stdarg.h>
|
||||||
|
|
||||||
#include <dev/hyperv/include/hyperv_busdma.h>
|
#include <vm/vm.h>
|
||||||
|
#include <vm/pmap.h>
|
||||||
|
#include <vm/vm_extern.h>
|
||||||
|
|
||||||
#include <dev/hyperv/include/vmbus_xact.h>
|
#include <dev/hyperv/include/vmbus_xact.h>
|
||||||
#include <dev/hyperv/vmbus/hyperv_var.h>
|
#include <dev/hyperv/vmbus/hyperv_var.h>
|
||||||
#include <dev/hyperv/vmbus/vmbus_reg.h>
|
#include <dev/hyperv/vmbus/vmbus_reg.h>
|
||||||
@ -137,7 +140,8 @@ vmbus_chan_signal(const struct vmbus_channel *chan)
|
|||||||
if (chan->ch_txflags & VMBUS_CHAN_TXF_HASMNF)
|
if (chan->ch_txflags & VMBUS_CHAN_TXF_HASMNF)
|
||||||
atomic_set_int(chan->ch_montrig, chan->ch_montrig_mask);
|
atomic_set_int(chan->ch_montrig, chan->ch_montrig_mask);
|
||||||
else
|
else
|
||||||
hypercall_signal_event(chan->ch_monprm_dma.hv_paddr);
|
hypercall_signal_event(pmap_kextract(
|
||||||
|
(vm_offset_t)chan->ch_monprm));
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline void
|
static __inline void
|
||||||
@ -340,16 +344,16 @@ vmbus_chan_open(struct vmbus_channel *chan, int txbr_size, int rxbr_size,
|
|||||||
* Allocate the TX+RX bufrings.
|
* Allocate the TX+RX bufrings.
|
||||||
*/
|
*/
|
||||||
KASSERT(chan->ch_bufring == NULL, ("bufrings are allocated"));
|
KASSERT(chan->ch_bufring == NULL, ("bufrings are allocated"));
|
||||||
chan->ch_bufring = hyperv_dmamem_alloc(bus_get_dma_tag(chan->ch_dev),
|
chan->ch_bufring_size = txbr_size + rxbr_size;
|
||||||
PAGE_SIZE, 0, txbr_size + rxbr_size, &chan->ch_bufring_dma,
|
chan->ch_bufring = contigmalloc(chan->ch_bufring_size, M_DEVBUF,
|
||||||
BUS_DMA_WAITOK);
|
M_WAITOK | M_ZERO, 0ul, ~0ul, PAGE_SIZE, 0);
|
||||||
if (chan->ch_bufring == NULL) {
|
if (chan->ch_bufring == NULL) {
|
||||||
vmbus_chan_printf(chan, "bufring allocation failed\n");
|
vmbus_chan_printf(chan, "bufring allocation failed\n");
|
||||||
return (ENOMEM);
|
return (ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
cbr.cbr = chan->ch_bufring;
|
cbr.cbr = chan->ch_bufring;
|
||||||
cbr.cbr_paddr = chan->ch_bufring_dma.hv_paddr;
|
cbr.cbr_paddr = pmap_kextract((vm_offset_t)chan->ch_bufring);
|
||||||
cbr.cbr_txsz = txbr_size;
|
cbr.cbr_txsz = txbr_size;
|
||||||
cbr.cbr_rxsz = rxbr_size;
|
cbr.cbr_rxsz = rxbr_size;
|
||||||
|
|
||||||
@ -367,8 +371,8 @@ vmbus_chan_open(struct vmbus_channel *chan, int txbr_size, int rxbr_size,
|
|||||||
"leak %d bytes memory\n", chan->ch_id,
|
"leak %d bytes memory\n", chan->ch_id,
|
||||||
txbr_size + rxbr_size);
|
txbr_size + rxbr_size);
|
||||||
} else {
|
} else {
|
||||||
hyperv_dmamem_free(&chan->ch_bufring_dma,
|
contigfree(chan->ch_bufring, chan->ch_bufring_size,
|
||||||
chan->ch_bufring);
|
M_DEVBUF);
|
||||||
}
|
}
|
||||||
chan->ch_bufring = NULL;
|
chan->ch_bufring = NULL;
|
||||||
}
|
}
|
||||||
@ -938,7 +942,7 @@ vmbus_chan_close_internal(struct vmbus_channel *chan)
|
|||||||
* Destroy the TX+RX bufrings.
|
* Destroy the TX+RX bufrings.
|
||||||
*/
|
*/
|
||||||
if (chan->ch_bufring != NULL) {
|
if (chan->ch_bufring != NULL) {
|
||||||
hyperv_dmamem_free(&chan->ch_bufring_dma, chan->ch_bufring);
|
contigfree(chan->ch_bufring, chan->ch_bufring_size, M_DEVBUF);
|
||||||
chan->ch_bufring = NULL;
|
chan->ch_bufring = NULL;
|
||||||
}
|
}
|
||||||
return (error);
|
return (error);
|
||||||
@ -1630,9 +1634,8 @@ vmbus_chan_alloc(struct vmbus_softc *sc)
|
|||||||
|
|
||||||
chan = malloc(sizeof(*chan), M_DEVBUF, M_WAITOK | M_ZERO);
|
chan = malloc(sizeof(*chan), M_DEVBUF, M_WAITOK | M_ZERO);
|
||||||
|
|
||||||
chan->ch_monprm = hyperv_dmamem_alloc(bus_get_dma_tag(sc->vmbus_dev),
|
chan->ch_monprm = contigmalloc(sizeof(struct hyperv_mon_param),
|
||||||
HYPERCALL_PARAM_ALIGN, 0, sizeof(struct hyperv_mon_param),
|
M_DEVBUF, M_WAITOK | M_ZERO, 0ul, ~0ul, HYPERCALL_PARAM_ALIGN, 0);
|
||||||
&chan->ch_monprm_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO);
|
|
||||||
if (chan->ch_monprm == NULL) {
|
if (chan->ch_monprm == NULL) {
|
||||||
device_printf(sc->vmbus_dev, "monprm alloc failed\n");
|
device_printf(sc->vmbus_dev, "monprm alloc failed\n");
|
||||||
free(chan, M_DEVBUF);
|
free(chan, M_DEVBUF);
|
||||||
@ -1671,7 +1674,7 @@ vmbus_chan_free(struct vmbus_channel *chan)
|
|||||||
KASSERT(chan->ch_poll_intvl == 0, ("chan%u: polling is activated",
|
KASSERT(chan->ch_poll_intvl == 0, ("chan%u: polling is activated",
|
||||||
chan->ch_id));
|
chan->ch_id));
|
||||||
|
|
||||||
hyperv_dmamem_free(&chan->ch_monprm_dma, chan->ch_monprm);
|
contigfree(chan->ch_monprm, sizeof(struct hyperv_mon_param), M_DEVBUF);
|
||||||
mtx_destroy(&chan->ch_subchan_lock);
|
mtx_destroy(&chan->ch_subchan_lock);
|
||||||
sx_destroy(&chan->ch_orphan_lock);
|
sx_destroy(&chan->ch_orphan_lock);
|
||||||
vmbus_rxbr_deinit(&chan->ch_rxbr);
|
vmbus_rxbr_deinit(&chan->ch_rxbr);
|
||||||
|
@ -39,7 +39,6 @@
|
|||||||
#include <sys/taskqueue.h>
|
#include <sys/taskqueue.h>
|
||||||
|
|
||||||
#include <dev/hyperv/include/hyperv.h>
|
#include <dev/hyperv/include/hyperv.h>
|
||||||
#include <dev/hyperv/include/hyperv_busdma.h>
|
|
||||||
#include <dev/hyperv/include/vmbus.h>
|
#include <dev/hyperv/include/vmbus.h>
|
||||||
#include <dev/hyperv/vmbus/vmbus_brvar.h>
|
#include <dev/hyperv/vmbus/vmbus_brvar.h>
|
||||||
|
|
||||||
@ -99,7 +98,6 @@ struct vmbus_channel {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
struct hyperv_mon_param *ch_monprm;
|
struct hyperv_mon_param *ch_monprm;
|
||||||
struct hyperv_dma ch_monprm_dma;
|
|
||||||
|
|
||||||
uint32_t ch_id; /* channel id */
|
uint32_t ch_id; /* channel id */
|
||||||
device_t ch_dev;
|
device_t ch_dev;
|
||||||
@ -127,7 +125,7 @@ struct vmbus_channel {
|
|||||||
struct vmbus_channel *ch_prichan; /* owner primary chan */
|
struct vmbus_channel *ch_prichan; /* owner primary chan */
|
||||||
|
|
||||||
void *ch_bufring; /* TX+RX bufrings */
|
void *ch_bufring; /* TX+RX bufrings */
|
||||||
struct hyperv_dma ch_bufring_dma;
|
size_t ch_bufring_size;
|
||||||
uint32_t ch_bufring_gpadl;
|
uint32_t ch_bufring_gpadl;
|
||||||
|
|
||||||
struct task ch_attach_task; /* run in ch_mgmt_tq */
|
struct task ch_attach_task; /* run in ch_mgmt_tq */
|
||||||
|
@ -34,7 +34,6 @@
|
|||||||
#include <sys/taskqueue.h>
|
#include <sys/taskqueue.h>
|
||||||
#include <sys/rman.h>
|
#include <sys/rman.h>
|
||||||
|
|
||||||
#include <dev/hyperv/include/hyperv_busdma.h>
|
|
||||||
#include <dev/pci/pcivar.h>
|
#include <dev/pci/pcivar.h>
|
||||||
#include <dev/pci/pcib_private.h>
|
#include <dev/pci/pcib_private.h>
|
||||||
|
|
||||||
@ -74,8 +73,6 @@ struct vmbus_pcpu_data {
|
|||||||
struct vmbus_evtflags *event_flags; /* event flags from host */
|
struct vmbus_evtflags *event_flags; /* event flags from host */
|
||||||
|
|
||||||
/* Rarely used fields */
|
/* Rarely used fields */
|
||||||
struct hyperv_dma message_dma; /* busdma glue */
|
|
||||||
struct hyperv_dma event_flags_dma;/* busdma glue */
|
|
||||||
struct taskqueue *event_tq; /* event taskq */
|
struct taskqueue *event_tq; /* event taskq */
|
||||||
struct taskqueue *message_tq; /* message taskq */
|
struct taskqueue *message_tq; /* message taskq */
|
||||||
struct task message_task; /* message task */
|
struct task message_task; /* message task */
|
||||||
@ -105,11 +102,8 @@ struct vmbus_softc {
|
|||||||
|
|
||||||
/* Shared memory for vmbus_{rx,tx}_evtflags */
|
/* Shared memory for vmbus_{rx,tx}_evtflags */
|
||||||
void *vmbus_evtflags;
|
void *vmbus_evtflags;
|
||||||
struct hyperv_dma vmbus_evtflags_dma;
|
|
||||||
|
|
||||||
void *vmbus_mnf1; /* monitored by VM, unused */
|
void *vmbus_mnf1; /* monitored by VM, unused */
|
||||||
struct hyperv_dma vmbus_mnf1_dma;
|
|
||||||
struct hyperv_dma vmbus_mnf2_dma;
|
|
||||||
|
|
||||||
bool vmbus_scandone;
|
bool vmbus_scandone;
|
||||||
struct task vmbus_scandone_task;
|
struct task vmbus_scandone_task;
|
||||||
|
@ -34,7 +34,10 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/proc.h>
|
#include <sys/proc.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
|
|
||||||
#include <dev/hyperv/include/hyperv_busdma.h>
|
#include <vm/vm.h>
|
||||||
|
#include <vm/vm_extern.h>
|
||||||
|
#include <vm/pmap.h>
|
||||||
|
|
||||||
#include <dev/hyperv/include/vmbus_xact.h>
|
#include <dev/hyperv/include/vmbus_xact.h>
|
||||||
|
|
||||||
struct vmbus_xact {
|
struct vmbus_xact {
|
||||||
@ -42,7 +45,6 @@ struct vmbus_xact {
|
|||||||
void *x_priv;
|
void *x_priv;
|
||||||
|
|
||||||
void *x_req;
|
void *x_req;
|
||||||
struct hyperv_dma x_req_dma;
|
|
||||||
|
|
||||||
const void *x_resp;
|
const void *x_resp;
|
||||||
size_t x_resp_len;
|
size_t x_resp_len;
|
||||||
@ -88,8 +90,8 @@ vmbus_xact_alloc(struct vmbus_xact_ctx *ctx, bus_dma_tag_t parent_dtag)
|
|||||||
xact->x_ctx = ctx;
|
xact->x_ctx = ctx;
|
||||||
|
|
||||||
/* XXX assume that page aligned is enough */
|
/* XXX assume that page aligned is enough */
|
||||||
xact->x_req = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
|
xact->x_req = contigmalloc(ctx->xc_req_size, M_DEVBUF,
|
||||||
ctx->xc_req_size, &xact->x_req_dma, BUS_DMA_WAITOK);
|
M_WAITOK | M_ZERO, 0ul, ~0ul, PAGE_SIZE, 0);
|
||||||
if (xact->x_req == NULL) {
|
if (xact->x_req == NULL) {
|
||||||
free(xact, M_DEVBUF);
|
free(xact, M_DEVBUF);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
@ -105,7 +107,7 @@ static void
|
|||||||
vmbus_xact_free(struct vmbus_xact *xact)
|
vmbus_xact_free(struct vmbus_xact *xact)
|
||||||
{
|
{
|
||||||
|
|
||||||
hyperv_dmamem_free(&xact->x_req_dma, xact->x_req);
|
contigfree(xact->x_req, xact->x_ctx->xc_req_size, M_DEVBUF);
|
||||||
free(xact->x_resp0, M_DEVBUF);
|
free(xact->x_resp0, M_DEVBUF);
|
||||||
if (xact->x_priv != NULL)
|
if (xact->x_priv != NULL)
|
||||||
free(xact->x_priv, M_DEVBUF);
|
free(xact->x_priv, M_DEVBUF);
|
||||||
@ -243,7 +245,7 @@ bus_addr_t
|
|||||||
vmbus_xact_req_paddr(const struct vmbus_xact *xact)
|
vmbus_xact_req_paddr(const struct vmbus_xact *xact)
|
||||||
{
|
{
|
||||||
|
|
||||||
return (xact->x_req_dma.hv_paddr);
|
return (pmap_kextract((vm_offset_t)xact->x_req));
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
Loading…
Reference in New Issue
Block a user