Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 228067
b: refs/heads/master
c: 6a0aaa1
h: refs/heads/master
i:
  228065: 0006bb4
  228063: f93ea5e
v: v3
  • Loading branch information
Haiyang Zhang authored and Greg Kroah-Hartman committed Nov 10, 2010
1 parent 16ec042 commit a001eb6
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 59 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f6feebe073db4c97dc10f6fab54f9d4b5816886b
refs/heads/master: 6a0aaa185057801343e000183ef0695c2a2b75a9
95 changes: 50 additions & 45 deletions trunk/drivers/staging/hv/hv.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@
#include "vmbus_private.h"

/* The one and only */
struct hv_context gHvContext = {
.SynICInitialized = false,
.HypercallPage = NULL,
.SignalEventParam = NULL,
.SignalEventBuffer = NULL,
struct hv_context hv_context = {
.synic_initialized = false,
.hypercall_page = NULL,
.signal_event_param = NULL,
.signal_event_buffer = NULL,
};

/*
Expand Down Expand Up @@ -134,7 +134,7 @@ static u64 HvDoHypercall(u64 Control, void *Input, void *Output)
u64 hvStatus = 0;
u64 inputAddress = (Input) ? virt_to_phys(Input) : 0;
u64 outputAddress = (Output) ? virt_to_phys(Output) : 0;
volatile void *hypercallPage = gHvContext.HypercallPage;
volatile void *hypercallPage = hv_context.hypercall_page;

DPRINT_DBG(VMBUS, "Hypercall <control %llx input phys %llx virt %p "
"output phys %llx virt %p hypercall %p>",
Expand Down Expand Up @@ -162,7 +162,7 @@ static u64 HvDoHypercall(u64 Control, void *Input, void *Output)
u64 outputAddress = (Output) ? virt_to_phys(Output) : 0;
u32 outputAddressHi = outputAddress >> 32;
u32 outputAddressLo = outputAddress & 0xFFFFFFFF;
volatile void *hypercallPage = gHvContext.HypercallPage;
volatile void *hypercallPage = hv_context.hypercall_page;

DPRINT_DBG(VMBUS, "Hypercall <control %llx input %p output %p>",
Control, Input, Output);
Expand Down Expand Up @@ -192,8 +192,9 @@ int HvInit(void)
union hv_x64_msr_hypercall_contents hypercallMsr;
void *virtAddr = NULL;

memset(gHvContext.synICEventPage, 0, sizeof(void *) * MAX_NUM_CPUS);
memset(gHvContext.synICMessagePage, 0, sizeof(void *) * MAX_NUM_CPUS);
memset(hv_context.synic_event_page, 0, sizeof(void *) * MAX_NUM_CPUS);
memset(hv_context.synic_message_page, 0,
sizeof(void *) * MAX_NUM_CPUS);

if (!HvQueryHypervisorPresence()) {
DPRINT_ERR(VMBUS, "No Windows hypervisor detected!!");
Expand All @@ -209,17 +210,17 @@ int HvInit(void)
/*
* We only support running on top of Hyper-V
*/
rdmsrl(HV_X64_MSR_GUEST_OS_ID, gHvContext.GuestId);
rdmsrl(HV_X64_MSR_GUEST_OS_ID, hv_context.guestid);

if (gHvContext.GuestId != 0) {
if (hv_context.guestid != 0) {
DPRINT_ERR(VMBUS, "Unknown guest id (0x%llx)!!",
gHvContext.GuestId);
hv_context.guestid);
goto Cleanup;
}

/* Write our OS info */
wrmsrl(HV_X64_MSR_GUEST_OS_ID, HV_LINUX_GUEST_ID);
gHvContext.GuestId = HV_LINUX_GUEST_ID;
hv_context.guestid = HV_LINUX_GUEST_ID;

/* See if the hypercall page is already set */
rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.as_uint64);
Expand Down Expand Up @@ -250,28 +251,29 @@ int HvInit(void)
goto Cleanup;
}

gHvContext.HypercallPage = virtAddr;
hv_context.hypercall_page = virtAddr;

DPRINT_INFO(VMBUS, "Hypercall page VA=%p, PA=0x%0llx",
gHvContext.HypercallPage,
hv_context.hypercall_page,
(u64)hypercallMsr.guest_physical_address << PAGE_SHIFT);

/* Setup the global signal event param for the signal event hypercall */
gHvContext.SignalEventBuffer =
hv_context.signal_event_buffer =
kmalloc(sizeof(struct hv_input_signal_event_buffer),
GFP_KERNEL);
if (!gHvContext.SignalEventBuffer)
if (!hv_context.signal_event_buffer)
goto Cleanup;

