Skip to content

Commit cb3f09f

Browse files
committed
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
2 parents 4d66020 + 4eea533 commit cb3f09f

File tree

18 files changed

+328
-45
lines changed

18 files changed

+328
-45
lines changed

arch/x86/hyperv/hv_init.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <linux/syscore_ops.h>
2929
#include <clocksource/hyperv_timer.h>
3030
#include <linux/highmem.h>
31+
#include <linux/swiotlb.h>
3132

3233
int hyperv_init_cpuhp;
3334
u64 hv_current_partition_id = ~0ull;
@@ -36,7 +37,7 @@ EXPORT_SYMBOL_GPL(hv_current_partition_id);
3637
void *hv_hypercall_pg;
3738
EXPORT_SYMBOL_GPL(hv_hypercall_pg);
3839

39-
union hv_ghcb __percpu **hv_ghcb_pg;
40+
union hv_ghcb * __percpu *hv_ghcb_pg;
4041

4142
/* Storage to save the hypercall page temporarily for hibernation */
4243
static void *hv_hypercall_pg_saved;
@@ -498,6 +499,17 @@ void __init hyperv_init(void)
498499

499500
/* Query the VMs extended capability once, so that it can be cached. */
500501
hv_query_ext_cap(0);
502+
503+
#ifdef CONFIG_SWIOTLB
504+
/*
505+
* Swiotlb bounce buffer needs to be mapped in extra address
506+
* space. Map function doesn't work in the early place and so
507+
* call swiotlb_update_mem_attributes() here.
508+
*/
509+
if (hv_is_isolation_supported())
510+
swiotlb_update_mem_attributes();
511+
#endif
512+
501513
return;
502514

503515
clean_guest_os_id:

arch/x86/hyperv/ivm.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,3 +287,31 @@ int hv_set_mem_host_visibility(unsigned long kbuffer, int pagecount, bool visibl
287287
kfree(pfn_array);
288288
return ret;
289289
}
290+
291+
/*
292+
* hv_map_memory - map memory to extra space in the AMD SEV-SNP Isolation VM.
293+
*/
294+
void *hv_map_memory(void *addr, unsigned long size)
295+
{
296+
unsigned long *pfns = kcalloc(size / PAGE_SIZE,
297+
sizeof(unsigned long), GFP_KERNEL);
298+
void *vaddr;
299+
int i;
300+
301+
if (!pfns)
302+
return NULL;
303+
304+
for (i = 0; i < size / PAGE_SIZE; i++)
305+
pfns[i] = vmalloc_to_pfn(addr + i * PAGE_SIZE) +
306+
(ms_hyperv.shared_gpa_boundary >> PAGE_SHIFT);
307+
308+
vaddr = vmap_pfn(pfns, size / PAGE_SIZE, PAGE_KERNEL_IO);
309+
kfree(pfns);
310+
311+
return vaddr;
312+
}
313+
314+
void hv_unmap_memory(void *addr)
315+
{
316+
vunmap(addr);
317+
}

