| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: hypervisor.c,v 1.73.2.8 2020/04/20 11:29:01 bouyer Exp $ */ | | 1 | /* $NetBSD: hypervisor.c,v 1.73.2.9 2020/04/22 20:49:08 bouyer Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2005 Manuel Bouyer. | | 4 | * Copyright (c) 2005 Manuel Bouyer. |
5 | * | | 5 | * |
6 | * Redistribution and use in source and binary forms, with or without | | 6 | * Redistribution and use in source and binary forms, with or without |
7 | * modification, are permitted provided that the following conditions | | 7 | * modification, are permitted provided that the following conditions |
8 | * are met: | | 8 | * are met: |
9 | * 1. Redistributions of source code must retain the above copyright | | 9 | * 1. Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. | | 10 | * notice, this list of conditions and the following disclaimer. |
11 | * 2. Redistributions in binary form must reproduce the above copyright | | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
12 | * notice, this list of conditions and the following disclaimer in the | | 12 | * notice, this list of conditions and the following disclaimer in the |
13 | * documentation and/or other materials provided with the distribution. | | 13 | * documentation and/or other materials provided with the distribution. |
14 | * | | 14 | * |
| @@ -43,27 +43,27 @@ | | | @@ -43,27 +43,27 @@ |
43 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 43 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
44 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 44 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
45 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 45 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
46 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | | 46 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
47 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | | 47 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
48 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | | 48 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
49 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 49 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
50 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | | 50 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
51 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 51 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
52 | */ | | 52 | */ |
53 | | | 53 | |
54 | | | 54 | |
55 | #include <sys/cdefs.h> | | 55 | #include <sys/cdefs.h> |
56 | __KERNEL_RCSID(0, "$NetBSD: hypervisor.c,v 1.73.2.8 2020/04/20 11:29:01 bouyer Exp $"); | | 56 | __KERNEL_RCSID(0, "$NetBSD: hypervisor.c,v 1.73.2.9 2020/04/22 20:49:08 bouyer Exp $"); |
57 | | | 57 | |
58 | #include <sys/param.h> | | 58 | #include <sys/param.h> |
59 | #include <sys/systm.h> | | 59 | #include <sys/systm.h> |
60 | #include <sys/device.h> | | 60 | #include <sys/device.h> |
61 | #include <sys/sysctl.h> | | 61 | #include <sys/sysctl.h> |
62 | | | 62 | |
63 | #include "xenbus.h" | | 63 | #include "xenbus.h" |
64 | #include "xencons.h" | | 64 | #include "xencons.h" |
65 | #include "isa.h" | | 65 | #include "isa.h" |
66 | #include "pci.h" | | 66 | #include "pci.h" |
67 | #include "acpica.h" | | 67 | #include "acpica.h" |
68 | | | 68 | |
69 | #include "opt_xen.h" | | 69 | #include "opt_xen.h" |
| @@ -389,28 +389,26 @@ xen_hvm_init_cpu(struct cpu_info *ci) | | | @@ -389,28 +389,26 @@ xen_hvm_init_cpu(struct cpu_info *ci) |
389 | | | 389 | |
390 | if (vm_guest != VM_GUEST_XENPVHVM) | | 390 | if (vm_guest != VM_GUEST_XENPVHVM) |
391 | return 0; | | 391 | return 0; |
392 | | | 392 | |
393 | KASSERT(ci == curcpu()); | | 393 | KASSERT(ci == curcpu()); |
394 | | | 394 | |
395 | descs[0] = 0; | | 395 | descs[0] = 0; |
396 | x86_cpuid(XEN_CPUID_LEAF(4), descs); | | 396 | x86_cpuid(XEN_CPUID_LEAF(4), descs); |
397 | if (!(descs[0] & XEN_HVM_CPUID_VCPU_ID_PRESENT)) { | | 397 | if (!(descs[0] & XEN_HVM_CPUID_VCPU_ID_PRESENT)) { |
398 | aprint_error_dev(ci->ci_dev, "Xen HVM: can't get VCPU id\n"); | | 398 | aprint_error_dev(ci->ci_dev, "Xen HVM: can't get VCPU id\n"); |
399 | vm_guest = VM_GUEST_XENHVM; | | 399 | vm_guest = VM_GUEST_XENHVM; |
400 | return 0; | | 400 | return 0; |
401 | } | | 401 | } |
402 | printf("cpu %s ci_acpiid %d vcpuid %d domid %d\n", | | | |
403 | device_xname(ci->ci_dev), ci->ci_acpiid, descs[1], descs[2]); | | | |
404 | | | 402 | |
405 | ci->ci_vcpuid = descs[1]; | | 403 | ci->ci_vcpuid = descs[1]; |
406 | ci->ci_vcpu = &HYPERVISOR_shared_info->vcpu_info[ci->ci_vcpuid]; | | 404 | ci->ci_vcpu = &HYPERVISOR_shared_info->vcpu_info[ci->ci_vcpuid]; |
407 | | | 405 | |
408 | /* Register event callback handler. */ | | 406 | /* Register event callback handler. */ |
409 | | | 407 | |
410 | xen_hvm_param.domid = DOMID_SELF; | | 408 | xen_hvm_param.domid = DOMID_SELF; |
411 | xen_hvm_param.index = HVM_PARAM_CALLBACK_IRQ; | | 409 | xen_hvm_param.index = HVM_PARAM_CALLBACK_IRQ; |
412 | | | 410 | |
413 | /* val[63:56] = 2, val[7:0] = vec */ | | 411 | /* val[63:56] = 2, val[7:0] = vec */ |
414 | xen_hvm_param.value = ((int64_t)0x2 << 56) | xen_hvm_vec; | | 412 | xen_hvm_param.value = ((int64_t)0x2 << 56) | xen_hvm_vec; |
415 | | | 413 | |
416 | /* First try to set up a per-cpu vector. */ | | 414 | /* First try to set up a per-cpu vector. */ |
| @@ -424,29 +422,29 @@ xen_hvm_init_cpu(struct cpu_info *ci) | | | @@ -424,29 +422,29 @@ xen_hvm_init_cpu(struct cpu_info *ci) |
424 | HVMOP_set_evtchn_upcall_vector, &xen_hvm_uvec); | | 422 | HVMOP_set_evtchn_upcall_vector, &xen_hvm_uvec); |
425 | if (error < 0) { | | 423 | if (error < 0) { |
426 | aprint_error_dev(ci->ci_dev, | | 424 | aprint_error_dev(ci->ci_dev, |
427 | "failed to set event upcall vector: %d\n", error); | | 425 | "failed to set event upcall vector: %d\n", error); |
428 | if (again) | | 426 | if (again) |
429 | panic("event upcall vector"); | | 427 | panic("event upcall vector"); |
430 | aprint_error_dev(ci->ci_dev, | | 428 | aprint_error_dev(ci->ci_dev, |
431 | "falling back to global vector\n"); | | 429 | "falling back to global vector\n"); |
432 | } else { | | 430 | } else { |
433 | /* | | 431 | /* |
434 | * From FreeBSD: | | 432 | * From FreeBSD: |
435 | * Trick toolstack to think we are enlightened | | 433 | * Trick toolstack to think we are enlightened |
436 | */ | | 434 | */ |
| | | 435 | xen_hvm_param.value = 1; |
437 | aprint_verbose_dev(ci->ci_dev, | | 436 | aprint_verbose_dev(ci->ci_dev, |
438 | "using event upcall vector: %d\n", xen_hvm_vec ); | | 437 | "using event upcall vector: %d\n", xen_hvm_vec ); |
439 | xen_hvm_param.value = 1; | | | |
440 | } | | 438 | } |
441 | } | | 439 | } |
442 | | | 440 | |
443 | if (again) | | 441 | if (again) |
444 | return 1; | | 442 | return 1; |
445 | | | 443 | |
446 | if (HYPERVISOR_hvm_op(HVMOP_set_param, &xen_hvm_param) < 0) { | | 444 | if (HYPERVISOR_hvm_op(HVMOP_set_param, &xen_hvm_param) < 0) { |
447 | aprint_error_dev(ci->ci_dev, | | 445 | aprint_error_dev(ci->ci_dev, |
448 | "Xen HVM: Unable to register event callback vector\n"); | | 446 | "Xen HVM: Unable to register event callback vector\n"); |
449 | vm_guest = VM_GUEST_XENHVM; | | 447 | vm_guest = VM_GUEST_XENHVM; |
450 | return 0; | | 448 | return 0; |
451 | } | | 449 | } |
452 | again = 1; | | 450 | again = 1; |
| @@ -466,34 +464,34 @@ hypervisor_match(device_t parent, cfdata | | | @@ -466,34 +464,34 @@ hypervisor_match(device_t parent, cfdata |
466 | /* Attach path sanity check */ | | 464 | /* Attach path sanity check */ |
467 | if (strncmp(haa->haa_busname, "hypervisor", sizeof("hypervisor")) != 0) | | 465 | if (strncmp(haa->haa_busname, "hypervisor", sizeof("hypervisor")) != 0) |
468 | return 0; | | 466 | return 0; |
469 | | | 467 | |
470 | | | 468 | |
471 | #ifdef XENPVHVM | | 469 | #ifdef XENPVHVM |
472 | if (vm_guest != VM_GUEST_XENPVHVM) | | 470 | if (vm_guest != VM_GUEST_XENPVHVM) |
473 | return 0; | | 471 | return 0; |
474 | #endif | | 472 | #endif |
475 | /* If we got here, it must mean we matched */ | | 473 | /* If we got here, it must mean we matched */ |
476 | return 1; | | 474 | return 1; |
477 | } | | 475 | } |
478 | | | 476 | |
479 | #ifdef MULTIPROCESSOR | | 477 | #if defined(MULTIPROCESSOR) && defined(XENPV) |
480 | static int | | 478 | static int |
481 | hypervisor_vcpu_print(void *aux, const char *parent) | | 479 | hypervisor_vcpu_print(void *aux, const char *parent) |
482 | { | | 480 | { |
483 | /* Unconfigured cpus are ignored quietly. */ | | 481 | /* Unconfigured cpus are ignored quietly. */ |
484 | return (QUIET); | | 482 | return (QUIET); |
485 | } | | 483 | } |
486 | #endif /* MULTIPROCESSOR */ | | 484 | #endif /* MULTIPROCESSOR && XENPV */ |
487 | | | 485 | |
488 | /* | | 486 | /* |
489 | * Attach the hypervisor. | | 487 | * Attach the hypervisor. |
490 | */ | | 488 | */ |
491 | void | | 489 | void |
492 | hypervisor_attach(device_t parent, device_t self, void *aux) | | 490 | hypervisor_attach(device_t parent, device_t self, void *aux) |
493 | { | | 491 | { |
494 | | | 492 | |
495 | #if NPCI >0 | | 493 | #if NPCI >0 |
496 | #ifdef PCI_BUS_FIXUP | | 494 | #ifdef PCI_BUS_FIXUP |
497 | int pci_maxbus = 0; | | 495 | int pci_maxbus = 0; |
498 | #endif | | 496 | #endif |
499 | #endif /* NPCI */ | | 497 | #endif /* NPCI */ |
| @@ -581,26 +579,27 @@ hypervisor_attach(device_t parent, devic | | | @@ -581,26 +579,27 @@ hypervisor_attach(device_t parent, devic |
581 | XEN_TST_F(pae_pgdir_above_4gb); | | 579 | XEN_TST_F(pae_pgdir_above_4gb); |
582 | XEN_TST_F(mmu_pt_update_preserve_ad); | | 580 | XEN_TST_F(mmu_pt_update_preserve_ad); |
583 | XEN_TST_F(highmem_assist); | | 581 | XEN_TST_F(highmem_assist); |
584 | XEN_TST_F(gnttab_map_avail_bits); | | 582 | XEN_TST_F(gnttab_map_avail_bits); |
585 | XEN_TST_F(hvm_callback_vector); | | 583 | XEN_TST_F(hvm_callback_vector); |
586 | XEN_TST_F(hvm_safe_pvclock); | | 584 | XEN_TST_F(hvm_safe_pvclock); |
587 | XEN_TST_F(hvm_pirqs); | | 585 | XEN_TST_F(hvm_pirqs); |
588 | #undef XEN_TST_F | | 586 | #undef XEN_TST_F |
589 | aprint_verbose("\n"); | | 587 | aprint_verbose("\n"); |
590 | | | 588 | |
591 | xengnt_init(); | | 589 | xengnt_init(); |
592 | events_init(); | | 590 | events_init(); |
593 | | | 591 | |
| | | 592 | #ifdef XENPV |
594 | memset(&hac, 0, sizeof(hac)); | | 593 | memset(&hac, 0, sizeof(hac)); |
595 | hac.hac_vcaa.vcaa_name = "vcpu"; | | 594 | hac.hac_vcaa.vcaa_name = "vcpu"; |
596 | hac.hac_vcaa.vcaa_caa.cpu_number = 0; | | 595 | hac.hac_vcaa.vcaa_caa.cpu_number = 0; |
597 | hac.hac_vcaa.vcaa_caa.cpu_role = CPU_ROLE_BP; | | 596 | hac.hac_vcaa.vcaa_caa.cpu_role = CPU_ROLE_BP; |
598 | hac.hac_vcaa.vcaa_caa.cpu_func = NULL; /* See xen/x86/cpu.c:vcpu_attach() */ | | 597 | hac.hac_vcaa.vcaa_caa.cpu_func = NULL; /* See xen/x86/cpu.c:vcpu_attach() */ |
599 | config_found_ia(self, "xendevbus", &hac.hac_vcaa, hypervisor_print); | | 598 | config_found_ia(self, "xendevbus", &hac.hac_vcaa, hypervisor_print); |
600 | | | 599 | |
601 | #ifdef MULTIPROCESSOR | | 600 | #ifdef MULTIPROCESSOR |
602 | | | 601 | |
603 | /* | | 602 | /* |
604 | * The xenstore contains the configured number of vcpus. | | 603 | * The xenstore contains the configured number of vcpus. |
605 | * The xenstore however, is not accessible until much later in | | 604 | * The xenstore however, is not accessible until much later in |
606 | * the boot sequence. We therefore bruteforce check for | | 605 | * the boot sequence. We therefore bruteforce check for |
| @@ -612,26 +611,27 @@ hypervisor_attach(device_t parent, devic | | | @@ -612,26 +611,27 @@ hypervisor_attach(device_t parent, devic |
612 | for (vcpuid = 1; vcpuid < maxcpus; vcpuid++) { | | 611 | for (vcpuid = 1; vcpuid < maxcpus; vcpuid++) { |
613 | memset(&hac, 0, sizeof(hac)); | | 612 | memset(&hac, 0, sizeof(hac)); |
614 | hac.hac_vcaa.vcaa_name = "vcpu"; | | 613 | hac.hac_vcaa.vcaa_name = "vcpu"; |
615 | hac.hac_vcaa.vcaa_caa.cpu_number = vcpuid; | | 614 | hac.hac_vcaa.vcaa_caa.cpu_number = vcpuid; |
616 | hac.hac_vcaa.vcaa_caa.cpu_role = CPU_ROLE_AP; | | 615 | hac.hac_vcaa.vcaa_caa.cpu_role = CPU_ROLE_AP; |
617 | hac.hac_vcaa.vcaa_caa.cpu_func = NULL; /* See xen/x86/cpu.c:vcpu_attach() */ | | 616 | hac.hac_vcaa.vcaa_caa.cpu_func = NULL; /* See xen/x86/cpu.c:vcpu_attach() */ |
618 | if (NULL == config_found_ia(self, "xendevbus", &hac.hac_vcaa, | | 617 | if (NULL == config_found_ia(self, "xendevbus", &hac.hac_vcaa, |
619 | hypervisor_vcpu_print)) { | | 618 | hypervisor_vcpu_print)) { |
620 | break; | | 619 | break; |
621 | } | | 620 | } |
622 | } | | 621 | } |
623 | | | 622 | |
624 | #endif /* MULTIPROCESSOR */ | | 623 | #endif /* MULTIPROCESSOR */ |
| | | 624 | #endif /* XENPV */ |
625 | | | 625 | |
626 | #if NXENBUS > 0 | | 626 | #if NXENBUS > 0 |
627 | extern struct x86_bus_dma_tag xenbus_bus_dma_tag; | | 627 | extern struct x86_bus_dma_tag xenbus_bus_dma_tag; |
628 | memset(&hac, 0, sizeof(hac)); | | 628 | memset(&hac, 0, sizeof(hac)); |
629 | hac.hac_xenbus.xa_device = "xenbus"; | | 629 | hac.hac_xenbus.xa_device = "xenbus"; |
630 | hac.hac_xenbus.xa_dmat = &xenbus_bus_dma_tag; | | 630 | hac.hac_xenbus.xa_dmat = &xenbus_bus_dma_tag; |
631 | config_found_ia(self, "xendevbus", &hac.hac_xenbus, hypervisor_print); | | 631 | config_found_ia(self, "xendevbus", &hac.hac_xenbus, hypervisor_print); |
632 | #endif | | 632 | #endif |
633 | #if NXENCONS > 0 | | 633 | #if NXENCONS > 0 |
634 | memset(&hac, 0, sizeof(hac)); | | 634 | memset(&hac, 0, sizeof(hac)); |
635 | hac.hac_xencons.xa_device = "xencons"; | | 635 | hac.hac_xencons.xa_device = "xencons"; |
636 | config_found_ia(self, "xendevbus", &hac.hac_xencons, hypervisor_print); | | 636 | config_found_ia(self, "xendevbus", &hac.hac_xencons, hypervisor_print); |
637 | #endif | | 637 | #endif |