X86: Hyper-V: APIC enlightenments
Subsystems (2)
v3 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]>.
V3: Address build issues reported by kbuild test robot <[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 | 261 +++++++++++++++++++++++++++++ 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, 367 insertions(+), 72 deletions(-) create mode 100644 arch/x86/hyperv/hv_apic.c
Signature · 6 lines
2.17.0 _______________________________________________ devel mailing list [email protected] http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
PATCH v3 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 | 104 ++++++++++++++++++++++++++++++++ arch/x86/hyperv/hv_init.c | 5 +- arch/x86/include/asm/mshyperv.h | 4 +- 4 files changed, 112 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 +104 -0
104 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.17.0 _______________________________________________ devel mailing list [email protected] http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
PATCH v3 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 | 117 +++++++++++++++++++++++++++++ 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, 160 insertions(+)
arch/x86/hyperv/hv_apic.c +117 -0
@@ -33,6 +33,8 @@ #ifdef CONFIG_X86_64 #if IS_ENABLED(CONFIG_HYPERV) +static struct apic orig_apic; + static u64 hv_apic_icr_read(void) { u64 reg_val;
@@ -88,8 +90,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 · 6 lines
2.17.0 _______________________________________________ devel mailing list [email protected] http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
tip-bot for K. Y. Srinivasan
merge bot[tip:x86/hyperv] X86/Hyper-V: Enable IPI enlightenments
X86/Hyper-V: Enable IPI enlightenments
Commit-ID: 68bb7bfb7985df2bd15c2dc975cb68b7a901488a Gitweb: https://git.kernel.org/tip/68bb7bfb7985df2bd15c2dc975cb68b7a901488a Author: K. Y. Srinivasan <[email protected]> AuthorDate: Wed, 16 May 2018 14:53:31 -0700 Committer: Thomas Gleixner <[email protected]> CommitDate: Sat, 19 May 2018 13:23:17 +0200
X86/Hyper-V: Enable IPI enlightenments
Hyper-V supports hypercalls to implement IPI; use them.
--- arch/x86/hyperv/hv_apic.c | 117 +++++++++++++++++++++++++++++++++++++ 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, 160 insertions(+)
arch/x86/hyperv/hv_apic.c +117 -0
@@ -33,6 +33,8 @@ #ifdef CONFIG_X86_64 #if IS_ENABLED(CONFIG_HYPERV) +static struct apic orig_apic; + static u64 hv_apic_icr_read(void) { u64 reg_val;
@@ -88,8 +90,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) {
kbuild test robot
build botRe: [PATCH V3 2/5] X86: Hyper-V: Enable IPI enlightenments
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-rc5]
[also build test ERROR on next-20180517]
[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/20180520-040432
config: x86_64-randconfig-s5-05201710 (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:70: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:84: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:154: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:160: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:173: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:184: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:190: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:200:16: error: 'apic' undeclared (first use in this function)
orig_apic = *apic;
^~~~
arch/x86/hyperv/hv_apic.c:200:16: note: each undeclared identifier is reported only once for each function it appears in
>> arch/x86/hyperv/hv_apic.c:200:13: error: 'orig_apic' has an incomplete type 'struct apic'
orig_apic = *apic;
^
arch/x86/hyperv/hv_apic.c:212: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:36:20: error: storage size of 'orig_apic' isn't known
static struct apic orig_apic;
^~~~~~~~~cc1: some warnings being treated as errors
vim +154 arch/x86/hyperv/hv_apic.c
35
> 36 static struct apic orig_apic;
37
38 static u64 hv_apic_icr_read(void)
39 {
40 u64 reg_val;
41
42 rdmsrl(HV_X64_MSR_ICR, reg_val);
43 return reg_val;
44 }
45
46 static void hv_apic_icr_write(u32 low, u32 id)
47 {
48 u64 reg_val;
49
50 reg_val = SET_APIC_DEST_FIELD(id);
51 reg_val = reg_val << 32;
52 reg_val |= low;
53
54 wrmsrl(HV_X64_MSR_ICR, reg_val);
55 }
56
57 static u32 hv_apic_read(u32 reg)
58 {
59 u32 reg_val, hi;
60
61 switch (reg) {
62 case APIC_EOI:
63 rdmsr(HV_X64_MSR_EOI, reg_val, hi);
64 return reg_val;
65 case APIC_TASKPRI:
66 rdmsr(HV_X64_MSR_TPR, reg_val, hi);
67 return reg_val;
68
69 default:
70 return native_apic_mem_read(reg);
71 }
72 }
73
74 static void hv_apic_write(u32 reg, u32 val)
75 {
76 switch (reg) {
77 case APIC_EOI:
78 wrmsr(HV_X64_MSR_EOI, val, 0);
79 break;
80 case APIC_TASKPRI:
81 wrmsr(HV_X64_MSR_TPR, val, 0);
82 break;
83 default:
> 84 native_apic_mem_write(reg, val);
85 }
86 }
87
88 static void hv_apic_eoi_write(u32 reg, u32 val)
89 {
90 wrmsr(HV_X64_MSR_EOI, val, 0);
91 }
92
93 /*
94 * IPI implementation on Hyper-V.
95 */
96 static bool __send_ipi_mask(const struct cpumask *mask, int vector)
97 {
98 int cur_cpu, vcpu;
99 struct ipi_arg_non_ex **arg;
100 struct ipi_arg_non_ex *ipi_arg;
101 int ret = 1;
102 unsigned long flags;
103
104 if (cpumask_empty(mask))
105 return true;
106
107 if (!hv_hypercall_pg)
108 return false;
109
110 if ((vector < HV_IPI_LOW_VECTOR) || (vector > HV_IPI_HIGH_VECTOR))
111 return false;
112
113 local_irq_save(flags);
114 arg = (struct ipi_arg_non_ex **)this_cpu_ptr(hyperv_pcpu_input_arg);
115
116 ipi_arg = *arg;
117 if (unlikely(!ipi_arg))
118 goto ipi_mask_done;
119
120 ipi_arg->vector = vector;
121 ipi_arg->reserved = 0;
122 ipi_arg->cpu_mask = 0;
123
124 for_each_cpu(cur_cpu, mask) {
125 vcpu = hv_cpu_number_to_vp_number(cur_cpu);
126 /*
127 * This particular version of the IPI hypercall can
128 * only target upto 64 CPUs.
129 */
130 if (vcpu >= 64)
131 goto ipi_mask_done;
132
133 __set_bit(vcpu, (unsigned long *)&ipi_arg->cpu_mask);
134 }
135
136 ret = hv_do_hypercall(HVCALL_SEND_IPI, ipi_arg, NULL);
137
138 ipi_mask_done:
139 local_irq_restore(flags);
140 return ((ret == 0) ? true : false);
141 }
142
143 static bool __send_ipi_one(int cpu, int vector)
144 {
145 struct cpumask mask = CPU_MASK_NONE;
146
147 cpumask_set_cpu(cpu, &mask);
148 return __send_ipi_mask(&mask, vector);
149 }
150
151 static void hv_send_ipi(int cpu, int vector)
152 {
153 if (!__send_ipi_one(cpu, vector))
> 154 orig_apic.send_IPI(cpu, vector);
155 }
156
157 static void hv_send_ipi_mask(const struct cpumask *mask, int vector)
158 {
159 if (!__send_ipi_mask(mask, vector))
160 orig_apic.send_IPI_mask(mask, vector);
161 }
162
163 static void hv_send_ipi_mask_allbutself(const struct cpumask *mask, int vector)
164 {
165 unsigned int this_cpu = smp_processor_id();
166 struct cpumask new_mask;
167 const struct cpumask *local_mask;
168
169 cpumask_copy(&new_mask, mask);
170 cpumask_clear_cpu(this_cpu, &new_mask);
171 local_mask = &new_mask;
172 if (!__send_ipi_mask(local_mask, vector))
173 orig_apic.send_IPI_mask_allbutself(mask, vector);
174 }
175
176 static void hv_send_ipi_allbutself(int vector)
177 {
178 hv_send_ipi_mask_allbutself(cpu_online_mask, vector);
179 }
180
181 static void hv_send_ipi_all(int vector)
182 {
183 if (!__send_ipi_mask(cpu_online_mask, vector))
> 184 orig_apic.send_IPI_all(vector);
185 }
186
187 static void hv_send_ipi_self(int vector)
188 {
189 if (!__send_ipi_one(smp_processor_id(), vector))
> 190 orig_apic.send_IPI_self(vector);
191 }
192
193 void __init hv_apic_init(void)
194 {
195 if (ms_hyperv.hints & HV_X64_CLUSTER_IPI_RECOMMENDED) {
196 pr_info("Hyper-V: Using IPI hypercalls\n");
197 /*
198 * Set the IPI entry points.
199 */
> 200 orig_apic = *apic; 201
202 apic->send_IPI = hv_send_ipi;
203 apic->send_IPI_mask = hv_send_ipi_mask;
204 apic->send_IPI_mask_allbutself = hv_send_ipi_mask_allbutself;
205 apic->send_IPI_allbutself = hv_send_ipi_allbutself;
206 apic->send_IPI_all = hv_send_ipi_all;
207 apic->send_IPI_self = hv_send_ipi_self;
208 }
209
210 if (ms_hyperv.hints & HV_X64_APIC_ACCESS_RECOMMENDED) {
211 pr_info("Hyper-V: Using MSR based APIC access\n");
212 apic_set_eoi_write(hv_apic_eoi_write);
213 apic->read = hv_apic_read;
214 apic->write = hv_apic_write;
215 apic->icr_write = hv_apic_icr_write;
216 apic->icr_read = hv_apic_icr_read;
217 }
218 }
219
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
_______________________________________________
devel mailing list
[email protected]
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
PATCH v3 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
@@ -93,6 +93,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;
@@ -110,6 +144,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);
@@ -193,7 +230,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.17.0 _______________________________________________ devel mailing list [email protected] http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
tip-bot for K. Y. Srinivasan
merge bot[tip:x86/hyperv] X86/Hyper-V: Enhanced IPI enlightenment
X86/Hyper-V: Enhanced IPI enlightenment
Commit-ID: 366f03b0cf90ef55f063d4a54cf62b0ac9b6da9d Gitweb: https://git.kernel.org/tip/366f03b0cf90ef55f063d4a54cf62b0ac9b6da9d Author: K. Y. Srinivasan <[email protected]> AuthorDate: Wed, 16 May 2018 14:53:32 -0700 Committer: Thomas Gleixner <[email protected]> CommitDate: Sat, 19 May 2018 13:23:17 +0200
X86/Hyper-V: Enhanced IPI enlightenment
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
@@ -93,6 +93,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;
@@ -110,6 +144,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);
@@ -193,7 +230,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 );
PATCH v3 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.17.0 _______________________________________________ devel mailing list [email protected] http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
tip-bot for K. Y. Srinivasan
merge bot[tip:x86/hyperv] X86/Hyper-V: Consolidate code for converting cpumask to vpset
X86/Hyper-V: Consolidate code for converting cpumask to vpset
Commit-ID: 800b8f03fdc8d66885ff03de531285526a4ca0d4 Gitweb: https://git.kernel.org/tip/800b8f03fdc8d66885ff03de531285526a4ca0d4 Author: K. Y. Srinivasan <[email protected]> AuthorDate: Wed, 16 May 2018 14:53:33 -0700 Committer: Thomas Gleixner <[email protected]> CommitDate: Sat, 19 May 2018 13:23:18 +0200
X86/Hyper-V: Consolidate code for converting cpumask to vpset
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) {
PATCH v3 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 · 6 lines
2.17.0 _______________________________________________ devel mailing list [email protected] http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
tip-bot for K. Y. Srinivasan
merge bot[tip:x86/hyperv] X86/Hyper-V: Consolidate the allocation of the hypercall input page
X86/Hyper-V: Consolidate the allocation of the hypercall input page
Commit-ID: 9a2d78e291a7dea0ae4b4a06ce6bbbe4f1ab7c13 Gitweb: https://git.kernel.org/tip/9a2d78e291a7dea0ae4b4a06ce6bbbe4f1ab7c13 Author: K. Y. Srinivasan <[email protected]> AuthorDate: Wed, 16 May 2018 14:53:34 -0700 Committer: Thomas Gleixner <[email protected]> CommitDate: Sat, 19 May 2018 13:23:18 +0200
X86/Hyper-V: Consolidate the allocation of the hypercall input page
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 );
tip-bot for K. Y. Srinivasan
merge bot[tip:x86/hyperv] X86/Hyper-V: Enlighten APIC access
In reply to [email protected]X86/Hyper-V: Enlighten APIC access
Commit-ID: 6b48cb5f8347bc0153ff1d7b075db92e6723ffdb Gitweb: https://git.kernel.org/tip/6b48cb5f8347bc0153ff1d7b075db92e6723ffdb Author: K. Y. Srinivasan <[email protected]> AuthorDate: Wed, 16 May 2018 14:53:30 -0700 Committer: Thomas Gleixner <[email protected]> CommitDate: Sat, 19 May 2018 13:23:17 +0200
X86/Hyper-V: Enlighten APIC access
Hyper-V supports MSR based APIC access; implement
the enlightenment.
--- arch/x86/hyperv/Makefile | 2 +- arch/x86/hyperv/hv_apic.c | 104 ++++++++++++++++++++++++++++++++++++++++ arch/x86/hyperv/hv_init.c | 5 +- arch/x86/include/asm/mshyperv.h | 4 +- 4 files changed, 112 insertions(+), 3 deletions(-)
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 +104 -0
104 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 ;