]> Git Repo - linux.git/blobdiff - arch/x86/hyperv/hv_init.c
libbpf: Fix libbpf hashmap on (I)LP32 architectures
[linux.git] / arch / x86 / hyperv / hv_init.c
index fd51bac11b467d83e02d6156c310359ff70ac19e..a54c6a401581dd1528af4f29c3fca5a85c875090 100644 (file)
@@ -15,6 +15,7 @@
 #include <asm/hypervisor.h>
 #include <asm/hyperv-tlfs.h>
 #include <asm/mshyperv.h>
+#include <asm/idtentry.h>
 #include <linux/version.h>
 #include <linux/vmalloc.h>
 #include <linux/mm.h>
@@ -97,8 +98,7 @@ static int hv_cpu_init(unsigned int cpu)
         * not be stopped in the case of CPU offlining and the VM will hang.
         */
        if (!*hvp) {
-               *hvp = __vmalloc(PAGE_SIZE, GFP_KERNEL | __GFP_ZERO,
-                                PAGE_KERNEL);
+               *hvp = __vmalloc(PAGE_SIZE, GFP_KERNEL | __GFP_ZERO);
        }
 
        if (*hvp) {
@@ -153,15 +153,11 @@ static inline bool hv_reenlightenment_available(void)
                ms_hyperv.features & HV_X64_ACCESS_REENLIGHTENMENT;
 }
 
-__visible void __irq_entry hyperv_reenlightenment_intr(struct pt_regs *regs)
+DEFINE_IDTENTRY_SYSVEC(sysvec_hyperv_reenlightenment)
 {
-       entering_ack_irq();
-
+       ack_APIC_irq();
        inc_irq_stat(irq_hv_reenlightenment_count);
-
        schedule_delayed_work(&hv_reenlightenment_work, HZ/10);
-
-       exiting_irq();
 }
 
 void set_hv_tscchange_cb(void (*cb)(void))
@@ -226,10 +222,18 @@ static int hv_cpu_die(unsigned int cpu)
 
        rdmsrl(HV_X64_MSR_REENLIGHTENMENT_CONTROL, *((u64 *)&re_ctrl));
        if (re_ctrl.target_vp == hv_vp_index[cpu]) {
-               /* Reassign to some other online CPU */
+               /*
+                * Reassign reenlightenment notifications to some other online
+                * CPU or just disable the feature if there are no online CPUs
+                * left (happens on hibernation).
+                */
                new_cpu = cpumask_any_but(cpu_online_mask, cpu);
 
-               re_ctrl.target_vp = hv_vp_index[new_cpu];
+               if (new_cpu < nr_cpu_ids)
+                       re_ctrl.target_vp = hv_vp_index[new_cpu];
+               else
+                       re_ctrl.enabled = 0;
+
                wrmsrl(HV_X64_MSR_REENLIGHTENMENT_CONTROL, *((u64 *)&re_ctrl));
        }
 
@@ -293,6 +297,13 @@ static void hv_resume(void)
 
        hv_hypercall_pg = hv_hypercall_pg_saved;
        hv_hypercall_pg_saved = NULL;
+
+       /*
+        * Reenlightenment notifications are disabled by hv_cpu_die(0),
+        * reenable them here if hv_reenlightenment_cb was previously set.
+        */
+       if (hv_reenlightenment_cb)
+               set_hv_tscchange_cb(hv_reenlightenment_cb);
 }
 
 /* Note: when the ops are called, only CPU0 is online and IRQs are disabled. */
@@ -364,7 +375,7 @@ void __init hyperv_init(void)
        guest_id = generate_guest_id(0, LINUX_VERSION_CODE, 0);
        wrmsrl(HV_X64_MSR_GUEST_OS_ID, guest_id);
 
-       hv_hypercall_pg  = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_RX);
+       hv_hypercall_pg = vmalloc_exec(PAGE_SIZE);
        if (hv_hypercall_pg == NULL) {
                wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0);
                goto remove_cpuhp_state;
This page took 0.032333 seconds and 4 git commands to generate.