From: "K. Y. Srinivasan" <[email protected]>
Implement APIC related enlightenments.
V2: Addressed comments from Thomas Gleixner <[email protected]>
and Michael Kelley (EOSG) <[email protected]>.
K. Y. Srinivasan (5):
X86: Hyper-V: Enlighten APIC access
X86: Hyper-V: Enable IPI enlightenments
X86: Hyper-V: Enhanced IPI enlightenment
X86: Hyper-V: Consolidate code for converting cpumask to vpset
X86: Hyper-V: Consolidate the allocation of the hypercall input page
arch/x86/hyperv/Makefile | 2 +-
arch/x86/hyperv/hv_apic.c | 259 +++++++++++++++++++++++++++++++++++++
arch/x86/hyperv/hv_init.c | 32 ++++-
arch/x86/hyperv/mmu.c | 75 ++---------
arch/x86/include/asm/hyperv-tlfs.h | 30 ++++-
arch/x86/include/asm/mshyperv.h | 39 +++++-
6 files changed, 365 insertions(+), 72 deletions(-)
create mode 100644 arch/x86/hyperv/hv_apic.c
--
2.15.1
From: "K. Y. Srinivasan" <[email protected]>
Hyper-V supports MSR based APIC access; implement
the enlightenment.
Signed-off-by: K. Y. Srinivasan <[email protected]>
---
arch/x86/hyperv/Makefile | 2 +-
arch/x86/hyperv/hv_apic.c | 101 ++++++++++++++++++++++++++++++++++++++++
arch/x86/hyperv/hv_init.c | 5 +-
arch/x86/include/asm/mshyperv.h | 4 +-
4 files changed, 109 insertions(+), 3 deletions(-)
create mode 100644 arch/x86/hyperv/hv_apic.c
diff --git a/arch/x86/hyperv/Makefile b/arch/x86/hyperv/Makefile
index 367a8203cfcf..00ce4df01a09 100644
--- a/arch/x86/hyperv/Makefile
+++ b/arch/x86/hyperv/Makefile
@@ -1 +1 @@
-obj-y := hv_init.o mmu.o
+obj-y := hv_init.o mmu.o hv_apic.o
diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c
new file mode 100644
index 000000000000..41f8b71ca19e
--- /dev/null
+++ b/arch/x86/hyperv/hv_apic.c
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Hyper-V specific APIC code.
+ *
+ * Copyright (C) 2018, Microsoft, Inc.
+ *
+ * Author : K. Y. Srinivasan <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/version.h>
+#include <linux/vmalloc.h>
+#include <linux/mm.h>
+#include <linux/clockchips.h>
+#include <linux/hyperv.h>
+#include <linux/slab.h>
+#include <linux/cpuhotplug.h>
+#include <asm/hypervisor.h>
+#include <asm/mshyperv.h>
+
+#if IS_ENABLED(CONFIG_HYPERV)
+static u64 hv_apic_icr_read(void)
+{
+ u64 reg_val;
+
+ rdmsrl(HV_X64_MSR_ICR, reg_val);
+ return reg_val;
+}
+
+static void hv_apic_icr_write(u32 low, u32 id)
+{
+ u64 reg_val;
+
+ reg_val = SET_APIC_DEST_FIELD(id);
+ reg_val = reg_val << 32;
+ reg_val |= low;
+
+ wrmsrl(HV_X64_MSR_ICR, reg_val);
+}
+
+static u32 hv_apic_read(u32 reg)
+{
+ u32 reg_val, hi;
+
+ switch (reg) {
+ case APIC_EOI:
+ rdmsr(HV_X64_MSR_EOI, reg_val, hi);
+ return reg_val;
+ case APIC_TASKPRI:
+ rdmsr(HV_X64_MSR_TPR, reg_val, hi);
+ return reg_val;
+
+ default:
+ return native_apic_mem_read(reg);
+ }
+}
+
+static void hv_apic_write(u32 reg, u32 val)
+{
+ switch (reg) {
+ case APIC_EOI:
+ wrmsr(HV_X64_MSR_EOI, val, 0);
+ break;
+ case APIC_TASKPRI:
+ wrmsr(HV_X64_MSR_TPR, val, 0);
+ break;
+ default:
+ native_apic_mem_write(reg, val);
+ }
+}
+
+static void hv_apic_eoi_write(u32 reg, u32 val)
+{
+ wrmsr(HV_X64_MSR_EOI, val, 0);
+}
+
+void __init hv_apic_init(void)
+{
+ if (ms_hyperv.hints & HV_X64_APIC_ACCESS_RECOMMENDED) {
+ pr_info("Hyper-V: Using MSR based APIC access\n");
+ apic_set_eoi_write(hv_apic_eoi_write);
+ apic->read = hv_apic_read;
+ apic->write = hv_apic_write;
+ apic->icr_write = hv_apic_icr_write;
+ apic->icr_read = hv_apic_icr_read;
+ }
+}
+
+#endif /*CONFIG_HYPERV */
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index cfecc2272f2d..71e50fc2b7ef 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -242,8 +242,9 @@ static int hv_cpu_die(unsigned int cpu)
*
* 1. Setup the hypercall page.
* 2. Register Hyper-V specific clocksource.
+ * 3. Setup Hyper-V specific APIC entry points.
*/
-void hyperv_init(void)
+void __init hyperv_init(void)
{
u64 guest_id, required_msrs;
union hv_x64_msr_hypercall_contents hypercall_msr;
@@ -298,6 +299,8 @@ void hyperv_init(void)
hyper_alloc_mmu();
+ hv_apic_init();
+
/*
* Register Hyper-V specific clocksource.
*/
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index b90e79610cf7..162977b82e2e 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -258,7 +258,7 @@ static inline int hv_cpu_number_to_vp_number(int cpu_number)
return hv_vp_index[cpu_number];
}
-void hyperv_init(void);
+void __init hyperv_init(void);
void hyperv_setup_mmu_ops(void);
void hyper_alloc_mmu(void);
void hyperv_report_panic(struct pt_regs *regs, long err);
@@ -269,6 +269,7 @@ void hyperv_reenlightenment_intr(struct pt_regs *regs);
void set_hv_tscchange_cb(void (*cb)(void));
void clear_hv_tscchange_cb(void);
void hyperv_stop_tsc_emulation(void);
+void hv_apic_init(void);
#else /* CONFIG_HYPERV */
static inline void hyperv_init(void) {}
static inline bool hv_is_hyperv_initialized(void) { return false; }
@@ -277,6 +278,7 @@ static inline void hyperv_setup_mmu_ops(void) {}
static inline void set_hv_tscchange_cb(void (*cb)(void)) {}
static inline void clear_hv_tscchange_cb(void) {}
static inline void hyperv_stop_tsc_emulation(void) {};
+static inline void hv_apic_init(void) {}
static inline struct hv_vp_assist_page *hv_get_vp_assist_page(unsigned int cpu)
{
return NULL;
--
2.15.1
From: "K. Y. Srinivasan" <[email protected]>
Consolidate the allocation of the hypercall input page.
Signed-off-by: K. Y. Srinivasan <[email protected]>
---
arch/x86/hyperv/hv_init.c | 2 --
arch/x86/hyperv/mmu.c | 30 ++++++------------------------
arch/x86/include/asm/mshyperv.h | 1 -
3 files changed, 6 insertions(+), 27 deletions(-)
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 6bc90d68ac8b..4c431e1c1eff 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -324,8 +324,6 @@ void __init hyperv_init(void)
hypercall_msr.guest_physical_address = vmalloc_to_pfn(hv_hypercall_pg);
wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
- hyper_alloc_mmu();
-
hv_apic_init();
/*
diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c
index c9cd28f0bae4..5f053d7d1bd9 100644
--- a/arch/x86/hyperv/mmu.c
+++ b/arch/x86/hyperv/mmu.c
@@ -32,9 +32,6 @@ struct hv_flush_pcpu_ex {
/* Each gva in gva_list encodes up to 4096 pages to flush */
#define HV_TLB_FLUSH_UNIT (4096 * PAGE_SIZE)
-static struct hv_flush_pcpu __percpu **pcpu_flush;
-
-static struct hv_flush_pcpu_ex __percpu **pcpu_flush_ex;
/*
* Fills in gva_list starting from offset. Returns the number of items added.
@@ -77,7 +74,7 @@ static void hyperv_flush_tlb_others(const struct cpumask *cpus,
trace_hyperv_mmu_flush_tlb_others(cpus, info);
- if (!pcpu_flush || !hv_hypercall_pg)
+ if (!hv_hypercall_pg)
goto do_native;
if (cpumask_empty(cpus))
@@ -85,10 +82,8 @@ static void hyperv_flush_tlb_others(const struct cpumask *cpus,
local_irq_save(flags);
- flush_pcpu = this_cpu_ptr(pcpu_flush);
-
- if (unlikely(!*flush_pcpu))
- *flush_pcpu = page_address(alloc_page(GFP_ATOMIC));
+ flush_pcpu = (struct hv_flush_pcpu **)
+ this_cpu_ptr(hyperv_pcpu_input_arg);
flush = *flush_pcpu;
@@ -164,7 +159,7 @@ static void hyperv_flush_tlb_others_ex(const struct cpumask *cpus,
trace_hyperv_mmu_flush_tlb_others(cpus, info);
- if (!pcpu_flush_ex || !hv_hypercall_pg)
+ if (!hv_hypercall_pg)
goto do_native;
if (cpumask_empty(cpus))
@@ -172,10 +167,8 @@ static void hyperv_flush_tlb_others_ex(const struct cpumask *cpus,
local_irq_save(flags);
- flush_pcpu = this_cpu_ptr(pcpu_flush_ex);
-
- if (unlikely(!*flush_pcpu))
- *flush_pcpu = page_address(alloc_page(GFP_ATOMIC));
+ flush_pcpu = (struct hv_flush_pcpu_ex **)
+ this_cpu_ptr(hyperv_pcpu_input_arg);
flush = *flush_pcpu;
@@ -257,14 +250,3 @@ void hyperv_setup_mmu_ops(void)
pv_mmu_ops.flush_tlb_others = hyperv_flush_tlb_others_ex;
}
}
-
-void hyper_alloc_mmu(void)
-{
- if (!(ms_hyperv.hints & HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED))
- return;
-
- if (!(ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED))
- pcpu_flush = alloc_percpu(struct hv_flush_pcpu *);
- else
- pcpu_flush_ex = alloc_percpu(struct hv_flush_pcpu_ex *);
-}
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 0ee82519957b..9aaa493f5756 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -294,7 +294,6 @@ static inline int cpumask_to_vpset(struct hv_vpset *vpset,
void __init hyperv_init(void);
void hyperv_setup_mmu_ops(void);
-void hyper_alloc_mmu(void);
void hyperv_report_panic(struct pt_regs *regs, long err);
bool hv_is_hyperv_initialized(void);
void hyperv_cleanup(void);
--
2.15.1
From: "K. Y. Srinivasan" <[email protected]>
Support enhanced IPI enlightenments (to target more than 64 CPUs).
Signed-off-by: K. Y. Srinivasan <[email protected]>
---
arch/x86/hyperv/hv_apic.c | 42 +++++++++++++++++++++++++++++++++++++-
arch/x86/hyperv/mmu.c | 2 +-
arch/x86/include/asm/hyperv-tlfs.h | 15 +++++++++++++-
arch/x86/include/asm/mshyperv.h | 33 ++++++++++++++++++++++++++++++
4 files changed, 89 insertions(+), 3 deletions(-)
diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c
index f52d08a7a343..1e269a318c27 100644
--- a/arch/x86/hyperv/hv_apic.c
+++ b/arch/x86/hyperv/hv_apic.c
@@ -92,6 +92,40 @@ static void hv_apic_eoi_write(u32 reg, u32 val)
/*
* IPI implementation on Hyper-V.
*/
+static bool __send_ipi_mask_ex(const struct cpumask *mask, int vector)
+{
+ struct ipi_arg_ex **arg;
+ struct ipi_arg_ex *ipi_arg;
+ unsigned long flags;
+ int nr_bank = 0;
+ int ret = 1;
+
+ local_irq_save(flags);
+ arg = (struct ipi_arg_ex **)this_cpu_ptr(hyperv_pcpu_input_arg);
+
+ ipi_arg = *arg;
+ if (unlikely(!ipi_arg))
+ goto ipi_mask_ex_done;
+
+ ipi_arg->vector = vector;
+ ipi_arg->reserved = 0;
+ ipi_arg->vp_set.valid_bank_mask = 0;
+
+ if (!cpumask_equal(mask, cpu_present_mask)) {
+ ipi_arg->vp_set.format = HV_GENERIC_SET_SPARSE_4K;
+ nr_bank = cpumask_to_vpset(&(ipi_arg->vp_set), mask);
+ }
+ if (!nr_bank)
+ ipi_arg->vp_set.format = HV_GENERIC_SET_ALL;
+
+ ret = hv_do_rep_hypercall(HVCALL_SEND_IPI_EX, 0, nr_bank,
+ ipi_arg, NULL);
+
+ipi_mask_ex_done:
+ local_irq_restore(flags);
+ return ((ret == 0) ? true : false);
+}
+
static bool __send_ipi_mask(const struct cpumask *mask, int vector)
{
int cur_cpu, vcpu;
@@ -109,6 +143,9 @@ static bool __send_ipi_mask(const struct cpumask *mask, int vector)
if ((vector < HV_IPI_LOW_VECTOR) || (vector > HV_IPI_HIGH_VECTOR))
return false;
+ if ((ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED))
+ return __send_ipi_mask_ex(mask, vector);
+
local_irq_save(flags);
arg = (struct ipi_arg_non_ex **)this_cpu_ptr(hyperv_pcpu_input_arg);
@@ -192,7 +229,10 @@ static void hv_send_ipi_self(int vector)
void __init hv_apic_init(void)
{
if (ms_hyperv.hints & HV_X64_CLUSTER_IPI_RECOMMENDED) {
- pr_info("Hyper-V: Using IPI hypercalls\n");
+ if ((ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED))
+ pr_info("Hyper-V: Using ext hypercalls for IPI\n");
+ else
+ pr_info("Hyper-V: Using IPI hypercalls\n");
/*
* Set the IPI entry points.
*/
diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c
index 56c9ebac946f..adee39a7a3f2 100644
--- a/arch/x86/hyperv/mmu.c
+++ b/arch/x86/hyperv/mmu.c
@@ -239,7 +239,7 @@ static void hyperv_flush_tlb_others_ex(const struct cpumask *cpus,
flush->hv_vp_set.valid_bank_mask = 0;
if (!cpumask_equal(cpus, cpu_present_mask)) {
- flush->hv_vp_set.format = HV_GENERIC_SET_SPARCE_4K;
+ flush->hv_vp_set.format = HV_GENERIC_SET_SPARSE_4K;
nr_bank = cpumask_to_vp_set(flush, cpus);
}
diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h
index 332e786d4deb..3bfa92c2793c 100644
--- a/arch/x86/include/asm/hyperv-tlfs.h
+++ b/arch/x86/include/asm/hyperv-tlfs.h
@@ -344,6 +344,7 @@ struct hv_tsc_emulation_status {
#define HVCALL_SEND_IPI 0x000b
#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX 0x0013
#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX 0x0014
+#define HVCALL_SEND_IPI_EX 0x0015
#define HVCALL_POST_MESSAGE 0x005c
#define HVCALL_SIGNAL_EVENT 0x005d
@@ -369,7 +370,7 @@ struct hv_tsc_emulation_status {
#define HV_FLUSH_USE_EXTENDED_RANGE_FORMAT BIT(3)
enum HV_GENERIC_SET_FORMAT {
- HV_GENERIC_SET_SPARCE_4K,
+ HV_GENERIC_SET_SPARSE_4K,
HV_GENERIC_SET_ALL,
};
@@ -721,4 +722,16 @@ struct ipi_arg_non_ex {
u64 cpu_mask;
};
+struct hv_vpset {
+ u64 format;
+ u64 valid_bank_mask;
+ u64 bank_contents[];
+};
+
+struct ipi_arg_ex {
+ u32 vector;
+ u32 reserved;
+ struct hv_vpset vp_set;
+};
+
#endif
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 1eff91599c2b..0ee82519957b 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -259,6 +259,39 @@ static inline int hv_cpu_number_to_vp_number(int cpu_number)
return hv_vp_index[cpu_number];
}
+static inline int cpumask_to_vpset(struct hv_vpset *vpset,
+ const struct cpumask *cpus)
+{
+ int cpu, vcpu, vcpu_bank, vcpu_offset, nr_bank = 1;
+
+ /* valid_bank_mask can represent up to 64 banks */
+ if (hv_max_vp_index / 64 >= 64)
+ return 0;
+
+ /*
+ * Clear all banks up to the maximum possible bank as hv_flush_pcpu_ex
+ * structs are not cleared between calls, we risk flushing unneeded
+ * vCPUs otherwise.
+ */
+ for (vcpu_bank = 0; vcpu_bank <= hv_max_vp_index / 64; vcpu_bank++)
+ vpset->bank_contents[vcpu_bank] = 0;
+
+ /*
+ * Some banks may end up being empty but this is acceptable.
+ */
+ for_each_cpu(cpu, cpus) {
+ vcpu = hv_cpu_number_to_vp_number(cpu);
+ vcpu_bank = vcpu / 64;
+ vcpu_offset = vcpu % 64;
+ __set_bit(vcpu_offset, (unsigned long *)
+ &vpset->bank_contents[vcpu_bank]);
+ if (vcpu_bank >= nr_bank)
+ nr_bank = vcpu_bank + 1;
+ }
+ vpset->valid_bank_mask = GENMASK_ULL(nr_bank - 1, 0);
+ return nr_bank;
+}
+
void __init hyperv_init(void);
void hyperv_setup_mmu_ops(void);
void hyper_alloc_mmu(void);
--
2.15.1
From: "K. Y. Srinivasan" <[email protected]>
Consolidate code for converting cpumask to vpset.
Signed-off-by: K. Y. Srinivasan <[email protected]>
---
arch/x86/hyperv/mmu.c | 43 ++-----------------------------------------
1 file changed, 2 insertions(+), 41 deletions(-)
diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c
index adee39a7a3f2..c9cd28f0bae4 100644
--- a/arch/x86/hyperv/mmu.c
+++ b/arch/x86/hyperv/mmu.c
@@ -25,11 +25,7 @@ struct hv_flush_pcpu {
struct hv_flush_pcpu_ex {
u64 address_space;
u64 flags;
- struct {
- u64 format;
- u64 valid_bank_mask;
- u64 bank_contents[];
- } hv_vp_set;
+ struct hv_vpset hv_vp_set;
u64 gva_list[];
};
@@ -70,41 +66,6 @@ static inline int fill_gva_list(u64 gva_list[], int offset,
return gva_n - offset;
}
-/* Return the number of banks in the resulting vp_set */
-static inline int cpumask_to_vp_set(struct hv_flush_pcpu_ex *flush,
- const struct cpumask *cpus)
-{
- int cpu, vcpu, vcpu_bank, vcpu_offset, nr_bank = 1;
-
- /* valid_bank_mask can represent up to 64 banks */
- if (hv_max_vp_index / 64 >= 64)
- return 0;
-
- /*
- * Clear all banks up to the maximum possible bank as hv_flush_pcpu_ex
- * structs are not cleared between calls, we risk flushing unneeded
- * vCPUs otherwise.
- */
- for (vcpu_bank = 0; vcpu_bank <= hv_max_vp_index / 64; vcpu_bank++)
- flush->hv_vp_set.bank_contents[vcpu_bank] = 0;
-
- /*
- * Some banks may end up being empty but this is acceptable.
- */
- for_each_cpu(cpu, cpus) {
- vcpu = hv_cpu_number_to_vp_number(cpu);
- vcpu_bank = vcpu / 64;
- vcpu_offset = vcpu % 64;
- __set_bit(vcpu_offset, (unsigned long *)
- &flush->hv_vp_set.bank_contents[vcpu_bank]);
- if (vcpu_bank >= nr_bank)
- nr_bank = vcpu_bank + 1;
- }
- flush->hv_vp_set.valid_bank_mask = GENMASK_ULL(nr_bank - 1, 0);
-
- return nr_bank;
-}
-
static void hyperv_flush_tlb_others(const struct cpumask *cpus,
const struct flush_tlb_info *info)
{
@@ -240,7 +201,7 @@ static void hyperv_flush_tlb_others_ex(const struct cpumask *cpus,
if (!cpumask_equal(cpus, cpu_present_mask)) {
flush->hv_vp_set.format = HV_GENERIC_SET_SPARSE_4K;
- nr_bank = cpumask_to_vp_set(flush, cpus);
+ nr_bank = cpumask_to_vpset(&(flush->hv_vp_set), cpus);
}
if (!nr_bank) {
--
2.15.1
From: "K. Y. Srinivasan" <[email protected]>
Hyper-V supports hypercalls to implement IPI; use them.
Signed-off-by: K. Y. Srinivasan <[email protected]>
---
arch/x86/hyperv/hv_apic.c | 118 +++++++++++++++++++++++++++++++++++++
arch/x86/hyperv/hv_init.c | 27 +++++++++
arch/x86/include/asm/hyperv-tlfs.h | 15 +++++
arch/x86/include/asm/mshyperv.h | 1 +
4 files changed, 161 insertions(+)
diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c
index 41f8b71ca19e..f52d08a7a343 100644
--- a/arch/x86/hyperv/hv_apic.c
+++ b/arch/x86/hyperv/hv_apic.c
@@ -31,6 +31,9 @@
#include <asm/mshyperv.h>
#if IS_ENABLED(CONFIG_HYPERV)
+
+static struct apic orig_apic;
+
static u64 hv_apic_icr_read(void)
{
u64 reg_val;
@@ -86,8 +89,123 @@ static void hv_apic_eoi_write(u32 reg, u32 val)
wrmsr(HV_X64_MSR_EOI, val, 0);
}
+/*
+ * IPI implementation on Hyper-V.
+ */
+static bool __send_ipi_mask(const struct cpumask *mask, int vector)
+{
+ int cur_cpu, vcpu;
+ struct ipi_arg_non_ex **arg;
+ struct ipi_arg_non_ex *ipi_arg;
+ int ret = 1;
+ unsigned long flags;
+
+ if (cpumask_empty(mask))
+ return true;
+
+ if (!hv_hypercall_pg)
+ return false;
+
+ if ((vector < HV_IPI_LOW_VECTOR) || (vector > HV_IPI_HIGH_VECTOR))
+ return false;
+
+ local_irq_save(flags);
+ arg = (struct ipi_arg_non_ex **)this_cpu_ptr(hyperv_pcpu_input_arg);
+
+ ipi_arg = *arg;
+ if (unlikely(!ipi_arg))
+ goto ipi_mask_done;
+
+ ipi_arg->vector = vector;
+ ipi_arg->reserved = 0;
+ ipi_arg->cpu_mask = 0;
+
+ for_each_cpu(cur_cpu, mask) {
+ vcpu = hv_cpu_number_to_vp_number(cur_cpu);
+ /*
+ * This particular version of the IPI hypercall can
+ * only target upto 64 CPUs.
+ */
+ if (vcpu >= 64)
+ goto ipi_mask_done;
+
+ __set_bit(vcpu, (unsigned long *)&ipi_arg->cpu_mask);
+ }
+
+ ret = hv_do_hypercall(HVCALL_SEND_IPI, ipi_arg, NULL);
+
+ipi_mask_done:
+ local_irq_restore(flags);
+ return ((ret == 0) ? true : false);
+}
+
+static bool __send_ipi_one(int cpu, int vector)
+{
+ struct cpumask mask = CPU_MASK_NONE;
+
+ cpumask_set_cpu(cpu, &mask);
+ return __send_ipi_mask(&mask, vector);
+}
+
+static void hv_send_ipi(int cpu, int vector)
+{
+ if (!__send_ipi_one(cpu, vector))
+ orig_apic.send_IPI(cpu, vector);
+}
+
+static void hv_send_ipi_mask(const struct cpumask *mask, int vector)
+{
+ if (!__send_ipi_mask(mask, vector))
+ orig_apic.send_IPI_mask(mask, vector);
+}
+
+static void hv_send_ipi_mask_allbutself(const struct cpumask *mask, int vector)
+{
+ unsigned int this_cpu = smp_processor_id();
+ struct cpumask new_mask;
+ const struct cpumask *local_mask;
+
+ cpumask_copy(&new_mask, mask);
+ cpumask_clear_cpu(this_cpu, &new_mask);
+ local_mask = &new_mask;
+ if (!__send_ipi_mask(local_mask, vector))
+ orig_apic.send_IPI_mask_allbutself(mask, vector);
+}
+
+static void hv_send_ipi_allbutself(int vector)
+{
+ hv_send_ipi_mask_allbutself(cpu_online_mask, vector);
+}
+
+static void hv_send_ipi_all(int vector)
+{
+ if (!__send_ipi_mask(cpu_online_mask, vector))
+ orig_apic.send_IPI_all(vector);
+}
+
+static void hv_send_ipi_self(int vector)
+{
+ if (!__send_ipi_one(smp_processor_id(), vector))
+ orig_apic.send_IPI_self(vector);
+}
+
void __init hv_apic_init(void)
{
+ if (ms_hyperv.hints & HV_X64_CLUSTER_IPI_RECOMMENDED) {
+ pr_info("Hyper-V: Using IPI hypercalls\n");
+ /*
+ * Set the IPI entry points.
+ */
+ orig_apic = *apic;
+
+ apic->send_IPI = hv_send_ipi;
+ apic->send_IPI_mask = hv_send_ipi_mask;
+ apic->send_IPI_mask_allbutself = hv_send_ipi_mask_allbutself;
+ apic->send_IPI_allbutself = hv_send_ipi_allbutself;
+ apic->send_IPI_all = hv_send_ipi_all;
+ apic->send_IPI_self = hv_send_ipi_self;
+ }
+
if (ms_hyperv.hints & HV_X64_APIC_ACCESS_RECOMMENDED) {
pr_info("Hyper-V: Using MSR based APIC access\n");
apic_set_eoi_write(hv_apic_eoi_write);
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 71e50fc2b7ef..6bc90d68ac8b 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -91,12 +91,19 @@ EXPORT_SYMBOL_GPL(hv_vp_index);
struct hv_vp_assist_page **hv_vp_assist_page;
EXPORT_SYMBOL_GPL(hv_vp_assist_page);
+void __percpu **hyperv_pcpu_input_arg;
+EXPORT_SYMBOL_GPL(hyperv_pcpu_input_arg);
+
u32 hv_max_vp_index;
static int hv_cpu_init(unsigned int cpu)
{
u64 msr_vp_index;
struct hv_vp_assist_page **hvp = &hv_vp_assist_page[smp_processor_id()];
+ void **input_arg;
+
+ input_arg = (void **)this_cpu_ptr(hyperv_pcpu_input_arg);
+ *input_arg = page_address(alloc_page(GFP_KERNEL));
hv_get_vp_index(msr_vp_index);
@@ -217,6 +224,16 @@ static int hv_cpu_die(unsigned int cpu)
{
struct hv_reenlightenment_control re_ctrl;
unsigned int new_cpu;
+ unsigned long flags;
+ void **input_arg;
+ void *input_pg = NULL;
+
+ local_irq_save(flags);
+ input_arg = (void **)this_cpu_ptr(hyperv_pcpu_input_arg);
+ input_pg = *input_arg;
+ *input_arg = NULL;
+ local_irq_restore(flags);
+ free_page((unsigned long)input_pg);
if (hv_vp_assist_page && hv_vp_assist_page[cpu])
wrmsrl(HV_X64_MSR_VP_ASSIST_PAGE, 0);
@@ -260,6 +277,16 @@ void __init hyperv_init(void)
if ((ms_hyperv.features & required_msrs) != required_msrs)
return;
+ /*
+ * Allocate the per-CPU state for the hypercall input arg.
+ * If this allocation fails, we will not be able to setup
+ * (per-CPU) hypercall input page and thus this failure is
+ * fatal on Hyper-V.
+ */
+ hyperv_pcpu_input_arg = alloc_percpu(void *);
+
+ BUG_ON(hyperv_pcpu_input_arg == NULL);
+
/* Allocate percpu VP index */
hv_vp_index = kmalloc_array(num_possible_cpus(), sizeof(*hv_vp_index),
GFP_KERNEL);
diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h
index 416cb0e0c496..332e786d4deb 100644
--- a/arch/x86/include/asm/hyperv-tlfs.h
+++ b/arch/x86/include/asm/hyperv-tlfs.h
@@ -164,6 +164,11 @@
*/
#define HV_X64_DEPRECATING_AEOI_RECOMMENDED (1 << 9)
+/*
+ * Recommend using cluster IPI hypercalls.
+ */
+#define HV_X64_CLUSTER_IPI_RECOMMENDED (1 << 10)
+
/* Recommend using the newer ExProcessorMasks interface */
#define HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED (1 << 11)
@@ -329,10 +334,14 @@ struct hv_tsc_emulation_status {
#define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_MASK \
(~((1ull << HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT) - 1))
+#define HV_IPI_LOW_VECTOR 0x10
+#define HV_IPI_HIGH_VECTOR 0xff
+
/* Declare the various hypercall operations. */
#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE 0x0002
#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST 0x0003
#define HVCALL_NOTIFY_LONG_SPIN_WAIT 0x0008
+#define HVCALL_SEND_IPI 0x000b
#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX 0x0013
#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX 0x0014
#define HVCALL_POST_MESSAGE 0x005c
@@ -706,4 +715,10 @@ struct hv_enlightened_vmcs {
#define HV_STIMER_AUTOENABLE (1ULL << 3)
#define HV_STIMER_SINT(config) (__u8)(((config) >> 16) & 0x0F)
+struct ipi_arg_non_ex {
+ u32 vector;
+ u32 reserved;
+ u64 cpu_mask;
+};
+
#endif
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 162977b82e2e..1eff91599c2b 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -122,6 +122,7 @@ static inline void hv_disable_stimer0_percpu_irq(int irq) {}
#if IS_ENABLED(CONFIG_HYPERV)
extern struct clocksource *hyperv_cs;
extern void *hv_hypercall_pg;
+extern void __percpu **hyperv_pcpu_input_arg;
static inline u64 hv_do_hypercall(u64 control, void *input, void *output)
{
--
2.15.1
Hi Srinivasan,
I love your patch! Yet something to improve:
[auto build test ERROR on v4.17-rc3]
[also build test ERROR on next-20180504]
[cannot apply to tip/x86/core]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/kys-linuxonhyperv-com/X86-Hyper-V-APIC-enlightenments/20180505-045627
config: x86_64-randconfig-a0-05050447 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-16) 7.3.0
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All errors (new ones prefixed by >>):
arch/x86/hyperv/hv_apic.c: In function 'hv_apic_read':
>> arch/x86/hyperv/hv_apic.c:66:10: error: implicit declaration of function 'native_apic_mem_read'; did you mean 'hv_apic_icr_read'? [-Werror=implicit-function-declaration]
return native_apic_mem_read(reg);
^~~~~~~~~~~~~~~~~~~~
hv_apic_icr_read
arch/x86/hyperv/hv_apic.c: In function 'hv_apic_write':
>> arch/x86/hyperv/hv_apic.c:80:3: error: implicit declaration of function 'native_apic_mem_write'; did you mean 'hv_apic_icr_write'? [-Werror=implicit-function-declaration]
native_apic_mem_write(reg, val);
^~~~~~~~~~~~~~~~~~~~~
hv_apic_icr_write
arch/x86/hyperv/hv_apic.c: In function 'hv_apic_init':
>> arch/x86/hyperv/hv_apic.c:93:3: error: implicit declaration of function 'apic_set_eoi_write'; did you mean 'hv_apic_eoi_write'? [-Werror=implicit-function-declaration]
apic_set_eoi_write(hv_apic_eoi_write);
^~~~~~~~~~~~~~~~~~
hv_apic_eoi_write
arch/x86/hyperv/hv_apic.c:94:3: error: 'apic' undeclared (first use in this function); did you mean 'pid'?
apic->read = hv_apic_read;
^~~~
pid
arch/x86/hyperv/hv_apic.c:94:3: note: each undeclared identifier is reported only once for each function it appears in
cc1: some warnings being treated as errors
vim +66 arch/x86/hyperv/hv_apic.c
52
53 static u32 hv_apic_read(u32 reg)
54 {
55 u32 reg_val, hi;
56
57 switch (reg) {
58 case APIC_EOI:
59 rdmsr(HV_X64_MSR_EOI, reg_val, hi);
60 return reg_val;
61 case APIC_TASKPRI:
62 rdmsr(HV_X64_MSR_TPR, reg_val, hi);
63 return reg_val;
64
65 default:
> 66 return native_apic_mem_read(reg);
67 }
68 }
69
70 static void hv_apic_write(u32 reg, u32 val)
71 {
72 switch (reg) {
73 case APIC_EOI:
74 wrmsr(HV_X64_MSR_EOI, val, 0);
75 break;
76 case APIC_TASKPRI:
77 wrmsr(HV_X64_MSR_TPR, val, 0);
78 break;
79 default:
> 80 native_apic_mem_write(reg, val);
81 }
82 }
83
84 static void hv_apic_eoi_write(u32 reg, u32 val)
85 {
86 wrmsr(HV_X64_MSR_EOI, val, 0);
87 }
88
89 void __init hv_apic_init(void)
90 {
91 if (ms_hyperv.hints & HV_X64_APIC_ACCESS_RECOMMENDED) {
92 pr_info("Hyper-V: Using MSR based APIC access\n");
> 93 apic_set_eoi_write(hv_apic_eoi_write);
94 apic->read = hv_apic_read;
95 apic->write = hv_apic_write;
96 apic->icr_write = hv_apic_icr_write;
97 apic->icr_read = hv_apic_icr_read;
98 }
99 }
100
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
Hi Srinivasan,
I love your patch! Yet something to improve:
[auto build test ERROR on v4.17-rc3]
[also build test ERROR on next-20180504]
[cannot apply to tip/x86/core]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/kys-linuxonhyperv-com/X86-Hyper-V-APIC-enlightenments/20180505-045627
config: x86_64-randconfig-a0-05050447 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-16) 7.3.0
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All errors (new ones prefixed by >>):
arch/x86/hyperv/hv_apic.c: In function 'hv_apic_read':
arch/x86/hyperv/hv_apic.c:69:10: error: implicit declaration of function 'native_apic_mem_read'; did you mean 'hv_apic_icr_read'? [-Werror=implicit-function-declaration]
return native_apic_mem_read(reg);
^~~~~~~~~~~~~~~~~~~~
hv_apic_icr_read
arch/x86/hyperv/hv_apic.c: In function 'hv_apic_write':
arch/x86/hyperv/hv_apic.c:83:3: error: implicit declaration of function 'native_apic_mem_write'; did you mean 'hv_apic_icr_write'? [-Werror=implicit-function-declaration]
native_apic_mem_write(reg, val);
^~~~~~~~~~~~~~~~~~~~~
hv_apic_icr_write
arch/x86/hyperv/hv_apic.c: In function 'hv_send_ipi':
>> arch/x86/hyperv/hv_apic.c:153:12: error: invalid use of undefined type 'struct apic'
orig_apic.send_IPI(cpu, vector);
^
arch/x86/hyperv/hv_apic.c: In function 'hv_send_ipi_mask':
arch/x86/hyperv/hv_apic.c:159:12: error: invalid use of undefined type 'struct apic'
orig_apic.send_IPI_mask(mask, vector);
^
arch/x86/hyperv/hv_apic.c: In function 'hv_send_ipi_mask_allbutself':
arch/x86/hyperv/hv_apic.c:172:12: error: invalid use of undefined type 'struct apic'
orig_apic.send_IPI_mask_allbutself(mask, vector);
^
arch/x86/hyperv/hv_apic.c: In function 'hv_send_ipi_all':
arch/x86/hyperv/hv_apic.c:183:12: error: invalid use of undefined type 'struct apic'
orig_apic.send_IPI_all(vector);
^
arch/x86/hyperv/hv_apic.c: In function 'hv_send_ipi_self':
arch/x86/hyperv/hv_apic.c:189:12: error: invalid use of undefined type 'struct apic'
orig_apic.send_IPI_self(vector);
^
arch/x86/hyperv/hv_apic.c: In function 'hv_apic_init':
>> arch/x86/hyperv/hv_apic.c:199:16: error: 'apic' undeclared (first use in this function)
orig_apic = *apic;
^~~~
arch/x86/hyperv/hv_apic.c:199:16: note: each undeclared identifier is reported only once for each function it appears in
>> arch/x86/hyperv/hv_apic.c:199:13: error: 'orig_apic' has an incomplete type 'struct apic'
orig_apic = *apic;
^
arch/x86/hyperv/hv_apic.c:211:3: error: implicit declaration of function 'apic_set_eoi_write'; did you mean 'hv_apic_eoi_write'? [-Werror=implicit-function-declaration]
apic_set_eoi_write(hv_apic_eoi_write);
^~~~~~~~~~~~~~~~~~
hv_apic_eoi_write
arch/x86/hyperv/hv_apic.c: At top level:
>> arch/x86/hyperv/hv_apic.c:35:20: error: storage size of 'orig_apic' isn't known
static struct apic orig_apic;
^~~~~~~~~
cc1: some warnings being treated as errors
vim +153 arch/x86/hyperv/hv_apic.c
34
> 35 static struct apic orig_apic;
36
37 static u64 hv_apic_icr_read(void)
38 {
39 u64 reg_val;
40
41 rdmsrl(HV_X64_MSR_ICR, reg_val);
42 return reg_val;
43 }
44
45 static void hv_apic_icr_write(u32 low, u32 id)
46 {
47 u64 reg_val;
48
49 reg_val = SET_APIC_DEST_FIELD(id);
50 reg_val = reg_val << 32;
51 reg_val |= low;
52
53 wrmsrl(HV_X64_MSR_ICR, reg_val);
54 }
55
56 static u32 hv_apic_read(u32 reg)
57 {
58 u32 reg_val, hi;
59
60 switch (reg) {
61 case APIC_EOI:
62 rdmsr(HV_X64_MSR_EOI, reg_val, hi);
63 return reg_val;
64 case APIC_TASKPRI:
65 rdmsr(HV_X64_MSR_TPR, reg_val, hi);
66 return reg_val;
67
68 default:
69 return native_apic_mem_read(reg);
70 }
71 }
72
73 static void hv_apic_write(u32 reg, u32 val)
74 {
75 switch (reg) {
76 case APIC_EOI:
77 wrmsr(HV_X64_MSR_EOI, val, 0);
78 break;
79 case APIC_TASKPRI:
80 wrmsr(HV_X64_MSR_TPR, val, 0);
81 break;
82 default:
> 83 native_apic_mem_write(reg, val);
84 }
85 }
86
87 static void hv_apic_eoi_write(u32 reg, u32 val)
88 {
89 wrmsr(HV_X64_MSR_EOI, val, 0);
90 }
91
92 /*
93 * IPI implementation on Hyper-V.
94 */
95 static bool __send_ipi_mask(const struct cpumask *mask, int vector)
96 {
97 int cur_cpu, vcpu;
98 struct ipi_arg_non_ex **arg;
99 struct ipi_arg_non_ex *ipi_arg;
100 int ret = 1;
101 unsigned long flags;
102
103 if (cpumask_empty(mask))
104 return true;
105
106 if (!hv_hypercall_pg)
107 return false;
108
109 if ((vector < HV_IPI_LOW_VECTOR) || (vector > HV_IPI_HIGH_VECTOR))
110 return false;
111
112 local_irq_save(flags);
113 arg = (struct ipi_arg_non_ex **)this_cpu_ptr(hyperv_pcpu_input_arg);
114
115 ipi_arg = *arg;
116 if (unlikely(!ipi_arg))
117 goto ipi_mask_done;
118
119 ipi_arg->vector = vector;
120 ipi_arg->reserved = 0;
121 ipi_arg->cpu_mask = 0;
122
123 for_each_cpu(cur_cpu, mask) {
124 vcpu = hv_cpu_number_to_vp_number(cur_cpu);
125 /*
126 * This particular version of the IPI hypercall can
127 * only target upto 64 CPUs.
128 */
129 if (vcpu >= 64)
130 goto ipi_mask_done;
131
132 __set_bit(vcpu, (unsigned long *)&ipi_arg->cpu_mask);
133 }
134
135 ret = hv_do_hypercall(HVCALL_SEND_IPI, ipi_arg, NULL);
136
137 ipi_mask_done:
138 local_irq_restore(flags);
139 return ((ret == 0) ? true : false);
140 }
141
142 static bool __send_ipi_one(int cpu, int vector)
143 {
144 struct cpumask mask = CPU_MASK_NONE;
145
146 cpumask_set_cpu(cpu, &mask);
147 return __send_ipi_mask(&mask, vector);
148 }
149
150 static void hv_send_ipi(int cpu, int vector)
151 {
152 if (!__send_ipi_one(cpu, vector))
> 153 orig_apic.send_IPI(cpu, vector);
154 }
155
156 static void hv_send_ipi_mask(const struct cpumask *mask, int vector)
157 {
158 if (!__send_ipi_mask(mask, vector))
159 orig_apic.send_IPI_mask(mask, vector);
160 }
161
162 static void hv_send_ipi_mask_allbutself(const struct cpumask *mask, int vector)
163 {
164 unsigned int this_cpu = smp_processor_id();
165 struct cpumask new_mask;
166 const struct cpumask *local_mask;
167
168 cpumask_copy(&new_mask, mask);
169 cpumask_clear_cpu(this_cpu, &new_mask);
170 local_mask = &new_mask;
171 if (!__send_ipi_mask(local_mask, vector))
172 orig_apic.send_IPI_mask_allbutself(mask, vector);
173 }
174
175 static void hv_send_ipi_allbutself(int vector)
176 {
177 hv_send_ipi_mask_allbutself(cpu_online_mask, vector);
178 }
179
180 static void hv_send_ipi_all(int vector)
181 {
182 if (!__send_ipi_mask(cpu_online_mask, vector))
> 183 orig_apic.send_IPI_all(vector);
184 }
185
186 static void hv_send_ipi_self(int vector)
187 {
188 if (!__send_ipi_one(smp_processor_id(), vector))
> 189 orig_apic.send_IPI_self(vector);
190 }
191
192 void __init hv_apic_init(void)
193 {
194 if (ms_hyperv.hints & HV_X64_CLUSTER_IPI_RECOMMENDED) {
195 pr_info("Hyper-V: Using IPI hypercalls\n");
196 /*
197 * Set the IPI entry points.
198 */
> 199 orig_apic = *apic;
200
201 apic->send_IPI = hv_send_ipi;
202 apic->send_IPI_mask = hv_send_ipi_mask;
203 apic->send_IPI_mask_allbutself = hv_send_ipi_mask_allbutself;
204 apic->send_IPI_allbutself = hv_send_ipi_allbutself;
205 apic->send_IPI_all = hv_send_ipi_all;
206 apic->send_IPI_self = hv_send_ipi_self;
207 }
208
209 if (ms_hyperv.hints & HV_X64_APIC_ACCESS_RECOMMENDED) {
210 pr_info("Hyper-V: Using MSR based APIC access\n");
211 apic_set_eoi_write(hv_apic_eoi_write);
212 apic->read = hv_apic_read;
213 apic->write = hv_apic_write;
214 apic->icr_write = hv_apic_icr_write;
215 apic->icr_read = hv_apic_icr_read;
216 }
217 }
218
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
> -----Original Message-----
> From: [email protected] <[email protected]>
> Sent: Thursday, May 3, 2018 11:08 PM
> To: [email protected]; [email protected]; [email protected];
> [email protected]; [email protected]; [email protected]; [email protected];
> [email protected]; [email protected]; Stephen Hemminger <[email protected]>;
> Michael Kelley (EOSG) <[email protected]>; [email protected]
> Cc: KY Srinivasan <[email protected]>
> Subject: [PATCH V2 1/5] X86: Hyper-V: Enlighten APIC access
>
> From: "K. Y. Srinivasan" <[email protected]>
>
> Hyper-V supports MSR based APIC access; implement
> the enlightenment.
>
> Signed-off-by: K. Y. Srinivasan <[email protected]>
> ---
Reviewed-by: Michael Kelley <[email protected]>
> -----Original Message-----
> From: [email protected] <[email protected]>
> Sent: Thursday, May 3, 2018 11:08 PM
> To: [email protected]; [email protected]; [email protected];
> [email protected]; [email protected]; [email protected]; [email protected];
> [email protected]; [email protected]; Stephen Hemminger <[email protected]>;
> Michael Kelley (EOSG) <[email protected]>; [email protected]
> Cc: KY Srinivasan <[email protected]>
> Subject: [PATCH V2 2/5] X86: Hyper-V: Enable IPI enlightenments
>
> From: "K. Y. Srinivasan" <[email protected]>
>
> Hyper-V supports hypercalls to implement IPI; use them.
>
> Signed-off-by: K. Y. Srinivasan <[email protected]>
> ---
Reviewed-by: Michael Kelley <[email protected]>
> -----Original Message-----
> From: [email protected] <[email protected]>
> Sent: Thursday, May 3, 2018 11:08 PM
> To: [email protected]; [email protected]; [email protected];
> [email protected]; [email protected]; [email protected]; [email protected];
> [email protected]; [email protected]; Stephen Hemminger <[email protected]>;
> Michael Kelley (EOSG) <[email protected]>; [email protected]
> Cc: KY Srinivasan <[email protected]>
> Subject: [PATCH V2 4/5] X86: Hyper-V: Consolidate code for converting cpumask to vpset
>
> From: "K. Y. Srinivasan" <[email protected]>
>
> Consolidate code for converting cpumask to vpset.
>
> Signed-off-by: K. Y. Srinivasan <[email protected]>
> ---
Reviewed-by: Michael Kelley <[email protected]>
> -----Original Message-----
> From: [email protected] <[email protected]>
> Sent: Thursday, May 3, 2018 11:08 PM
> To: [email protected]; [email protected]; [email protected];
> [email protected]; [email protected]; [email protected]; [email protected];
> [email protected]; [email protected]; Stephen Hemminger <[email protected]>;
> Michael Kelley (EOSG) <[email protected]>; [email protected]
> Cc: KY Srinivasan <[email protected]>
> Subject: [PATCH V2 5/5] X86: Hyper-V: Consolidate the allocation of the hypercall input page
>
> From: "K. Y. Srinivasan" <[email protected]>
>
> Consolidate the allocation of the hypercall input page.
>
> Signed-off-by: K. Y. Srinivasan <[email protected]>
> ---
Reviewed-by: Michael Kelley <[email protected]>
> -----Original Message-----
> From: [email protected] <[email protected]>
> Sent: Thursday, May 3, 2018 11:08 PM
> To: [email protected]; [email protected]; [email protected];
> [email protected]; [email protected]; [email protected]; [email protected];
> [email protected]; [email protected]; Stephen Hemminger <[email protected]>;
> Michael Kelley (EOSG) <[email protected]>; [email protected]
> Cc: KY Srinivasan <[email protected]>
> Subject: [PATCH V2 3/5] X86: Hyper-V: Enhanced IPI enlightenment
>
> From: "K. Y. Srinivasan" <[email protected]>
>
> Support enhanced IPI enlightenments (to target more than 64 CPUs).
>
> Signed-off-by: K. Y. Srinivasan <[email protected]>
> ---
Reviewed-by: Michael Kelley <[email protected]>
> -----Original Message-----
> From: [email protected] <[email protected]>
> Sent: Thursday, May 3, 2018 11:07 PM
> To: [email protected]; [email protected]; linux-
> [email protected]; [email protected]; [email protected];
> [email protected]; [email protected]; [email protected];
> [email protected]; Stephen Hemminger <[email protected]>; Michael
> Kelley (EOSG) <[email protected]>; [email protected]
> Cc: KY Srinivasan <[email protected]>
> Subject: [PATCH V2 0/5] X86: Hyper-V: APIC enlightenments
>
> From: "K. Y. Srinivasan" <[email protected]>
>
> Implement APIC related enlightenments.
>
> V2: Addressed comments from Thomas Gleixner <[email protected]>
> and Michael Kelley (EOSG) <[email protected]>.
Thomas,
I think I have addressed all your comments;
let me know if you have any additional comments on this patch set.
Regards,
K. Y
>
> K. Y. Srinivasan (5):
> X86: Hyper-V: Enlighten APIC access
> X86: Hyper-V: Enable IPI enlightenments
> X86: Hyper-V: Enhanced IPI enlightenment
> X86: Hyper-V: Consolidate code for converting cpumask to vpset
> X86: Hyper-V: Consolidate the allocation of the hypercall input page
>
> arch/x86/hyperv/Makefile | 2 +-
> arch/x86/hyperv/hv_apic.c | 259
> +++++++++++++++++++++++++++++++++++++
> arch/x86/hyperv/hv_init.c | 32 ++++-
> arch/x86/hyperv/mmu.c | 75 ++---------
> arch/x86/include/asm/hyperv-tlfs.h | 30 ++++-
> arch/x86/include/asm/mshyperv.h | 39 +++++-
> 6 files changed, 365 insertions(+), 72 deletions(-)
> create mode 100644 arch/x86/hyperv/hv_apic.c
>
> --
> 2.15.1
On Wed, 16 May 2018, KY Srinivasan wrote:
>
>
> > -----Original Message-----
> > From: [email protected] <[email protected]>
> > Sent: Thursday, May 3, 2018 11:07 PM
> > To: [email protected]; [email protected]; linux-
> > [email protected]; [email protected]; [email protected];
> > [email protected]; [email protected]; [email protected];
> > [email protected]; Stephen Hemminger <[email protected]>; Michael
> > Kelley (EOSG) <[email protected]>; [email protected]
> > Cc: KY Srinivasan <[email protected]>
> > Subject: [PATCH V2 0/5] X86: Hyper-V: APIC enlightenments
> >
> > From: "K. Y. Srinivasan" <[email protected]>
> >
> > Implement APIC related enlightenments.
> >
> > V2: Addressed comments from Thomas Gleixner <[email protected]>
> > and Michael Kelley (EOSG) <[email protected]>.
>
> Thomas,
>
> I think I have addressed all your comments;
> let me know if you have any additional comments on this patch set.
Looks good now. There is just the build robot fallout which needs to be
addressed AFAICT.
Thanks,
tglx