Skip to content

Commit 5ee1098

Browse files
Jorgen Hansengregkh
authored andcommitted
VMCI: dma dg: allocate send and receive buffers for DMA datagrams
If DMA datagrams are used, allocate send and receive buffers in coherent DMA memory. This is done in preparation for the send and receive datagram operations, where the buffers are used for the exchange of data between driver and device. Reviewed-by: Vishnu Dasa <[email protected]> Signed-off-by: Jorgen Hansen <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent cc68f21 commit 5ee1098

File tree

2 files changed

+66
-9
lines changed

2 files changed

+66
-9
lines changed

drivers/misc/vmw_vmci/vmci_guest.c

Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@
3131

3232
#define VMCI_UTIL_NUM_RESOURCES 1
3333

34+
/*
35+
* Datagram buffers for DMA send/receive must accommodate at least
36+
* a maximum sized datagram and the header.
37+
*/
38+
#define VMCI_DMA_DG_BUFFER_SIZE (VMCI_MAX_DG_SIZE + PAGE_SIZE)
39+
3440
static bool vmci_disable_msi;
3541
module_param_named(disable_msi, vmci_disable_msi, bool, 0);
3642
MODULE_PARM_DESC(disable_msi, "Disable MSI use in driver - (default=0)");
@@ -53,6 +59,9 @@ struct vmci_guest_device {
5359
struct tasklet_struct bm_tasklet;
5460

5561
void *data_buffer;
62+
dma_addr_t data_buffer_base;
63+
void *tx_buffer;
64+
dma_addr_t tx_buffer_base;
5665
void *notification_bitmap;
5766
dma_addr_t notification_base;
5867
};
@@ -451,6 +460,24 @@ static irqreturn_t vmci_interrupt_dma_datagram(int irq, void *_dev)
451460
return IRQ_HANDLED;
452461
}
453462

463+
static void vmci_free_dg_buffers(struct vmci_guest_device *vmci_dev)
464+
{
465+
if (vmci_dev->mmio_base != NULL) {
466+
if (vmci_dev->tx_buffer != NULL)
467+
dma_free_coherent(vmci_dev->dev,
468+
VMCI_DMA_DG_BUFFER_SIZE,
469+
vmci_dev->tx_buffer,
470+
vmci_dev->tx_buffer_base);
471+
if (vmci_dev->data_buffer != NULL)
472+
dma_free_coherent(vmci_dev->dev,
473+
VMCI_DMA_DG_BUFFER_SIZE,
474+
vmci_dev->data_buffer,
475+
vmci_dev->data_buffer_base);
476+
} else {
477+
vfree(vmci_dev->data_buffer);
478+
}
479+
}
480+
454481
/*
455482
* Most of the initialization at module load time is done here.
456483
*/
@@ -517,11 +544,27 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
517544
tasklet_init(&vmci_dev->bm_tasklet,
518545
vmci_process_bitmap, (unsigned long)vmci_dev);
519546

520-
vmci_dev->data_buffer = vmalloc(VMCI_MAX_DG_SIZE);
547+
if (mmio_base != NULL) {
548+
vmci_dev->tx_buffer = dma_alloc_coherent(&pdev->dev, VMCI_DMA_DG_BUFFER_SIZE,
549+
&vmci_dev->tx_buffer_base,
550+
GFP_KERNEL);
551+
if (!vmci_dev->tx_buffer) {
552+
dev_err(&pdev->dev,
553+
"Can't allocate memory for datagram tx buffer\n");
554+
return -ENOMEM;
555+
}
556+
557+
vmci_dev->data_buffer = dma_alloc_coherent(&pdev->dev, VMCI_DMA_DG_BUFFER_SIZE,
558+
&vmci_dev->data_buffer_base,
559+
GFP_KERNEL);
560+
} else {
561+
vmci_dev->data_buffer = vmalloc(VMCI_MAX_DG_SIZE);
562+
}
521563
if (!vmci_dev->data_buffer) {
522564
dev_err(&pdev->dev,
523565
"Can't allocate memory for datagram buffer\n");
524-
return -ENOMEM;
566+
error = -ENOMEM;
567+
goto err_free_data_buffers;
525568
}
526569

