Skip to content
This repository has been archived by the owner on Sep 28, 2024. It is now read-only.

Commit

Permalink
Merge pull request #1 from LIS/master
Browse files Browse the repository at this point in the history
make repo current
  • Loading branch information
vyadavmsft committed Feb 11, 2016
2 parents 290b64d + a1057cf commit 71f9e25
Show file tree
Hide file tree
Showing 16 changed files with 2,359 additions and 2,206 deletions.
25 changes: 22 additions & 3 deletions hv-rhel5.x/hv/hyperv_vmbus.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,31 @@ enum hv_cpuid_function {
* HVCPUID_INTERFACE
*/
HVCPUID_VERSION = 0x40000002,
HVCPUID_FEATURES = 0x40000003,
HVCPUID_FEATURES = 0x40000003,
HVCPUID_ENLIGHTENMENT_INFO = 0x40000004,
HVCPUID_IMPLEMENTATION_LIMITS = 0x40000005,
HVCPUID_IMPLEMENTATION_LIMITS = 0x40000005,
};

#define HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE 0x400
/*
* Feature identification. EDX bits which identify miscellaneous
* features that are available to the partition. Defined in
* section 3.4 of the HV Top Level Functional spec.
*/
#define HV_FEATURE_MWAIT_INSTRUCTION_AVAILABLE 0x1
#define HV_FEATURE_GUEST_DEBUGGING_SUPPORT 0x2
#define HV_FEATURE_PERFORMANCE_MONITOR_SUPPORT 0x4
#define HV_FEATURE_PHYSICAL_CPU_DYNAMIC_PARTITIONING 0x8
#define HV_FEATURE_HYPERCALL_PARAMETER_BLOCK_XMM_REGISTER 0x10
#define HV_FEATURE_VIRTUAL_GUEST_IDLE_STATE 0x20
#define HV_FEATURE_HYPERVISOR_SLEEP_STATE 0x40
#define HV_FEATURE_QUERY_NUMA_DISTANCE 0x80
#define HV_FEATURE_DETERMINE_TIMER_FREQUENCIES 0x100
#define HV_FEATURE_SYNTHETIC_MACHINE_CHECK 0x200
#define HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE 0x400
#define HV_FEATURE_DEBUG_MSG_AVAILABLE 0x800
#define HV_FEATURE_NPIPE_1_AVAILABLE 0x1000
#define HV_FEATURE_DISABLE_HYPERVISOR_AVAILABLE 0x200
/* Bits 14 - 31 reserved */

#define HV_X64_MSR_CRASH_P0 0x40000100
#define HV_X64_MSR_CRASH_P1 0x40000101
Expand Down
1 change: 1 addition & 0 deletions hv-rhel5.x/hv/include/asm/mshyperv.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

struct ms_hyperv_info {
u32 features;
u32 misc_features;
u32 hints;
};

Expand Down
9 changes: 4 additions & 5 deletions hv-rhel5.x/hv/vmbus_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,7 @@ bool using_null_legacy_pic = false;
EXPORT_SYMBOL(using_null_legacy_pic);


struct ms_hyperv_info ms_hyperv = {
.features = HV_X64_MSR_TIME_REF_COUNT_AVAILABLE |
HV_X64_MSR_SYNTIMER_AVAILABLE,
};
struct ms_hyperv_info ms_hyperv;
EXPORT_SYMBOL(ms_hyperv);

#endif
Expand Down Expand Up @@ -819,7 +816,9 @@ static int vmbus_bus_init(int irq)


#if defined(RHEL_RELEASE_VERSION) && (RHEL_RELEASE_CODE < 1540)
ms_hyperv.features |= HV_X64_MSR_TIME_REF_COUNT_AVAILABLE;
ms_hyperv.features = cpuid_eax(HYPERV_CPUID_FEATURES);
ms_hyperv.misc_features = cpuid_edx(HYPERV_CPUID_FEATURES);
ms_hyperv.hints = cpuid_eax(HYPERV_CPUID_ENLIGHTMENT_INFO);
#endif

/*
Expand Down
55 changes: 54 additions & 1 deletion hv-rhel6.x/hv/channel_mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <linux/list.h>
#include <linux/module.h>
#include <linux/completion.h>
#include <linux/delay.h>
#include "include/linux/hyperv.h"

#include "hyperv_vmbus.h"
Expand Down Expand Up @@ -477,6 +478,17 @@ static void init_vp_index(struct vmbus_channel *channel, const uuid_le *type_gui
cpumask_of_node(primary->numa_node));

cur_cpu = -1;

/*
* Normally Hyper-V host doesn't create more subchannels than there
* are VCPUs on the node but it is possible when not all present VCPUs
* on the node are initialized by guest. Clear the alloced_cpus_in_node
* to start over.
*/
if (cpumask_equal(&primary->alloced_cpus_in_node,
cpumask_of_node(primary->numa_node)))
cpumask_clear(&primary->alloced_cpus_in_node);

