Skip to content

Commit 29d5052

Browse files
committed
Merge branch 'x86-hyperv-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86/hyperv changes from Ingo Molnar: "The biggest change is support for Windows 8's improved hypervisor interrupt model on the Linux Hyper-V guest subsystem code side. Smallish fixes otherwise." * 'x86-hyperv-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86, hyperv: HYPERV depends on X86_LOCAL_APIC X86: Handle Hyper-V vmbus interrupts as special hypervisor interrupts X86: Add a check to catch Xen emulation of Hyper-V x86: Hyper-V: register clocksource only if its advertised
2 parents 026f149 + cb20e5f commit 29d5052

File tree

7 files changed

+78
-9
lines changed

7 files changed

+78
-9
lines changed

arch/x86/include/asm/irq_vectors.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@
109109

110110
#define UV_BAU_MESSAGE 0xf5
111111

112-
/* Xen vector callback to receive events in a HVM domain */
113-
#define XEN_HVM_EVTCHN_CALLBACK 0xf3
112+
/* Vector on which hypervisor callbacks will be delivered */
113+
#define HYPERVISOR_CALLBACK_VECTOR 0xf3
114114

115115
/*
116116
* Local APIC timer IRQ vector is on a different priority level,

arch/x86/include/asm/mshyperv.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,8 @@ struct ms_hyperv_info {
1111

1212
extern struct ms_hyperv_info ms_hyperv;
1313

14+
void hyperv_callback_vector(void);
15+
void hyperv_vector_handler(struct pt_regs *regs);
16+
void hv_register_vmbus_handler(int irq, irq_handler_t handler);
17+
1418
#endif

arch/x86/kernel/cpu/mshyperv.c

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,15 @@
1414
#include <linux/time.h>
1515
#include <linux/clocksource.h>
1616
#include <linux/module.h>
17+
#include <linux/hardirq.h>
18+
#include <linux/interrupt.h>
1719
#include <asm/processor.h>
1820
#include <asm/hypervisor.h>
1921
#include <asm/hyperv.h>
2022
#include <asm/mshyperv.h>
23+
#include <asm/desc.h>
24+
#include <asm/idle.h>
25+
#include <asm/irq_regs.h>
2126

2227
struct ms_hyperv_info ms_hyperv;
2328
EXPORT_SYMBOL_GPL(ms_hyperv);
@@ -30,6 +35,13 @@ static bool __init ms_hyperv_platform(void)
3035
if (!boot_cpu_has(X86_FEATURE_HYPERVISOR))
3136
return false;
3237

38+
/*
39+
* Xen emulates Hyper-V to support enlightened Windows.
40+
* Check to see first if we are on a Xen Hypervisor.
41+
*/
42+
if (xen_cpuid_base())
43+
return false;
44+
3345
cpuid(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS,
3446
&eax, &hyp_signature[0], &hyp_signature[1], &hyp_signature[2]);
3547

@@ -68,7 +80,14 @@ static void __init ms_hyperv_init_platform(void)
6880
printk(KERN_INFO "HyperV: features 0x%x, hints 0x%x\n",
6981
ms_hyperv.features, ms_hyperv.hints);
7082

71-
clocksource_register_hz(&hyperv_cs, NSEC_PER_SEC/100);
83+
if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE)
84+
clocksource_register_hz(&hyperv_cs, NSEC_PER_SEC/100);
85+
#if IS_ENABLED(CONFIG_HYPERV)
86+
/*
87+
* Setup the IDT for hypervisor callback.
88+
*/
89+
alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector);
90+
#endif
7291
}
7392

