Staging: hv: cleanup coding style issues in RingBuffer.h
[deliverable/linux.git] / drivers / staging / hv / Hv.c
CommitLineData
3e7ee490
HJ
1/*
2 *
3 * Copyright (c) 2009, Microsoft Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16 * Place - Suite 330, Boston, MA 02111-1307 USA.
17 *
18 * Authors:
19 * Haiyang Zhang <haiyangz@microsoft.com>
20 * Hank Janssen <hjanssen@microsoft.com>
21 *
22 */
23
b7c947f0 24#include <linux/vmalloc.h>
fa56d361 25#include <asm/io.h>
09d50ff8 26#include "include/logging.h"
3e7ee490
HJ
27#include "VmbusPrivate.h"
28
454f18a9 29/* Globals */
3e7ee490 30
454f18a9 31/* The one and only */
3e7ee490 32HV_CONTEXT gHvContext={
0e727613 33 .SynICInitialized = false,
3e7ee490
HJ
34 .HypercallPage = NULL,
35 .SignalEventParam = NULL,
36 .SignalEventBuffer = NULL,
37};
38
39
40/*++
41
42Name:
43 HvQueryHypervisorPresence()
44
45Description:
46 Query the cpuid for presense of windows hypervisor
47
48--*/
49static int
50HvQueryHypervisorPresence (
51 void
52 )
53{
54 unsigned int eax;
55 unsigned int ebx;
56 unsigned int ecx;
57 unsigned int edx;
58 unsigned int op;
59
60 eax = 0;
61 ebx = 0;
62 ecx = 0;
63 edx = 0;
64 op = HvCpuIdFunctionVersionAndFeatures;
f931a70c 65 cpuid(op, &eax, &ebx, &ecx, &edx);
3e7ee490
HJ
66
67 return (ecx & HV_PRESENT_BIT);
68}
69
70
71/*++
72
73Name:
74 HvQueryHypervisorInfo()
75
76Description:
77 Get version info of the windows hypervisor
78
79--*/
80static int
81HvQueryHypervisorInfo (
82 void
83 )
84{
85 unsigned int eax;
86 unsigned int ebx;
87 unsigned int ecx;
88 unsigned int edx;
89 unsigned int maxLeaf;
90 unsigned int op;
91
454f18a9
BP
92 /*
93 * Its assumed that this is called after confirming that Viridian
94 * is present. Query id and revision.
95 */
96
3e7ee490
HJ
97
98 eax = 0;
99 ebx = 0;
100 ecx = 0;
101 edx = 0;
102 op = HvCpuIdFunctionHvVendorAndMaxFunction;
f931a70c 103 cpuid(op, &eax, &ebx, &ecx, &edx);
3e7ee490
HJ
104
105 DPRINT_INFO(VMBUS, "Vendor ID: %c%c%c%c%c%c%c%c%c%c%c%c",
454f18a9
BP
106 (ebx & 0xFF),
107 ((ebx >> 8) & 0xFF),
108 ((ebx >> 16) & 0xFF),
109 ((ebx >> 24) & 0xFF),
110 (ecx & 0xFF),
111 ((ecx >> 8) & 0xFF),
112 ((ecx >> 16) & 0xFF),
113 ((ecx >> 24) & 0xFF),
114 (edx & 0xFF),
115 ((edx >> 8) & 0xFF),
116 ((edx >> 16) & 0xFF),
117 ((edx >> 24) & 0xFF));
3e7ee490
HJ
118
119 maxLeaf = eax;
120 eax = 0;
121 ebx = 0;
122 ecx = 0;
123 edx = 0;
124 op = HvCpuIdFunctionHvInterface;
f931a70c 125 cpuid(op, &eax, &ebx, &ecx, &edx);
3e7ee490
HJ
126
127 DPRINT_INFO(VMBUS, "Interface ID: %c%c%c%c",
454f18a9
BP
128 (eax & 0xFF),
129 ((eax >> 8) & 0xFF),
130 ((eax >> 16) & 0xFF),
131 ((eax >> 24) & 0xFF));
3e7ee490
HJ
132
133 if (maxLeaf >= HvCpuIdFunctionMsHvVersion) {
454f18a9
BP
134 eax = 0;
135 ebx = 0;
136 ecx = 0;
137 edx = 0;
138 op = HvCpuIdFunctionMsHvVersion;
f931a70c 139 cpuid(op, &eax, &ebx, &ecx, &edx);
454f18a9
BP
140 DPRINT_INFO(VMBUS, "OS Build:%d-%d.%d-%d-%d.%d",
141 eax,
142 ebx >> 16,
143 ebx & 0xFFFF,
144 ecx,
145 edx >> 24,
146 edx & 0xFFFFFF);
3e7ee490
HJ
147 }
148 return maxLeaf;
149}
150
151
152/*++
153
154Name:
155 HvDoHypercall()
156
157Description:
158 Invoke the specified hypercall
159
160--*/
59471438 161static u64
3e7ee490 162HvDoHypercall (
59471438 163 u64 Control,
3e7ee490
HJ
164 void* Input,
165 void* Output
166 )
167{
530cf207 168#ifdef CONFIG_X86_64
59471438 169 u64 hvStatus=0;
fa56d361
GKH
170 u64 inputAddress = (Input)? virt_to_phys(Input) : 0;
171 u64 outputAddress = (Output)? virt_to_phys(Output) : 0;
3e7ee490
HJ
172 volatile void* hypercallPage = gHvContext.HypercallPage;
173
174 DPRINT_DBG(VMBUS, "Hypercall <control %llx input phys %llx virt %p output phys %llx virt %p hypercall %p>",
175 Control,
176 inputAddress,
177 Input,
178 outputAddress,
179 Output,
180 hypercallPage);
181
182 __asm__ __volatile__ ("mov %0, %%r8" : : "r" (outputAddress): "r8");
183 __asm__ __volatile__ ("call *%3" : "=a"(hvStatus): "c" (Control), "d" (inputAddress), "m" (hypercallPage));
184
185 DPRINT_DBG(VMBUS, "Hypercall <return %llx>", hvStatus);
186
187 return hvStatus;
188
189#else
190
4d643114
GKH
191 u32 controlHi = Control >> 32;
192 u32 controlLo = Control & 0xFFFFFFFF;
193 u32 hvStatusHi = 1;
194 u32 hvStatusLo = 1;
fa56d361 195 u64 inputAddress = (Input) ? virt_to_phys(Input) : 0;
4d643114
GKH
196 u32 inputAddressHi = inputAddress >> 32;
197 u32 inputAddressLo = inputAddress & 0xFFFFFFFF;
fa56d361 198 u64 outputAddress = (Output) ? virt_to_phys(Output) : 0;
4d643114
GKH
199 u32 outputAddressHi = outputAddress >> 32;
200 u32 outputAddressLo = outputAddress & 0xFFFFFFFF;
3e7ee490
HJ
201 volatile void* hypercallPage = gHvContext.HypercallPage;
202
203 DPRINT_DBG(VMBUS, "Hypercall <control %llx input %p output %p>",
204 Control,
205 Input,
206 Output);
207
208 __asm__ __volatile__ ("call *%8" : "=d"(hvStatusHi), "=a"(hvStatusLo) : "d" (controlHi), "a" (controlLo), "b" (inputAddressHi), "c" (inputAddressLo), "D"(outputAddressHi), "S"(outputAddressLo), "m" (hypercallPage));
209
210
59471438 211 DPRINT_DBG(VMBUS, "Hypercall <return %llx>", hvStatusLo | ((u64)hvStatusHi << 32));
3e7ee490 212
59471438 213 return (hvStatusLo | ((u64)hvStatusHi << 32));
454f18a9 214#endif /* x86_64 */
3e7ee490
HJ
215}
216
217/*++
218
219Name:
220 HvInit()
221
222Description:
223 Main initialization routine. This routine must be called
224 before any other routines in here are called
225
226--*/
98d9fac4 227int HvInit (void)
3e7ee490
HJ
228{
229 int ret=0;
230 int maxLeaf;
231 HV_X64_MSR_HYPERCALL_CONTENTS hypercallMsr;
949cadaa 232 void *virtAddr = NULL;
3e7ee490
HJ
233
234 DPRINT_ENTER(VMBUS);
235
44f357f8
BP
236 memset(gHvContext.synICEventPage, 0, sizeof(void *) * MAX_NUM_CPUS);
237 memset(gHvContext.synICMessagePage, 0, sizeof(void *) * MAX_NUM_CPUS);
3e7ee490
HJ
238
239 if (!HvQueryHypervisorPresence())
240 {
241 DPRINT_ERR(VMBUS, "No Windows hypervisor detected!!");
242 goto Cleanup;
243 }
244
245 DPRINT_INFO(VMBUS, "Windows hypervisor detected! Retrieving more info...");
246
247 maxLeaf = HvQueryHypervisorInfo();
454f18a9 248 /* HvQueryHypervisorFeatures(maxLeaf); */
3e7ee490 249
454f18a9 250 /* Determine if we are running on xenlinux (ie x2v shim) or native linux */
a51ed7d6 251 rdmsrl(HV_X64_MSR_GUEST_OS_ID, gHvContext.GuestId);
3e7ee490
HJ
252 if (gHvContext.GuestId == 0)
253 {
454f18a9 254 /* Write our OS info */
a51ed7d6 255 wrmsrl(HV_X64_MSR_GUEST_OS_ID, HV_LINUX_GUEST_ID);
3e7ee490
HJ
256
257 gHvContext.GuestId = HV_LINUX_GUEST_ID;
258 }
259
454f18a9 260 /* See if the hypercall page is already set */
a51ed7d6 261 rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
3e7ee490
HJ
262 if (gHvContext.GuestId == HV_LINUX_GUEST_ID)
263 {
454f18a9 264 /* Allocate the hypercall page memory */
bfc30aae
GKH
265 /* virtAddr = osd_PageAlloc(1); */
266 virtAddr = osd_VirtualAllocExec(PAGE_SIZE);
3e7ee490
HJ
267
268 if (!virtAddr)
269 {
270 DPRINT_ERR(VMBUS, "unable to allocate hypercall page!!");
271 goto Cleanup;
272 }
273
274 hypercallMsr.Enable = 1;
fa56d361
GKH
275 /* hypercallMsr.GuestPhysicalAddress = virt_to_phys(virtAddr) >> PAGE_SHIFT; */
276 hypercallMsr.GuestPhysicalAddress = vmalloc_to_pfn(virtAddr);
a51ed7d6 277 wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
3e7ee490 278
454f18a9 279 /* Confirm that hypercall page did get setup. */
3e7ee490 280 hypercallMsr.AsUINT64 = 0;
a51ed7d6 281 rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
3e7ee490
HJ
282 if (!hypercallMsr.Enable)
283 {
284 DPRINT_ERR(VMBUS, "unable to set hypercall page!!");
285 goto Cleanup;
286 }
287
288 gHvContext.HypercallPage = virtAddr;
289 }
290 else
291 {
292 DPRINT_ERR(VMBUS, "Unknown guest id (0x%llx)!!", gHvContext.GuestId);
293 goto Cleanup;
294 }
295
2701f686
GKH
296 DPRINT_INFO(VMBUS, "Hypercall page VA=%p, PA=0x%0llx",
297 gHvContext.HypercallPage,
298 (u64)hypercallMsr.GuestPhysicalAddress << PAGE_SHIFT);
3e7ee490 299
454f18a9 300 /* Setup the global signal event param for the signal event hypercall */
e40d37cc 301 gHvContext.SignalEventBuffer = kmalloc(sizeof(HV_INPUT_SIGNAL_EVENT_BUFFER), GFP_KERNEL);
3e7ee490
HJ
302 if (!gHvContext.SignalEventBuffer)
303 {
304 goto Cleanup;
305 }
306
c4b0bc94 307 gHvContext.SignalEventParam = (PHV_INPUT_SIGNAL_EVENT)(ALIGN_UP((unsigned long)gHvContext.SignalEventBuffer, HV_HYPERCALL_PARAM_ALIGN));
4d643114 308 gHvContext.SignalEventParam->ConnectionId.Asu32 = 0;
3e7ee490
HJ
309 gHvContext.SignalEventParam->ConnectionId.u.Id = VMBUS_EVENT_CONNECTION_ID;
310 gHvContext.SignalEventParam->FlagNumber = 0;
311 gHvContext.SignalEventParam->RsvdZ = 0;
312
454f18a9 313 /* DPRINT_DBG(VMBUS, "My id %llu", HvGetCurrentPartitionId()); */
3e7ee490
HJ
314
315 DPRINT_EXIT(VMBUS);
316
317 return ret;
318
319Cleanup:
320 if (virtAddr)
321 {
322 if (hypercallMsr.Enable)
323 {
324 hypercallMsr.AsUINT64 = 0;
a51ed7d6 325 wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
3e7ee490
HJ
326 }
327
b7c947f0 328 vfree(virtAddr);
3e7ee490
HJ
329 }
330 ret = -1;
331 DPRINT_EXIT(VMBUS);
332
333 return ret;
334}
335
336
337/*++
338
339Name:
340 HvCleanup()
341
342Description:
343 Cleanup routine. This routine is called normally during driver unloading or exiting.
344
345--*/
98d9fac4 346void HvCleanup (void)
3e7ee490
HJ
347{
348 HV_X64_MSR_HYPERCALL_CONTENTS hypercallMsr;
349
350 DPRINT_ENTER(VMBUS);
351
352 if (gHvContext.SignalEventBuffer)
353 {
8c69f52a 354 kfree(gHvContext.SignalEventBuffer);
3e7ee490
HJ
355 gHvContext.SignalEventBuffer = NULL;
356 gHvContext.SignalEventParam = NULL;
357 }
358
359 if (gHvContext.GuestId == HV_LINUX_GUEST_ID)
360 {
361 if (gHvContext.HypercallPage)
362 {
363 hypercallMsr.AsUINT64 = 0;
a51ed7d6 364 wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
b7c947f0 365 vfree(gHvContext.HypercallPage);
3e7ee490
HJ
366 gHvContext.HypercallPage = NULL;
367 }
368 }
369
370 DPRINT_EXIT(VMBUS);
371
372}
373
374
375/*++
376
377Name:
378 HvPostMessage()
379
380Description:
381 Post a message using the hypervisor message IPC. This
382 involves a hypercall.
383
384--*/
98d9fac4 385HV_STATUS HvPostMessage(
3e7ee490
HJ
386 HV_CONNECTION_ID connectionId,
387 HV_MESSAGE_TYPE messageType,
8282c400 388 void * payload,
45635d97 389 size_t payloadSize
3e7ee490
HJ
390 )
391{
392 struct alignedInput {
59471438 393 u64 alignment8;
3e7ee490
HJ
394 HV_INPUT_POST_MESSAGE msg;
395 };
396
397 PHV_INPUT_POST_MESSAGE alignedMsg;
398 HV_STATUS status;
c4b0bc94 399 unsigned long addr;
3e7ee490
HJ
400
401 if (payloadSize > HV_MESSAGE_PAYLOAD_BYTE_COUNT)
402 {
403 return -1;
404 }
405
0a72f3cf 406 addr = (unsigned long)kmalloc(sizeof(struct alignedInput), GFP_ATOMIC);
3e7ee490
HJ
407
408 if (!addr)
409 {
410 return -1;
411 }
412
413 alignedMsg = (PHV_INPUT_POST_MESSAGE)(ALIGN_UP(addr, HV_HYPERCALL_PARAM_ALIGN));
414
415 alignedMsg->ConnectionId = connectionId;
416 alignedMsg->MessageType = messageType;
417 alignedMsg->PayloadSize = payloadSize;
418 memcpy((void*)alignedMsg->Payload, payload, payloadSize);
419
949cadaa 420 status = HvDoHypercall(HvCallPostMessage, alignedMsg, NULL) & 0xFFFF;
3e7ee490 421
8c69f52a 422 kfree((void*)addr);
3e7ee490
HJ
423
424 return status;
425}
426
427
428/*++
429
430Name:
431 HvSignalEvent()
432
433Description:
434 Signal an event on the specified connection using the hypervisor event IPC. This
435 involves a hypercall.
436
437--*/
98d9fac4 438HV_STATUS HvSignalEvent(void)
3e7ee490
HJ
439{
440 HV_STATUS status;
441
949cadaa 442 status = HvDoHypercall(HvCallSignalEvent, gHvContext.SignalEventParam, NULL) & 0xFFFF;
3e7ee490
HJ
443
444 return status;
445}
446
447
448/*++
449
450Name:
451 HvSynicInit()
452
453Description:
454 Initialize the Synthethic Interrupt Controller. If it is already initialized by
455 another entity (ie x2v shim), we need to retrieve the initialized message and event pages.
456 Otherwise, we create and initialize the message and event pages.
457
458--*/
98d9fac4 459int HvSynicInit (u32 irqVector)
3e7ee490 460{
59471438 461 u64 version;
3e7ee490
HJ
462 HV_SYNIC_SIMP simp;
463 HV_SYNIC_SIEFP siefp;
464 HV_SYNIC_SINT sharedSint;
465 HV_SYNIC_SCONTROL sctrl;
59471438 466 u64 guestID;
3e7ee490
HJ
467 int ret=0;
468
469 DPRINT_ENTER(VMBUS);
470
471 if (!gHvContext.HypercallPage)
472 {
473 DPRINT_EXIT(VMBUS);
474 return ret;
475 }
476
454f18a9 477 /* Check the version */
a51ed7d6 478 rdmsrl(HV_X64_MSR_SVERSION, version);
3e7ee490
HJ
479
480 DPRINT_INFO(VMBUS, "SynIC version: %llx", version);
481
454f18a9 482 /* TODO: Handle SMP */
3e7ee490
HJ
483 if (gHvContext.GuestId == HV_XENLINUX_GUEST_ID)
484 {
485 DPRINT_INFO(VMBUS, "Skipping SIMP and SIEFP setup since it is already set.");
486
a51ed7d6
GKH
487 rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
488 rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
3e7ee490
HJ
489
490 DPRINT_DBG(VMBUS, "Simp: %llx, Sifep: %llx", simp.AsUINT64, siefp.AsUINT64);
491
454f18a9 492 /* Determine if we are running on xenlinux (ie x2v shim) or native linux */
a51ed7d6 493 rdmsrl(HV_X64_MSR_GUEST_OS_ID, guestID);
3e7ee490
HJ
494 if (guestID == HV_LINUX_GUEST_ID)
495 {
fa56d361
GKH
496 gHvContext.synICMessagePage[0] = phys_to_virt(simp.BaseSimpGpa << PAGE_SHIFT);
497 gHvContext.synICEventPage[0] = phys_to_virt(siefp.BaseSiefpGpa << PAGE_SHIFT);
3e7ee490
HJ
498 }
499 else
500 {
501 DPRINT_ERR(VMBUS, "unknown guest id!!");
502 goto Cleanup;
503 }
504 DPRINT_DBG(VMBUS, "MAPPED: Simp: %p, Sifep: %p", gHvContext.synICMessagePage[0], gHvContext.synICEventPage[0]);
505 }
506 else
507 {
bfc30aae 508 gHvContext.synICMessagePage[0] = osd_PageAlloc(1);
3e7ee490
HJ
509 if (gHvContext.synICMessagePage[0] == NULL)
510 {
511 DPRINT_ERR(VMBUS, "unable to allocate SYNIC message page!!");
512 goto Cleanup;
513 }
514
bfc30aae 515 gHvContext.synICEventPage[0] = osd_PageAlloc(1);
3e7ee490
HJ
516 if (gHvContext.synICEventPage[0] == NULL)
517 {
518 DPRINT_ERR(VMBUS, "unable to allocate SYNIC event page!!");
519 goto Cleanup;
520 }
521
454f18a9 522 /* Setup the Synic's message page */
a51ed7d6 523 rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
3e7ee490 524 simp.SimpEnabled = 1;
fa56d361 525 simp.BaseSimpGpa = virt_to_phys(gHvContext.synICMessagePage[0]) >> PAGE_SHIFT;
3e7ee490
HJ
526
527 DPRINT_DBG(VMBUS, "HV_X64_MSR_SIMP msr set to: %llx", simp.AsUINT64);
528
a51ed7d6 529 wrmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
3e7ee490 530
454f18a9 531 /* Setup the Synic's event page */
a51ed7d6 532 rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
3e7ee490 533 siefp.SiefpEnabled = 1;
fa56d361 534 siefp.BaseSiefpGpa = virt_to_phys(gHvContext.synICEventPage[0]) >> PAGE_SHIFT;
3e7ee490
HJ
535
536 DPRINT_DBG(VMBUS, "HV_X64_MSR_SIEFP msr set to: %llx", siefp.AsUINT64);
537
a51ed7d6 538 wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
3e7ee490 539 }
454f18a9 540 /* Setup the interception SINT. */
a51ed7d6 541 /* wrmsrl((HV_X64_MSR_SINT0 + HV_SYNIC_INTERCEPTION_SINT_INDEX), */
454f18a9
BP
542 /* interceptionSint.AsUINT64); */
543
544 /* Setup the shared SINT. */
a51ed7d6 545 rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64);
3e7ee490
HJ
546
547 sharedSint.AsUINT64 = 0;
454f18a9
BP
548 sharedSint.Vector = irqVector; /* HV_SHARED_SINT_IDT_VECTOR + 0x20; */
549 sharedSint.Masked = false;
550 sharedSint.AutoEoi = true;
3e7ee490
HJ
551
552 DPRINT_DBG(VMBUS, "HV_X64_MSR_SINT1 msr set to: %llx", sharedSint.AsUINT64);
553
a51ed7d6 554 wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64);
3e7ee490 555
454f18a9 556 /* Enable the global synic bit */
a51ed7d6 557 rdmsrl(HV_X64_MSR_SCONTROL, sctrl.AsUINT64);
3e7ee490
HJ
558 sctrl.Enable = 1;
559
a51ed7d6 560 wrmsrl(HV_X64_MSR_SCONTROL, sctrl.AsUINT64);
3e7ee490 561
0e727613 562 gHvContext.SynICInitialized = true;
3e7ee490
HJ
563
564 DPRINT_EXIT(VMBUS);
565
566 return ret;
567
568Cleanup:
569 ret = -1;
570
571 if (gHvContext.GuestId == HV_LINUX_GUEST_ID)
572 {
573 if (gHvContext.synICEventPage[0])
574 {
bfc30aae 575 osd_PageFree(gHvContext.synICEventPage[0],1);
3e7ee490
HJ
576 }
577
578 if (gHvContext.synICMessagePage[0])
579 {
bfc30aae 580 osd_PageFree(gHvContext.synICMessagePage[0], 1);
3e7ee490
HJ
581 }
582 }
583
584 DPRINT_EXIT(VMBUS);
585
586 return ret;
587
588}
589
590/*++
591
592Name:
593 HvSynicCleanup()
594
595Description:
596 Cleanup routine for HvSynicInit().
597
598--*/
98d9fac4 599void HvSynicCleanup(void)
3e7ee490
HJ
600{
601 HV_SYNIC_SINT sharedSint;
602 HV_SYNIC_SIMP simp;
603 HV_SYNIC_SIEFP siefp;
604
605 DPRINT_ENTER(VMBUS);
606
607 if (!gHvContext.SynICInitialized)
608 {
609 DPRINT_EXIT(VMBUS);
610 return;
611 }
612
a51ed7d6 613 rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64);
3e7ee490
HJ
614
615 sharedSint.Masked = 1;
616
454f18a9 617 /* Disable the interrupt */
a51ed7d6 618 wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64);
3e7ee490 619
454f18a9
BP
620 /*
621 * Disable and free the resources only if we are running as
622 * native linux since in xenlinux, we are sharing the
623 * resources with the x2v shim
624 */
3e7ee490
HJ
625 if (gHvContext.GuestId == HV_LINUX_GUEST_ID)
626 {
a51ed7d6 627 rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
3e7ee490
HJ
628 simp.SimpEnabled = 0;
629 simp.BaseSimpGpa = 0;
630
a51ed7d6 631 wrmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
3e7ee490 632
a51ed7d6 633 rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
3e7ee490
HJ
634 siefp.SiefpEnabled = 0;
635 siefp.BaseSiefpGpa = 0;
636
a51ed7d6 637 wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
3e7ee490 638
bfc30aae
GKH
639 osd_PageFree(gHvContext.synICMessagePage[0], 1);
640 osd_PageFree(gHvContext.synICEventPage[0], 1);
3e7ee490
HJ
641 }
642
643 DPRINT_EXIT(VMBUS);
644}
645
646
454f18a9 647/* eof */
This page took 0.059015 seconds and 5 git commands to generate.