while (true) {
cur_cpu = cpumask_next(cur_cpu, &available_mask);
if (cur_cpu >= nr_cpu_ids) {
Expand Down Expand Up @@ -506,6 +518,40 @@ static void init_vp_index(struct vmbus_channel *channel, const uuid_le *type_gui
channel->target_vp = hv_context.vp_index[cur_cpu];
}

static void vmbus_wait_for_unload(void)
{
int cpu = smp_processor_id();
void *page_addr = hv_context.synic_message_page[cpu];
struct hv_message *msg = (struct hv_message *)page_addr +
VMBUS_MESSAGE_SINT;
struct vmbus_channel_message_header *hdr;
bool unloaded = false;

while (1) {
if (msg->header.message_type == HVMSG_NONE) {
mdelay(10);
continue;
}

hdr = (struct vmbus_channel_message_header *)msg->u.payload;
if (hdr->msgtype == CHANNELMSG_UNLOAD_RESPONSE)
unloaded = true;

msg->header.message_type = HVMSG_NONE;
/*
* header.message_type needs to be written before we do
* wrmsrl() below.
*/
mb();

if (msg->header.message_flags.msg_pending)
wrmsrl(HV_X64_MSR_EOM, 0);

if (unloaded)
break;
}
}

/*
* vmbus_unload_response - Handler for the unload response.
*/
Expand All @@ -531,7 +577,14 @@ void vmbus_initiate_unload(void)
hdr.msgtype = CHANNELMSG_UNLOAD;
vmbus_post_msg(&hdr, sizeof(struct vmbus_channel_message_header));

wait_for_completion(&vmbus_connection.unload_event);
/*
* vmbus_initiate_unload() is also called on crash and the crash can be
* happening in an interrupt context, where scheduling is impossible.
*/
if (!in_interrupt())
wait_for_completion(&vmbus_connection.unload_event);
else
vmbus_wait_for_unload();
}

/*
Expand Down
20 changes: 15 additions & 5 deletions hv-rhel6.x/hv/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,23 @@ static int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo,
msg->interrupt_page = virt_to_phys(vmbus_connection.int_page);
msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages[0]);
msg->monitor_page2 = virt_to_phys(vmbus_connection.monitor_pages[1]);

/*
* We want all channel messages to be delivered on CPU 0.
* This has been the behavior pre-win8. This is not a
* perf issue and having all channel messages delivered on
* CPU 0 would be OK.
* For Win8 and below, we want all channel messages to be delivered
* on CPU 0. This is not a perf issue and having all channel messages
* delivered on CPU 0 would be OK.
*
* For Win 8.1 and above, we want messages delivered on current
* CPU, as this is necessary when a connection already exists.
* For example, in the case of a crash kernel coming up.
*/
msg->target_vcpu = 0;
if (version >= VERSION_WIN8_1) {
msg->target_vcpu = hv_context.vp_index[get_cpu()];
put_cpu();
}
else {
msg->target_vcpu = 0;
}

/*
* Add to list before we send the request since we may
Expand Down
28 changes: 17 additions & 11 deletions hv-rhel6.x/hv/hv.c
Original file line number Diff line number Diff line change
Expand Up @@ -342,18 +342,24 @@ void hv_cleanup(void)
hv_context.hypercall_page = NULL;
}
#ifdef CONFIG_X86_64
/*
* Cleanup the TSC page based CS.
*/
if (ms_hyperv.features & HV_X64_MSR_REFERENCE_TSC_AVAILABLE) {
clocksource_change_rating(&hyperv_cs_tsc, 10);
clocksource_unregister(&hyperv_cs_tsc);
/*
* Cleanup the TSC page based CS.
*/
if (ms_hyperv.features & HV_X64_MSR_REFERENCE_TSC_AVAILABLE) {
/*
* Crash can happen in an interrupt context and unregistering
* a clocksource is impossible and redundant in this case.
*/
if (!oops_in_progress) {
clocksource_change_rating(&hyperv_cs_tsc, 10);
clocksource_unregister(&hyperv_cs_tsc);
}

hypercall_msr.as_uint64 = 0;
wrmsrl(HV_X64_MSR_REFERENCE_TSC, hypercall_msr.as_uint64);
vfree(hv_context.tsc_page);
hv_context.tsc_page = NULL;
}
hypercall_msr.as_uint64 = 0;
wrmsrl(HV_X64_MSR_REFERENCE_TSC, hypercall_msr.as_uint64);
vfree(hv_context.tsc_page);
hv_context.tsc_page = NULL;
}
#endif

}
Expand Down
Loading

0 comments on commit 71f9e25

Please sign in to comment.