gHvContext.SignalEventParam =
hv_context.signal_event_param =
(struct hv_input_signal_event *)
(ALIGN_UP((unsigned long)gHvContext.SignalEventBuffer,
(ALIGN_UP((unsigned long)
hv_context.signal_event_buffer,
HV_HYPERCALL_PARAM_ALIGN));
gHvContext.SignalEventParam->connectionid.asu32 = 0;
gHvContext.SignalEventParam->connectionid.u.id =
hv_context.signal_event_param->connectionid.asu32 = 0;
hv_context.signal_event_param->connectionid.u.id =
VMBUS_EVENT_CONNECTION_ID;
gHvContext.SignalEventParam->flag_number = 0;
gHvContext.SignalEventParam->rsvdz = 0;
hv_context.signal_event_param->flag_number = 0;
hv_context.signal_event_param->rsvdz = 0;

return ret;

Expand All @@ -297,15 +299,15 @@ void HvCleanup(void)
{
union hv_x64_msr_hypercall_contents hypercallMsr;

kfree(gHvContext.SignalEventBuffer);
gHvContext.SignalEventBuffer = NULL;
gHvContext.SignalEventParam = NULL;
kfree(hv_context.signal_event_buffer);
hv_context.signal_event_buffer = NULL;
hv_context.signal_event_param = NULL;

if (gHvContext.HypercallPage) {
if (hv_context.hypercall_page) {
hypercallMsr.as_uint64 = 0;
wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.as_uint64);
vfree(gHvContext.HypercallPage);
gHvContext.HypercallPage = NULL;
vfree(hv_context.hypercall_page);
hv_context.hypercall_page = NULL;
}
}

Expand Down Expand Up @@ -359,7 +361,8 @@ u16 HvSignalEvent(void)
{
u16 status;

status = HvDoHypercall(HVCALL_SIGNAL_EVENT, gHvContext.SignalEventParam,
status = HvDoHypercall(HVCALL_SIGNAL_EVENT,
hv_context.signal_event_param,
NULL) & 0xFFFF;
return status;
}
Expand All @@ -382,25 +385,27 @@ void HvSynicInit(void *irqarg)
u32 irqVector = *((u32 *)(irqarg));
int cpu = smp_processor_id();

if (!gHvContext.HypercallPage)
if (!hv_context.hypercall_page)
return;

/* Check the version */
rdmsrl(HV_X64_MSR_SVERSION, version);

DPRINT_INFO(VMBUS, "SynIC version: %llx", version);

gHvContext.synICMessagePage[cpu] = (void *)get_zeroed_page(GFP_ATOMIC);
hv_context.synic_message_page[cpu] =
(void *)get_zeroed_page(GFP_ATOMIC);

if (gHvContext.synICMessagePage[cpu] == NULL) {
if (hv_context.synic_message_page[cpu] == NULL) {
DPRINT_ERR(VMBUS,
"unable to allocate SYNIC message page!!");
goto Cleanup;
}

gHvContext.synICEventPage[cpu] = (void *)get_zeroed_page(GFP_ATOMIC);
hv_context.synic_event_page[cpu] =
(void *)get_zeroed_page(GFP_ATOMIC);

if (gHvContext.synICEventPage[cpu] == NULL) {
if (hv_context.synic_event_page[cpu] == NULL) {
DPRINT_ERR(VMBUS,
"unable to allocate SYNIC event page!!");
goto Cleanup;
Expand All @@ -409,7 +414,7 @@ void HvSynicInit(void *irqarg)
/* Setup the Synic's message page */
rdmsrl(HV_X64_MSR_SIMP, simp.as_uint64);
simp.simp_enabled = 1;
simp.base_simp_gpa = virt_to_phys(gHvContext.synICMessagePage[cpu])
simp.base_simp_gpa = virt_to_phys(hv_context.synic_message_page[cpu])
>> PAGE_SHIFT;

DPRINT_DBG(VMBUS, "HV_X64_MSR_SIMP msr set to: %llx", simp.as_uint64);
Expand All @@ -419,7 +424,7 @@ void HvSynicInit(void *irqarg)
/* Setup the Synic's event page */
rdmsrl(HV_X64_MSR_SIEFP, siefp.as_uint64);
siefp.siefp_enabled = 1;
siefp.base_siefp_gpa = virt_to_phys(gHvContext.synICEventPage[cpu])
siefp.base_siefp_gpa = virt_to_phys(hv_context.synic_event_page[cpu])
>> PAGE_SHIFT;

DPRINT_DBG(VMBUS, "HV_X64_MSR_SIEFP msr set to: %llx", siefp.as_uint64);
Expand Down Expand Up @@ -449,15 +454,15 @@ void HvSynicInit(void *irqarg)

wrmsrl(HV_X64_MSR_SCONTROL, sctrl.as_uint64);

gHvContext.SynICInitialized = true;
hv_context.synic_initialized = true;
return;

Cleanup:
if (gHvContext.synICEventPage[cpu])
osd_PageFree(gHvContext.synICEventPage[cpu], 1);
if (hv_context.synic_event_page[cpu])
osd_PageFree(hv_context.synic_event_page[cpu], 1);

if (gHvContext.synICMessagePage[cpu])
osd_PageFree(gHvContext.synICMessagePage[cpu], 1);
if (hv_context.synic_message_page[cpu])
osd_PageFree(hv_context.synic_message_page[cpu], 1);
return;
}

Expand All @@ -471,7 +476,7 @@ void HvSynicCleanup(void *arg)
union hv_synic_siefp siefp;
int cpu = smp_processor_id();

if (!gHvContext.SynICInitialized)
if (!hv_context.synic_initialized)
return;

rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.as_uint64);
Expand All @@ -494,6 +499,6 @@ void HvSynicCleanup(void *arg)

wrmsrl(HV_X64_MSR_SIEFP, siefp.as_uint64);

osd_PageFree(gHvContext.synICMessagePage[cpu], 1);
osd_PageFree(gHvContext.synICEventPage[cpu], 1);
osd_PageFree(hv_context.synic_message_page[cpu], 1);
osd_PageFree(hv_context.synic_event_page[cpu], 1);
}
20 changes: 10 additions & 10 deletions trunk/drivers/staging/hv/hv.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,33 +92,33 @@ static const struct hv_guid VMBUS_SERVICE_ID = {


struct hv_input_signal_event_buffer {
u64 Align8;
struct hv_input_signal_event Event;
u64 align8;
struct hv_input_signal_event event;
};

struct hv_context {
/* We only support running on top of Hyper-V
* So at this point this really can only contain the Hyper-V ID
*/
u64 GuestId;
u64 guestid;

void *HypercallPage;
void *hypercall_page;

bool SynICInitialized;
bool synic_initialized;

/*
* This is used as an input param to HvCallSignalEvent hypercall. The
* input param is immutable in our usage and must be dynamic mem (vs
* stack or global). */
struct hv_input_signal_event_buffer *SignalEventBuffer;
struct hv_input_signal_event_buffer *signal_event_buffer;
/* 8-bytes aligned of the buffer above */
struct hv_input_signal_event *SignalEventParam;
struct hv_input_signal_event *signal_event_param;

void *synICMessagePage[MAX_NUM_CPUS];
void *synICEventPage[MAX_NUM_CPUS];
void *synic_message_page[MAX_NUM_CPUS];
void *synic_event_page[MAX_NUM_CPUS];
};

extern struct hv_context gHvContext;
extern struct hv_context hv_context;


/* Hv Interface */
Expand Down
6 changes: 3 additions & 3 deletions trunk/drivers/staging/hv/vmbus.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ static void VmbusOnCleanup(struct hv_driver *drv)
static void VmbusOnMsgDPC(struct hv_driver *drv)
{
int cpu = smp_processor_id();
void *page_addr = gHvContext.synICMessagePage[cpu];
void *page_addr = hv_context.synic_message_page[cpu];
struct hv_message *msg = (struct hv_message *)page_addr +
VMBUS_MESSAGE_SINT;
struct hv_message *copied;
Expand Down Expand Up @@ -208,7 +208,7 @@ static int VmbusOnISR(struct hv_driver *drv)
struct hv_message *msg;
union hv_synic_event_flags *event;

page_addr = gHvContext.synICMessagePage[cpu];
page_addr = hv_context.synic_message_page[cpu];
msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT;

/* Check if there are actual msgs to be process */
Expand All @@ -220,7 +220,7 @@ static int VmbusOnISR(struct hv_driver *drv)
}

/* TODO: Check if there are events to be process */
page_addr = gHvContext.synICEventPage[cpu];
page_addr = hv_context.synic_event_page[cpu];
event = (union hv_synic_event_flags *)page_addr + VMBUS_MESSAGE_SINT;

/* Since we are a child, we only need to check bit 0 */
Expand Down

0 comments on commit a001eb6

Please sign in to comment.