Merge tag 'hyperv-next-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/hyper...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 15 Oct 2020 22:48:06 +0000 (15:48 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 15 Oct 2020 22:48:06 +0000 (15:48 -0700)
Pull another Hyper-V update from Wei Liu:
 "One patch from Michael to get VMbus interrupt from ACPI DSDT"

* tag 'hyperv-next-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux:
  Drivers: hv: vmbus: Add parsing of VMbus interrupt in ACPI DSDT

arch/x86/include/asm/mshyperv.h
arch/x86/kernel/cpu/mshyperv.c
drivers/hv/hv.c
drivers/hv/vmbus_drv.c
include/asm-generic/mshyperv.h

index 4f77b8f..ffc2899 100644 (file)
@@ -54,6 +54,7 @@ typedef int (*hyperv_fill_flush_list_func)(
 #define hv_enable_vdso_clocksource() \
        vclocks_set_used(VDSO_CLOCKMODE_HVCLOCK);
 #define hv_get_raw_timer() rdtsc_ordered()
+#define hv_get_vector() HYPERVISOR_CALLBACK_VECTOR
 
 /*
  * Reference to pv_ops must be inline so objtool
index 9834a43..05ef1f4 100644 (file)
@@ -55,9 +55,14 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_hyperv_callback)
        set_irq_regs(old_regs);
 }
 
-void hv_setup_vmbus_irq(void (*handler)(void))
+int hv_setup_vmbus_irq(int irq, void (*handler)(void))
 {
+       /*
+        * The 'irq' argument is ignored on x86/x64 because a hard-coded
+        * interrupt vector is used for Hyper-V interrupts.
+        */
        vmbus_handler = handler;
+       return 0;
 }
 
 void hv_remove_vmbus_irq(void)
index 410f1fa..0cde10f 100644 (file)
@@ -180,7 +180,7 @@ void hv_synic_enable_regs(unsigned int cpu)
        /* Setup the shared SINT. */
        hv_get_synint_state(VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
 
-       shared_sint.vector = HYPERVISOR_CALLBACK_VECTOR;
+       shared_sint.vector = hv_get_vector();
        shared_sint.masked = false;
        shared_sint.auto_eoi = hv_recommend_using_aeoi();
        hv_set_synint_state(VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
index 7b8816c..4fad3e6 100644 (file)
@@ -48,6 +48,10 @@ static int hyperv_cpuhp_online;
 
 static void *hv_panic_page;
 
+/* Values parsed from ACPI DSDT */
+static int vmbus_irq;
+int vmbus_interrupt;
+
 /*
  * Boolean to control whether to report panic messages over Hyper-V.
  *
@@ -1347,7 +1351,7 @@ static void vmbus_isr(void)
                        tasklet_schedule(&hv_cpu->msg_dpc);
        }
 
-       add_interrupt_randomness(HYPERVISOR_CALLBACK_VECTOR, 0);
+       add_interrupt_randomness(hv_get_vector(), 0);
 }
 
 /*
@@ -1430,7 +1434,9 @@ static int vmbus_bus_init(void)
        if (ret)
                return ret;
 
-       hv_setup_vmbus_irq(vmbus_isr);
+       ret = hv_setup_vmbus_irq(vmbus_irq, vmbus_isr);
+       if (ret)
+               goto err_setup;
 
        ret = hv_synic_alloc();
        if (ret)
@@ -1505,7 +1511,7 @@ err_cpuhp:
        hv_synic_free();
 err_alloc:
        hv_remove_vmbus_irq();
-
+err_setup:
        bus_unregister(&hv_bus);
        unregister_sysctl_table(hv_ctl_table_hdr);
        hv_ctl_table_hdr = NULL;
@@ -2070,6 +2076,7 @@ static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx)
        struct resource *new_res;
        struct resource **old_res = &hyperv_mmio;
        struct resource **prev_res = NULL;
+       struct resource r;
 
        switch (res->type) {
 
@@ -2088,6 +2095,23 @@ static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx)
                end = res->data.address64.address.maximum;
                break;
 
+       /*
+        * The IRQ information is needed only on ARM64, which Hyper-V
+        * sets up in the extended format. IRQ information is present
+        * on x86/x64 in the non-extended format but it is not used by
+        * Linux. So don't bother checking for the non-extended format.
+        */
+       case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
+               if (!acpi_dev_resource_interrupt(res, 0, &r)) {
+                       pr_err("Unable to parse Hyper-V ACPI interrupt\n");
+                       return AE_ERROR;
+               }
+               /* ARM64 INTID for VMbus */
+               vmbus_interrupt = res->data.extended_irq.interrupts[0];
+               /* Linux IRQ number */
+               vmbus_irq = r.start;
+               return AE_OK;
+
        default:
                /* Unused resource type */
                return AE_OK;
index c5edc5e..c577996 100644 (file)
@@ -89,7 +89,7 @@ static inline void vmbus_signal_eom(struct hv_message *msg, u32 old_msg_type)
        }
 }
 
-void hv_setup_vmbus_irq(void (*handler)(void));
+int hv_setup_vmbus_irq(int irq, void (*handler)(void));
 void hv_remove_vmbus_irq(void);
 void hv_enable_vmbus_irq(void);
 void hv_disable_vmbus_irq(void);
@@ -99,6 +99,8 @@ void hv_remove_kexec_handler(void);
 void hv_setup_crash_handler(void (*handler)(struct pt_regs *regs));
 void hv_remove_crash_handler(void);
 
+extern int vmbus_interrupt;
+
 #if IS_ENABLED(CONFIG_HYPERV)
 /*
  * Hypervisor's notion of virtual processor ID is different from