7493
const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = {
@@ -77,3 +96,36 @@ const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = {
7796
.init_platform = ms_hyperv_init_platform,
7897
};
7998
EXPORT_SYMBOL(x86_hyper_ms_hyperv);
99+
100+
#if IS_ENABLED(CONFIG_HYPERV)
101+
static int vmbus_irq = -1;
102+
static irq_handler_t vmbus_isr;
103+
104+
void hv_register_vmbus_handler(int irq, irq_handler_t handler)
105+
{
106+
vmbus_irq = irq;
107+
vmbus_isr = handler;
108+
}
109+
110+
void hyperv_vector_handler(struct pt_regs *regs)
111+
{
112+
struct pt_regs *old_regs = set_irq_regs(regs);
113+
struct irq_desc *desc;
114+
115+
irq_enter();
116+
exit_idle();
117+
118+
desc = irq_to_desc(vmbus_irq);
119+
120+
if (desc)
121+
generic_handle_irq_desc(vmbus_irq, desc);
122+
123+
irq_exit();
124+
set_irq_regs(old_regs);
125+
}
126+
#else
127+
void hv_register_vmbus_handler(int irq, irq_handler_t handler)
128+
{
129+
}
130+
#endif
131+
EXPORT_SYMBOL_GPL(hv_register_vmbus_handler);

arch/x86/kernel/entry_32.S

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1091,11 +1091,18 @@ ENTRY(xen_failsafe_callback)
10911091
_ASM_EXTABLE(4b,9b)
10921092
ENDPROC(xen_failsafe_callback)
10931093

1094-
BUILD_INTERRUPT3(xen_hvm_callback_vector, XEN_HVM_EVTCHN_CALLBACK,
1094+
BUILD_INTERRUPT3(xen_hvm_callback_vector, HYPERVISOR_CALLBACK_VECTOR,
10951095
xen_evtchn_do_upcall)
10961096

10971097
#endif /* CONFIG_XEN */
10981098

1099+
#if IS_ENABLED(CONFIG_HYPERV)
1100+
1101+
BUILD_INTERRUPT3(hyperv_callback_vector, HYPERVISOR_CALLBACK_VECTOR,
1102+
hyperv_vector_handler)
1103+
1104+
#endif /* CONFIG_HYPERV */
1105+
10991106
#ifdef CONFIG_FUNCTION_TRACER
11001107
#ifdef CONFIG_DYNAMIC_FTRACE
11011108

arch/x86/kernel/entry_64.S

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1454,11 +1454,16 @@ ENTRY(xen_failsafe_callback)
14541454
CFI_ENDPROC
14551455
END(xen_failsafe_callback)
14561456

1457-
apicinterrupt XEN_HVM_EVTCHN_CALLBACK \
1457+
apicinterrupt HYPERVISOR_CALLBACK_VECTOR \
14581458
xen_hvm_callback_vector xen_evtchn_do_upcall
14591459

14601460
#endif /* CONFIG_XEN */
14611461

1462+
#if IS_ENABLED(CONFIG_HYPERV)
1463+
apicinterrupt HYPERVISOR_CALLBACK_VECTOR \
1464+
hyperv_callback_vector hyperv_vector_handler
1465+
#endif /* CONFIG_HYPERV */
1466+
14621467
/*
14631468
* Some functions should be protected against kprobes
14641469
*/

drivers/hv/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ menu "Microsoft Hyper-V guest support"
22

33
config HYPERV
44
tristate "Microsoft Hyper-V client drivers"
5-
depends on X86 && ACPI && PCI
5+
depends on X86 && ACPI && PCI && X86_LOCAL_APIC
66
help
77
Select this option to run Linux as a Hyper-V client operating
88
system.

drivers/xen/events.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1787,7 +1787,7 @@ void xen_callback_vector(void)
17871787
int rc;
17881788
uint64_t callback_via;
17891789
if (xen_have_vector_callback) {
1790-
callback_via = HVM_CALLBACK_VECTOR(XEN_HVM_EVTCHN_CALLBACK);
1790+
callback_via = HVM_CALLBACK_VECTOR(HYPERVISOR_CALLBACK_VECTOR);
17911791
rc = xen_set_callback_via(callback_via);
17921792
if (rc) {
17931793
printk(KERN_ERR "Request for Xen HVM callback vector"
@@ -1798,8 +1798,9 @@ void xen_callback_vector(void)
17981798
printk(KERN_INFO "Xen HVM callback vector for event delivery is "
17991799
"enabled\n");
18001800
/* in the restore case the vector has already been allocated */
1801-
if (!test_bit(XEN_HVM_EVTCHN_CALLBACK, used_vectors))
1802-
alloc_intr_gate(XEN_HVM_EVTCHN_CALLBACK, xen_hvm_callback_vector);
1801+
if (!test_bit(HYPERVISOR_CALLBACK_VECTOR, used_vectors))
1802+
alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR,
1803+
xen_hvm_callback_vector);
18031804
}
18041805
}
18051806
#else

0 commit comments

Comments
 (0)