|
19 | 19 | #include <linux/vmalloc.h>
|
20 | 20 | #include <linux/hyperv.h>
|
21 | 21 | #include <linux/export.h>
|
| 22 | +#include <linux/io.h> |
| 23 | +#include <linux/set_memory.h> |
22 | 24 | #include <asm/mshyperv.h>
|
23 | 25 |
|
24 | 26 | #include "hyperv_vmbus.h"
|
@@ -102,8 +104,9 @@ int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, u32 version)
|
102 | 104 | vmbus_connection.msg_conn_id = VMBUS_MESSAGE_CONNECTION_ID;
|
103 | 105 | }
|
104 | 106 |
|
105 |
| - msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages[0]); |
106 |
| - msg->monitor_page2 = virt_to_phys(vmbus_connection.monitor_pages[1]); |
| 107 | + msg->monitor_page1 = vmbus_connection.monitor_pages_pa[0]; |
| 108 | + msg->monitor_page2 = vmbus_connection.monitor_pages_pa[1]; |
| 109 | + |
107 | 110 | msg->target_vcpu = hv_cpu_number_to_vp_number(VMBUS_CONNECT_CPU);
|
108 | 111 |
|
109 | 112 | /*
|
@@ -216,6 +219,65 @@ int vmbus_connect(void)
|
216 | 219 | goto cleanup;
|
217 | 220 | }
|
218 | 221 |
|
| 222 | + vmbus_connection.monitor_pages_original[0] |
| 223 | + = vmbus_connection.monitor_pages[0]; |
| 224 | + vmbus_connection.monitor_pages_original[1] |
| 225 | + = vmbus_connection.monitor_pages[1]; |
| 226 | + vmbus_connection.monitor_pages_pa[0] |
| 227 | + = virt_to_phys(vmbus_connection.monitor_pages[0]); |
| 228 | + vmbus_connection.monitor_pages_pa[1] |
| 229 | + = virt_to_phys(vmbus_connection.monitor_pages[1]); |
| 230 | + |
| 231 | + if (hv_is_isolation_supported()) { |
| 232 | + ret = set_memory_decrypted((unsigned long) |
| 233 | + vmbus_connection.monitor_pages[0], |
| 234 | + 1); |
| 235 | + ret |= set_memory_decrypted((unsigned long) |
| 236 | + vmbus_connection.monitor_pages[1], |
| 237 | + 1); |
| 238 | + if (ret) |
| 239 | + goto cleanup; |
| 240 | + |
| 241 | + /* |
| 242 | + * Isolation VM with AMD SNP needs to access monitor page via |
| 243 | + * address space above shared gpa boundary. |
| 244 | + */ |
| 245 | + if (hv_isolation_type_snp()) { |
| 246 | + vmbus_connection.monitor_pages_pa[0] += |
| 247 | + ms_hyperv.shared_gpa_boundary; |
| 248 | + vmbus_connection.monitor_pages_pa[1] += |
| 249 | + ms_hyperv.shared_gpa_boundary; |
| 250 | + |
| 251 | + vmbus_connection.monitor_pages[0] |
| 252 | + = memremap(vmbus_connection.monitor_pages_pa[0], |
| 253 | + HV_HYP_PAGE_SIZE, |
| 254 | + MEMREMAP_WB); |
| 255 | + if (!vmbus_connection.monitor_pages[0]) { |
| 256 | + ret = -ENOMEM; |
| 257 | + goto cleanup; |
| 258 | + } |
| 259 | + |
| 260 | + vmbus_connection.monitor_pages[1] |
| 261 | + = memremap(vmbus_connection.monitor_pages_pa[1], |
| 262 | + HV_HYP_PAGE_SIZE, |
| 263 | + MEMREMAP_WB); |
| 264 | + if (!vmbus_connection.monitor_pages[1]) { |
| 265 | + ret = -ENOMEM; |
| 266 | + goto cleanup; |
| 267 | + } |
| 268 | + } |
| 269 | + |
| 270 | + /* |
| 271 | + * Set memory host visibility hvcall smears memory |
| 272 | + * and so zero monitor pages here. |
| 273 | + */ |
| 274 | + memset(vmbus_connection.monitor_pages[0], 0x00, |
| 275 | + HV_HYP_PAGE_SIZE); |
| 276 | + memset(vmbus_connection.monitor_pages[1], 0x00, |
| 277 | + HV_HYP_PAGE_SIZE); |
| 278 | + |
| 279 | + } |
| 280 | + |
219 | 281 | msginfo = kzalloc(sizeof(*msginfo) +
|
220 | 282 | sizeof(struct vmbus_channel_initiate_contact),
|
221 | 283 | GFP_KERNEL);
|
@@ -303,10 +365,31 @@ void vmbus_disconnect(void)
|
303 | 365 | vmbus_connection.int_page = NULL;
|
304 | 366 | }
|
305 | 367 |
|
306 |
| - hv_free_hyperv_page((unsigned long)vmbus_connection.monitor_pages[0]); |
307 |
| - hv_free_hyperv_page((unsigned long)vmbus_connection.monitor_pages[1]); |
308 |
| - vmbus_connection.monitor_pages[0] = NULL; |
309 |
| - vmbus_connection.monitor_pages[1] = NULL; |
| 368 | + if (hv_is_isolation_supported()) { |
| 369 | + /* |
| 370 | + * memunmap() checks input address is ioremap address or not |
| 371 | + * inside. It doesn't unmap any thing in the non-SNP CVM and |
| 372 | + * so not check CVM type here. |
| 373 | + */ |
| 374 | + memunmap(vmbus_connection.monitor_pages[0]); |
| 375 | + memunmap(vmbus_connection.monitor_pages[1]); |
| 376 | + |
| 377 | + set_memory_encrypted((unsigned long) |
| 378 | + vmbus_connection.monitor_pages_original[0], |
| 379 | + 1); |
| 380 | + set_memory_encrypted((unsigned long) |
| 381 | + vmbus_connection.monitor_pages_original[1], |
| 382 | + 1); |
| 383 | + } |
| 384 | + |
| 385 | + hv_free_hyperv_page((unsigned long) |
| 386 | + vmbus_connection.monitor_pages_original[0]); |
| 387 | + hv_free_hyperv_page((unsigned long) |
| 388 | + vmbus_connection.monitor_pages_original[1]); |
| 389 | + vmbus_connection.monitor_pages_original[0] = |
| 390 | + vmbus_connection.monitor_pages[0] = NULL; |
| 391 | + vmbus_connection.monitor_pages_original[1] = |
| 392 | + vmbus_connection.monitor_pages[1] = NULL; |
310 | 393 | }
|
311 | 394 |
|
312 | 395 | /*
|
|
0 commit comments