527570
pci_set_master(pdev); /* To enable queue_pair functionality. */
@@ -539,7 +582,7 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
539582
if (!(capabilities & VMCI_CAPS_DATAGRAM)) {
540583
dev_err(&pdev->dev, "Device does not support datagrams\n");
541584
error = -ENXIO;
542-
goto err_free_data_buffer;
585+
goto err_free_data_buffers;
543586
}
544587
caps_in_use = VMCI_CAPS_DATAGRAM;
545588

@@ -583,7 +626,7 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
583626
dev_err(&pdev->dev,
584627
"Missing capability: VMCI_CAPS_DMA_DATAGRAM\n");
585628
error = -ENXIO;
586-
goto err_free_data_buffer;
629+
goto err_free_data_buffers;
587630
}
588631
}
589632

@@ -592,10 +635,17 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
592635
/* Let the host know which capabilities we intend to use. */
593636
vmci_write_reg(vmci_dev, caps_in_use, VMCI_CAPS_ADDR);
594637

595-
/* Let the device know the size for pages passed down. */
596-
if (caps_in_use & VMCI_CAPS_DMA_DATAGRAM)
638+
if (caps_in_use & VMCI_CAPS_DMA_DATAGRAM) {
639+
/* Let the device know the size for pages passed down. */
597640
vmci_write_reg(vmci_dev, PAGE_SHIFT, VMCI_GUEST_PAGE_SHIFT);
598641

642+
/* Configure the high order parts of the data in/out buffers. */
643+
vmci_write_reg(vmci_dev, upper_32_bits(vmci_dev->data_buffer_base),
644+
VMCI_DATA_IN_HIGH_ADDR);
645+
vmci_write_reg(vmci_dev, upper_32_bits(vmci_dev->tx_buffer_base),
646+
VMCI_DATA_OUT_HIGH_ADDR);
647+
}
648+
599649
/* Set up global device so that we can start sending datagrams */
600650
spin_lock_irq(&vmci_dev_spinlock);
601651
vmci_dev_g = vmci_dev;
@@ -747,8 +797,8 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
747797
vmci_dev_g = NULL;
748798
spin_unlock_irq(&vmci_dev_spinlock);
749799

750-
err_free_data_buffer:
751-
vfree(vmci_dev->data_buffer);
800+
err_free_data_buffers:
801+
vmci_free_dg_buffers(vmci_dev);
752802

753803
/* The rest are managed resources and will be freed by PCI core */
754804
return error;
@@ -806,7 +856,10 @@ static void vmci_guest_remove_device(struct pci_dev *pdev)
806856
vmci_dev->notification_base);
807857
}
808858

809-
vfree(vmci_dev->data_buffer);
859+
vmci_free_dg_buffers(vmci_dev);
860+
861+
if (vmci_dev->mmio_base != NULL)
862+
pci_iounmap(pdev, vmci_dev->mmio_base);
810863

811864
/* The rest are managed resources and will be freed by PCI core */
812865
}

include/linux/vmw_vmci_defs.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121
#define VMCI_CAPS_ADDR 0x18
2222
#define VMCI_RESULT_LOW_ADDR 0x1c
2323
#define VMCI_RESULT_HIGH_ADDR 0x20
24+
#define VMCI_DATA_OUT_LOW_ADDR 0x24
25+
#define VMCI_DATA_OUT_HIGH_ADDR 0x28
26+
#define VMCI_DATA_IN_LOW_ADDR 0x2c
27+
#define VMCI_DATA_IN_HIGH_ADDR 0x30
2428
#define VMCI_GUEST_PAGE_SHIFT 0x34
2529

2630
/* Max number of devices. */

0 commit comments

Comments
 (0)