Deleted Added
full compact
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);