The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/hyperv/vmbus/hyperv.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2009-2012,2016-2017 Microsoft Corp.
    3  * Copyright (c) 2012 NetApp Inc.
    4  * Copyright (c) 2012 Citrix Inc.
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice unmodified, this list of conditions, and the following
   12  *    disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   27  */
   28 
   29 /**
   30  * Implements low-level interactions with Hyper-V/Azure
   31  */
   32 #include <sys/cdefs.h>
   33 __FBSDID("$FreeBSD$");
   34 
   35 #include <sys/param.h>
   36 #include <sys/kernel.h>
   37 #include <sys/malloc.h>
   38 #include <sys/systm.h>
   39 #include <sys/timetc.h>
   40 
   41 #include <vm/vm.h>
   42 #include <vm/vm_extern.h>
   43 #include <vm/vm_kern.h>
   44 #include <vm/pmap.h>
   45 
   46 #include <dev/hyperv/include/hyperv.h>
   47 #include <dev/hyperv/include/hyperv_busdma.h>
   48 #if defined(__aarch64__)
   49 #include <dev/hyperv/vmbus/aarch64/hyperv_machdep.h>
   50 #include <dev/hyperv/vmbus/aarch64/hyperv_reg.h>
   51 #else
   52 #include <dev/hyperv/vmbus/x86/hyperv_machdep.h>
   53 #include <dev/hyperv/vmbus/x86/hyperv_reg.h>
   54 #endif
   55 #include <dev/hyperv/vmbus/hyperv_common_reg.h>
   56 #include <dev/hyperv/vmbus/hyperv_var.h>
   57 
   58 #define HYPERV_FREEBSD_BUILD            0ULL
   59 #define HYPERV_FREEBSD_VERSION          ((uint64_t)__FreeBSD_version)
   60 #define HYPERV_FREEBSD_OSID             0ULL
   61 
   62 #define MSR_HV_GUESTID_BUILD_FREEBSD    \
   63         (HYPERV_FREEBSD_BUILD & MSR_HV_GUESTID_BUILD_MASK)
   64 #define MSR_HV_GUESTID_VERSION_FREEBSD  \
   65         ((HYPERV_FREEBSD_VERSION << MSR_HV_GUESTID_VERSION_SHIFT) & \
   66          MSR_HV_GUESTID_VERSION_MASK)
   67 #define MSR_HV_GUESTID_OSID_FREEBSD     \
   68         ((HYPERV_FREEBSD_OSID << MSR_HV_GUESTID_OSID_SHIFT) & \
   69          MSR_HV_GUESTID_OSID_MASK)
   70 
   71 #define MSR_HV_GUESTID_FREEBSD          \
   72         (MSR_HV_GUESTID_BUILD_FREEBSD | \
   73          MSR_HV_GUESTID_VERSION_FREEBSD | \
   74          MSR_HV_GUESTID_OSID_FREEBSD |  \
   75          MSR_HV_GUESTID_OSTYPE_FREEBSD)
   76 
   77 static bool                     hyperv_identify(void);
   78 static void                     hypercall_memfree(void);
   79 
   80 static struct hypercall_ctx     hypercall_context;
   81 uint64_t
   82 hypercall_post_message(bus_addr_t msg_paddr)
   83 {
   84         return hypercall_md(hypercall_context.hc_addr,
   85             HYPERCALL_POST_MESSAGE, msg_paddr, 0);
   86 }
   87 
   88 uint64_t
   89 hypercall_signal_event(bus_addr_t monprm_paddr)
   90 {
   91         return hypercall_md(hypercall_context.hc_addr,
   92             HYPERCALL_SIGNAL_EVENT, monprm_paddr, 0);
   93 }
   94 
   95 int
   96 hyperv_guid2str(const struct hyperv_guid *guid, char *buf, size_t sz)
   97 {
   98         const uint8_t *d = guid->hv_guid;
   99 
  100         return snprintf(buf, sz, "%02x%02x%02x%02x-"
  101             "%02x%02x-%02x%02x-%02x%02x-"
  102             "%02x%02x%02x%02x%02x%02x",
  103             d[3], d[2], d[1], d[0],
  104             d[5], d[4], d[7], d[6], d[8], d[9],
  105             d[10], d[11], d[12], d[13], d[14], d[15]);
  106 }
  107 
  108 static bool
  109 hyperv_identify(void)
  110 {
  111         return(hyperv_identify_features());
  112 }
  113 static void
  114 hyperv_init(void *dummy __unused)
  115 {
  116         if (!hyperv_identify()) {
  117                 /* Not Hyper-V; reset guest id to the generic one. */
  118                 if (vm_guest == VM_GUEST_HV)
  119                         vm_guest = VM_GUEST_VM;
  120                 return;
  121         }
  122 
  123         /* Set guest id */
  124         WRMSR(MSR_HV_GUEST_OS_ID, MSR_HV_GUESTID_FREEBSD);
  125         hyperv_init_tc();       
  126 }
  127 SYSINIT(hyperv_initialize, SI_SUB_HYPERVISOR, SI_ORDER_FIRST, hyperv_init,
  128     NULL);
  129 
  130 static void
  131 hypercall_memfree(void)
  132 {
  133         kmem_free(hypercall_context.hc_addr, PAGE_SIZE);
  134         hypercall_context.hc_addr = NULL;
  135 }
  136 
  137 static void
  138 hypercall_create(void *arg __unused)
  139 {
  140 
  141         int ret;
  142         if (vm_guest != VM_GUEST_HV)
  143                 return;
  144 
  145         /*
  146          * NOTE:
  147          * - busdma(9), i.e. hyperv_dmamem APIs, can _not_ be used due to
  148          *   the NX bit.
  149          * - Assume kmem_malloc() returns properly aligned memory.
  150          */
  151         hypercall_context.hc_addr = kmem_malloc(PAGE_SIZE, M_EXEC | M_WAITOK);
  152         hypercall_context.hc_paddr = vtophys(hypercall_context.hc_addr);
  153         ret = hypercall_page_setup(hypercall_context.hc_paddr);
  154         if (ret) {
  155                 hypercall_memfree();
  156                 return;
  157         }
  158         if (bootverbose)
  159                 printf("hyperv: Hypercall created\n");
  160 }
  161 SYSINIT(hypercall_ctor, SI_SUB_DRIVERS, SI_ORDER_FIRST, hypercall_create, NULL);
  162 
  163 static void
  164 hypercall_destroy(void *arg __unused)
  165 {
  166 
  167         if (hypercall_context.hc_addr == NULL)
  168                 return;
  169         hypercall_disable();
  170         hypercall_memfree();
  171         if (bootverbose)
  172                 printf("hyperv: Hypercall destroyed\n");
  173 }
  174 SYSUNINIT(hypercall_dtor, SI_SUB_DRIVERS, SI_ORDER_FIRST, hypercall_destroy,
  175     NULL);

Cache object: a7c09b855739e9d0d48a37aaeb756b77


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.