lkml.org 
[lkml]   [2021]   [Dec]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    From
    SubjectRE: [PATCH V7 4/5] scsi: storvsc: Add Isolation VM support for storvsc driver
    Date
    > From: Tianyu Lan <ltykernel@gmail.com>
    > Sent: Sunday, December 12, 2021 11:14 PM
    > To: KY Srinivasan <kys@microsoft.com>; Haiyang Zhang
    > <haiyangz@microsoft.com>; Stephen Hemminger <sthemmin@microsoft.com>;
    > wei.liu@kernel.org; Dexuan Cui <decui@microsoft.com>; tglx@linutronix.de;
    > mingo@redhat.com; bp@alien8.de; dave.hansen@linux.intel.com;
    > x86@kernel.org; hpa@zytor.com; davem@davemloft.net; kuba@kernel.org;
    > jejb@linux.ibm.com; martin.petersen@oracle.com; arnd@arndb.de;
    > hch@infradead.org; m.szyprowski@samsung.com; robin.murphy@arm.com;
    > thomas.lendacky@amd.com; Tianyu Lan <Tianyu.Lan@microsoft.com>; Michael
    > Kelley (LINUX) <mikelley@microsoft.com>
    > Cc: iommu@lists.linux-foundation.org; linux-arch@vger.kernel.org; linux-
    > hyperv@vger.kernel.org; linux-kernel@vger.kernel.org; linux-
    > scsi@vger.kernel.org; netdev@vger.kernel.org; vkuznets
    > <vkuznets@redhat.com>; brijesh.singh@amd.com; konrad.wilk@oracle.com;
    > hch@lst.de; joro@8bytes.org; parri.andrea@gmail.com;
    > dave.hansen@intel.com
    > Subject: [PATCH V7 4/5] scsi: storvsc: Add Isolation VM support for storvsc driver
    >
    > From: Tianyu Lan <Tianyu.Lan@microsoft.com>
    >
    > In Isolation VM, all shared memory with host needs to mark visible to host via
    > hvcall. vmbus_establish_gpadl() has already done it for storvsc rx/tx ring buffer.
    > The page buffer used by vmbus_sendpacket_
    > mpb_desc() still needs to be handled. Use DMA API(scsi_dma_map/unmap) to
    > map these memory during sending/receiving packet and return swiotlb bounce
    > buffer dma address. In Isolation VM, swiotlb bounce buffer is marked to be
    > visible to host and the swiotlb force mode is enabled.
    >
    > Set device's dma min align mask to HV_HYP_PAGE_SIZE - 1 in order to keep the
    > original data offset in the bounce buffer.
    >
    > Signed-off-by: Tianyu Lan <Tianyu.Lan@microsoft.com>

    Reviewed-by: Long Li <longli@microsoft.com>

    > ---
    > drivers/hv/vmbus_drv.c | 4 ++++
    > drivers/scsi/storvsc_drv.c | 37 +++++++++++++++++++++----------------
    > include/linux/hyperv.h | 1 +
    > 3 files changed, 26 insertions(+), 16 deletions(-)
    >
    > diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index
    > 392c1ac4f819..ae6ec503399a 100644
    > --- a/drivers/hv/vmbus_drv.c
    > +++ b/drivers/hv/vmbus_drv.c
    > @@ -33,6 +33,7 @@
    > #include <linux/random.h>
    > #include <linux/kernel.h>
    > #include <linux/syscore_ops.h>
    > +#include <linux/dma-map-ops.h>
    > #include <clocksource/hyperv_timer.h>
    > #include "hyperv_vmbus.h"
    >
    > @@ -2078,6 +2079,7 @@ struct hv_device *vmbus_device_create(const guid_t
    > *type,
    > return child_device_obj;
    > }
    >
    > +static u64 vmbus_dma_mask = DMA_BIT_MASK(64);
    > /*
    > * vmbus_device_register - Register the child device
    > */
    > @@ -2118,6 +2120,8 @@ int vmbus_device_register(struct hv_device
    > *child_device_obj)
    > }
    > hv_debug_add_dev_dir(child_device_obj);
    >
    > + child_device_obj->device.dma_mask = &vmbus_dma_mask;
    > + child_device_obj->device.dma_parms = &child_device_obj->dma_parms;
    > return 0;
    >
    > err_kset_unregister:
    > diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index
    > 20595c0ba0ae..ae293600d799 100644
    > --- a/drivers/scsi/storvsc_drv.c
    > +++ b/drivers/scsi/storvsc_drv.c
    > @@ -21,6 +21,8 @@
    > #include <linux/device.h>
    > #include <linux/hyperv.h>
    > #include <linux/blkdev.h>
    > +#include <linux/dma-mapping.h>
    > +
    > #include <scsi/scsi.h>
    > #include <scsi/scsi_cmnd.h>
    > #include <scsi/scsi_host.h>
    > @@ -1336,6 +1338,7 @@ static void storvsc_on_channel_callback(void
    > *context)
    > continue;
    > }
    > request = (struct storvsc_cmd_request
    > *)scsi_cmd_priv(scmnd);
    > + scsi_dma_unmap(scmnd);
    > }
    >
    > storvsc_on_receive(stor_device, packet, request); @@
    > -1749,7 +1752,6 @@ static int storvsc_queuecommand(struct Scsi_Host *host,
    > struct scsi_cmnd *scmnd)
    > struct hv_host_device *host_dev = shost_priv(host);
    > struct hv_device *dev = host_dev->dev;
    > struct storvsc_cmd_request *cmd_request = scsi_cmd_priv(scmnd);
    > - int i;
    > struct scatterlist *sgl;
    > unsigned int sg_count;
    > struct vmscsi_request *vm_srb;
    > @@ -1831,10 +1833,11 @@ static int storvsc_queuecommand(struct Scsi_Host
    > *host, struct scsi_cmnd *scmnd)
    > payload_sz = sizeof(cmd_request->mpb);
    >
    > if (sg_count) {
    > - unsigned int hvpgoff, hvpfns_to_add;
    > unsigned long offset_in_hvpg = offset_in_hvpage(sgl->offset);
    > unsigned int hvpg_count = HVPFN_UP(offset_in_hvpg + length);
    > - u64 hvpfn;
    > + struct scatterlist *sg;
    > + unsigned long hvpfn, hvpfns_to_add;
    > + int j, i = 0;
    >
    > if (hvpg_count > MAX_PAGE_BUFFER_COUNT) {
    >
    > @@ -1848,21 +1851,22 @@ static int storvsc_queuecommand(struct Scsi_Host
    > *host, struct scsi_cmnd *scmnd)
    > payload->range.len = length;
    > payload->range.offset = offset_in_hvpg;
    >
    > + sg_count = scsi_dma_map(scmnd);
    > + if (sg_count < 0)
    > + return SCSI_MLQUEUE_DEVICE_BUSY;
    >
    > - for (i = 0; sgl != NULL; sgl = sg_next(sgl)) {
    > + for_each_sg(sgl, sg, sg_count, j) {
    > /*
    > - * Init values for the current sgl entry. hvpgoff
    > - * and hvpfns_to_add are in units of Hyper-V size
    > - * pages. Handling the PAGE_SIZE !=
    > HV_HYP_PAGE_SIZE
    > - * case also handles values of sgl->offset that are
    > - * larger than PAGE_SIZE. Such offsets are handled
    > - * even on other than the first sgl entry, provided
    > - * they are a multiple of PAGE_SIZE.
    > + * Init values for the current sgl entry. hvpfns_to_add
    > + * is in units of Hyper-V size pages. Handling the
    > + * PAGE_SIZE != HV_HYP_PAGE_SIZE case also handles
    > + * values of sgl->offset that are larger than PAGE_SIZE.
    > + * Such offsets are handled even on other than the first
    > + * sgl entry, provided they are a multiple of PAGE_SIZE.
    > */
    > - hvpgoff = HVPFN_DOWN(sgl->offset);
    > - hvpfn = page_to_hvpfn(sg_page(sgl)) + hvpgoff;
    > - hvpfns_to_add = HVPFN_UP(sgl->offset + sgl-
    > >length) -
    > - hvpgoff;
    > + hvpfn = HVPFN_DOWN(sg_dma_address(sg));
    > + hvpfns_to_add = HVPFN_UP(sg_dma_address(sg) +
    > + sg_dma_len(sg)) - hvpfn;
    >
    > /*
    > * Fill the next portion of the PFN array with @@ -
    > 1872,7 +1876,7 @@ static int storvsc_queuecommand(struct Scsi_Host *host,
    > struct scsi_cmnd *scmnd)
    > * the PFN array is filled.
    > */
    > while (hvpfns_to_add--)
    > - payload->range.pfn_array[i++] = hvpfn++;
    > + payload->range.pfn_array[i++] = hvpfn++;
    > }
    > }
    >
    > @@ -2016,6 +2020,7 @@ static int storvsc_probe(struct hv_device *device,
    > stor_device->vmscsi_size_delta = sizeof(struct vmscsi_win8_extension);
    > spin_lock_init(&stor_device->lock);
    > hv_set_drvdata(device, stor_device);
    > + dma_set_min_align_mask(&device->device, HV_HYP_PAGE_SIZE - 1);
    >
    > stor_device->port_number = host->host_no;
    > ret = storvsc_connect_to_vsp(device, storvsc_ringbuffer_size, is_fc);
    > diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index
    > b823311eac79..650a0574b746 100644
    > --- a/include/linux/hyperv.h
    > +++ b/include/linux/hyperv.h
    > @@ -1261,6 +1261,7 @@ struct hv_device {
    >
    > struct vmbus_channel *channel;
    > struct kset *channels_kset;
    > + struct device_dma_parameters dma_parms;
    >
    > /* place holder to keep track of the dir for hv device in debugfs */
    > struct dentry *debug_dir;
    > --
    > 2.25.1

    \
     
     \ /
      Last update: 2021-12-15 20:20    [W:3.852 / U:0.108 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site