Deleted Added
sdiff udiff text old ( 256425 ) new ( 282212 )
full compact
1/*-
2 * Copyright (c) 2009-2012 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

--- 16 unchanged lines hidden (view full) ---

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 Hypver-V/Azure
31 */
32#include <sys/cdefs.h>
33__FBSDID("$FreeBSD: head/sys/dev/hyperv/vmbus/hv_hv.c 282212 2015-04-29 10:12:34Z whu $");
34
35#include <sys/param.h>
36#include <sys/malloc.h>
37#include <sys/pcpu.h>
38#include <sys/timetc.h>
39#include <machine/bus.h>
40#include <vm/vm.h>
41#include <vm/vm_param.h>

--- 20 unchanged lines hidden (view full) ---

62}
63
64/**
65 * Globals
66 */
67hv_vmbus_context hv_vmbus_g_context = {
68 .syn_ic_initialized = FALSE,
69 .hypercall_page = NULL,
70};
71
72static struct timecounter hv_timecounter = {
73 hv_get_timecount, 0, ~0u, HV_NANOSECONDS_PER_SEC/100, "Hyper-V", HV_NANOSECONDS_PER_SEC/100
74};
75
76static u_int
77hv_get_timecount(struct timecounter *tc)

--- 171 unchanged lines hidden (view full) ---

249 hypercall_msr.as_uint64_t = 0;
250 hypercall_msr.as_uint64_t = rdmsr(HV_X64_MSR_HYPERCALL);
251
252 if (!hypercall_msr.u.enable)
253 goto cleanup;
254
255 hv_vmbus_g_context.hypercall_page = virt_addr;
256
257 tc_init(&hv_timecounter); /* register virtual timecount */
258
259 return (0);
260
261 cleanup:
262 if (virt_addr != NULL) {
263 if (hypercall_msr.u.enable) {
264 hypercall_msr.as_uint64_t = 0;

--- 9 unchanged lines hidden (view full) ---

274/**
275 * @brief Cleanup routine, called normally during driver unloading or exiting
276 */
277void
278hv_vmbus_cleanup(void)
279{
280 hv_vmbus_x64_msr_hypercall_contents hypercall_msr;
281
282 if (hv_vmbus_g_context.guest_id == HV_FREEBSD_GUEST_ID) {
283 if (hv_vmbus_g_context.hypercall_page != NULL) {
284 hypercall_msr.as_uint64_t = 0;
285 wrmsr(HV_X64_MSR_HYPERCALL,
286 hypercall_msr.as_uint64_t);
287 free(hv_vmbus_g_context.hypercall_page, M_DEVBUF);
288 hv_vmbus_g_context.hypercall_page = NULL;
289 }

--- 45 unchanged lines hidden (view full) ---

335 return (status);
336}
337
338/**
339 * @brief Signal an event on the specified connection using the hypervisor
340 * event IPC. (This involves a hypercall.)
341 */
342hv_vmbus_status
343hv_vmbus_signal_event(void *con_id)
344{
345 hv_vmbus_status status;
346
347 status = hv_vmbus_do_hypercall(
348 HV_CALL_SIGNAL_EVENT,
349 con_id,
350 0) & 0xFFFF;
351
352 return (status);
353}
354
355/**
356 * @brief hv_vmbus_synic_init
357 */
358void
359hv_vmbus_synic_init(void *arg)
360
361{
362 int cpu;
363 uint64_t hv_vcpu_index;
364 hv_vmbus_synic_simp simp;
365 hv_vmbus_synic_siefp siefp;
366 hv_vmbus_synic_scontrol sctrl;
367 hv_vmbus_synic_sint shared_sint;
368 uint64_t version;
369 hv_setup_args* setup_args = (hv_setup_args *)arg;
370
371 cpu = PCPU_GET(cpuid);
372
373 if (hv_vmbus_g_context.hypercall_page == NULL)
374 return;
375
376 /*
377 * TODO: Check the version
378 */
379 version = rdmsr(HV_X64_MSR_SVERSION);
380
381 hv_vmbus_g_context.syn_ic_msg_page[cpu] =
382 setup_args->page_buffers[2 * cpu];
383 hv_vmbus_g_context.syn_ic_event_page[cpu] =
384 setup_args->page_buffers[2 * cpu + 1];
385
386 /*
387 * Setup the Synic's message page
388 */
389
390 simp.as_uint64_t = rdmsr(HV_X64_MSR_SIMP);
391 simp.u.simp_enabled = 1;
392 simp.u.base_simp_gpa = ((hv_get_phys_addr(

--- 7 unchanged lines hidden (view full) ---

400 siefp.as_uint64_t = rdmsr(HV_X64_MSR_SIEFP);
401 siefp.u.siefp_enabled = 1;
402 siefp.u.base_siefp_gpa = ((hv_get_phys_addr(
403 hv_vmbus_g_context.syn_ic_event_page[cpu])) >> PAGE_SHIFT);
404
405 wrmsr(HV_X64_MSR_SIEFP, siefp.as_uint64_t);
406
407 /*HV_SHARED_SINT_IDT_VECTOR + 0x20; */
408 shared_sint.as_uint64_t = 0;
409 shared_sint.u.vector = setup_args->vector;
410 shared_sint.u.masked = FALSE;
411 shared_sint.u.auto_eoi = TRUE;
412
413 wrmsr(HV_X64_MSR_SINT0 + HV_VMBUS_MESSAGE_SINT,
414 shared_sint.as_uint64_t);
415
416 /* Enable the global synic bit */
417 sctrl.as_uint64_t = rdmsr(HV_X64_MSR_SCONTROL);
418 sctrl.u.enable = 1;
419
420 wrmsr(HV_X64_MSR_SCONTROL, sctrl.as_uint64_t);
421
422 hv_vmbus_g_context.syn_ic_initialized = TRUE;
423
424 /*
425 * Set up the cpuid mapping from Hyper-V to FreeBSD.
426 * The array is indexed using FreeBSD cpuid.
427 */
428 hv_vcpu_index = rdmsr(HV_X64_MSR_VP_INDEX);
429 hv_vmbus_g_context.hv_vcpu_index[cpu] = (uint32_t)hv_vcpu_index;
430
431 return;
432}
433
434/**
435 * @brief Cleanup routine for hv_vmbus_synic_init()
436 */
437void hv_vmbus_synic_cleanup(void *arg)
438{
439 hv_vmbus_synic_sint shared_sint;
440 hv_vmbus_synic_simp simp;
441 hv_vmbus_synic_siefp siefp;
442
443 if (!hv_vmbus_g_context.syn_ic_initialized)
444 return;
445
446 shared_sint.as_uint64_t = rdmsr(
447 HV_X64_MSR_SINT0 + HV_VMBUS_MESSAGE_SINT);
448
449 shared_sint.u.masked = 1;
450
451 /*
452 * Disable the interrupt
453 */

--- 17 unchanged lines hidden ---