X86: Hyper-V: APIC enlightenments
Subsystems (2)
v2 cover 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]>.
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
Signature · 6 lines
2.15.1 _______________________________________________ devel mailing list [email protected] http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
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.
--- 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
arch/x86/hyperv/Makefile +1 -1
@@ -1 +1 @@ -obj-y := hv_init.o mmu.o +obj-y := hv_init.o mmu.o hv_apic.o
arch/x86/hyperv/hv_apic.c new file +101 -0
101 lines not on this page · raw message
arch/x86/hyperv/hv_init.c +4 -1
@@ -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. */
arch/x86/include/asm/mshyperv.h +3 -1
@@ -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 ;
Signature · 6 lines
2.15.1 _______________________________________________ devel mailing list [email protected] http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
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.
--- 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(+)
arch/x86/hyperv/hv_apic.c +118 -0
@@ -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);
arch/x86/hyperv/hv_init.c +27 -0
@@ -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 );
arch/x86/include/asm/hyperv-tlfs.h +15 -0
@@ -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
arch/x86/include/asm/mshyperv.h +1 -0
@@ -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) {
Signature · 1 line
2.15.1
kbuild test robot
build botRe: [PATCH V2 2/5] X86: Hyper-V: Enable IPI enlightenments
I love your patch! Yet something to improve:
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
RE: [PATCH V2 2/5] X86: Hyper-V: Enable IPI enlightenments
In reply to [email protected]Quoted 10 lines
-----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
Quoted 6 lines
From: "K. Y. Srinivasan" <[email protected]>
Hyper-V supports hypercalls to implement IPI; use them.
Signed-off-by K. Y. Srinivasan <[email protected]>---
_______________________________________________
devel mailing list
[email protected]
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
PATCH v2 3/5 X86: Hyper-V: Enhanced IPI enlightenment
In reply to [email protected]From: "K. Y. Srinivasan" <[email protected]>
Support enhanced IPI enlightenments (to target more than 64 CPUs).
--- 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(-)
arch/x86/hyperv/hv_apic.c +41 -1
@@ -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. */
arch/x86/hyperv/mmu.c +1 -1
@@ -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); }
arch/x86/include/asm/hyperv-tlfs.h +14 -1
@@ -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
arch/x86/include/asm/mshyperv.h +33 -0
@@ -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 );
Signature · 6 lines
2.15.1 _______________________________________________ devel mailing list [email protected] http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
RE: [PATCH V2 3/5] X86: Hyper-V: Enhanced IPI enlightenment
Quoted 10 lines
-----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
Quoted 6 lines
From: "K. Y. Srinivasan" <[email protected]>
Support enhanced IPI enlightenments (to target more than 64 CPUs).
Signed-off-by K. Y. Srinivasan <[email protected]>---
_______________________________________________
devel mailing list
[email protected]
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
PATCH v2 4/5 X86: Hyper-V: Consolidate code for converting cpumask to vpset
In reply to [email protected]From: "K. Y. Srinivasan" <[email protected]>
Consolidate code for converting cpumask to vpset.
--- arch/x86/hyperv/mmu.c | 43 ++----------------------------------------- 1 file changed, 2 insertions(+), 41 deletions(-)
arch/x86/hyperv/mmu.c +2 -41
@@ -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) {
Signature · 6 lines
2.15.1 _______________________________________________ devel mailing list [email protected] http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
RE: [PATCH V2 4/5] X86: Hyper-V: Consolidate code for converting cpumask to vpset
Quoted 10 lines
-----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
Quoted 6 lines
From: "K. Y. Srinivasan" <[email protected]>
Consolidate code for converting cpumask to vpset.
Signed-off-by K. Y. Srinivasan <[email protected]>---
_______________________________________________
devel mailing list
[email protected]
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
PATCH v2 5/5 X86: Hyper-V: Consolidate the allocation of the hypercall input page
In reply to [email protected]From: "K. Y. Srinivasan" <[email protected]>
Consolidate the allocation of the hypercall input page.
--- 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(-)
arch/x86/hyperv/hv_init.c +0 -2
@@ -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 ();/*
arch/x86/hyperv/mmu.c +6 -24
@@ -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 *); -}
arch/x86/include/asm/mshyperv.h +0 -1
@@ -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 );
Signature · 1 line
2.15.1
RE: [PATCH V2 5/5] X86: Hyper-V: Consolidate the allocation of the hypercall input page
Quoted 10 lines
-----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
Quoted 6 lines
From: "K. Y. Srinivasan" <[email protected]>
Consolidate the allocation of the hypercall input page.
Signed-off-by K. Y. Srinivasan <[email protected]>---
_______________________________________________
devel mailing list
[email protected]
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
kbuild test robot
build botRe: [PATCH V2 1/5] X86: Hyper-V: Enlighten APIC access
In reply to [email protected]I love your patch! Yet something to improve:
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
RE: [PATCH V2 1/5] X86: Hyper-V: Enlighten APIC access
In reply to [email protected]Quoted 10 lines
-----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
Quoted 7 lines
From: "K. Y. Srinivasan" <[email protected]>
Hyper-V supports MSR based APIC access; implement
the enlightenment.Signed-off-by K. Y. Srinivasan <[email protected]>---
_______________________________________________
devel mailing list
[email protected]
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Quoted 13 lines
-----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
Quoted 6 lines
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
Quoted 18 lines
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 pagearch/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
Quoted 2 lines
--
2.15.1
_______________________________________________
devel mailing list
[email protected]
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Quoted 17 lines · KY Srinivasan
Quoted 17 lines
-----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 enlightenmentsFrom: "K. Y. Srinivasan" <[email protected]>
Implement APIC related enlightenments.
Quoted 7 lines
Quoted 2 lines
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