arch/x86/hyperv/mmu.c

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,6 @@ static void hyperv_flush_tlb_multi(const struct cpumask *cpus,
6868

6969
local_irq_save(flags);
7070

71-
/*
72-
* Only check the mask _after_ interrupt has been disabled to avoid the
73-
* mask changing under our feet.
74-
*/
75-
if (cpumask_empty(cpus)) {
76-
local_irq_restore(flags);
77-
return;
78-
}
79-
8071
flush_pcpu = (struct hv_tlb_flush **)
8172
this_cpu_ptr(hyperv_pcpu_input_arg);
8273

@@ -115,7 +106,9 @@ static void hyperv_flush_tlb_multi(const struct cpumask *cpus,
115106
* must. We will also check all VP numbers when walking the
116107
* supplied CPU set to remain correct in all cases.
117108
*/
118-
if (hv_cpu_number_to_vp_number(cpumask_last(cpus)) >= 64)
109+
cpu = cpumask_last(cpus);
110+
111+
if (cpu < nr_cpumask_bits && hv_cpu_number_to_vp_number(cpu) >= 64)
119112
goto do_ex_hypercall;
120113

121114
for_each_cpu(cpu, cpus) {
@@ -131,6 +124,12 @@ static void hyperv_flush_tlb_multi(const struct cpumask *cpus,
131124
__set_bit(vcpu, (unsigned long *)
132125
&flush->processor_mask);
133126
}
127+
128+
/* nothing to flush if 'processor_mask' ends up being empty */
129+
if (!flush->processor_mask) {
130+
local_irq_restore(flags);
131+
return;
132+
}
134133
}
135134

136135
/*

arch/x86/include/asm/mshyperv.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ extern void *hv_hypercall_pg;
3030

3131
extern u64 hv_current_partition_id;
3232

33-
extern union hv_ghcb __percpu **hv_ghcb_pg;
33+
extern union hv_ghcb * __percpu *hv_ghcb_pg;
3434

3535
int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages);
3636
int hv_call_add_logical_proc(int node, u32 lp_index, u32 acpi_id);

arch/x86/kernel/cc_platform.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <linux/cc_platform.h>
1212
#include <linux/mem_encrypt.h>
1313

14+
#include <asm/mshyperv.h>
1415
#include <asm/processor.h>
1516

1617
static bool __maybe_unused intel_cc_platform_has(enum cc_attr attr)
@@ -66,12 +67,19 @@ static bool amd_cc_platform_has(enum cc_attr attr)
6667
#endif
6768
}
6869

70+
static bool hyperv_cc_platform_has(enum cc_attr attr)
71+
{
72+
return attr == CC_ATTR_GUEST_MEM_ENCRYPT;
73+
}
6974

7075
bool cc_platform_has(enum cc_attr attr)
7176
{
7277
if (sme_me_mask)
7378
return amd_cc_platform_has(attr);
7479

80+
if (hv_is_isolation_supported())
81+
return hyperv_cc_platform_has(attr);
82+
7583
return false;
7684
}
7785
EXPORT_SYMBOL_GPL(cc_platform_has);

arch/x86/kernel/cpu/mshyperv.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <linux/kexec.h>
1919
#include <linux/i8253.h>
2020
#include <linux/random.h>
21+
#include <linux/swiotlb.h>
2122
#include <asm/processor.h>
2223
#include <asm/hypervisor.h>
2324
#include <asm/hyperv-tlfs.h>
@@ -329,8 +330,20 @@ static void __init ms_hyperv_init_platform(void)
329330
pr_info("Hyper-V: Isolation Config: Group A 0x%x, Group B 0x%x\n",
330331
ms_hyperv.isolation_config_a, ms_hyperv.isolation_config_b);
331332

332-
if (hv_get_isolation_type() == HV_ISOLATION_TYPE_SNP)
333+
if (hv_get_isolation_type() == HV_ISOLATION_TYPE_SNP) {
333334
static_branch_enable(&isolation_type_snp);
335+
#ifdef CONFIG_SWIOTLB
336+
swiotlb_unencrypted_base = ms_hyperv.shared_gpa_boundary;
337+
#endif
338+
}
339+
340+
#ifdef CONFIG_SWIOTLB
341+
/*
342+
* Enable swiotlb force mode in Isolation VM to
343+
* use swiotlb bounce buffer for dma transaction.
344+
*/
345+
swiotlb_force = SWIOTLB_FORCE;
346+
#endif
334347
}
335348

336349
if (hv_max_functions_eax >= HYPERV_CPUID_NESTED_FEATURES) {

drivers/hv/channel_mgmt.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1554,7 +1554,7 @@ int vmbus_request_offers(void)
15541554
struct vmbus_channel_msginfo *msginfo;
15551555
int ret;
15561556

1557-
msginfo = kmalloc(sizeof(*msginfo) +
1557+
msginfo = kzalloc(sizeof(*msginfo) +
15581558
sizeof(struct vmbus_channel_message_header),
15591559
GFP_KERNEL);
15601560
if (!msginfo)

drivers/hv/hv_common.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ EXPORT_SYMBOL_GPL(hv_vp_index);
4444
u32 hv_max_vp_index;
4545
EXPORT_SYMBOL_GPL(hv_max_vp_index);
4646

47-
void __percpu **hyperv_pcpu_input_arg;
47+
void * __percpu *hyperv_pcpu_input_arg;
4848
EXPORT_SYMBOL_GPL(hyperv_pcpu_input_arg);
4949

50-
void __percpu **hyperv_pcpu_output_arg;
50+
void * __percpu *hyperv_pcpu_output_arg;
5151
EXPORT_SYMBOL_GPL(hyperv_pcpu_output_arg);
5252

5353
/*
@@ -295,3 +295,14 @@ u64 __weak hv_ghcb_hypercall(u64 control, void *input, void *output, u32 input_s
295295
return HV_STATUS_INVALID_PARAMETER;
296296
}
297297
EXPORT_SYMBOL_GPL(hv_ghcb_hypercall);
298+
299+
void __weak *hv_map_memory(void *addr, unsigned long size)
300+
{
301+
return NULL;
302+
}
303+
EXPORT_SYMBOL_GPL(hv_map_memory);
304+
305+
void __weak hv_unmap_memory(void *addr)
306+
{
307+
}
308+
EXPORT_SYMBOL_GPL(hv_unmap_memory);

drivers/hv/vmbus_drv.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include <linux/random.h>
3434
#include <linux/kernel.h>
3535
#include <linux/syscore_ops.h>
36+
#include <linux/dma-map-ops.h>
3637
#include <clocksource/hyperv_timer.h>
3738
#include "hyperv_vmbus.h"
3839

@@ -2078,6 +2079,7 @@ struct hv_device *vmbus_device_create(const guid_t *type,
20782079
return child_device_obj;
20792080
}
20802081

2082+
static u64 vmbus_dma_mask = DMA_BIT_MASK(64);
20812083
/*
20822084
* vmbus_device_register - Register the child device
20832085
*/
@@ -2118,6 +2120,8 @@ int vmbus_device_register(struct hv_device *child_device_obj)
21182120
}
21192121
hv_debug_add_dev_dir(child_device_obj);
21202122

2123+
child_device_obj->device.dma_mask = &vmbus_dma_mask;
2124+
child_device_obj->device.dma_parms = &child_device_obj->dma_parms;
21212125
return 0;
21222126

21232127
err_kset_unregister:

drivers/net/hyperv/hyperv_net.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ struct hv_netvsc_packet {
164164
u32 total_bytes;
165165
u32 send_buf_index;
166166
u32 total_data_buflen;
167+
struct hv_dma_range *dma_range;
167168
};
168169

169170
#define NETVSC_HASH_KEYLEN 40
@@ -1074,6 +1075,7 @@ struct netvsc_device {
10741075

10751076
/* Receive buffer allocated by us but manages by NetVSP */
10761077
void *recv_buf;
1078+
void *recv_original_buf;
10771079
u32 recv_buf_size; /* allocated bytes */
10781080
struct vmbus_gpadl recv_buf_gpadl_handle;
10791081
u32 recv_section_cnt;
@@ -1082,6 +1084,7 @@ struct netvsc_device {
10821084

10831085
/* Send buffer allocated by us */
10841086
void *send_buf;
1087+
void *send_original_buf;
10851088
u32 send_buf_size;
10861089
struct vmbus_gpadl send_buf_gpadl_handle;
10871090
u32 send_section_cnt;
@@ -1731,4 +1734,6 @@ struct rndis_message {
17311734
#define RETRY_US_HI 10000
17321735
#define RETRY_MAX 2000 /* >10 sec */
17331736

1737+
void netvsc_dma_unmap(struct hv_device *hv_dev,
1738+
struct hv_netvsc_packet *packet);
17341739
#endif /* _HYPERV_NET_H */

0 commit comments

Comments
 (0)