History

Merge tag 'hyperv-next-signed-20220114' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux

Pull hyperv updates from Wei Liu: - More patches for Hyper-V isolation VM support (Tianyu Lan) - Bug fixes and clean-up patches from various people * tag 'hyperv-next-signed-20220114' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux: scsi: storvsc: Fix storvsc_queuecommand() memory leak x86/hyperv: Properly deal with empty cpumasks in hyperv_flush_tlb_multi() Drivers: hv: vmbus: Initialize request offers message for Isolation VM scsi: storvsc: Fix unsigned comparison to zero swiotlb: Add CONFIG_HAS_IOMEM check around swiotlb_mem_remap() x86/hyperv: Fix definition of hv_ghcb_pg variable Drivers: hv: Fix definition of hypercall input & output arg variables net: netvsc: Add Isolation VM support for netvsc driver scsi: storvsc: Add Isolation VM support for storvsc driver hyper-v: Enable swiotlb bounce buffer for Isolation VM x86/hyper-v: Add hyperv Isolation VM check in the cc_platform_has() swiotlb: Add swiotlb bounce buffer remap function for HV IVM

Linus Torvalds committed 4 years ago

Commit cb3f09f2 parents 4d66020 4eea53318 files · +328 −45Browse files

Showing the changes to kernel (1 of 18 files). Show all

Unified · Split

kernel/dma/swiotlb.c+48−2
@@ -50,6 +50,7 @@ · 49 unmodified lines
5050 #include <asm/io.h>
5151 #include <asm/dma.h>
5252
53+#include <linux/io.h>
5354 #include <linux/init.h>
5455 #include <linux/memblock.h>
5556 #include <linux/iommu-helper.h>
@@ -72,6 +73,8 @@ enum swiotlb_force swiotlb_force; · 16 unmodified lines
7273
7374 struct io_tlb_mem io_tlb_default_mem;
7475
76+phys_addr_t swiotlb_unencrypted_base;
77+
7578 /*
7679 * Max segment that we can provide which (if pages are contingous) will
7780 * not be bounced (unless SWIOTLB_FORCE is set).
@@ -155,6 +158,34 @@ static inline unsigned long nr_slots(u64 val) · 77 unmodified lines
155158 return DIV_ROUND_UP(val, IO_TLB_SIZE);
156159 }
157160
161+/*
162+ * Remap swioltb memory in the unencrypted physical address space
163+ * when swiotlb_unencrypted_base is set. (e.g. for Hyper-V AMD SEV-SNP
164+ * Isolation VMs).
165+ */
166+#ifdef CONFIG_HAS_IOMEM
167+static void *swiotlb_mem_remap(struct io_tlb_mem *mem, unsigned long bytes)
168+{
169+ void *vaddr = NULL;
170+
171+ if (swiotlb_unencrypted_base) {
172+ phys_addr_t paddr = mem->start + swiotlb_unencrypted_base;
173+
174+ vaddr = memremap(paddr, bytes, MEMREMAP_WB);
175+ if (!vaddr)
176+ pr_err("Failed to map the unencrypted memory %pa size %lx.\n",
177+ &paddr, bytes);
178+ }
179+
180+ return vaddr;
181+}
182+#else
183+static void *swiotlb_mem_remap(struct io_tlb_mem *mem, unsigned long bytes)
184+{
185+ return NULL;
186+}
187+#endif
188+
158189 /*
159190 * Early SWIOTLB allocation may be too early to allow an architecture to
160191 * perform the desired operations. This function allows the architecture to
@@ -172,7 +203,12 @@ void __init swiotlb_update_mem_attributes(void) · 11 unmodified lines
172203 vaddr = phys_to_virt(mem->start);
173204 bytes = PAGE_ALIGN(mem->nslabs << IO_TLB_SHIFT);
174205 set_memory_decrypted((unsigned long)vaddr, bytes >> PAGE_SHIFT);
175− memset(vaddr, 0, bytes);
206+
207+ mem->vaddr = swiotlb_mem_remap(mem, bytes);
208+ if (!mem->vaddr)
209+ mem->vaddr = vaddr;
210+
211+ memset(mem->vaddr, 0, bytes);
176212 }
177213
178214 static void swiotlb_init_io_tlb_mem(struct io_tlb_mem *mem, phys_addr_t start,
@@ -196,7 +232,17 @@ static void swiotlb_init_io_tlb_mem(struct io_tlb_mem *mem, phys_addr_t start, · 17 unmodified lines
196232 mem->slots[i].orig_addr = INVALID_PHYS_ADDR;
197233 mem->slots[i].alloc_size = 0;
198234 }
235+
236+ /*
237+ * If swiotlb_unencrypted_base is set, the bounce buffer memory will
238+ * be remapped and cleared in swiotlb_update_mem_attributes.
239+ */
240+ if (swiotlb_unencrypted_base)
241+ return;
242+
199243 memset(vaddr, 0, bytes);
244+ mem->vaddr = vaddr;
245+ return;
200246 }
201247
202248 int __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose)
@@ -371,7 +417,7 @@ static void swiotlb_bounce(struct device *dev, phys_addr_t tlb_addr, size_t size · 168 unmodified lines
371417 phys_addr_t orig_addr = mem->slots[index].orig_addr;
372418 size_t alloc_size = mem->slots[index].alloc_size;
373419 unsigned long pfn = PFN_DOWN(orig_addr);
374− unsigned char *vaddr = phys_to_virt(tlb_addr);
420+ unsigned char *vaddr = mem->vaddr + tlb_addr - mem->start;
375421 unsigned int tlb_offset, orig_addr_offset;
376422
377423 if (orig_addr == INVALID_PHYS_ADDR)