Commit 0831ad04 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Staging: hv: fix coding style issues in Hv.c

Lots of cleanups.

Note, the use of volatile still needs to be resolved, and
possibly the #ifdef could be done a bit "better".

Cc: Hank Janssen <hjanssen@microsoft.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent b3bfb3ce
/* /*
*
* Copyright (c) 2009, Microsoft Corporation. * Copyright (c) 2009, Microsoft Corporation.
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
...@@ -20,7 +19,6 @@ ...@@ -20,7 +19,6 @@
* Hank Janssen <hjanssen@microsoft.com> * Hank Janssen <hjanssen@microsoft.com>
* *
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
...@@ -28,8 +26,6 @@ ...@@ -28,8 +26,6 @@
#include "logging.h" #include "logging.h"
#include "VmbusPrivate.h" #include "VmbusPrivate.h"
/* Globals */
/* The one and only */ /* The one and only */
struct hv_context gHvContext = { struct hv_context gHvContext = {
.SynICInitialized = false, .SynICInitialized = false,
...@@ -38,198 +34,160 @@ struct hv_context gHvContext = { ...@@ -38,198 +34,160 @@ struct hv_context gHvContext = {
.SignalEventBuffer = NULL, .SignalEventBuffer = NULL,
}; };
/**
/*++ * HvQueryHypervisorPresence - Query the cpuid for presense of windows hypervisor
*/
Name: static int HvQueryHypervisorPresence(void)
HvQueryHypervisorPresence()
Description:
Query the cpuid for presense of windows hypervisor
--*/
static int
HvQueryHypervisorPresence (
void
)
{ {
unsigned int eax; unsigned int eax;
unsigned int ebx; unsigned int ebx;
unsigned int ecx; unsigned int ecx;
unsigned int edx; unsigned int edx;
unsigned int op; unsigned int op;
eax = 0;
ebx = 0;
ecx = 0;
edx = 0;
op = HvCpuIdFunctionVersionAndFeatures;
cpuid(op, &eax, &ebx, &ecx, &edx);
return (ecx & HV_PRESENT_BIT);
}
/*++
Name:
HvQueryHypervisorInfo()
Description:
Get version info of the windows hypervisor
--*/
static int
HvQueryHypervisorInfo (
void
)
{
unsigned int eax;
unsigned int ebx;
unsigned int ecx;
unsigned int edx;
unsigned int maxLeaf;
unsigned int op;
/*
* Its assumed that this is called after confirming that Viridian
* is present. Query id and revision.
*/
eax = 0;
ebx = 0;
ecx = 0;
edx = 0;
op = HvCpuIdFunctionHvVendorAndMaxFunction;
cpuid(op, &eax, &ebx, &ecx, &edx);
DPRINT_INFO(VMBUS, "Vendor ID: %c%c%c%c%c%c%c%c%c%c%c%c",
(ebx & 0xFF),
((ebx >> 8) & 0xFF),
((ebx >> 16) & 0xFF),
((ebx >> 24) & 0xFF),
(ecx & 0xFF),
((ecx >> 8) & 0xFF),
((ecx >> 16) & 0xFF),
((ecx >> 24) & 0xFF),
(edx & 0xFF),
((edx >> 8) & 0xFF),
((edx >> 16) & 0xFF),
((edx >> 24) & 0xFF));
maxLeaf = eax;
eax = 0;
ebx = 0;
ecx = 0;
edx = 0;
op = HvCpuIdFunctionHvInterface;
cpuid(op, &eax, &ebx, &ecx, &edx);
DPRINT_INFO(VMBUS, "Interface ID: %c%c%c%c",
(eax & 0xFF),
((eax >> 8) & 0xFF),
((eax >> 16) & 0xFF),
((eax >> 24) & 0xFF));
if (maxLeaf >= HvCpuIdFunctionMsHvVersion) {
eax = 0; eax = 0;
ebx = 0; ebx = 0;
ecx = 0; ecx = 0;
edx = 0; edx = 0;
op = HvCpuIdFunctionMsHvVersion; op = HvCpuIdFunctionVersionAndFeatures;
cpuid(op, &eax, &ebx, &ecx, &edx); cpuid(op, &eax, &ebx, &ecx, &edx);
DPRINT_INFO(VMBUS, "OS Build:%d-%d.%d-%d-%d.%d",
eax, return ecx & HV_PRESENT_BIT;
ebx >> 16,
ebx & 0xFFFF,
ecx,
edx >> 24,
edx & 0xFFFFFF);
}
return maxLeaf;
} }
/**
* HvQueryHypervisorInfo - Get version info of the windows hypervisor
*/
static int HvQueryHypervisorInfo(void)
{
unsigned int eax;
unsigned int ebx;
unsigned int ecx;
unsigned int edx;
unsigned int maxLeaf;
unsigned int op;
/*++ /*
* Its assumed that this is called after confirming that Viridian
* is present. Query id and revision.
*/
eax = 0;
ebx = 0;
ecx = 0;
edx = 0;
op = HvCpuIdFunctionHvVendorAndMaxFunction;
cpuid(op, &eax, &ebx, &ecx, &edx);
Name: DPRINT_INFO(VMBUS, "Vendor ID: %c%c%c%c%c%c%c%c%c%c%c%c",
HvDoHypercall() (ebx & 0xFF),
((ebx >> 8) & 0xFF),
((ebx >> 16) & 0xFF),
((ebx >> 24) & 0xFF),
(ecx & 0xFF),
((ecx >> 8) & 0xFF),
((ecx >> 16) & 0xFF),
((ecx >> 24) & 0xFF),
(edx & 0xFF),
((edx >> 8) & 0xFF),
((edx >> 16) & 0xFF),
((edx >> 24) & 0xFF));
maxLeaf = eax;
eax = 0;
ebx = 0;
ecx = 0;
edx = 0;
op = HvCpuIdFunctionHvInterface;
cpuid(op, &eax, &ebx, &ecx, &edx);
Description: DPRINT_INFO(VMBUS, "Interface ID: %c%c%c%c",
Invoke the specified hypercall (eax & 0xFF),
((eax >> 8) & 0xFF),
((eax >> 16) & 0xFF),
((eax >> 24) & 0xFF));
if (maxLeaf >= HvCpuIdFunctionMsHvVersion) {
eax = 0;
ebx = 0;
ecx = 0;
edx = 0;
op = HvCpuIdFunctionMsHvVersion;
cpuid(op, &eax, &ebx, &ecx, &edx);
DPRINT_INFO(VMBUS, "OS Build:%d-%d.%d-%d-%d.%d",\
eax,
ebx >> 16,
ebx & 0xFFFF,
ecx,
edx >> 24,
edx & 0xFFFFFF);
}
return maxLeaf;
}
--*/ /**
static u64 * HvDoHypercall - Invoke the specified hypercall
HvDoHypercall ( */
u64 Control, static u64 HvDoHypercall(u64 Control, void *Input, void *Output)
void* Input,
void* Output
)
{ {
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_64
u64 hvStatus=0; u64 hvStatus = 0;
u64 inputAddress = (Input)? virt_to_phys(Input) : 0; u64 inputAddress = (Input) ? virt_to_phys(Input) : 0;
u64 outputAddress = (Output)? virt_to_phys(Output) : 0; u64 outputAddress = (Output) ? virt_to_phys(Output) : 0;
volatile void* hypercallPage = gHvContext.HypercallPage; volatile void *hypercallPage = gHvContext.HypercallPage;
DPRINT_DBG(VMBUS, "Hypercall <control %llx input phys %llx virt %p output phys %llx virt %p hypercall %p>", DPRINT_DBG(VMBUS, "Hypercall <control %llx input phys %llx virt %p "
Control, "output phys %llx virt %p hypercall %p>",
inputAddress, Control, inputAddress, Input,
Input, outputAddress, Output, hypercallPage);
outputAddress,
Output,
hypercallPage);
__asm__ __volatile__ ("mov %0, %%r8" : : "r" (outputAddress): "r8"); __asm__ __volatile__("mov %0, %%r8" : : "r" (outputAddress) : "r8");
__asm__ __volatile__ ("call *%3" : "=a"(hvStatus): "c" (Control), "d" (inputAddress), "m" (hypercallPage)); __asm__ __volatile__("call *%3" : "=a" (hvStatus) :
"c" (Control), "d" (inputAddress),
"m" (hypercallPage));
DPRINT_DBG(VMBUS, "Hypercall <return %llx>", hvStatus); DPRINT_DBG(VMBUS, "Hypercall <return %llx>", hvStatus);
return hvStatus; return hvStatus;
#else #else
u32 controlHi = Control >> 32; u32 controlHi = Control >> 32;
u32 controlLo = Control & 0xFFFFFFFF; u32 controlLo = Control & 0xFFFFFFFF;
u32 hvStatusHi = 1; u32 hvStatusHi = 1;
u32 hvStatusLo = 1; u32 hvStatusLo = 1;
u64 inputAddress = (Input) ? virt_to_phys(Input) : 0; u64 inputAddress = (Input) ? virt_to_phys(Input) : 0;
u32 inputAddressHi = inputAddress >> 32; u32 inputAddressHi = inputAddress >> 32;
u32 inputAddressLo = inputAddress & 0xFFFFFFFF; u32 inputAddressLo = inputAddress & 0xFFFFFFFF;
u64 outputAddress = (Output) ? virt_to_phys(Output) : 0; u64 outputAddress = (Output) ? virt_to_phys(Output) : 0;
u32 outputAddressHi = outputAddress >> 32; u32 outputAddressHi = outputAddress >> 32;
u32 outputAddressLo = outputAddress & 0xFFFFFFFF; u32 outputAddressLo = outputAddress & 0xFFFFFFFF;
volatile void* hypercallPage = gHvContext.HypercallPage; volatile void *hypercallPage = gHvContext.HypercallPage;
DPRINT_DBG(VMBUS, "Hypercall <control %llx input %p output %p>",
Control,
Input,
Output);
__asm__ __volatile__ ("call *%8" : "=d"(hvStatusHi), "=a"(hvStatusLo) : "d" (controlHi), "a" (controlLo), "b" (inputAddressHi), "c" (inputAddressLo), "D"(outputAddressHi), "S"(outputAddressLo), "m" (hypercallPage)); DPRINT_DBG(VMBUS, "Hypercall <control %llx input %p output %p>",
Control, Input, Output);
__asm__ __volatile__ ("call *%8" : "=d"(hvStatusHi),
"=a"(hvStatusLo) : "d" (controlHi),
"a" (controlLo), "b" (inputAddressHi),
"c" (inputAddressLo), "D"(outputAddressHi),
"S"(outputAddressLo), "m" (hypercallPage));
DPRINT_DBG(VMBUS, "Hypercall <return %llx>", hvStatusLo | ((u64)hvStatusHi << 32)); DPRINT_DBG(VMBUS, "Hypercall <return %llx>",
hvStatusLo | ((u64)hvStatusHi << 32));
return (hvStatusLo | ((u64)hvStatusHi << 32)); return hvStatusLo | ((u64)hvStatusHi << 32);
#endif /* x86_64 */ #endif /* !x86_64 */
} }
/*++ /**
* HvInit - Main initialization routine.
Name: *
HvInit() * This routine must be called before any other routines in here are called
*/
Description: int HvInit(void)
Main initialization routine. This routine must be called
before any other routines in here are called
--*/
int HvInit (void)
{ {
int ret=0; int ret = 0;
int maxLeaf; int maxLeaf;
union hv_x64_msr_hypercall_contents hypercallMsr; union hv_x64_msr_hypercall_contents hypercallMsr;
void *virtAddr = NULL; void *virtAddr = NULL;
...@@ -238,60 +196,59 @@ int HvInit (void) ...@@ -238,60 +196,59 @@ int HvInit (void)
memset(gHvContext.synICEventPage, 0, sizeof(void *) * MAX_NUM_CPUS); memset(gHvContext.synICEventPage, 0, sizeof(void *) * MAX_NUM_CPUS);
memset(gHvContext.synICMessagePage, 0, sizeof(void *) * MAX_NUM_CPUS); memset(gHvContext.synICMessagePage, 0, sizeof(void *) * MAX_NUM_CPUS);
if (!HvQueryHypervisorPresence()) if (!HvQueryHypervisorPresence()) {
{
DPRINT_ERR(VMBUS, "No Windows hypervisor detected!!"); DPRINT_ERR(VMBUS, "No Windows hypervisor detected!!");
goto Cleanup; goto Cleanup;
} }
DPRINT_INFO(VMBUS, "Windows hypervisor detected! Retrieving more info..."); DPRINT_INFO(VMBUS,
"Windows hypervisor detected! Retrieving more info...");
maxLeaf = HvQueryHypervisorInfo(); maxLeaf = HvQueryHypervisorInfo();
/* HvQueryHypervisorFeatures(maxLeaf); */ /* HvQueryHypervisorFeatures(maxLeaf); */
/* Determine if we are running on xenlinux (ie x2v shim) or native linux */ /*
* Determine if we are running on xenlinux (ie x2v shim) or native
* linux
*/
rdmsrl(HV_X64_MSR_GUEST_OS_ID, gHvContext.GuestId); rdmsrl(HV_X64_MSR_GUEST_OS_ID, gHvContext.GuestId);
if (gHvContext.GuestId == 0) if (gHvContext.GuestId == 0) {
{
/* Write our OS info */ /* Write our OS info */
wrmsrl(HV_X64_MSR_GUEST_OS_ID, HV_LINUX_GUEST_ID); wrmsrl(HV_X64_MSR_GUEST_OS_ID, HV_LINUX_GUEST_ID);
gHvContext.GuestId = HV_LINUX_GUEST_ID; gHvContext.GuestId = HV_LINUX_GUEST_ID;
} }
/* See if the hypercall page is already set */ /* See if the hypercall page is already set */
rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64); rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
if (gHvContext.GuestId == HV_LINUX_GUEST_ID) if (gHvContext.GuestId == HV_LINUX_GUEST_ID) {
{
/* Allocate the hypercall page memory */ /* Allocate the hypercall page memory */
/* virtAddr = osd_PageAlloc(1); */ /* virtAddr = osd_PageAlloc(1); */
virtAddr = osd_VirtualAllocExec(PAGE_SIZE); virtAddr = osd_VirtualAllocExec(PAGE_SIZE);
if (!virtAddr) if (!virtAddr) {
{ DPRINT_ERR(VMBUS,
DPRINT_ERR(VMBUS, "unable to allocate hypercall page!!"); "unable to allocate hypercall page!!");
goto Cleanup; goto Cleanup;
} }
hypercallMsr.Enable = 1; hypercallMsr.Enable = 1;
/* hypercallMsr.GuestPhysicalAddress = virt_to_phys(virtAddr) >> PAGE_SHIFT; */ /* hypercallMsr.GuestPhysicalAddress =
* virt_to_phys(virtAddr) >> PAGE_SHIFT; */
hypercallMsr.GuestPhysicalAddress = vmalloc_to_pfn(virtAddr); hypercallMsr.GuestPhysicalAddress = vmalloc_to_pfn(virtAddr);
wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64); wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
/* Confirm that hypercall page did get setup. */ /* Confirm that hypercall page did get setup. */
hypercallMsr.AsUINT64 = 0; hypercallMsr.AsUINT64 = 0;
rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64); rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
if (!hypercallMsr.Enable) if (!hypercallMsr.Enable) {
{
DPRINT_ERR(VMBUS, "unable to set hypercall page!!"); DPRINT_ERR(VMBUS, "unable to set hypercall page!!");
goto Cleanup; goto Cleanup;
} }
gHvContext.HypercallPage = virtAddr; gHvContext.HypercallPage = virtAddr;
} } else {
else DPRINT_ERR(VMBUS, "Unknown guest id (0x%llx)!!",
{ gHvContext.GuestId);
DPRINT_ERR(VMBUS, "Unknown guest id (0x%llx)!!", gHvContext.GuestId);
goto Cleanup; goto Cleanup;
} }
...@@ -300,29 +257,31 @@ int HvInit (void) ...@@ -300,29 +257,31 @@ int HvInit (void)
(u64)hypercallMsr.GuestPhysicalAddress << PAGE_SHIFT); (u64)hypercallMsr.GuestPhysicalAddress << PAGE_SHIFT);
/* Setup the global signal event param for the signal event hypercall */ /* Setup the global signal event param for the signal event hypercall */
gHvContext.SignalEventBuffer = kmalloc(sizeof(struct hv_input_signal_event_buffer), GFP_KERNEL); gHvContext.SignalEventBuffer =
kmalloc(sizeof(struct hv_input_signal_event_buffer),
GFP_KERNEL);
if (!gHvContext.SignalEventBuffer) if (!gHvContext.SignalEventBuffer)
{
goto Cleanup; goto Cleanup;
}
gHvContext.SignalEventParam = (struct hv_input_signal_event *)(ALIGN_UP((unsigned long)gHvContext.SignalEventBuffer, HV_HYPERCALL_PARAM_ALIGN)); gHvContext.SignalEventParam =
(struct hv_input_signal_event *)
(ALIGN_UP((unsigned long)gHvContext.SignalEventBuffer,
HV_HYPERCALL_PARAM_ALIGN));
gHvContext.SignalEventParam->ConnectionId.Asu32 = 0; gHvContext.SignalEventParam->ConnectionId.Asu32 = 0;
gHvContext.SignalEventParam->ConnectionId.u.Id = VMBUS_EVENT_CONNECTION_ID; gHvContext.SignalEventParam->ConnectionId.u.Id =
VMBUS_EVENT_CONNECTION_ID;
gHvContext.SignalEventParam->FlagNumber = 0; gHvContext.SignalEventParam->FlagNumber = 0;
gHvContext.SignalEventParam->RsvdZ = 0; gHvContext.SignalEventParam->RsvdZ = 0;
/* DPRINT_DBG(VMBUS, "My id %llu", HvGetCurrentPartitionId()); */ /* DPRINT_DBG(VMBUS, "My id %llu", HvGetCurrentPartitionId()); */
DPRINT_EXIT(VMBUS); DPRINT_EXIT(VMBUS);
return ret; return ret;
Cleanup: Cleanup:
if (virtAddr) if (virtAddr) {
{ if (hypercallMsr.Enable) {
if (hypercallMsr.Enable)
{
hypercallMsr.AsUINT64 = 0; hypercallMsr.AsUINT64 = 0;
wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64); wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
} }
...@@ -335,33 +294,25 @@ int HvInit (void) ...@@ -335,33 +294,25 @@ int HvInit (void)
return ret; return ret;
} }
/**
/*++ * HvCleanup - Cleanup routine.
*
Name: * This routine is called normally during driver unloading or exiting.
HvCleanup() */
void HvCleanup(void)
Description:
Cleanup routine. This routine is called normally during driver unloading or exiting.
--*/
void HvCleanup (void)
{ {
union hv_x64_msr_hypercall_contents hypercallMsr; union hv_x64_msr_hypercall_contents hypercallMsr;
DPRINT_ENTER(VMBUS); DPRINT_ENTER(VMBUS);
if (gHvContext.SignalEventBuffer) if (gHvContext.SignalEventBuffer) {
{
kfree(gHvContext.SignalEventBuffer);
gHvContext.SignalEventBuffer = NULL; gHvContext.SignalEventBuffer = NULL;
gHvContext.SignalEventParam = NULL; gHvContext.SignalEventParam = NULL;
kfree(gHvContext.SignalEventBuffer);
} }
if (gHvContext.GuestId == HV_LINUX_GUEST_ID) if (gHvContext.GuestId == HV_LINUX_GUEST_ID) {
{ if (gHvContext.HypercallPage) {
if (gHvContext.HypercallPage)
{
hypercallMsr.AsUINT64 = 0; hypercallMsr.AsUINT64 = 0;
wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64); wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
vfree(gHvContext.HypercallPage); vfree(gHvContext.HypercallPage);
...@@ -373,23 +324,17 @@ void HvCleanup (void) ...@@ -373,23 +324,17 @@ void HvCleanup (void)
} }
/**
/*++ * HvPostMessage - Post a message using the hypervisor message IPC.
*
Name: * This involves a hypercall.
HvPostMessage() */
Description:
Post a message using the hypervisor message IPC. This
involves a hypercall.
--*/
u16 HvPostMessage(union hv_connection_id connectionId, u16 HvPostMessage(union hv_connection_id connectionId,
enum hv_message_type messageType, enum hv_message_type messageType,
void *payload, size_t payloadSize) void *payload, size_t payloadSize)
{ {
struct alignedInput { struct alignedInput {
u64 alignment8; u64 alignment8;
struct hv_input_post_message msg; struct hv_input_post_message msg;
}; };
...@@ -398,77 +343,62 @@ u16 HvPostMessage(union hv_connection_id connectionId, ...@@ -398,77 +343,62 @@ u16 HvPostMessage(union hv_connection_id connectionId,
unsigned long addr; unsigned long addr;
if (payloadSize > HV_MESSAGE_PAYLOAD_BYTE_COUNT) if (payloadSize > HV_MESSAGE_PAYLOAD_BYTE_COUNT)
{
return -1; return -1;
}
addr = (unsigned long)kmalloc(sizeof(struct alignedInput), GFP_ATOMIC); addr = (unsigned long)kmalloc(sizeof(struct alignedInput), GFP_ATOMIC);
if (!addr) if (!addr)
{
return -1; return -1;
}
alignedMsg = (struct hv_input_post_message *)(ALIGN_UP(addr, HV_HYPERCALL_PARAM_ALIGN)); alignedMsg = (struct hv_input_post_message *)
(ALIGN_UP(addr, HV_HYPERCALL_PARAM_ALIGN));
alignedMsg->ConnectionId = connectionId; alignedMsg->ConnectionId = connectionId;
alignedMsg->MessageType = messageType; alignedMsg->MessageType = messageType;
alignedMsg->PayloadSize = payloadSize; alignedMsg->PayloadSize = payloadSize;
memcpy((void*)alignedMsg->Payload, payload, payloadSize); memcpy((void *)alignedMsg->Payload, payload, payloadSize);
status = HvDoHypercall(HvCallPostMessage, alignedMsg, NULL) & 0xFFFF; status = HvDoHypercall(HvCallPostMessage, alignedMsg, NULL) & 0xFFFF;
kfree((void*)addr); kfree((void *)addr);
return status; return status;
} }
/*++ /**
* HvSignalEvent - Signal an event on the specified connection using the hypervisor event IPC.
Name: *
HvSignalEvent() * This involves a hypercall.
*/
Description:
Signal an event on the specified connection using the hypervisor event IPC. This
involves a hypercall.
--*/
u16 HvSignalEvent(void) u16 HvSignalEvent(void)
{ {
u16 status; u16 status;
status = HvDoHypercall(HvCallSignalEvent, gHvContext.SignalEventParam, NULL) & 0xFFFF; status = HvDoHypercall(HvCallSignalEvent, gHvContext.SignalEventParam,
NULL) & 0xFFFF;
return status; return status;
} }
/**
/*++ * HvSynicInit - Initialize the Synthethic Interrupt Controller.
*
Name: * If it is already initialized by another entity (ie x2v shim), we need to
HvSynicInit() * retrieve the initialized message and event pages. Otherwise, we create and
* initialize the message and event pages.
Description: */
Initialize the Synthethic Interrupt Controller. If it is already initialized by int HvSynicInit(u32 irqVector)
another entity (ie x2v shim), we need to retrieve the initialized message and event pages.
Otherwise, we create and initialize the message and event pages.
--*/
int HvSynicInit (u32 irqVector)
{ {
u64 version; u64 version;
union hv_synic_simp simp; union hv_synic_simp simp;
union hv_synic_siefp siefp; union hv_synic_siefp siefp;
union hv_synic_sint sharedSint; union hv_synic_sint sharedSint;
union hv_synic_scontrol sctrl; union hv_synic_scontrol sctrl;
u64 guestID; u64 guestID;
int ret=0; int ret = 0;
DPRINT_ENTER(VMBUS); DPRINT_ENTER(VMBUS);
if (!gHvContext.HypercallPage) if (!gHvContext.HypercallPage) {
{
DPRINT_EXIT(VMBUS); DPRINT_EXIT(VMBUS);
return ret; return ret;
} }
...@@ -479,68 +409,76 @@ int HvSynicInit (u32 irqVector) ...@@ -479,68 +409,76 @@ int HvSynicInit (u32 irqVector)
DPRINT_INFO(VMBUS, "SynIC version: %llx", version); DPRINT_INFO(VMBUS, "SynIC version: %llx", version);
/* TODO: Handle SMP */ /* TODO: Handle SMP */
if (gHvContext.GuestId == HV_XENLINUX_GUEST_ID) if (gHvContext.GuestId == HV_XENLINUX_GUEST_ID) {
{ DPRINT_INFO(VMBUS, "Skipping SIMP and SIEFP setup since "
DPRINT_INFO(VMBUS, "Skipping SIMP and SIEFP setup since it is already set."); "it is already set.");
rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64); rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64); rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
DPRINT_DBG(VMBUS, "Simp: %llx, Sifep: %llx", simp.AsUINT64, siefp.AsUINT64); DPRINT_DBG(VMBUS, "Simp: %llx, Sifep: %llx",
simp.AsUINT64, siefp.AsUINT64);
/* Determine if we are running on xenlinux (ie x2v shim) or native linux */ /*
* Determine if we are running on xenlinux (ie x2v shim) or
* native linux
*/
rdmsrl(HV_X64_MSR_GUEST_OS_ID, guestID); rdmsrl(HV_X64_MSR_GUEST_OS_ID, guestID);
if (guestID == HV_LINUX_GUEST_ID) if (guestID == HV_LINUX_GUEST_ID) {
{ gHvContext.synICMessagePage[0] =
gHvContext.synICMessagePage[0] = phys_to_virt(simp.BaseSimpGpa << PAGE_SHIFT); phys_to_virt(simp.BaseSimpGpa << PAGE_SHIFT);
gHvContext.synICEventPage[0] = phys_to_virt(siefp.BaseSiefpGpa << PAGE_SHIFT); gHvContext.synICEventPage[0] =
} phys_to_virt(siefp.BaseSiefpGpa << PAGE_SHIFT);
else } else {
{
DPRINT_ERR(VMBUS, "unknown guest id!!"); DPRINT_ERR(VMBUS, "unknown guest id!!");
goto Cleanup; goto Cleanup;
} }
DPRINT_DBG(VMBUS, "MAPPED: Simp: %p, Sifep: %p", gHvContext.synICMessagePage[0], gHvContext.synICEventPage[0]); DPRINT_DBG(VMBUS, "MAPPED: Simp: %p, Sifep: %p",
} gHvContext.synICMessagePage[0],
else gHvContext.synICEventPage[0]);
{ } else {
gHvContext.synICMessagePage[0] = osd_PageAlloc(1); gHvContext.synICMessagePage[0] = osd_PageAlloc(1);
if (gHvContext.synICMessagePage[0] == NULL) if (gHvContext.synICMessagePage[0] == NULL) {
{ DPRINT_ERR(VMBUS,
DPRINT_ERR(VMBUS, "unable to allocate SYNIC message page!!"); "unable to allocate SYNIC message page!!");
goto Cleanup; goto Cleanup;
} }
gHvContext.synICEventPage[0] = osd_PageAlloc(1); gHvContext.synICEventPage[0] = osd_PageAlloc(1);
if (gHvContext.synICEventPage[0] == NULL) if (gHvContext.synICEventPage[0] == NULL) {
{ DPRINT_ERR(VMBUS,
DPRINT_ERR(VMBUS, "unable to allocate SYNIC event page!!"); "unable to allocate SYNIC event page!!");
goto Cleanup; goto Cleanup;
} }
/* Setup the Synic's message page */ /* Setup the Synic's message page */
rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64); rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
simp.SimpEnabled = 1; simp.SimpEnabled = 1;
simp.BaseSimpGpa = virt_to_phys(gHvContext.synICMessagePage[0]) >> PAGE_SHIFT; simp.BaseSimpGpa = virt_to_phys(gHvContext.synICMessagePage[0])
>> PAGE_SHIFT;
DPRINT_DBG(VMBUS, "HV_X64_MSR_SIMP msr set to: %llx", simp.AsUINT64); DPRINT_DBG(VMBUS, "HV_X64_MSR_SIMP msr set to: %llx",
simp.AsUINT64);
wrmsrl(HV_X64_MSR_SIMP, simp.AsUINT64); wrmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
/* Setup the Synic's event page */ /* Setup the Synic's event page */
rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64); rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
siefp.SiefpEnabled = 1; siefp.SiefpEnabled = 1;
siefp.BaseSiefpGpa = virt_to_phys(gHvContext.synICEventPage[0]) >> PAGE_SHIFT; siefp.BaseSiefpGpa = virt_to_phys(gHvContext.synICEventPage[0])
>> PAGE_SHIFT;
DPRINT_DBG(VMBUS, "HV_X64_MSR_SIEFP msr set to: %llx", siefp.AsUINT64); DPRINT_DBG(VMBUS, "HV_X64_MSR_SIEFP msr set to: %llx",
siefp.AsUINT64);
wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64); wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
} }
/* Setup the interception SINT. */
/* Setup the interception SINT. */
/* wrmsrl((HV_X64_MSR_SINT0 + HV_SYNIC_INTERCEPTION_SINT_INDEX), */ /* wrmsrl((HV_X64_MSR_SINT0 + HV_SYNIC_INTERCEPTION_SINT_INDEX), */
/* interceptionSint.AsUINT64); */ /* interceptionSint.AsUINT64); */
/* Setup the shared SINT. */ /* Setup the shared SINT. */
rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64); rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64);
sharedSint.AsUINT64 = 0; sharedSint.AsUINT64 = 0;
...@@ -548,7 +486,8 @@ int HvSynicInit (u32 irqVector) ...@@ -548,7 +486,8 @@ int HvSynicInit (u32 irqVector)
sharedSint.Masked = false; sharedSint.Masked = false;
sharedSint.AutoEoi = true; sharedSint.AutoEoi = true;
DPRINT_DBG(VMBUS, "HV_X64_MSR_SINT1 msr set to: %llx", sharedSint.AsUINT64); DPRINT_DBG(VMBUS, "HV_X64_MSR_SINT1 msr set to: %llx",
sharedSint.AsUINT64);
wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64); wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64);
...@@ -567,34 +506,22 @@ int HvSynicInit (u32 irqVector) ...@@ -567,34 +506,22 @@ int HvSynicInit (u32 irqVector)
Cleanup: Cleanup:
ret = -1; ret = -1;
if (gHvContext.GuestId == HV_LINUX_GUEST_ID) if (gHvContext.GuestId == HV_LINUX_GUEST_ID) {
{
if (gHvContext.synICEventPage[0]) if (gHvContext.synICEventPage[0])
{ osd_PageFree(gHvContext.synICEventPage[0], 1);
osd_PageFree(gHvContext.synICEventPage[0],1);
}
if (gHvContext.synICMessagePage[0]) if (gHvContext.synICMessagePage[0])
{
osd_PageFree(gHvContext.synICMessagePage[0], 1); osd_PageFree(gHvContext.synICMessagePage[0], 1);
}
} }
DPRINT_EXIT(VMBUS); DPRINT_EXIT(VMBUS);
return ret; return ret;
} }
/*++ /**
* HvSynicCleanup - Cleanup routine for HvSynicInit().
Name: */
HvSynicCleanup()
Description:
Cleanup routine for HvSynicInit().
--*/
void HvSynicCleanup(void) void HvSynicCleanup(void)
{ {
union hv_synic_sint sharedSint; union hv_synic_sint sharedSint;
...@@ -603,8 +530,7 @@ void HvSynicCleanup(void) ...@@ -603,8 +530,7 @@ void HvSynicCleanup(void)
DPRINT_ENTER(VMBUS); DPRINT_ENTER(VMBUS);
if (!gHvContext.SynICInitialized) if (!gHvContext.SynICInitialized) {
{
DPRINT_EXIT(VMBUS); DPRINT_EXIT(VMBUS);
return; return;
} }
...@@ -621,8 +547,7 @@ void HvSynicCleanup(void) ...@@ -621,8 +547,7 @@ void HvSynicCleanup(void)
* native linux since in xenlinux, we are sharing the * native linux since in xenlinux, we are sharing the
* resources with the x2v shim * resources with the x2v shim
*/ */
if (gHvContext.GuestId == HV_LINUX_GUEST_ID) if (gHvContext.GuestId == HV_LINUX_GUEST_ID) {
{
rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64); rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
simp.SimpEnabled = 0; simp.SimpEnabled = 0;
simp.BaseSimpGpa = 0; simp.BaseSimpGpa = 0;
...@@ -641,6 +566,3 @@ void HvSynicCleanup(void) ...@@ -641,6 +566,3 @@ void HvSynicCleanup(void)
DPRINT_EXIT(VMBUS); DPRINT_EXIT(VMBUS);
} }
/* eof */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment