hvm.c (255726) | hvm.c (255744) |
---|---|
1/* 2 * Copyright (c) 2008, 2013 Citrix Systems, Inc. 3 * Copyright (c) 2012 Spectra Logic Corporation 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 12 unchanged lines hidden (view full) --- 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28#include <sys/cdefs.h> | 1/* 2 * Copyright (c) 2008, 2013 Citrix Systems, Inc. 3 * Copyright (c) 2012 Spectra Logic Corporation 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 12 unchanged lines hidden (view full) --- 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28#include <sys/cdefs.h> |
29__FBSDID("$FreeBSD: head/sys/x86/xen/hvm.c 255726 2013-09-20 05:06:03Z gibbs $"); | 29__FBSDID("$FreeBSD: head/sys/x86/xen/hvm.c 255744 2013-09-20 22:59:22Z gibbs $"); |
30 31#include <sys/param.h> 32#include <sys/bus.h> 33#include <sys/kernel.h> 34#include <sys/malloc.h> 35#include <sys/proc.h> 36#include <sys/smp.h> 37#include <sys/systm.h> --- 29 unchanged lines hidden (view full) --- 67#ifdef __i386__ 68static driver_filter_t xen_lazypmap; 69#endif 70static driver_filter_t xen_ipi_bitmap_handler; 71static driver_filter_t xen_cpustop_handler; 72static driver_filter_t xen_cpususpend_handler; 73static driver_filter_t xen_cpustophard_handler; 74#endif | 30 31#include <sys/param.h> 32#include <sys/bus.h> 33#include <sys/kernel.h> 34#include <sys/malloc.h> 35#include <sys/proc.h> 36#include <sys/smp.h> 37#include <sys/systm.h> --- 29 unchanged lines hidden (view full) --- 67#ifdef __i386__ 68static driver_filter_t xen_lazypmap; 69#endif 70static driver_filter_t xen_ipi_bitmap_handler; 71static driver_filter_t xen_cpustop_handler; 72static driver_filter_t xen_cpususpend_handler; 73static driver_filter_t xen_cpustophard_handler; 74#endif |
75static void xen_ipi_vectored(u_int vector, int dest); 76static void xen_hvm_cpu_resume(void); 77static void xen_hvm_cpu_init(void); |
|
75 76/*---------------------------- Extern Declarations ---------------------------*/ 77/* Variables used by mp_machdep to perform the MMU related IPIs */ 78extern volatile int smp_tlb_wait; 79extern vm_offset_t smp_tlb_addr2; 80#ifdef __i386__ 81extern vm_offset_t smp_tlb_addr1; 82#else 83extern struct invpcid_descr smp_tlb_invpcid; 84extern uint64_t pcid_cr3; 85extern int invpcid_works; 86extern int pmap_pcid_enabled; 87extern pmap_t smp_tlb_pmap; 88#endif 89 90#ifdef __i386__ 91extern void pmap_lazyfix_action(void); 92#endif 93 | 78 79/*---------------------------- Extern Declarations ---------------------------*/ 80/* Variables used by mp_machdep to perform the MMU related IPIs */ 81extern volatile int smp_tlb_wait; 82extern vm_offset_t smp_tlb_addr2; 83#ifdef __i386__ 84extern vm_offset_t smp_tlb_addr1; 85#else 86extern struct invpcid_descr smp_tlb_invpcid; 87extern uint64_t pcid_cr3; 88extern int invpcid_works; 89extern int pmap_pcid_enabled; 90extern pmap_t smp_tlb_pmap; 91#endif 92 93#ifdef __i386__ 94extern void pmap_lazyfix_action(void); 95#endif 96 |
97/* Variables used by mp_machdep to perform the bitmap IPI */ 98extern volatile u_int cpu_ipi_pending[MAXCPU]; 99 |
|
94/*---------------------------------- Macros ----------------------------------*/ 95#define IPI_TO_IDX(ipi) ((ipi) - APIC_IPI_INTS) 96 97/*-------------------------------- Local Types -------------------------------*/ 98enum xen_hvm_init_type { 99 XEN_HVM_INIT_COLD, 100 XEN_HVM_INIT_CANCELLED_SUSPEND, 101 XEN_HVM_INIT_RESUME 102}; 103 104struct xen_ipi_handler 105{ 106 driver_filter_t *filter; 107 const char *description; 108}; 109 110/*-------------------------------- Global Data -------------------------------*/ 111enum xen_domain_type xen_domain_type = XEN_NATIVE; 112 | 100/*---------------------------------- Macros ----------------------------------*/ 101#define IPI_TO_IDX(ipi) ((ipi) - APIC_IPI_INTS) 102 103/*-------------------------------- Local Types -------------------------------*/ 104enum xen_hvm_init_type { 105 XEN_HVM_INIT_COLD, 106 XEN_HVM_INIT_CANCELLED_SUSPEND, 107 XEN_HVM_INIT_RESUME 108}; 109 110struct xen_ipi_handler 111{ 112 driver_filter_t *filter; 113 const char *description; 114}; 115 116/*-------------------------------- Global Data -------------------------------*/ 117enum xen_domain_type xen_domain_type = XEN_NATIVE; 118 |
119struct cpu_ops xen_hvm_cpu_ops = { 120 .ipi_vectored = xen_ipi_vectored, 121 .cpu_init = xen_hvm_cpu_init, 122 .cpu_resume = xen_hvm_cpu_resume 123}; 124 |
|
113static MALLOC_DEFINE(M_XENHVM, "xen_hvm", "Xen HVM PV Support"); 114 115#ifdef SMP 116static struct xen_ipi_handler xen_ipis[] = 117{ 118 [IPI_TO_IDX(IPI_RENDEZVOUS)] = { xen_smp_rendezvous_action, "r" }, 119 [IPI_TO_IDX(IPI_INVLTLB)] = { xen_invltlb, "itlb"}, 120 [IPI_TO_IDX(IPI_INVLPG)] = { xen_invlpg, "ipg" }, --- 336 unchanged lines hidden (view full) --- 457 default: 458 to_cpu = apic_cpuid(dest); 459 ipi_handle = DPCPU_ID_GET(to_cpu, ipi_handle); 460 xen_intr_signal(ipi_handle[ipi_idx]); 461 break; 462 } 463} 464 | 125static MALLOC_DEFINE(M_XENHVM, "xen_hvm", "Xen HVM PV Support"); 126 127#ifdef SMP 128static struct xen_ipi_handler xen_ipis[] = 129{ 130 [IPI_TO_IDX(IPI_RENDEZVOUS)] = { xen_smp_rendezvous_action, "r" }, 131 [IPI_TO_IDX(IPI_INVLTLB)] = { xen_invltlb, "itlb"}, 132 [IPI_TO_IDX(IPI_INVLPG)] = { xen_invlpg, "ipg" }, --- 336 unchanged lines hidden (view full) --- 469 default: 470 to_cpu = apic_cpuid(dest); 471 ipi_handle = DPCPU_ID_GET(to_cpu, ipi_handle); 472 xen_intr_signal(ipi_handle[ipi_idx]); 473 break; 474 } 475} 476 |
477/* XEN diverged cpu operations */ |
|
465static void | 478static void |
479xen_hvm_cpu_resume(void) 480{ 481 u_int cpuid = PCPU_GET(cpuid); 482 483 /* 484 * Reset pending bitmap IPIs, because Xen doesn't preserve pending 485 * event channels on migration. 486 */ 487 cpu_ipi_pending[cpuid] = 0; 488 489 /* register vcpu_info area */ 490 xen_hvm_cpu_init(); 491} 492 493static void |
|
466xen_cpu_ipi_init(int cpu) 467{ 468 xen_intr_handle_t *ipi_handle; 469 const struct xen_ipi_handler *ipi; 470 device_t dev; 471 int idx, rc; 472 473 ipi_handle = DPCPU_ID_GET(cpu, ipi_handle); --- 11 unchanged lines hidden (view full) --- 485 INTR_TYPE_TTY, &ipi_handle[idx]); 486 if (rc != 0) 487 panic("Unable to allocate a XEN IPI port"); 488 xen_intr_describe(ipi_handle[idx], "%s", ipi->description); 489 } 490} 491 492static void | 494xen_cpu_ipi_init(int cpu) 495{ 496 xen_intr_handle_t *ipi_handle; 497 const struct xen_ipi_handler *ipi; 498 device_t dev; 499 int idx, rc; 500 501 ipi_handle = DPCPU_ID_GET(cpu, ipi_handle); --- 11 unchanged lines hidden (view full) --- 513 INTR_TYPE_TTY, &ipi_handle[idx]); 514 if (rc != 0) 515 panic("Unable to allocate a XEN IPI port"); 516 xen_intr_describe(ipi_handle[idx], "%s", ipi->description); 517 } 518} 519 520static void |
493xen_init_ipis(void) | 521xen_setup_cpus(void) |
494{ 495 int i; 496 497 if (!xen_hvm_domain() || !xen_vector_callback_enabled) 498 return; 499 500#ifdef __amd64__ 501 if (pmap_pcid_enabled) { 502 xen_ipis[IPI_TO_IDX(IPI_INVLTLB)].filter = xen_invltlb_pcid; 503 xen_ipis[IPI_TO_IDX(IPI_INVLPG)].filter = xen_invlpg_pcid; 504 } 505#endif 506 CPU_FOREACH(i) 507 xen_cpu_ipi_init(i); 508 509 /* Set the xen pv ipi ops to replace the native ones */ | 522{ 523 int i; 524 525 if (!xen_hvm_domain() || !xen_vector_callback_enabled) 526 return; 527 528#ifdef __amd64__ 529 if (pmap_pcid_enabled) { 530 xen_ipis[IPI_TO_IDX(IPI_INVLTLB)].filter = xen_invltlb_pcid; 531 xen_ipis[IPI_TO_IDX(IPI_INVLPG)].filter = xen_invlpg_pcid; 532 } 533#endif 534 CPU_FOREACH(i) 535 xen_cpu_ipi_init(i); 536 537 /* Set the xen pv ipi ops to replace the native ones */ |
510 cpu_ops.ipi_vectored = xen_ipi_vectored; | 538 cpu_ops = xen_hvm_cpu_ops; |
511} 512#endif 513 514/*---------------------- XEN Hypervisor Probe and Setup ----------------------*/ 515static uint32_t 516xen_hvm_cpuid_base(void) 517{ 518 uint32_t base, regs[4]; --- 151 unchanged lines hidden (view full) --- 670 if (error != 0) 671 return; 672 673 setup_xen_features(); 674 break; 675 case XEN_HVM_INIT_RESUME: 676 if (error != 0) 677 panic("Unable to init Xen hypercall stubs on resume"); | 539} 540#endif 541 542/*---------------------- XEN Hypervisor Probe and Setup ----------------------*/ 543static uint32_t 544xen_hvm_cpuid_base(void) 545{ 546 uint32_t base, regs[4]; --- 151 unchanged lines hidden (view full) --- 698 if (error != 0) 699 return; 700 701 setup_xen_features(); 702 break; 703 case XEN_HVM_INIT_RESUME: 704 if (error != 0) 705 panic("Unable to init Xen hypercall stubs on resume"); |
706 707 /* Clear stale vcpu_info. */ 708 CPU_FOREACH(i) 709 DPCPU_ID_SET(i, vcpu_info, NULL); |
|
678 break; 679 default: 680 panic("Unsupported HVM initialization type"); 681 } 682 | 710 break; 711 default: 712 panic("Unsupported HVM initialization type"); 713 } 714 |
683 /* Clear any stale vcpu_info. */ 684 CPU_FOREACH(i) 685 DPCPU_ID_SET(i, vcpu_info, NULL); 686 | |
687 xen_vector_callback_enabled = 0; 688 xen_domain_type = XEN_HVM_DOMAIN; 689 xen_hvm_init_shared_info_page(); 690 xen_hvm_set_callback(NULL); 691 xen_hvm_disable_emulated_devices(); 692} 693 694void --- 4 unchanged lines hidden (view full) --- 699void 700xen_hvm_resume(bool suspend_cancelled) 701{ 702 703 xen_hvm_init(suspend_cancelled ? 704 XEN_HVM_INIT_CANCELLED_SUSPEND : XEN_HVM_INIT_RESUME); 705 706 /* Register vcpu_info area for CPU#0. */ | 715 xen_vector_callback_enabled = 0; 716 xen_domain_type = XEN_HVM_DOMAIN; 717 xen_hvm_init_shared_info_page(); 718 xen_hvm_set_callback(NULL); 719 xen_hvm_disable_emulated_devices(); 720} 721 722void --- 4 unchanged lines hidden (view full) --- 727void 728xen_hvm_resume(bool suspend_cancelled) 729{ 730 731 xen_hvm_init(suspend_cancelled ? 732 XEN_HVM_INIT_CANCELLED_SUSPEND : XEN_HVM_INIT_RESUME); 733 734 /* Register vcpu_info area for CPU#0. */ |
707 xen_hvm_init_cpu(); | 735 xen_hvm_cpu_init(); |
708} 709 710static void 711xen_hvm_sysinit(void *arg __unused) 712{ 713 xen_hvm_init(XEN_HVM_INIT_COLD); 714} 715 | 736} 737 738static void 739xen_hvm_sysinit(void *arg __unused) 740{ 741 xen_hvm_init(XEN_HVM_INIT_COLD); 742} 743 |
716void 717xen_hvm_init_cpu(void) | 744static void 745xen_hvm_cpu_init(void) |
718{ 719 struct vcpu_register_vcpu_info info; 720 struct vcpu_info *vcpu_info; 721 int cpu, rc; 722 | 746{ 747 struct vcpu_register_vcpu_info info; 748 struct vcpu_info *vcpu_info; 749 int cpu, rc; 750 |
751 if (!xen_domain()) 752 return; 753 |
|
723 if (DPCPU_GET(vcpu_info) != NULL) { 724 /* 725 * vcpu_info is already set. We're resuming 726 * from a failed migration and our pre-suspend 727 * configuration is still valid. 728 */ 729 return; 730 } --- 7 unchanged lines hidden (view full) --- 738 if (rc != 0) 739 DPCPU_SET(vcpu_info, &HYPERVISOR_shared_info->vcpu_info[cpu]); 740 else 741 DPCPU_SET(vcpu_info, vcpu_info); 742} 743 744SYSINIT(xen_hvm_init, SI_SUB_HYPERVISOR, SI_ORDER_FIRST, xen_hvm_sysinit, NULL); 745#ifdef SMP | 754 if (DPCPU_GET(vcpu_info) != NULL) { 755 /* 756 * vcpu_info is already set. We're resuming 757 * from a failed migration and our pre-suspend 758 * configuration is still valid. 759 */ 760 return; 761 } --- 7 unchanged lines hidden (view full) --- 769 if (rc != 0) 770 DPCPU_SET(vcpu_info, &HYPERVISOR_shared_info->vcpu_info[cpu]); 771 else 772 DPCPU_SET(vcpu_info, vcpu_info); 773} 774 775SYSINIT(xen_hvm_init, SI_SUB_HYPERVISOR, SI_ORDER_FIRST, xen_hvm_sysinit, NULL); 776#ifdef SMP |
746SYSINIT(xen_init_ipis, SI_SUB_SMP, SI_ORDER_FIRST, xen_init_ipis, NULL); | 777SYSINIT(xen_setup_cpus, SI_SUB_SMP, SI_ORDER_FIRST, xen_setup_cpus, NULL); |
747#endif | 778#endif |
748SYSINIT(xen_hvm_init_cpu, SI_SUB_INTR, SI_ORDER_FIRST, xen_hvm_init_cpu, NULL); | 779SYSINIT(xen_hvm_cpu_init, SI_SUB_INTR, SI_ORDER_FIRST, xen_hvm_cpu_init, NULL); |