hvm.c (ef90af83a58199ef3980d8c9a7dad07ec9b4bea3) | hvm.c (428b7ca290208e6b15d46440cd8d6309dc92dd2d) |
---|---|
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: --- 44 unchanged lines hidden (view full) --- 53#include <xen/hypervisor.h> 54#include <xen/hvm.h> 55#include <xen/xen_intr.h> 56 57#include <xen/interface/hvm/params.h> 58#include <xen/interface/vcpu.h> 59 60/*--------------------------- Forward Declarations ---------------------------*/ | 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: --- 44 unchanged lines hidden (view full) --- 53#include <xen/hypervisor.h> 54#include <xen/hvm.h> 55#include <xen/xen_intr.h> 56 57#include <xen/interface/hvm/params.h> 58#include <xen/interface/vcpu.h> 59 60/*--------------------------- Forward Declarations ---------------------------*/ |
61#ifdef SMP |
|
61static driver_filter_t xen_smp_rendezvous_action; 62static driver_filter_t xen_invltlb; 63static driver_filter_t xen_invlpg; 64static driver_filter_t xen_invlrng; 65static driver_filter_t xen_invlcache; 66#ifdef __i386__ 67static driver_filter_t xen_lazypmap; 68#endif 69static driver_filter_t xen_ipi_bitmap_handler; 70static driver_filter_t xen_cpustop_handler; 71static driver_filter_t xen_cpususpend_handler; 72static driver_filter_t xen_cpustophard_handler; | 62static driver_filter_t xen_smp_rendezvous_action; 63static driver_filter_t xen_invltlb; 64static driver_filter_t xen_invlpg; 65static driver_filter_t xen_invlrng; 66static driver_filter_t xen_invlcache; 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 |
|
73 74/*---------------------------- Extern Declarations ---------------------------*/ 75/* Variables used by mp_machdep to perform the MMU related IPIs */ 76extern volatile int smp_tlb_wait; 77extern vm_offset_t smp_tlb_addr2; 78#ifdef __i386__ 79extern vm_offset_t smp_tlb_addr1; 80#else --- 7 unchanged lines hidden (view full) --- 88#ifdef __i386__ 89extern void pmap_lazyfix_action(void); 90#endif 91 92/*---------------------------------- Macros ----------------------------------*/ 93#define IPI_TO_IDX(ipi) ((ipi) - APIC_IPI_INTS) 94 95/*-------------------------------- Local Types -------------------------------*/ | 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 --- 7 unchanged lines hidden (view full) --- 90#ifdef __i386__ 91extern void pmap_lazyfix_action(void); 92#endif 93 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 |
|
96struct xen_ipi_handler 97{ 98 driver_filter_t *filter; 99 const char *description; 100}; 101 102/*-------------------------------- Global Data -------------------------------*/ 103enum xen_domain_type xen_domain_type = XEN_NATIVE; 104 105static MALLOC_DEFINE(M_XENHVM, "xen_hvm", "Xen HVM PV Support"); 106 | 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 113static MALLOC_DEFINE(M_XENHVM, "xen_hvm", "Xen HVM PV Support"); 114 |
115#ifdef SMP |
|
107static struct xen_ipi_handler xen_ipis[] = 108{ 109 [IPI_TO_IDX(IPI_RENDEZVOUS)] = { xen_smp_rendezvous_action, "r" }, 110 [IPI_TO_IDX(IPI_INVLTLB)] = { xen_invltlb, "itlb"}, 111 [IPI_TO_IDX(IPI_INVLPG)] = { xen_invlpg, "ipg" }, 112 [IPI_TO_IDX(IPI_INVLRNG)] = { xen_invlrng, "irg" }, 113 [IPI_TO_IDX(IPI_INVLCACHE)] = { xen_invlcache, "ic" }, 114#ifdef __i386__ 115 [IPI_TO_IDX(IPI_LAZYPMAP)] = { xen_lazypmap, "lp" }, 116#endif 117 [IPI_TO_IDX(IPI_BITMAP_VECTOR)] = { xen_ipi_bitmap_handler, "b" }, 118 [IPI_TO_IDX(IPI_STOP)] = { xen_cpustop_handler, "st" }, 119 [IPI_TO_IDX(IPI_SUSPEND)] = { xen_cpususpend_handler, "sp" }, 120 [IPI_TO_IDX(IPI_STOP_HARD)] = { xen_cpustophard_handler, "sth" }, 121}; | 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" }, 121 [IPI_TO_IDX(IPI_INVLRNG)] = { xen_invlrng, "irg" }, 122 [IPI_TO_IDX(IPI_INVLCACHE)] = { xen_invlcache, "ic" }, 123#ifdef __i386__ 124 [IPI_TO_IDX(IPI_LAZYPMAP)] = { xen_lazypmap, "lp" }, 125#endif 126 [IPI_TO_IDX(IPI_BITMAP_VECTOR)] = { xen_ipi_bitmap_handler, "b" }, 127 [IPI_TO_IDX(IPI_STOP)] = { xen_cpustop_handler, "st" }, 128 [IPI_TO_IDX(IPI_SUSPEND)] = { xen_cpususpend_handler, "sp" }, 129 [IPI_TO_IDX(IPI_STOP_HARD)] = { xen_cpustophard_handler, "sth" }, 130}; |
131#endif |
|
122 123/** 124 * If non-zero, the hypervisor has been configured to use a direct 125 * IDT event callback for interrupt injection. 126 */ 127int xen_vector_callback_enabled; 128 129/*------------------------------- Per-CPU Data -------------------------------*/ 130DPCPU_DEFINE(struct vcpu_info, vcpu_local_info); 131DPCPU_DEFINE(struct vcpu_info *, vcpu_info); | 132 133/** 134 * If non-zero, the hypervisor has been configured to use a direct 135 * IDT event callback for interrupt injection. 136 */ 137int xen_vector_callback_enabled; 138 139/*------------------------------- Per-CPU Data -------------------------------*/ 140DPCPU_DEFINE(struct vcpu_info, vcpu_local_info); 141DPCPU_DEFINE(struct vcpu_info *, vcpu_info); |
142#ifdef SMP |
|
132DPCPU_DEFINE(xen_intr_handle_t, ipi_handle[nitems(xen_ipis)]); | 143DPCPU_DEFINE(xen_intr_handle_t, ipi_handle[nitems(xen_ipis)]); |
144#endif |
|
133 134/*------------------ Hypervisor Access Shared Memory Regions -----------------*/ 135/** Hypercall table accessed via HYPERVISOR_*_op() methods. */ 136char *hypercall_stubs; 137shared_info_t *HYPERVISOR_shared_info; 138 | 145 146/*------------------ Hypervisor Access Shared Memory Regions -----------------*/ 147/** Hypercall table accessed via HYPERVISOR_*_op() methods. */ 148char *hypercall_stubs; 149shared_info_t *HYPERVISOR_shared_info; 150 |
151#ifdef SMP |
|
139/*---------------------------- XEN PV IPI Handlers ---------------------------*/ 140/* 141 * This are C clones of the ASM functions found in apic_vector.s 142 */ 143static int 144xen_ipi_bitmap_handler(void *arg) 145{ 146 struct trapframe *frame; --- 344 unchanged lines hidden (view full) --- 491 } 492#endif 493 CPU_FOREACH(i) 494 xen_cpu_ipi_init(i); 495 496 /* Set the xen pv ipi ops to replace the native ones */ 497 cpu_ops.ipi_vectored = xen_ipi_vectored; 498} | 152/*---------------------------- XEN PV IPI Handlers ---------------------------*/ 153/* 154 * This are C clones of the ASM functions found in apic_vector.s 155 */ 156static int 157xen_ipi_bitmap_handler(void *arg) 158{ 159 struct trapframe *frame; --- 344 unchanged lines hidden (view full) --- 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 */ 510 cpu_ops.ipi_vectored = xen_ipi_vectored; 511} |
512#endif |
|
499 500/*---------------------- XEN Hypervisor Probe and Setup ----------------------*/ 501static uint32_t 502xen_hvm_cpuid_base(void) 503{ 504 uint32_t base, regs[4]; 505 506 for (base = 0x40000000; base < 0x40010000; base += 0x100) { --- 67 unchanged lines hidden (view full) --- 574 * Tell the hypervisor how to contact us for event channel callbacks. 575 */ 576void 577xen_hvm_set_callback(device_t dev) 578{ 579 struct xen_hvm_param xhp; 580 int irq; 581 | 513 514/*---------------------- XEN Hypervisor Probe and Setup ----------------------*/ 515static uint32_t 516xen_hvm_cpuid_base(void) 517{ 518 uint32_t base, regs[4]; 519 520 for (base = 0x40000000; base < 0x40010000; base += 0x100) { --- 67 unchanged lines hidden (view full) --- 588 * Tell the hypervisor how to contact us for event channel callbacks. 589 */ 590void 591xen_hvm_set_callback(device_t dev) 592{ 593 struct xen_hvm_param xhp; 594 int irq; 595 |
596 if (xen_vector_callback_enabled) 597 return; 598 |
|
582 xhp.domid = DOMID_SELF; 583 xhp.index = HVM_PARAM_CALLBACK_IRQ; 584 if (xen_feature(XENFEAT_hvm_callback_vector) != 0) { 585 int error; 586 587 xhp.value = HVM_CALLBACK_VECTOR(IDT_EVTCHN); 588 error = HYPERVISOR_hvm_op(HVMOP_set_param, &xhp); 589 if (error == 0) { --- 42 unchanged lines hidden (view full) --- 632 if (inw(XEN_MAGIC_IOPORT) != XMI_MAGIC) 633 return; 634 635 if (bootverbose) 636 printf("XEN: Disabling emulated block and network devices\n"); 637 outw(XEN_MAGIC_IOPORT, XMI_UNPLUG_IDE_DISKS|XMI_UNPLUG_NICS); 638} 639 | 599 xhp.domid = DOMID_SELF; 600 xhp.index = HVM_PARAM_CALLBACK_IRQ; 601 if (xen_feature(XENFEAT_hvm_callback_vector) != 0) { 602 int error; 603 604 xhp.value = HVM_CALLBACK_VECTOR(IDT_EVTCHN); 605 error = HYPERVISOR_hvm_op(HVMOP_set_param, &xhp); 606 if (error == 0) { --- 42 unchanged lines hidden (view full) --- 649 if (inw(XEN_MAGIC_IOPORT) != XMI_MAGIC) 650 return; 651 652 if (bootverbose) 653 printf("XEN: Disabling emulated block and network devices\n"); 654 outw(XEN_MAGIC_IOPORT, XMI_UNPLUG_IDE_DISKS|XMI_UNPLUG_NICS); 655} 656 |
657static void 658xen_hvm_init(enum xen_hvm_init_type init_type) 659{ 660 int error; 661 int i; 662 663 if (init_type == XEN_HVM_INIT_CANCELLED_SUSPEND) 664 return; 665 666 error = xen_hvm_init_hypercall_stubs(); 667 668 switch (init_type) { 669 case XEN_HVM_INIT_COLD: 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"); 678 break; 679 default: 680 panic("Unsupported HVM initialization type"); 681 } 682 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 |
|
640void 641xen_hvm_suspend(void) 642{ 643} 644 645void | 694void 695xen_hvm_suspend(void) 696{ 697} 698 699void |
646xen_hvm_resume(void) | 700xen_hvm_resume(bool suspend_cancelled) |
647{ 648 | 701{ 702 |
649 xen_hvm_init_hypercall_stubs(); 650 xen_hvm_init_shared_info_page(); | 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. */ 707 xen_hvm_init_cpu(); |
651} 652 653static void | 708} 709 710static void |
654xen_hvm_init(void *dummy __unused) | 711xen_hvm_sysinit(void *arg __unused) |
655{ | 712{ |
713 xen_hvm_init(XEN_HVM_INIT_COLD); 714} |
|
656 | 715 |
657 if (xen_hvm_init_hypercall_stubs() != 0) 658 return; 659 660 xen_domain_type = XEN_HVM_DOMAIN; 661 setup_xen_features(); 662 xen_hvm_init_shared_info_page(); 663 xen_hvm_set_callback(NULL); 664 xen_hvm_disable_emulated_devices(); 665} 666 667void xen_hvm_init_cpu(void) | 716void 717xen_hvm_init_cpu(void) |
668{ 669 struct vcpu_register_vcpu_info info; 670 struct vcpu_info *vcpu_info; 671 int cpu, rc; 672 | 718{ 719 struct vcpu_register_vcpu_info info; 720 struct vcpu_info *vcpu_info; 721 int cpu, rc; 722 |
673 cpu = PCPU_GET(acpi_id); | 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 } 731 |
674 vcpu_info = DPCPU_PTR(vcpu_local_info); | 732 vcpu_info = DPCPU_PTR(vcpu_local_info); |
733 cpu = PCPU_GET(acpi_id); |
|
675 info.mfn = vtophys(vcpu_info) >> PAGE_SHIFT; 676 info.offset = vtophys(vcpu_info) - trunc_page(vtophys(vcpu_info)); 677 678 rc = HYPERVISOR_vcpu_op(VCPUOP_register_vcpu_info, cpu, &info); 679 if (rc != 0) 680 DPCPU_SET(vcpu_info, &HYPERVISOR_shared_info->vcpu_info[cpu]); 681 else 682 DPCPU_SET(vcpu_info, vcpu_info); 683} 684 | 734 info.mfn = vtophys(vcpu_info) >> PAGE_SHIFT; 735 info.offset = vtophys(vcpu_info) - trunc_page(vtophys(vcpu_info)); 736 737 rc = HYPERVISOR_vcpu_op(VCPUOP_register_vcpu_info, cpu, &info); 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 |
685SYSINIT(xen_hvm_init, SI_SUB_HYPERVISOR, SI_ORDER_FIRST, xen_hvm_init, NULL); | 744SYSINIT(xen_hvm_init, SI_SUB_HYPERVISOR, SI_ORDER_FIRST, xen_hvm_sysinit, NULL); 745#ifdef SMP |
686SYSINIT(xen_init_ipis, SI_SUB_SMP, SI_ORDER_FIRST, xen_init_ipis, NULL); | 746SYSINIT(xen_init_ipis, SI_SUB_SMP, SI_ORDER_FIRST, xen_init_ipis, NULL); |
747#endif |
|
687SYSINIT(xen_hvm_init_cpu, SI_SUB_INTR, SI_ORDER_FIRST, xen_hvm_init_cpu, NULL); | 748SYSINIT(xen_hvm_init_cpu, SI_SUB_INTR, SI_ORDER_FIRST, xen_hvm_init_cpu, NULL); |