Message ID | 20210228150315.2552437-13-ltykernel@gmail.com (mailing list archive) |
---|---|
State | Not Applicable |
Headers | show |
Series | x86/Hyper-V: Add Hyper-V Isolation VM support | expand |
This should be handled by the DMA mapping layer, just like for native SEV support.
Hi Christoph: Thanks a lot for your review. There are some reasons. 1) Vmbus drivers don't use DMA API now. 2) Hyper-V Vmbus channel ring buffer already play bounce buffer role for most vmbus drivers. Just two kinds of packets from netvsc/storvsc are uncovered. 3) In AMD SEV-SNP based Hyper-V guest, the access physical address of shared memory should be bounce buffer memory physical address plus with a shared memory boundary(e.g, 48bit) reported Hyper-V CPUID. It's called virtual top of memory(vTom) in AMD spec and works as a watermark. So it needs to ioremap/memremap the associated physical address above the share memory boundary before accessing them. swiotlb_bounce() uses low end physical address to access bounce buffer and this doesn't work in this senario. If something wrong, please help me correct me. Thanks. On 3/1/2021 2:54 PM, Christoph Hellwig wrote: > This should be handled by the DMA mapping layer, just like for native > SEV support. >
> Hi Christoph: > Thanks a lot for your review. There are some reasons. > 1) Vmbus drivers don't use DMA API now. What is blocking us from making the Hyper-V drivers use the DMA API's? They will be a null-op generally, when there is no bounce buffer support needed. > 2) Hyper-V Vmbus channel ring buffer already play bounce buffer > role for most vmbus drivers. Just two kinds of packets from > netvsc/storvsc are uncovered. How does this make a difference here? > 3) In AMD SEV-SNP based Hyper-V guest, the access physical address > of shared memory should be bounce buffer memory physical address plus > with a shared memory boundary(e.g, 48bit) reported Hyper-V CPUID. It's > called virtual top of memory(vTom) in AMD spec and works as a watermark. > So it needs to ioremap/memremap the associated physical address above > the share memory boundary before accessing them. swiotlb_bounce() uses > low end physical address to access bounce buffer and this doesn't work > in this senario. If something wrong, please help me correct me. > There are alternative implementations of swiotlb on top of the core swiotlb API's. One option is to have Hyper-V specific swiotlb wrapper DMA API's with the custom logic above. > Thanks. > > > On 3/1/2021 2:54 PM, Christoph Hellwig wrote: > > This should be handled by the DMA mapping layer, just like for native > > SEV support. I agree with Christoph's comment that in principle, this should be handled using the DMA API's
Hi Sunil: Thanks for your review. On 3/2/2021 3:45 AM, Sunil Muthuswamy wrote: >> Hi Christoph: >> Thanks a lot for your review. There are some reasons. >> 1) Vmbus drivers don't use DMA API now. > What is blocking us from making the Hyper-V drivers use the DMA API's? They > will be a null-op generally, when there is no bounce buffer support needed. > >> 2) Hyper-V Vmbus channel ring buffer already play bounce buffer >> role for most vmbus drivers. Just two kinds of packets from >> netvsc/storvsc are uncovered. > How does this make a difference here? > >> 3) In AMD SEV-SNP based Hyper-V guest, the access physical address >> of shared memory should be bounce buffer memory physical address plus >> with a shared memory boundary(e.g, 48bit) reported Hyper-V CPUID. It's >> called virtual top of memory(vTom) in AMD spec and works as a watermark. >> So it needs to ioremap/memremap the associated physical address above >> the share memory boundary before accessing them. swiotlb_bounce() uses >> low end physical address to access bounce buffer and this doesn't work >> in this senario. If something wrong, please help me correct me. >> > There are alternative implementations of swiotlb on top of the core swiotlb > API's. One option is to have Hyper-V specific swiotlb wrapper DMA API's with > the custom logic above. Agree. Hyper-V should have its own DMA ops and put Hyper-V bounce buffer code in DMA API callback. For vmbus channel ring buffer, it doesn't need additional bounce buffer and there are two options. 1) Not call DMA API around them 2) pass a flag in DMA API to notify Hyper-V DMA callback and not allocate bounce buffer for them. > >> Thanks. >> >> >> On 3/1/2021 2:54 PM, Christoph Hellwig wrote: >>> This should be handled by the DMA mapping layer, just like for native >>> SEV support. > I agree with Christoph's comment that in principle, this should be handled using > the DMA API's >
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index c5b4974eb41f..4ae8e2a427e4 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -33,6 +33,8 @@ #include <scsi/scsi_transport.h> #include <asm/mshyperv.h> +#include "../hv/hyperv_vmbus.h" + /* * All wire protocol details (storage protocol between the guest and the host) * are consolidated here. @@ -725,6 +727,10 @@ static void handle_sc_creation(struct vmbus_channel *new_sc) /* Add the sub-channel to the array of available channels. */ stor_device->stor_chns[new_sc->target_cpu] = new_sc; cpumask_set_cpu(new_sc->target_cpu, &stor_device->alloced_cpus); + + if (hv_bounce_resources_reserve(device->channel, + stor_device->max_transfer_bytes)) + pr_warn("Fail to reserve bounce buffer\n"); } static void handle_multichannel_storage(struct hv_device *device, int max_chns) @@ -964,6 +970,18 @@ static int storvsc_channel_init(struct hv_device *device, bool is_fc) stor_device->max_transfer_bytes = vstor_packet->storage_channel_properties.max_transfer_bytes; + /* + * Reserve enough bounce resources to be able to support paging + * operations under low memory conditions, that cannot rely on + * additional resources to be allocated. + */ + ret = hv_bounce_resources_reserve(device->channel, + stor_device->max_transfer_bytes); + if (ret < 0) { + pr_warn("Fail to reserve bounce buffer\n"); + goto done; + } + if (!is_fc) goto done; @@ -1263,6 +1281,11 @@ static void storvsc_on_channel_callback(void *context) request = (struct storvsc_cmd_request *)(unsigned long)cmd_rqst; + if (desc->type == VM_PKT_COMP && request->bounce_pkt) { + hv_pkt_bounce(channel, request->bounce_pkt); + request->bounce_pkt = NULL; + } + if (request == &stor_device->init_request || request == &stor_device->reset_request) { memcpy(&request->vstor_packet, packet,