1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2009, Microsoft Corporation. 4 * 5 * Authors: 6 * Haiyang Zhang <haiyangz@microsoft.com> 7 * Hank Janssen <hjanssen@microsoft.com> 8 */ 9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 10 11 #include <linux/io.h> 12 #include <linux/kernel.h> 13 #include <linux/mm.h> 14 #include <linux/slab.h> 15 #include <linux/vmalloc.h> 16 #include <linux/hyperv.h> 17 #include <linux/random.h> 18 #include <linux/clockchips.h> 19 #include <linux/delay.h> 20 #include <linux/interrupt.h> 21 #include <linux/export.h> 22 #include <clocksource/hyperv_timer.h> 23 #include <asm/mshyperv.h> 24 #include <linux/set_memory.h> 25 #include "hyperv_vmbus.h" 26 27 /* The one and only */ 28 struct hv_context hv_context; 29 EXPORT_SYMBOL_FOR_MODULES(hv_context, "mshv_vtl"); 30 31 /* 32 * hv_init - Main initialization routine. 33 * 34 * This routine must be called before any other routines in here are called 35 */ 36 int hv_init(void) 37 { 38 hv_context.cpu_context = alloc_percpu(struct hv_per_cpu_context); 39 if (!hv_context.cpu_context) 40 return -ENOMEM; 41 return 0; 42 } 43 44 /* 45 * hv_post_message - Post a message using the hypervisor message IPC. 46 * 47 * This involves a hypercall. 48 */ 49 int hv_post_message(union hv_connection_id connection_id, 50 enum hv_message_type message_type, 51 void *payload, size_t payload_size) 52 { 53 struct hv_input_post_message *aligned_msg; 54 unsigned long flags; 55 u64 status; 56 57 if (payload_size > HV_MESSAGE_PAYLOAD_BYTE_COUNT) 58 return -EMSGSIZE; 59 60 local_irq_save(flags); 61 62 /* 63 * A TDX VM with the paravisor must use the decrypted post_msg_page: see 64 * the comment in struct hv_per_cpu_context. A SNP VM with the paravisor 65 * can use the encrypted hyperv_pcpu_input_arg because it copies the 66 * input into the GHCB page, which has been decrypted by the paravisor. 67 */ 68 if (hv_isolation_type_tdx() && ms_hyperv.paravisor_present) 69 aligned_msg = this_cpu_ptr(hv_context.cpu_context)->post_msg_page; 70 else 71 aligned_msg = *this_cpu_ptr(hyperv_pcpu_input_arg); 72 73 aligned_msg->connectionid = connection_id; 74 aligned_msg->reserved = 0; 75 aligned_msg->message_type = message_type; 76 aligned_msg->payload_size = payload_size; 77 memcpy((void *)aligned_msg->payload, payload, payload_size); 78 79 if (ms_hyperv.paravisor_present && !vmbus_is_confidential()) { 80 /* 81 * If the VMBus isn't confidential, use the CoCo-specific 82 * mechanism to communicate with the hypervisor. 83 */ 84 if (hv_isolation_type_tdx()) 85 status = hv_tdx_hypercall(HVCALL_POST_MESSAGE, 86 virt_to_phys(aligned_msg), 0); 87 else if (hv_isolation_type_snp()) 88 status = hv_ghcb_hypercall(HVCALL_POST_MESSAGE, 89 aligned_msg, NULL, 90 sizeof(*aligned_msg)); 91 else 92 status = HV_STATUS_INVALID_PARAMETER; 93 } else { 94 u64 control = HVCALL_POST_MESSAGE; 95 96 control |= hv_nested ? HV_HYPERCALL_NESTED : 0; 97 /* 98 * If there is no paravisor, this will go to the hypervisor. 99 * In the Confidential VMBus case, there is the paravisor 100 * to which this will trap. 101 */ 102 status = hv_do_hypercall(control, aligned_msg, NULL); 103 } 104 105 local_irq_restore(flags); 106 107 return hv_result(status); 108 } 109 EXPORT_SYMBOL_FOR_MODULES(hv_post_message, "mshv_vtl"); 110 111 static int hv_alloc_page(void **page, bool decrypt, const char *note) 112 { 113 int ret = 0; 114 115 /* 116 * After the page changes its encryption status, its contents might 117 * appear scrambled on some hardware. Thus `get_zeroed_page` would 118 * zero the page out in vain, so do that explicitly exactly once. 119 * 120 * By default, the page is allocated encrypted in a CoCo VM. 121 */ 122 *page = (void *)__get_free_page(GFP_KERNEL); 123 if (!*page) 124 return -ENOMEM; 125 126 if (decrypt) 127 ret = set_memory_decrypted((unsigned long)*page, 1); 128 if (ret) 129 goto failed; 130 131 memset(*page, 0, PAGE_SIZE); 132 return 0; 133 134 failed: 135 /* 136 * Report the failure but don't put the page back on the free list as 137 * its encryption status is unknown. 138 */ 139 pr_err("allocation failed for %s page, error %d, decrypted %d\n", 140 note, ret, decrypt); 141 *page = NULL; 142 return ret; 143 } 144 145 static int hv_free_page(void **page, bool encrypt, const char *note) 146 { 147 int ret = 0; 148 149 if (!*page) 150 return 0; 151 152 if (encrypt) 153 ret = set_memory_encrypted((unsigned long)*page, 1); 154 155 /* 156 * In the case of the failure, the page is leaked. Something is wrong, 157 * prefer to lose the page with the unknown encryption status and stay afloat. 158 */ 159 if (ret) 160 pr_err("deallocation failed for %s page, error %d, encrypt %d\n", 161 note, ret, encrypt); 162 else 163 free_page((unsigned long)*page); 164 165 *page = NULL; 166 167 return ret; 168 } 169 170 int hv_synic_alloc(void) 171 { 172 int cpu, ret = -ENOMEM; 173 struct hv_per_cpu_context *hv_cpu; 174 const bool decrypt = !vmbus_is_confidential(); 175 176 /* 177 * First, zero all per-cpu memory areas so hv_synic_free() can 178 * detect what memory has been allocated and cleanup properly 179 * after any failures. 180 */ 181 for_each_present_cpu(cpu) { 182 hv_cpu = per_cpu_ptr(hv_context.cpu_context, cpu); 183 memset(hv_cpu, 0, sizeof(*hv_cpu)); 184 } 185 186 hv_context.hv_numa_map = kzalloc_objs(struct cpumask, nr_node_ids); 187 if (!hv_context.hv_numa_map) { 188 pr_err("Unable to allocate NUMA map\n"); 189 goto err; 190 } 191 192 for_each_present_cpu(cpu) { 193 hv_cpu = per_cpu_ptr(hv_context.cpu_context, cpu); 194 195 tasklet_init(&hv_cpu->msg_dpc, 196 vmbus_on_msg_dpc, (unsigned long)hv_cpu); 197 198 if (ms_hyperv.paravisor_present && hv_isolation_type_tdx()) { 199 ret = hv_alloc_page(&hv_cpu->post_msg_page, 200 decrypt, "post msg"); 201 if (ret) 202 goto err; 203 } 204 205 /* 206 * If these SynIC pages are not allocated, SIEF and SIM pages 207 * are configured using what the root partition or the paravisor 208 * provides upon reading the SIEFP and SIMP registers. 209 */ 210 if (!ms_hyperv.paravisor_present && !hv_root_partition()) { 211 ret = hv_alloc_page(&hv_cpu->hyp_synic_message_page, 212 decrypt, "hypervisor SynIC msg"); 213 if (ret) 214 goto err; 215 ret = hv_alloc_page(&hv_cpu->hyp_synic_event_page, 216 decrypt, "hypervisor SynIC event"); 217 if (ret) 218 goto err; 219 } 220 221 if (vmbus_is_confidential()) { 222 ret = hv_alloc_page(&hv_cpu->para_synic_message_page, 223 false, "paravisor SynIC msg"); 224 if (ret) 225 goto err; 226 ret = hv_alloc_page(&hv_cpu->para_synic_event_page, 227 false, "paravisor SynIC event"); 228 if (ret) 229 goto err; 230 } 231 } 232 233 return 0; 234 235 err: 236 /* 237 * Any memory allocations that succeeded will be freed when 238 * the caller cleans up by calling hv_synic_free() 239 */ 240 return ret; 241 } 242 243 void hv_synic_free(void) 244 { 245 int cpu; 246 const bool encrypt = !vmbus_is_confidential(); 247 248 for_each_present_cpu(cpu) { 249 struct hv_per_cpu_context *hv_cpu = 250 per_cpu_ptr(hv_context.cpu_context, cpu); 251 252 if (ms_hyperv.paravisor_present && hv_isolation_type_tdx()) 253 hv_free_page(&hv_cpu->post_msg_page, 254 encrypt, "post msg"); 255 if (!ms_hyperv.paravisor_present && !hv_root_partition()) { 256 hv_free_page(&hv_cpu->hyp_synic_event_page, 257 encrypt, "hypervisor SynIC event"); 258 hv_free_page(&hv_cpu->hyp_synic_message_page, 259 encrypt, "hypervisor SynIC msg"); 260 } 261 if (vmbus_is_confidential()) { 262 hv_free_page(&hv_cpu->para_synic_event_page, 263 false, "paravisor SynIC event"); 264 hv_free_page(&hv_cpu->para_synic_message_page, 265 false, "paravisor SynIC msg"); 266 } 267 } 268 269 kfree(hv_context.hv_numa_map); 270 } 271 272 /* 273 * hv_hyp_synic_enable_regs - Initialize the Synthetic Interrupt Controller 274 * with the hypervisor. 275 * 276 * Note: When MSHV is present, mshv_synic_cpu_init() intializes further 277 * registers later. 278 */ 279 void hv_hyp_synic_enable_regs(unsigned int cpu) 280 { 281 struct hv_per_cpu_context *hv_cpu = 282 per_cpu_ptr(hv_context.cpu_context, cpu); 283 union hv_synic_simp simp; 284 union hv_synic_siefp siefp; 285 union hv_synic_sint shared_sint; 286 287 /* Setup the Synic's message page with the hypervisor. */ 288 simp.as_uint64 = hv_get_msr(HV_MSR_SIMP); 289 simp.simp_enabled = 1; 290 291 if (ms_hyperv.paravisor_present || hv_root_partition()) { 292 /* Mask out vTOM bit and map as decrypted */ 293 u64 base = (simp.base_simp_gpa << HV_HYP_PAGE_SHIFT) & 294 ~ms_hyperv.shared_gpa_boundary; 295 hv_cpu->hyp_synic_message_page = 296 memremap(base, HV_HYP_PAGE_SIZE, MEMREMAP_WB | MEMREMAP_DEC); 297 if (!hv_cpu->hyp_synic_message_page) 298 pr_err("Fail to map synic message page.\n"); 299 } else { 300 simp.base_simp_gpa = virt_to_phys(hv_cpu->hyp_synic_message_page) 301 >> HV_HYP_PAGE_SHIFT; 302 } 303 304 hv_set_msr(HV_MSR_SIMP, simp.as_uint64); 305 306 /* Setup the Synic's event page with the hypervisor. */ 307 siefp.as_uint64 = hv_get_msr(HV_MSR_SIEFP); 308 siefp.siefp_enabled = 1; 309 310 if (ms_hyperv.paravisor_present || hv_root_partition()) { 311 /* Mask out vTOM bit and map as decrypted */ 312 u64 base = (siefp.base_siefp_gpa << HV_HYP_PAGE_SHIFT) & 313 ~ms_hyperv.shared_gpa_boundary; 314 hv_cpu->hyp_synic_event_page = 315 memremap(base, HV_HYP_PAGE_SIZE, MEMREMAP_WB | MEMREMAP_DEC); 316 if (!hv_cpu->hyp_synic_event_page) 317 pr_err("Fail to map synic event page.\n"); 318 } else { 319 siefp.base_siefp_gpa = virt_to_phys(hv_cpu->hyp_synic_event_page) 320 >> HV_HYP_PAGE_SHIFT; 321 } 322 323 hv_set_msr(HV_MSR_SIEFP, siefp.as_uint64); 324 hv_enable_coco_interrupt(cpu, vmbus_interrupt, true); 325 326 /* Setup the shared SINT. */ 327 if (vmbus_irq != -1) 328 enable_percpu_irq(vmbus_irq, 0); 329 shared_sint.as_uint64 = hv_get_msr(HV_MSR_SINT0 + VMBUS_MESSAGE_SINT); 330 331 shared_sint.vector = vmbus_interrupt; 332 shared_sint.masked = false; 333 shared_sint.auto_eoi = hv_recommend_using_aeoi(); 334 hv_set_msr(HV_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64); 335 } 336 337 static void hv_hyp_synic_enable_interrupts(void) 338 { 339 union hv_synic_scontrol sctrl; 340 341 /* Enable the global synic bit */ 342 sctrl.as_uint64 = hv_get_msr(HV_MSR_SCONTROL); 343 sctrl.enable = 1; 344 345 hv_set_msr(HV_MSR_SCONTROL, sctrl.as_uint64); 346 } 347 348 static void hv_para_synic_enable_regs(unsigned int cpu) 349 { 350 union hv_synic_simp simp; 351 union hv_synic_siefp siefp; 352 struct hv_per_cpu_context *hv_cpu 353 = per_cpu_ptr(hv_context.cpu_context, cpu); 354 355 /* Setup the Synic's message page with the paravisor. */ 356 simp.as_uint64 = hv_para_get_synic_register(HV_MSR_SIMP); 357 simp.simp_enabled = 1; 358 simp.base_simp_gpa = virt_to_phys(hv_cpu->para_synic_message_page) 359 >> HV_HYP_PAGE_SHIFT; 360 hv_para_set_synic_register(HV_MSR_SIMP, simp.as_uint64); 361 362 /* Setup the Synic's event page with the paravisor. */ 363 siefp.as_uint64 = hv_para_get_synic_register(HV_MSR_SIEFP); 364 siefp.siefp_enabled = 1; 365 siefp.base_siefp_gpa = virt_to_phys(hv_cpu->para_synic_event_page) 366 >> HV_HYP_PAGE_SHIFT; 367 hv_para_set_synic_register(HV_MSR_SIEFP, siefp.as_uint64); 368 } 369 370 static void hv_para_synic_enable_interrupts(void) 371 { 372 union hv_synic_scontrol sctrl; 373 374 /* Enable the global synic bit */ 375 sctrl.as_uint64 = hv_para_get_synic_register(HV_MSR_SCONTROL); 376 sctrl.enable = 1; 377 hv_para_set_synic_register(HV_MSR_SCONTROL, sctrl.as_uint64); 378 } 379 380 int hv_synic_init(unsigned int cpu) 381 { 382 if (vmbus_is_confidential()) 383 hv_para_synic_enable_regs(cpu); 384 385 /* 386 * The SINT is set in hv_hyp_synic_enable_regs() by calling 387 * hv_set_msr(). hv_set_msr() in turn has special case code for the 388 * SINT MSRs that write to the hypervisor version of the MSR *and* 389 * the paravisor version of the MSR (but *without* the proxy bit when 390 * VMBus is confidential). 391 * 392 * Then enable interrupts via the paravisor if VMBus is confidential, 393 * and otherwise via the hypervisor. 394 */ 395 396 hv_hyp_synic_enable_regs(cpu); 397 if (vmbus_is_confidential()) 398 hv_para_synic_enable_interrupts(); 399 else 400 hv_hyp_synic_enable_interrupts(); 401 402 hv_stimer_legacy_init(cpu, VMBUS_MESSAGE_SINT); 403 404 return 0; 405 } 406 407 void hv_hyp_synic_disable_regs(unsigned int cpu) 408 { 409 struct hv_per_cpu_context *hv_cpu = 410 per_cpu_ptr(hv_context.cpu_context, cpu); 411 union hv_synic_sint shared_sint; 412 union hv_synic_simp simp; 413 union hv_synic_siefp siefp; 414 415 shared_sint.as_uint64 = hv_get_msr(HV_MSR_SINT0 + VMBUS_MESSAGE_SINT); 416 417 shared_sint.masked = 1; 418 419 /* Need to correctly cleanup in the case of SMP!!! */ 420 /* Disable the interrupt */ 421 hv_set_msr(HV_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64); 422 hv_enable_coco_interrupt(cpu, vmbus_interrupt, false); 423 424 simp.as_uint64 = hv_get_msr(HV_MSR_SIMP); 425 /* 426 * In Isolation VM, simp and sief pages are allocated by 427 * paravisor. These pages also will be used by kdump 428 * kernel. So just reset enable bit here and keep page 429 * addresses. 430 */ 431 simp.simp_enabled = 0; 432 if (ms_hyperv.paravisor_present || hv_root_partition()) { 433 if (hv_cpu->hyp_synic_message_page) { 434 memunmap(hv_cpu->hyp_synic_message_page); 435 hv_cpu->hyp_synic_message_page = NULL; 436 } 437 } else { 438 simp.base_simp_gpa = 0; 439 } 440 441 hv_set_msr(HV_MSR_SIMP, simp.as_uint64); 442 443 siefp.as_uint64 = hv_get_msr(HV_MSR_SIEFP); 444 siefp.siefp_enabled = 0; 445 446 if (ms_hyperv.paravisor_present || hv_root_partition()) { 447 if (hv_cpu->hyp_synic_event_page) { 448 memunmap(hv_cpu->hyp_synic_event_page); 449 hv_cpu->hyp_synic_event_page = NULL; 450 } 451 } else { 452 siefp.base_siefp_gpa = 0; 453 } 454 455 hv_set_msr(HV_MSR_SIEFP, siefp.as_uint64); 456 } 457 458 static void hv_hyp_synic_disable_interrupts(void) 459 { 460 union hv_synic_scontrol sctrl; 461 462 /* Disable the global synic bit */ 463 sctrl.as_uint64 = hv_get_msr(HV_MSR_SCONTROL); 464 sctrl.enable = 0; 465 hv_set_msr(HV_MSR_SCONTROL, sctrl.as_uint64); 466 } 467 468 static void hv_para_synic_disable_regs(unsigned int cpu) 469 { 470 union hv_synic_simp simp; 471 union hv_synic_siefp siefp; 472 473 /* Disable SynIC's message page in the paravisor. */ 474 simp.as_uint64 = hv_para_get_synic_register(HV_MSR_SIMP); 475 simp.simp_enabled = 0; 476 hv_para_set_synic_register(HV_MSR_SIMP, simp.as_uint64); 477 478 /* Disable SynIC's event page in the paravisor. */ 479 siefp.as_uint64 = hv_para_get_synic_register(HV_MSR_SIEFP); 480 siefp.siefp_enabled = 0; 481 hv_para_set_synic_register(HV_MSR_SIEFP, siefp.as_uint64); 482 } 483 484 static void hv_para_synic_disable_interrupts(void) 485 { 486 union hv_synic_scontrol sctrl; 487 488 /* Disable the global synic bit */ 489 sctrl.as_uint64 = hv_para_get_synic_register(HV_MSR_SCONTROL); 490 sctrl.enable = 0; 491 hv_para_set_synic_register(HV_MSR_SCONTROL, sctrl.as_uint64); 492 } 493 494 #define HV_MAX_TRIES 3 495 /* 496 * Scan the event flags page of 'this' CPU looking for any bit that is set. If we find one 497 * bit set, then wait for a few milliseconds. Repeat these steps for a maximum of 3 times. 498 * Return 'true', if there is still any set bit after this operation; 'false', otherwise. 499 * 500 * If a bit is set, that means there is a pending channel interrupt. The expectation is 501 * that the normal interrupt handling mechanism will find and process the channel interrupt 502 * "very soon", and in the process clear the bit. 503 */ 504 static bool __hv_synic_event_pending(union hv_synic_event_flags *event, int sint) 505 { 506 unsigned long *recv_int_page; 507 bool pending; 508 u32 relid; 509 int tries = 0; 510 511 if (!event) 512 return false; 513 514 event += sint; 515 recv_int_page = event->flags; /* assumes VMBus version >= VERSION_WIN8 */ 516 retry: 517 pending = false; 518 for_each_set_bit(relid, recv_int_page, HV_EVENT_FLAGS_COUNT) { 519 /* Special case - VMBus channel protocol messages */ 520 if (relid == 0) 521 continue; 522 pending = true; 523 break; 524 } 525 if (pending && tries++ < HV_MAX_TRIES) { 526 usleep_range(10000, 20000); 527 goto retry; 528 } 529 return pending; 530 } 531 532 static bool hv_synic_event_pending(void) 533 { 534 struct hv_per_cpu_context *hv_cpu = this_cpu_ptr(hv_context.cpu_context); 535 union hv_synic_event_flags *hyp_synic_event_page = hv_cpu->hyp_synic_event_page; 536 union hv_synic_event_flags *para_synic_event_page = hv_cpu->para_synic_event_page; 537 538 return 539 __hv_synic_event_pending(hyp_synic_event_page, VMBUS_MESSAGE_SINT) || 540 __hv_synic_event_pending(para_synic_event_page, VMBUS_MESSAGE_SINT); 541 } 542 543 static int hv_pick_new_cpu(struct vmbus_channel *channel) 544 { 545 int ret = -EBUSY; 546 int start; 547 int cpu; 548 549 lockdep_assert_cpus_held(); 550 lockdep_assert_held(&vmbus_connection.channel_mutex); 551 552 /* 553 * We can't assume that the relevant interrupts will be sent before 554 * the cpu is offlined on older versions of hyperv. 555 */ 556 if (vmbus_proto_version < VERSION_WIN10_V5_3) 557 return -EBUSY; 558 559 start = get_random_u32_below(nr_cpu_ids); 560 561 for_each_cpu_wrap(cpu, cpu_online_mask, start) { 562 if (channel->target_cpu == cpu || 563 channel->target_cpu == VMBUS_CONNECT_CPU) 564 continue; 565 566 ret = vmbus_channel_set_cpu(channel, cpu); 567 if (!ret) 568 break; 569 } 570 571 if (ret) 572 ret = vmbus_channel_set_cpu(channel, VMBUS_CONNECT_CPU); 573 574 return ret; 575 } 576 577 /* 578 * hv_synic_cleanup - Cleanup routine for hv_synic_init(). 579 */ 580 int hv_synic_cleanup(unsigned int cpu) 581 { 582 struct vmbus_channel *channel, *sc; 583 int ret = 0; 584 585 if (vmbus_connection.conn_state != CONNECTED) 586 goto always_cleanup; 587 588 /* 589 * Hyper-V does not provide a way to change the connect CPU once 590 * it is set; we must prevent the connect CPU from going offline 591 * while the VM is running normally. But in the panic or kexec() 592 * path where the vmbus is already disconnected, the CPU must be 593 * allowed to shut down. 594 */ 595 if (cpu == VMBUS_CONNECT_CPU) 596 return -EBUSY; 597 598 /* 599 * Search for channels which are bound to the CPU we're about to 600 * cleanup. 601 */ 602 mutex_lock(&vmbus_connection.channel_mutex); 603 list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) { 604 if (channel->target_cpu == cpu) { 605 ret = hv_pick_new_cpu(channel); 606 if (ret) { 607 mutex_unlock(&vmbus_connection.channel_mutex); 608 return ret; 609 } 610 } 611 list_for_each_entry(sc, &channel->sc_list, sc_list) { 612 if (sc->target_cpu == cpu) { 613 ret = hv_pick_new_cpu(sc); 614 if (ret) { 615 mutex_unlock(&vmbus_connection.channel_mutex); 616 return ret; 617 } 618 } 619 } 620 } 621 mutex_unlock(&vmbus_connection.channel_mutex); 622 623 /* 624 * Scan the event flags page looking for bits that are set and waiting 625 * with a timeout for vmbus_chan_sched() to process such bits. If bits 626 * are still set after this operation and VMBus is connected, fail the 627 * CPU offlining operation. 628 */ 629 if (vmbus_proto_version >= VERSION_WIN10_V4_1 && hv_synic_event_pending()) 630 return -EBUSY; 631 632 always_cleanup: 633 hv_stimer_legacy_cleanup(cpu); 634 635 /* 636 * First, disable the event and message pages 637 * used for communicating with the host, and then 638 * disable the host interrupts if VMBus is not 639 * confidential. 640 */ 641 hv_hyp_synic_disable_regs(cpu); 642 if (!vmbus_is_confidential()) 643 hv_hyp_synic_disable_interrupts(); 644 645 /* 646 * Perform the same steps for the Confidential VMBus. 647 * The sequencing provides the guarantee that no data 648 * may be posted for processing before disabling interrupts. 649 */ 650 if (vmbus_is_confidential()) { 651 hv_para_synic_disable_regs(cpu); 652 hv_para_synic_disable_interrupts(); 653 } 654 if (vmbus_irq != -1) 655 disable_percpu_irq(vmbus_irq); 656 657 return ret; 658 } 659