Skip to content

Commit 626b901

Browse files
kelleymhliuw
authored andcommitted
Drivers: hv: vmbus: Add parsing of VMbus interrupt in ACPI DSDT
On ARM64, Hyper-V now specifies the interrupt to be used by VMbus in the ACPI DSDT. This information is not used on x86 because the interrupt vector must be hardcoded. But update the generic VMbus driver to do the parsing and pass the information to the architecture specific code that sets up the Linux IRQ. Update consumers of the interrupt to get it from an architecture specific function. Signed-off-by: Michael Kelley <mikelley@microsoft.com> Link: https://lore.kernel.org/r/1597434304-40631-1-git-send-email-mikelley@microsoft.com Signed-off-by: Wei Liu <wei.liu@kernel.org>
1 parent 1f3aed0 commit 626b901

5 files changed

Lines changed: 38 additions & 6 deletions

File tree

arch/x86/include/asm/mshyperv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ typedef int (*hyperv_fill_flush_list_func)(
5454
#define hv_enable_vdso_clocksource() \
5555
vclocks_set_used(VDSO_CLOCKMODE_HVCLOCK);
5656
#define hv_get_raw_timer() rdtsc_ordered()
57+
#define hv_get_vector() HYPERVISOR_CALLBACK_VECTOR
5758

5859
/*
5960
* Reference to pv_ops must be inline so objtool

arch/x86/kernel/cpu/mshyperv.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,14 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_hyperv_callback)
5555
set_irq_regs(old_regs);
5656
}
5757

58-
void hv_setup_vmbus_irq(void (*handler)(void))
58+
int hv_setup_vmbus_irq(int irq, void (*handler)(void))
5959
{
60+
/*
61+
* The 'irq' argument is ignored on x86/x64 because a hard-coded
62+
* interrupt vector is used for Hyper-V interrupts.
63+
*/
6064
vmbus_handler = handler;
65+
return 0;
6166
}
6267

6368
void hv_remove_vmbus_irq(void)

drivers/hv/hv.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ void hv_synic_enable_regs(unsigned int cpu)
180180
/* Setup the shared SINT. */
181181
hv_get_synint_state(VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
182182

183-
shared_sint.vector = HYPERVISOR_CALLBACK_VECTOR;
183+
shared_sint.vector = hv_get_vector();
184184
shared_sint.masked = false;
185185
shared_sint.auto_eoi = hv_recommend_using_aeoi();
186186
hv_set_synint_state(VMBUS_MESSAGE_SINT, shared_sint.as_uint64);

drivers/hv/vmbus_drv.c

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ static int hyperv_cpuhp_online;
4848

4949
static void *hv_panic_page;
5050

51+
/* Values parsed from ACPI DSDT */
52+
static int vmbus_irq;
53+
int vmbus_interrupt;
54+
5155
/*
5256
* Boolean to control whether to report panic messages over Hyper-V.
5357
*
@@ -1347,7 +1351,7 @@ static void vmbus_isr(void)
13471351
tasklet_schedule(&hv_cpu->msg_dpc);
13481352
}
13491353

1350-
add_interrupt_randomness(HYPERVISOR_CALLBACK_VECTOR, 0);
1354+
add_interrupt_randomness(hv_get_vector(), 0);
13511355
}
13521356

13531357
/*
@@ -1430,7 +1434,9 @@ static int vmbus_bus_init(void)
14301434
if (ret)
14311435
return ret;
14321436

1433-
hv_setup_vmbus_irq(vmbus_isr);
1437+
ret = hv_setup_vmbus_irq(vmbus_irq, vmbus_isr);
1438+
if (ret)
1439+
goto err_setup;
14341440

14351441
ret = hv_synic_alloc();
14361442
if (ret)
@@ -1505,7 +1511,7 @@ static int vmbus_bus_init(void)
15051511
hv_synic_free();
15061512
err_alloc:
15071513
hv_remove_vmbus_irq();
1508-
1514+
err_setup:
15091515
bus_unregister(&hv_bus);
15101516
unregister_sysctl_table(hv_ctl_table_hdr);
15111517
hv_ctl_table_hdr = NULL;
@@ -2070,6 +2076,7 @@ static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx)
20702076
struct resource *new_res;
20712077
struct resource **old_res = &hyperv_mmio;
20722078
struct resource **prev_res = NULL;
2079+
struct resource r;
20732080

20742081
switch (res->type) {
20752082

@@ -2088,6 +2095,23 @@ static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx)
20882095
end = res->data.address64.address.maximum;
20892096
break;
20902097

2098+
/*
2099+
* The IRQ information is needed only on ARM64, which Hyper-V
2100+
* sets up in the extended format. IRQ information is present
2101+
* on x86/x64 in the non-extended format but it is not used by
2102+
* Linux. So don't bother checking for the non-extended format.
2103+
*/
2104+
case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
2105+
if (!acpi_dev_resource_interrupt(res, 0, &r)) {
2106+
pr_err("Unable to parse Hyper-V ACPI interrupt\n");
2107+
return AE_ERROR;
2108+
}
2109+
/* ARM64 INTID for VMbus */
2110+
vmbus_interrupt = res->data.extended_irq.interrupts[0];
2111+
/* Linux IRQ number */
2112+
vmbus_irq = r.start;
2113+
return AE_OK;
2114+
20912115
default:
20922116
/* Unused resource type */
20932117
return AE_OK;

include/asm-generic/mshyperv.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ static inline void vmbus_signal_eom(struct hv_message *msg, u32 old_msg_type)
8989
}
9090
}
9191

92-
void hv_setup_vmbus_irq(void (*handler)(void));
92+
int hv_setup_vmbus_irq(int irq, void (*handler)(void));
9393
void hv_remove_vmbus_irq(void);
9494
void hv_enable_vmbus_irq(void);
9595
void hv_disable_vmbus_irq(void);
@@ -99,6 +99,8 @@ void hv_remove_kexec_handler(void);
9999
void hv_setup_crash_handler(void (*handler)(struct pt_regs *regs));
100100
void hv_remove_crash_handler(void);
101101

102+
extern int vmbus_interrupt;
103+
102104
#if IS_ENABLED(CONFIG_HYPERV)
103105
/*
104106
* Hypervisor's notion of virtual processor ID is different from

0 commit comments

Comments
 (0)