[tip:x86/hyperv] x86/hyper-v: Fix wrong merge conflict resolution

2018-07-19 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  be0e16ce7c3bf9855f1ef5ae46cf889e1784ddea
Gitweb: https://git.kernel.org/tip/be0e16ce7c3bf9855f1ef5ae46cf889e1784ddea
Author: K. Y. Srinivasan 
AuthorDate: Fri, 20 Jul 2018 03:50:09 +
Committer:  Thomas Gleixner 
CommitDate: Fri, 20 Jul 2018 06:56:23 +0200

x86/hyper-v: Fix wrong merge conflict resolution

When the mapping betwween the Linux notion of CPU ID to the hypervisor's
notion of CPU ID is not initialized, IPI must fall back to the
non-enlightened path.

The recent merge of upstream changes into the hyperv branch resolved a
merge conflict wronly by returning success in that case, which results in
the IPI not being sent at all. Fix it up.

Fixes: 8f63e9230dec ("Merge branch 'x86/urgent' into x86/hyperv")
Reported-by: Michael Kelley 
Signed-off-by: K. Y. Srinivasan 
Signed-off-by: Thomas Gleixner 
Cc: gre...@linuxfoundation.org
Cc: de...@linuxdriverproject.org
Cc: o...@aepfle.de
Cc: a...@canonical.com
Cc: jasow...@redhat.com
Cc: h...@zytor.com
Cc: sthem...@microsoft.com
Cc: michael.h.kel...@microsoft.com
Cc: vkuzn...@redhat.com
Link: https://lkml.kernel.org/r/20180720035009.3995-1-...@linuxonhyperv.com
---
 arch/x86/hyperv/hv_apic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c
index 0c3c9f8fee77..5b0f613428c2 100644
--- a/arch/x86/hyperv/hv_apic.c
+++ b/arch/x86/hyperv/hv_apic.c
@@ -168,7 +168,7 @@ static bool __send_ipi_mask(const struct cpumask *mask, int 
vector)
for_each_cpu(cur_cpu, mask) {
vcpu = hv_cpu_number_to_vp_number(cur_cpu);
if (vcpu == VP_INVAL)
-   return true;
+   return false;
 
/*
 * This particular version of the IPI hypercall can


[tip:x86/hyperv] x86/hyper-v: Fix wrong merge conflict resolution

2018-07-19 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  be0e16ce7c3bf9855f1ef5ae46cf889e1784ddea
Gitweb: https://git.kernel.org/tip/be0e16ce7c3bf9855f1ef5ae46cf889e1784ddea
Author: K. Y. Srinivasan 
AuthorDate: Fri, 20 Jul 2018 03:50:09 +
Committer:  Thomas Gleixner 
CommitDate: Fri, 20 Jul 2018 06:56:23 +0200

x86/hyper-v: Fix wrong merge conflict resolution

When the mapping betwween the Linux notion of CPU ID to the hypervisor's
notion of CPU ID is not initialized, IPI must fall back to the
non-enlightened path.

The recent merge of upstream changes into the hyperv branch resolved a
merge conflict wronly by returning success in that case, which results in
the IPI not being sent at all. Fix it up.

Fixes: 8f63e9230dec ("Merge branch 'x86/urgent' into x86/hyperv")
Reported-by: Michael Kelley 
Signed-off-by: K. Y. Srinivasan 
Signed-off-by: Thomas Gleixner 
Cc: gre...@linuxfoundation.org
Cc: de...@linuxdriverproject.org
Cc: o...@aepfle.de
Cc: a...@canonical.com
Cc: jasow...@redhat.com
Cc: h...@zytor.com
Cc: sthem...@microsoft.com
Cc: michael.h.kel...@microsoft.com
Cc: vkuzn...@redhat.com
Link: https://lkml.kernel.org/r/20180720035009.3995-1-...@linuxonhyperv.com
---
 arch/x86/hyperv/hv_apic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c
index 0c3c9f8fee77..5b0f613428c2 100644
--- a/arch/x86/hyperv/hv_apic.c
+++ b/arch/x86/hyperv/hv_apic.c
@@ -168,7 +168,7 @@ static bool __send_ipi_mask(const struct cpumask *mask, int 
vector)
for_each_cpu(cur_cpu, mask) {
vcpu = hv_cpu_number_to_vp_number(cur_cpu);
if (vcpu == VP_INVAL)
-   return true;
+   return false;
 
/*
 * This particular version of the IPI hypercall can


[tip:x86/hyperv] x86/hyper-v: Fix the circular dependency in IPI enlightenment

2018-07-06 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  1268ed0c474a5c8f165ef386f3310521b5e00e27
Gitweb: https://git.kernel.org/tip/1268ed0c474a5c8f165ef386f3310521b5e00e27
Author: K. Y. Srinivasan 
AuthorDate: Tue, 3 Jul 2018 16:01:55 -0700
Committer:  Thomas Gleixner 
CommitDate: Fri, 6 Jul 2018 12:32:59 +0200

x86/hyper-v: Fix the circular dependency in IPI enlightenment

The IPI hypercalls depend on being able to map the Linux notion of CPU ID
to the hypervisor's notion of the CPU ID. The array hv_vp_index[] provides
this mapping. Code for populating this array depends on the IPI functionality.
Break this circular dependency.

[ tglx: Use a proper define instead of '-1' with a u32 variable as pointed
out by Vitaly ]

Fixes: 68bb7bfb7985 ("X86/Hyper-V: Enable IPI enlightenments")
Signed-off-by: K. Y. Srinivasan 
Signed-off-by: Thomas Gleixner 
Tested-by: Michael Kelley 
Cc: gre...@linuxfoundation.org
Cc: de...@linuxdriverproject.org
Cc: o...@aepfle.de
Cc: a...@canonical.com
Cc: jasow...@redhat.com
Cc: h...@zytor.com
Cc: sthem...@microsoft.com
Cc: michael.h.kel...@microsoft.com
Cc: vkuzn...@redhat.com
Link: https://lkml.kernel.org/r/20180703230155.15160-1-...@linuxonhyperv.com


---
 arch/x86/hyperv/hv_apic.c   | 5 +
 arch/x86/hyperv/hv_init.c   | 5 -
 arch/x86/include/asm/mshyperv.h | 5 -
 3 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c
index f68855499391..402338365651 100644
--- a/arch/x86/hyperv/hv_apic.c
+++ b/arch/x86/hyperv/hv_apic.c
@@ -114,6 +114,8 @@ static bool __send_ipi_mask_ex(const struct cpumask *mask, 
int vector)
ipi_arg->vp_set.format = HV_GENERIC_SET_SPARSE_4K;
nr_bank = cpumask_to_vpset(&(ipi_arg->vp_set), mask);
}
+   if (nr_bank < 0)
+   goto ipi_mask_ex_done;
if (!nr_bank)
ipi_arg->vp_set.format = HV_GENERIC_SET_ALL;
 
@@ -158,6 +160,9 @@ static bool __send_ipi_mask(const struct cpumask *mask, int 
vector)
 
for_each_cpu(cur_cpu, mask) {
vcpu = hv_cpu_number_to_vp_number(cur_cpu);
+   if (vcpu == VP_INVAL)
+   goto ipi_mask_done;
+
/*
 * This particular version of the IPI hypercall can
 * only target upto 64 CPUs.
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 4c431e1c1eff..1ff420217298 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -265,7 +265,7 @@ void __init hyperv_init(void)
 {
u64 guest_id, required_msrs;
union hv_x64_msr_hypercall_contents hypercall_msr;
-   int cpuhp;
+   int cpuhp, i;
 
if (x86_hyper_type != X86_HYPER_MS_HYPERV)
return;
@@ -293,6 +293,9 @@ void __init hyperv_init(void)
if (!hv_vp_index)
return;
 
+   for (i = 0; i < num_possible_cpus(); i++)
+   hv_vp_index[i] = VP_INVAL;
+
hv_vp_assist_page = kcalloc(num_possible_cpus(),
sizeof(*hv_vp_assist_page), GFP_KERNEL);
if (!hv_vp_assist_page) {
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 3cd14311edfa..5a7375ed5f7c 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -9,6 +9,8 @@
 #include 
 #include 
 
+#define VP_INVAL   U32_MAX
+
 struct ms_hyperv_info {
u32 features;
u32 misc_features;
@@ -20,7 +22,6 @@ struct ms_hyperv_info {
 
 extern struct ms_hyperv_info ms_hyperv;
 
-
 /*
  * Generate the guest ID.
  */
@@ -281,6 +282,8 @@ static inline int cpumask_to_vpset(struct hv_vpset *vpset,
 */
for_each_cpu(cpu, cpus) {
vcpu = hv_cpu_number_to_vp_number(cpu);
+   if (vcpu == VP_INVAL)
+   return -1;
vcpu_bank = vcpu / 64;
vcpu_offset = vcpu % 64;
__set_bit(vcpu_offset, (unsigned long *)


[tip:x86/hyperv] x86/hyper-v: Fix the circular dependency in IPI enlightenment

2018-07-06 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  1268ed0c474a5c8f165ef386f3310521b5e00e27
Gitweb: https://git.kernel.org/tip/1268ed0c474a5c8f165ef386f3310521b5e00e27
Author: K. Y. Srinivasan 
AuthorDate: Tue, 3 Jul 2018 16:01:55 -0700
Committer:  Thomas Gleixner 
CommitDate: Fri, 6 Jul 2018 12:32:59 +0200

x86/hyper-v: Fix the circular dependency in IPI enlightenment

The IPI hypercalls depend on being able to map the Linux notion of CPU ID
to the hypervisor's notion of the CPU ID. The array hv_vp_index[] provides
this mapping. Code for populating this array depends on the IPI functionality.
Break this circular dependency.

[ tglx: Use a proper define instead of '-1' with a u32 variable as pointed
out by Vitaly ]

Fixes: 68bb7bfb7985 ("X86/Hyper-V: Enable IPI enlightenments")
Signed-off-by: K. Y. Srinivasan 
Signed-off-by: Thomas Gleixner 
Tested-by: Michael Kelley 
Cc: gre...@linuxfoundation.org
Cc: de...@linuxdriverproject.org
Cc: o...@aepfle.de
Cc: a...@canonical.com
Cc: jasow...@redhat.com
Cc: h...@zytor.com
Cc: sthem...@microsoft.com
Cc: michael.h.kel...@microsoft.com
Cc: vkuzn...@redhat.com
Link: https://lkml.kernel.org/r/20180703230155.15160-1-...@linuxonhyperv.com


---
 arch/x86/hyperv/hv_apic.c   | 5 +
 arch/x86/hyperv/hv_init.c   | 5 -
 arch/x86/include/asm/mshyperv.h | 5 -
 3 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c
index f68855499391..402338365651 100644
--- a/arch/x86/hyperv/hv_apic.c
+++ b/arch/x86/hyperv/hv_apic.c
@@ -114,6 +114,8 @@ static bool __send_ipi_mask_ex(const struct cpumask *mask, 
int vector)
ipi_arg->vp_set.format = HV_GENERIC_SET_SPARSE_4K;
nr_bank = cpumask_to_vpset(&(ipi_arg->vp_set), mask);
}
+   if (nr_bank < 0)
+   goto ipi_mask_ex_done;
if (!nr_bank)
ipi_arg->vp_set.format = HV_GENERIC_SET_ALL;
 
@@ -158,6 +160,9 @@ static bool __send_ipi_mask(const struct cpumask *mask, int 
vector)
 
for_each_cpu(cur_cpu, mask) {
vcpu = hv_cpu_number_to_vp_number(cur_cpu);
+   if (vcpu == VP_INVAL)
+   goto ipi_mask_done;
+
/*
 * This particular version of the IPI hypercall can
 * only target upto 64 CPUs.
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 4c431e1c1eff..1ff420217298 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -265,7 +265,7 @@ void __init hyperv_init(void)
 {
u64 guest_id, required_msrs;
union hv_x64_msr_hypercall_contents hypercall_msr;
-   int cpuhp;
+   int cpuhp, i;
 
if (x86_hyper_type != X86_HYPER_MS_HYPERV)
return;
@@ -293,6 +293,9 @@ void __init hyperv_init(void)
if (!hv_vp_index)
return;
 
+   for (i = 0; i < num_possible_cpus(); i++)
+   hv_vp_index[i] = VP_INVAL;
+
hv_vp_assist_page = kcalloc(num_possible_cpus(),
sizeof(*hv_vp_assist_page), GFP_KERNEL);
if (!hv_vp_assist_page) {
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 3cd14311edfa..5a7375ed5f7c 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -9,6 +9,8 @@
 #include 
 #include 
 
+#define VP_INVAL   U32_MAX
+
 struct ms_hyperv_info {
u32 features;
u32 misc_features;
@@ -20,7 +22,6 @@ struct ms_hyperv_info {
 
 extern struct ms_hyperv_info ms_hyperv;
 
-
 /*
  * Generate the guest ID.
  */
@@ -281,6 +282,8 @@ static inline int cpumask_to_vpset(struct hv_vpset *vpset,
 */
for_each_cpu(cpu, cpus) {
vcpu = hv_cpu_number_to_vp_number(cpu);
+   if (vcpu == VP_INVAL)
+   return -1;
vcpu_bank = vcpu / 64;
vcpu_offset = vcpu % 64;
__set_bit(vcpu_offset, (unsigned long *)


[tip:x86/urgent] x86/hyper-v: Fix the circular dependency in IPI enlightenment

2018-07-04 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  5e6f19db2deca9e7eaa378447c77616b35693399
Gitweb: https://git.kernel.org/tip/5e6f19db2deca9e7eaa378447c77616b35693399
Author: K. Y. Srinivasan 
AuthorDate: Tue, 3 Jul 2018 16:01:55 -0700
Committer:  Ingo Molnar 
CommitDate: Wed, 4 Jul 2018 10:50:03 +0200

x86/hyper-v: Fix the circular dependency in IPI enlightenment

The IPI hypercalls depend on being able to map the Linux notion of CPU ID
to the hypervisor's notion of the CPU ID. The array hv_vp_index[] provides
this mapping. Code for populating this array depends on the IPI functionality.
Break this circular dependency.

Tested-by: Michael Kelley 
Signed-off-by: K. Y. Srinivasan 
Acked-by: Thomas Gleixner 
Cc: Linus Torvalds 
Cc: michael.h.kel...@microsoft.com
Cc: Peter Zijlstra 
Cc: a...@canonical.com
Cc: de...@linuxdriverproject.org
Cc: gre...@linuxfoundation.org
Cc: jasow...@redhat.com
Cc: o...@aepfle.de
Cc: sthem...@microsoft.com
Cc: vkuzn...@redhat.com
Fixes: 68bb7bfb7985 ("X86/Hyper-V: Enable IPI enlightenments")
Link: http://lkml.kernel.org/r/20180703230155.15160-1-...@linuxonhyperv.com
Signed-off-by: Ingo Molnar 
---
 arch/x86/hyperv/hv_apic.c   | 5 +
 arch/x86/hyperv/hv_init.c   | 5 -
 arch/x86/include/asm/mshyperv.h | 2 ++
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c
index f68855499391..63d7c196739f 100644
--- a/arch/x86/hyperv/hv_apic.c
+++ b/arch/x86/hyperv/hv_apic.c
@@ -114,6 +114,8 @@ static bool __send_ipi_mask_ex(const struct cpumask *mask, 
int vector)
ipi_arg->vp_set.format = HV_GENERIC_SET_SPARSE_4K;
nr_bank = cpumask_to_vpset(&(ipi_arg->vp_set), mask);
}
+   if (nr_bank == -1)
+   goto ipi_mask_ex_done;
if (!nr_bank)
ipi_arg->vp_set.format = HV_GENERIC_SET_ALL;
 
@@ -158,6 +160,9 @@ static bool __send_ipi_mask(const struct cpumask *mask, int 
vector)
 
for_each_cpu(cur_cpu, mask) {
vcpu = hv_cpu_number_to_vp_number(cur_cpu);
+   if (vcpu == -1)
+   goto ipi_mask_done;
+
/*
 * This particular version of the IPI hypercall can
 * only target upto 64 CPUs.
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 4c431e1c1eff..04159893702e 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -265,7 +265,7 @@ void __init hyperv_init(void)
 {
u64 guest_id, required_msrs;
union hv_x64_msr_hypercall_contents hypercall_msr;
-   int cpuhp;
+   int cpuhp, i;
 
if (x86_hyper_type != X86_HYPER_MS_HYPERV)
return;
@@ -293,6 +293,9 @@ void __init hyperv_init(void)
if (!hv_vp_index)
return;
 
+   for (i = 0; i < num_possible_cpus(); i++)
+   hv_vp_index[i] = -1;
+
hv_vp_assist_page = kcalloc(num_possible_cpus(),
sizeof(*hv_vp_assist_page), GFP_KERNEL);
if (!hv_vp_assist_page) {
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 3cd14311edfa..dee3f7347253 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -281,6 +281,8 @@ static inline int cpumask_to_vpset(struct hv_vpset *vpset,
 */
for_each_cpu(cpu, cpus) {
vcpu = hv_cpu_number_to_vp_number(cpu);
+   if (vcpu == -1)
+   return -1;
vcpu_bank = vcpu / 64;
vcpu_offset = vcpu % 64;
__set_bit(vcpu_offset, (unsigned long *)


[tip:x86/urgent] x86/hyper-v: Fix the circular dependency in IPI enlightenment

2018-07-04 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  5e6f19db2deca9e7eaa378447c77616b35693399
Gitweb: https://git.kernel.org/tip/5e6f19db2deca9e7eaa378447c77616b35693399
Author: K. Y. Srinivasan 
AuthorDate: Tue, 3 Jul 2018 16:01:55 -0700
Committer:  Ingo Molnar 
CommitDate: Wed, 4 Jul 2018 10:50:03 +0200

x86/hyper-v: Fix the circular dependency in IPI enlightenment

The IPI hypercalls depend on being able to map the Linux notion of CPU ID
to the hypervisor's notion of the CPU ID. The array hv_vp_index[] provides
this mapping. Code for populating this array depends on the IPI functionality.
Break this circular dependency.

Tested-by: Michael Kelley 
Signed-off-by: K. Y. Srinivasan 
Acked-by: Thomas Gleixner 
Cc: Linus Torvalds 
Cc: michael.h.kel...@microsoft.com
Cc: Peter Zijlstra 
Cc: a...@canonical.com
Cc: de...@linuxdriverproject.org
Cc: gre...@linuxfoundation.org
Cc: jasow...@redhat.com
Cc: o...@aepfle.de
Cc: sthem...@microsoft.com
Cc: vkuzn...@redhat.com
Fixes: 68bb7bfb7985 ("X86/Hyper-V: Enable IPI enlightenments")
Link: http://lkml.kernel.org/r/20180703230155.15160-1-...@linuxonhyperv.com
Signed-off-by: Ingo Molnar 
---
 arch/x86/hyperv/hv_apic.c   | 5 +
 arch/x86/hyperv/hv_init.c   | 5 -
 arch/x86/include/asm/mshyperv.h | 2 ++
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c
index f68855499391..63d7c196739f 100644
--- a/arch/x86/hyperv/hv_apic.c
+++ b/arch/x86/hyperv/hv_apic.c
@@ -114,6 +114,8 @@ static bool __send_ipi_mask_ex(const struct cpumask *mask, 
int vector)
ipi_arg->vp_set.format = HV_GENERIC_SET_SPARSE_4K;
nr_bank = cpumask_to_vpset(&(ipi_arg->vp_set), mask);
}
+   if (nr_bank == -1)
+   goto ipi_mask_ex_done;
if (!nr_bank)
ipi_arg->vp_set.format = HV_GENERIC_SET_ALL;
 
@@ -158,6 +160,9 @@ static bool __send_ipi_mask(const struct cpumask *mask, int 
vector)
 
for_each_cpu(cur_cpu, mask) {
vcpu = hv_cpu_number_to_vp_number(cur_cpu);
+   if (vcpu == -1)
+   goto ipi_mask_done;
+
/*
 * This particular version of the IPI hypercall can
 * only target upto 64 CPUs.
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 4c431e1c1eff..04159893702e 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -265,7 +265,7 @@ void __init hyperv_init(void)
 {
u64 guest_id, required_msrs;
union hv_x64_msr_hypercall_contents hypercall_msr;
-   int cpuhp;
+   int cpuhp, i;
 
if (x86_hyper_type != X86_HYPER_MS_HYPERV)
return;
@@ -293,6 +293,9 @@ void __init hyperv_init(void)
if (!hv_vp_index)
return;
 
+   for (i = 0; i < num_possible_cpus(); i++)
+   hv_vp_index[i] = -1;
+
hv_vp_assist_page = kcalloc(num_possible_cpus(),
sizeof(*hv_vp_assist_page), GFP_KERNEL);
if (!hv_vp_assist_page) {
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 3cd14311edfa..dee3f7347253 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -281,6 +281,8 @@ static inline int cpumask_to_vpset(struct hv_vpset *vpset,
 */
for_each_cpu(cpu, cpus) {
vcpu = hv_cpu_number_to_vp_number(cpu);
+   if (vcpu == -1)
+   return -1;
vcpu_bank = vcpu / 64;
vcpu_offset = vcpu % 64;
__set_bit(vcpu_offset, (unsigned long *)


[tip:x86/hyperv] X86/Hyper-V: Consolidate the allocation of the hypercall input page

2018-05-19 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  9a2d78e291a7dea0ae4b4a06ce6bbbe4f1ab7c13
Gitweb: https://git.kernel.org/tip/9a2d78e291a7dea0ae4b4a06ce6bbbe4f1ab7c13
Author: K. Y. Srinivasan 
AuthorDate: Wed, 16 May 2018 14:53:34 -0700
Committer:  Thomas Gleixner 
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.

Signed-off-by: K. Y. Srinivasan 
Signed-off-by: Thomas Gleixner 
Reviewed-by: Michael Kelley 
Cc: o...@aepfle.de
Cc: sthem...@microsoft.com
Cc: gre...@linuxfoundation.org
Cc: jasow...@redhat.com
Cc: michael.h.kel...@microsoft.com
Cc: h...@zytor.com
Cc: a...@canonical.com
Cc: de...@linuxdriverproject.org
Cc: vkuzn...@redhat.com
Link: https://lkml.kernel.org/r/20180516215334.6547-5-...@linuxonhyperv.com

---
 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);


[tip:x86/hyperv] X86/Hyper-V: Consolidate the allocation of the hypercall input page

2018-05-19 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  9a2d78e291a7dea0ae4b4a06ce6bbbe4f1ab7c13
Gitweb: https://git.kernel.org/tip/9a2d78e291a7dea0ae4b4a06ce6bbbe4f1ab7c13
Author: K. Y. Srinivasan 
AuthorDate: Wed, 16 May 2018 14:53:34 -0700
Committer:  Thomas Gleixner 
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.

Signed-off-by: K. Y. Srinivasan 
Signed-off-by: Thomas Gleixner 
Reviewed-by: Michael Kelley 
Cc: o...@aepfle.de
Cc: sthem...@microsoft.com
Cc: gre...@linuxfoundation.org
Cc: jasow...@redhat.com
Cc: michael.h.kel...@microsoft.com
Cc: h...@zytor.com
Cc: a...@canonical.com
Cc: de...@linuxdriverproject.org
Cc: vkuzn...@redhat.com
Link: https://lkml.kernel.org/r/20180516215334.6547-5-...@linuxonhyperv.com

---
 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);


[tip:x86/hyperv] X86/Hyper-V: Consolidate code for converting cpumask to vpset

2018-05-19 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  800b8f03fdc8d66885ff03de531285526a4ca0d4
Gitweb: https://git.kernel.org/tip/800b8f03fdc8d66885ff03de531285526a4ca0d4
Author: K. Y. Srinivasan 
AuthorDate: Wed, 16 May 2018 14:53:33 -0700
Committer:  Thomas Gleixner 
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.

Signed-off-by: K. Y. Srinivasan 
Signed-off-by: Thomas Gleixner 
Reviewed-by: Michael Kelley 
Cc: o...@aepfle.de
Cc: sthem...@microsoft.com
Cc: gre...@linuxfoundation.org
Cc: jasow...@redhat.com
Cc: michael.h.kel...@microsoft.com
Cc: h...@zytor.com
Cc: a...@canonical.com
Cc: de...@linuxdriverproject.org
Cc: vkuzn...@redhat.com
Link: https://lkml.kernel.org/r/20180516215334.6547-4-...@linuxonhyperv.com

---
 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 *)
- >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) {


[tip:x86/hyperv] X86/Hyper-V: Consolidate code for converting cpumask to vpset

2018-05-19 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  800b8f03fdc8d66885ff03de531285526a4ca0d4
Gitweb: https://git.kernel.org/tip/800b8f03fdc8d66885ff03de531285526a4ca0d4
Author: K. Y. Srinivasan 
AuthorDate: Wed, 16 May 2018 14:53:33 -0700
Committer:  Thomas Gleixner 
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.

Signed-off-by: K. Y. Srinivasan 
Signed-off-by: Thomas Gleixner 
Reviewed-by: Michael Kelley 
Cc: o...@aepfle.de
Cc: sthem...@microsoft.com
Cc: gre...@linuxfoundation.org
Cc: jasow...@redhat.com
Cc: michael.h.kel...@microsoft.com
Cc: h...@zytor.com
Cc: a...@canonical.com
Cc: de...@linuxdriverproject.org
Cc: vkuzn...@redhat.com
Link: https://lkml.kernel.org/r/20180516215334.6547-4-...@linuxonhyperv.com

---
 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 *)
- >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) {


[tip:x86/hyperv] X86/Hyper-V: Enable IPI enlightenments

2018-05-19 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  68bb7bfb7985df2bd15c2dc975cb68b7a901488a
Gitweb: https://git.kernel.org/tip/68bb7bfb7985df2bd15c2dc975cb68b7a901488a
Author: K. Y. Srinivasan 
AuthorDate: Wed, 16 May 2018 14:53:31 -0700
Committer:  Thomas Gleixner 
CommitDate: Sat, 19 May 2018 13:23:17 +0200

X86/Hyper-V: Enable IPI enlightenments

Hyper-V supports hypercalls to implement IPI; use them.

Signed-off-by: K. Y. Srinivasan 
Signed-off-by: Thomas Gleixner 
Reviewed-by: Michael Kelley 
Cc: o...@aepfle.de
Cc: sthem...@microsoft.com
Cc: gre...@linuxfoundation.org
Cc: jasow...@redhat.com
Cc: michael.h.kel...@microsoft.com
Cc: h...@zytor.com
Cc: a...@canonical.com
Cc: de...@linuxdriverproject.org
Cc: vkuzn...@redhat.com
Link: https://lkml.kernel.org/r/20180516215334.6547-2-...@linuxonhyperv.com

---
 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(+)

diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c
index ca20e31d311c..3e0de61f1a7c 100644
--- a/arch/x86/hyperv/hv_apic.c
+++ b/arch/x86/hyperv/hv_apic.c
@@ -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 *)_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, );
+   return __send_ipi_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(_mask, mask);
+   cpumask_clear_cpu(this_cpu, _mask);
+   local_mask = _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;
+   }
+

[tip:x86/hyperv] X86/Hyper-V: Enhanced IPI enlightenment

2018-05-19 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  366f03b0cf90ef55f063d4a54cf62b0ac9b6da9d
Gitweb: https://git.kernel.org/tip/366f03b0cf90ef55f063d4a54cf62b0ac9b6da9d
Author: K. Y. Srinivasan 
AuthorDate: Wed, 16 May 2018 14:53:32 -0700
Committer:  Thomas Gleixner 
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).

Signed-off-by: K. Y. Srinivasan 
Signed-off-by: Thomas Gleixner 
Reviewed-by: Michael Kelley 
Cc: o...@aepfle.de
Cc: sthem...@microsoft.com
Cc: gre...@linuxfoundation.org
Cc: jasow...@redhat.com
Cc: michael.h.kel...@microsoft.com
Cc: h...@zytor.com
Cc: a...@canonical.com
Cc: de...@linuxdriverproject.org
Cc: vkuzn...@redhat.com
Link: https://lkml.kernel.org/r/20180516215334.6547-3-...@linuxonhyperv.com

---
 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 3e0de61f1a7c..192b6ad6a361 100644
--- a/arch/x86/hyperv/hv_apic.c
+++ b/arch/x86/hyperv/hv_apic.c
@@ -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.
 */
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_IPI0x000b
 #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_MESSAGE0x005c
 #define HVCALL_SIGNAL_EVENT0x005d
 
@@ -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,

[tip:x86/hyperv] X86/Hyper-V: Enable IPI enlightenments

2018-05-19 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  68bb7bfb7985df2bd15c2dc975cb68b7a901488a
Gitweb: https://git.kernel.org/tip/68bb7bfb7985df2bd15c2dc975cb68b7a901488a
Author: K. Y. Srinivasan 
AuthorDate: Wed, 16 May 2018 14:53:31 -0700
Committer:  Thomas Gleixner 
CommitDate: Sat, 19 May 2018 13:23:17 +0200

X86/Hyper-V: Enable IPI enlightenments

Hyper-V supports hypercalls to implement IPI; use them.

Signed-off-by: K. Y. Srinivasan 
Signed-off-by: Thomas Gleixner 
Reviewed-by: Michael Kelley 
Cc: o...@aepfle.de
Cc: sthem...@microsoft.com
Cc: gre...@linuxfoundation.org
Cc: jasow...@redhat.com
Cc: michael.h.kel...@microsoft.com
Cc: h...@zytor.com
Cc: a...@canonical.com
Cc: de...@linuxdriverproject.org
Cc: vkuzn...@redhat.com
Link: https://lkml.kernel.org/r/20180516215334.6547-2-...@linuxonhyperv.com

---
 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(+)

diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c
index ca20e31d311c..3e0de61f1a7c 100644
--- a/arch/x86/hyperv/hv_apic.c
+++ b/arch/x86/hyperv/hv_apic.c
@@ -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 *)_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, );
+   return __send_ipi_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(_mask, mask);
+   cpumask_clear_cpu(this_cpu, _mask);
+   local_mask = _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 

[tip:x86/hyperv] X86/Hyper-V: Enhanced IPI enlightenment

2018-05-19 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  366f03b0cf90ef55f063d4a54cf62b0ac9b6da9d
Gitweb: https://git.kernel.org/tip/366f03b0cf90ef55f063d4a54cf62b0ac9b6da9d
Author: K. Y. Srinivasan 
AuthorDate: Wed, 16 May 2018 14:53:32 -0700
Committer:  Thomas Gleixner 
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).

Signed-off-by: K. Y. Srinivasan 
Signed-off-by: Thomas Gleixner 
Reviewed-by: Michael Kelley 
Cc: o...@aepfle.de
Cc: sthem...@microsoft.com
Cc: gre...@linuxfoundation.org
Cc: jasow...@redhat.com
Cc: michael.h.kel...@microsoft.com
Cc: h...@zytor.com
Cc: a...@canonical.com
Cc: de...@linuxdriverproject.org
Cc: vkuzn...@redhat.com
Link: https://lkml.kernel.org/r/20180516215334.6547-3-...@linuxonhyperv.com

---
 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 3e0de61f1a7c..192b6ad6a361 100644
--- a/arch/x86/hyperv/hv_apic.c
+++ b/arch/x86/hyperv/hv_apic.c
@@ -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.
 */
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_IPI0x000b
 #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_MESSAGE0x005c
 #define HVCALL_SIGNAL_EVENT0x005d
 
@@ -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 {
+

[tip:x86/hyperv] X86/Hyper-V: Enlighten APIC access

2018-05-19 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  6b48cb5f8347bc0153ff1d7b075db92e6723ffdb
Gitweb: https://git.kernel.org/tip/6b48cb5f8347bc0153ff1d7b075db92e6723ffdb
Author: K. Y. Srinivasan 
AuthorDate: Wed, 16 May 2018 14:53:30 -0700
Committer:  Thomas Gleixner 
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.

Signed-off-by: K. Y. Srinivasan 
Signed-off-by: Thomas Gleixner 
Reviewed-by: Michael Kelley 
Cc: o...@aepfle.de
Cc: sthem...@microsoft.com
Cc: gre...@linuxfoundation.org
Cc: jasow...@redhat.com
Cc: michael.h.kel...@microsoft.com
Cc: h...@zytor.com
Cc: a...@canonical.com
Cc: de...@linuxdriverproject.org
Cc: vkuzn...@redhat.com
Link: https://lkml.kernel.org/r/20180516215334.6547-1-...@linuxonhyperv.com

---
 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(-)

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 ..ca20e31d311c
--- /dev/null
+++ b/arch/x86/hyperv/hv_apic.c
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Hyper-V specific APIC code.
+ *
+ * Copyright (C) 2018, Microsoft, Inc.
+ *
+ * Author : K. Y. Srinivasan 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifdef CONFIG_X86_64
+#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 */
+#endif /* CONFIG_X86_64 */
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
+++ 

[tip:x86/hyperv] X86/Hyper-V: Enlighten APIC access

2018-05-19 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  6b48cb5f8347bc0153ff1d7b075db92e6723ffdb
Gitweb: https://git.kernel.org/tip/6b48cb5f8347bc0153ff1d7b075db92e6723ffdb
Author: K. Y. Srinivasan 
AuthorDate: Wed, 16 May 2018 14:53:30 -0700
Committer:  Thomas Gleixner 
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.

Signed-off-by: K. Y. Srinivasan 
Signed-off-by: Thomas Gleixner 
Reviewed-by: Michael Kelley 
Cc: o...@aepfle.de
Cc: sthem...@microsoft.com
Cc: gre...@linuxfoundation.org
Cc: jasow...@redhat.com
Cc: michael.h.kel...@microsoft.com
Cc: h...@zytor.com
Cc: a...@canonical.com
Cc: de...@linuxdriverproject.org
Cc: vkuzn...@redhat.com
Link: https://lkml.kernel.org/r/20180516215334.6547-1-...@linuxonhyperv.com

---
 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(-)

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 ..ca20e31d311c
--- /dev/null
+++ b/arch/x86/hyperv/hv_apic.c
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Hyper-V specific APIC code.
+ *
+ * Copyright (C) 2018, Microsoft, Inc.
+ *
+ * Author : K. Y. Srinivasan 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifdef CONFIG_X86_64
+#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 */
+#endif /* CONFIG_X86_64 */
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 

[tip:x86/urgent] x86/hyper-V: Allocate the IDT entry early in boot

2017-09-13 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  213ff44ae4eb5224010166db2f851e4eea068268
Gitweb: http://git.kernel.org/tip/213ff44ae4eb5224010166db2f851e4eea068268
Author: K. Y. Srinivasan 
AuthorDate: Fri, 8 Sep 2017 16:15:57 -0700
Committer:  Ingo Molnar 
CommitDate: Wed, 13 Sep 2017 11:02:26 +0200

x86/hyper-V: Allocate the IDT entry early in boot

Allocate the hypervisor callback IDT entry early in the boot sequence.

The previous code would allocate the entry as part of registering the handler
when the vmbus driver loaded, and this caused a problem for the IDT cleanup
that Thomas is working on for v4.15.

Signed-off-by: K. Y. Srinivasan 
Cc: Linus Torvalds 
Cc: Peter Zijlstra 
Cc: Thomas Gleixner 
Cc: a...@canonical.com
Cc: de...@linuxdriverproject.org
Cc: gre...@linuxfoundation.org
Cc: jasow...@redhat.com
Cc: o...@aepfle.de
Link: http://lkml.kernel.org/r/20170908231557.2419-1-...@exchange.microsoft.com
Signed-off-by: Ingo Molnar 
---
 arch/x86/kernel/cpu/mshyperv.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 3b3f713..236324e8 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -59,8 +59,6 @@ void hyperv_vector_handler(struct pt_regs *regs)
 void hv_setup_vmbus_irq(void (*handler)(void))
 {
vmbus_handler = handler;
-   /* Setup the IDT for hypervisor callback */
-   alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector);
 }
 
 void hv_remove_vmbus_irq(void)
@@ -251,6 +249,8 @@ static void __init ms_hyperv_init_platform(void)
 */
x86_platform.apic_post_init = hyperv_init;
hyperv_setup_mmu_ops();
+   /* Setup the IDT for hypervisor callback */
+   alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector);
 #endif
 }
 


[tip:x86/urgent] x86/hyper-V: Allocate the IDT entry early in boot

2017-09-13 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  213ff44ae4eb5224010166db2f851e4eea068268
Gitweb: http://git.kernel.org/tip/213ff44ae4eb5224010166db2f851e4eea068268
Author: K. Y. Srinivasan 
AuthorDate: Fri, 8 Sep 2017 16:15:57 -0700
Committer:  Ingo Molnar 
CommitDate: Wed, 13 Sep 2017 11:02:26 +0200

x86/hyper-V: Allocate the IDT entry early in boot

Allocate the hypervisor callback IDT entry early in the boot sequence.

The previous code would allocate the entry as part of registering the handler
when the vmbus driver loaded, and this caused a problem for the IDT cleanup
that Thomas is working on for v4.15.

Signed-off-by: K. Y. Srinivasan 
Cc: Linus Torvalds 
Cc: Peter Zijlstra 
Cc: Thomas Gleixner 
Cc: a...@canonical.com
Cc: de...@linuxdriverproject.org
Cc: gre...@linuxfoundation.org
Cc: jasow...@redhat.com
Cc: o...@aepfle.de
Link: http://lkml.kernel.org/r/20170908231557.2419-1-...@exchange.microsoft.com
Signed-off-by: Ingo Molnar 
---
 arch/x86/kernel/cpu/mshyperv.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 3b3f713..236324e8 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -59,8 +59,6 @@ void hyperv_vector_handler(struct pt_regs *regs)
 void hv_setup_vmbus_irq(void (*handler)(void))
 {
vmbus_handler = handler;
-   /* Setup the IDT for hypervisor callback */
-   alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector);
 }
 
 void hv_remove_vmbus_irq(void)
@@ -251,6 +249,8 @@ static void __init ms_hyperv_init_platform(void)
 */
x86_platform.apic_post_init = hyperv_init;
hyperv_setup_mmu_ops();
+   /* Setup the IDT for hypervisor callback */
+   alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector);
 #endif
 }
 


[tip:x86/urgent] x86, hyperv: Mark the Hyper-V clocksource as being continuous

2015-01-20 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  32c6590d126836a062b3140ed52d898507987017
Gitweb: http://git.kernel.org/tip/32c6590d126836a062b3140ed52d898507987017
Author: K. Y. Srinivasan 
AuthorDate: Mon, 12 Jan 2015 16:26:02 -0800
Committer:  Thomas Gleixner 
CommitDate: Tue, 20 Jan 2015 14:36:25 +0100

x86, hyperv: Mark the Hyper-V clocksource as being continuous

The Hyper-V clocksource is continuous; mark it accordingly.

Signed-off-by: K. Y. Srinivasan 
Acked-by: jasow...@redhat.com
Cc: gre...@linuxfoundation.org
Cc: de...@linuxdriverproject.org
Cc: o...@aepfle.de
Cc: a...@canonical.com
Cc: sta...@vger.kernel.org
Link: 
http://lkml.kernel.org/r/1421108762-3331-1-git-send-email-...@microsoft.com
Signed-off-by: Thomas Gleixner 
---
 arch/x86/kernel/cpu/mshyperv.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index a450373..939155f 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -107,6 +107,7 @@ static struct clocksource hyperv_cs = {
.rating = 400, /* use this when running on Hyperv*/
.read   = read_hv_clock,
.mask   = CLOCKSOURCE_MASK(64),
+   .flags  = CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
 static void __init ms_hyperv_init_platform(void)
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[tip:x86/urgent] x86, hyperv: Mark the Hyper-V clocksource as being continuous

2015-01-20 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  32c6590d126836a062b3140ed52d898507987017
Gitweb: http://git.kernel.org/tip/32c6590d126836a062b3140ed52d898507987017
Author: K. Y. Srinivasan k...@microsoft.com
AuthorDate: Mon, 12 Jan 2015 16:26:02 -0800
Committer:  Thomas Gleixner t...@linutronix.de
CommitDate: Tue, 20 Jan 2015 14:36:25 +0100

x86, hyperv: Mark the Hyper-V clocksource as being continuous

The Hyper-V clocksource is continuous; mark it accordingly.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Acked-by: jasow...@redhat.com
Cc: gre...@linuxfoundation.org
Cc: de...@linuxdriverproject.org
Cc: o...@aepfle.de
Cc: a...@canonical.com
Cc: sta...@vger.kernel.org
Link: 
http://lkml.kernel.org/r/1421108762-3331-1-git-send-email-...@microsoft.com
Signed-off-by: Thomas Gleixner t...@linutronix.de
---
 arch/x86/kernel/cpu/mshyperv.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index a450373..939155f 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -107,6 +107,7 @@ static struct clocksource hyperv_cs = {
.rating = 400, /* use this when running on Hyperv*/
.read   = read_hv_clock,
.mask   = CLOCKSOURCE_MASK(64),
+   .flags  = CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
 static void __init ms_hyperv_init_platform(void)
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[tip:x86/irq] x86, irq, pic: Probe for legacy PIC and set legacy_pic appropriately

2014-04-14 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  e179f6914152eca9b338e7d8445684062f560c55
Gitweb: http://git.kernel.org/tip/e179f6914152eca9b338e7d8445684062f560c55
Author: K. Y. Srinivasan 
AuthorDate: Mon, 14 Apr 2014 11:43:49 -0700
Committer:  H. Peter Anvin 
CommitDate: Mon, 14 Apr 2014 11:49:55 -0700

x86, irq, pic: Probe for legacy PIC and set legacy_pic appropriately

The legacy PIC may or may not be available and we need a mechanism to
detect the existence of the legacy PIC that is applicable for all
hardware (both physical as well as virtual) currently supported by
Linux.

On Hyper-V, when our legacy firmware presented to the guests, emulates
the legacy PIC while when our EFI based firmware is presented we do
not emulate the PIC. To support Hyper-V EFI firmware, we had to set
the legacy_pic to the null_legacy_pic since we had to bypass PIC based
calibration in the early boot code. While, on the EFI firmware, we
know we don't emulate the legacy PIC, we need a generic mechanism to
detect the presence of the legacy PIC that is not based on boot time
state - this became apparent when we tried to get kexec to work on
Hyper-V EFI firmware.

This patch implements the proposal put forth by H. Peter Anvin
: Write a known value to the PIC data port and
read it back. If the value read is the value written, we do have the
PIC, if not there is no PIC and we can safely set the legacy_pic to
null_legacy_pic. Since the read from an unconnected I/O port returns
0xff, we will use ~(1 << PIC_CASCADE_IR) (0xfb: mask all lines except
the cascade line) to probe for the existence of the PIC.

In version V1 of the patch, I had cleaned up the code based on comments from 
Peter.
In version V2 of the patch, I have addressed additional comments from Peter.
In version V3 of the patch, I have addressed Jan's comments (jbeul...@suse.com).
In version V4 of the patch, I have addressed additional comments from Peter.

Signed-off-by: K. Y. Srinivasan 
Link: 
http://lkml.kernel.org/r/1397501029-29286-1-git-send-email-...@microsoft.com
Cc: Thomas Gleixner 
Signed-off-by: H. Peter Anvin 
---
 arch/x86/kernel/cpu/mshyperv.c |  9 -
 arch/x86/kernel/i8259.c| 20 +++-
 2 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 76f98fe..a450373 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -132,15 +132,6 @@ static void __init ms_hyperv_init_platform(void)
lapic_timer_frequency = hv_lapic_frequency;
printk(KERN_INFO "HyperV: LAPIC Timer Frequency: %#x\n",
lapic_timer_frequency);
-
-   /*
-* On Hyper-V, when we are booting off an EFI firmware stack,
-* we do not have many legacy devices including PIC, PIT etc.
-*/
-   if (efi_enabled(EFI_BOOT)) {
-   printk(KERN_INFO "HyperV: Using null_legacy_pic\n");
-   legacy_pic = _legacy_pic;
-   }
}
 #endif
 
diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c
index 2e977b5..8af8171 100644
--- a/arch/x86/kernel/i8259.c
+++ b/arch/x86/kernel/i8259.c
@@ -299,13 +299,31 @@ static void unmask_8259A(void)
 static void init_8259A(int auto_eoi)
 {
unsigned long flags;
+   unsigned char probe_val = ~(1 << PIC_CASCADE_IR);
+   unsigned char new_val;
 
i8259A_auto_eoi = auto_eoi;
 
raw_spin_lock_irqsave(_lock, flags);
 
-   outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */
+   /*
+* Check to see if we have a PIC.
+* Mask all except the cascade and read
+* back the value we just wrote. If we don't
+* have a PIC, we will read 0xff as opposed to the
+* value we wrote.
+*/
outb(0xff, PIC_SLAVE_IMR);  /* mask all of 8259A-2 */
+   outb(probe_val, PIC_MASTER_IMR);
+   new_val = inb(PIC_MASTER_IMR);
+   if (new_val != probe_val) {
+   printk(KERN_INFO "Using NULL legacy PIC\n");
+   legacy_pic = _legacy_pic;
+   raw_spin_unlock_irqrestore(_lock, flags);
+   return;
+   }
+
+   outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */
 
/*
 * outb_pic - this has to work on a wide range of PC hardware.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[tip:x86/irq] x86, irq, pic: Probe for legacy PIC and set legacy_pic appropriately

2014-04-14 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  e179f6914152eca9b338e7d8445684062f560c55
Gitweb: http://git.kernel.org/tip/e179f6914152eca9b338e7d8445684062f560c55
Author: K. Y. Srinivasan k...@microsoft.com
AuthorDate: Mon, 14 Apr 2014 11:43:49 -0700
Committer:  H. Peter Anvin h...@linux.intel.com
CommitDate: Mon, 14 Apr 2014 11:49:55 -0700

x86, irq, pic: Probe for legacy PIC and set legacy_pic appropriately

The legacy PIC may or may not be available and we need a mechanism to
detect the existence of the legacy PIC that is applicable for all
hardware (both physical as well as virtual) currently supported by
Linux.

On Hyper-V, when our legacy firmware presented to the guests, emulates
the legacy PIC while when our EFI based firmware is presented we do
not emulate the PIC. To support Hyper-V EFI firmware, we had to set
the legacy_pic to the null_legacy_pic since we had to bypass PIC based
calibration in the early boot code. While, on the EFI firmware, we
know we don't emulate the legacy PIC, we need a generic mechanism to
detect the presence of the legacy PIC that is not based on boot time
state - this became apparent when we tried to get kexec to work on
Hyper-V EFI firmware.

This patch implements the proposal put forth by H. Peter Anvin
h...@linux.intel.com: Write a known value to the PIC data port and
read it back. If the value read is the value written, we do have the
PIC, if not there is no PIC and we can safely set the legacy_pic to
null_legacy_pic. Since the read from an unconnected I/O port returns
0xff, we will use ~(1  PIC_CASCADE_IR) (0xfb: mask all lines except
the cascade line) to probe for the existence of the PIC.

In version V1 of the patch, I had cleaned up the code based on comments from 
Peter.
In version V2 of the patch, I have addressed additional comments from Peter.
In version V3 of the patch, I have addressed Jan's comments (jbeul...@suse.com).
In version V4 of the patch, I have addressed additional comments from Peter.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Link: 
http://lkml.kernel.org/r/1397501029-29286-1-git-send-email-...@microsoft.com
Cc: Thomas Gleixner t...@linutronix.de
Signed-off-by: H. Peter Anvin h...@linux.intel.com
---
 arch/x86/kernel/cpu/mshyperv.c |  9 -
 arch/x86/kernel/i8259.c| 20 +++-
 2 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 76f98fe..a450373 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -132,15 +132,6 @@ static void __init ms_hyperv_init_platform(void)
lapic_timer_frequency = hv_lapic_frequency;
printk(KERN_INFO HyperV: LAPIC Timer Frequency: %#x\n,
lapic_timer_frequency);
-
-   /*
-* On Hyper-V, when we are booting off an EFI firmware stack,
-* we do not have many legacy devices including PIC, PIT etc.
-*/
-   if (efi_enabled(EFI_BOOT)) {
-   printk(KERN_INFO HyperV: Using null_legacy_pic\n);
-   legacy_pic = null_legacy_pic;
-   }
}
 #endif
 
diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c
index 2e977b5..8af8171 100644
--- a/arch/x86/kernel/i8259.c
+++ b/arch/x86/kernel/i8259.c
@@ -299,13 +299,31 @@ static void unmask_8259A(void)
 static void init_8259A(int auto_eoi)
 {
unsigned long flags;
+   unsigned char probe_val = ~(1  PIC_CASCADE_IR);
+   unsigned char new_val;
 
i8259A_auto_eoi = auto_eoi;
 
raw_spin_lock_irqsave(i8259A_lock, flags);
 
-   outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */
+   /*
+* Check to see if we have a PIC.
+* Mask all except the cascade and read
+* back the value we just wrote. If we don't
+* have a PIC, we will read 0xff as opposed to the
+* value we wrote.
+*/
outb(0xff, PIC_SLAVE_IMR);  /* mask all of 8259A-2 */
+   outb(probe_val, PIC_MASTER_IMR);
+   new_val = inb(PIC_MASTER_IMR);
+   if (new_val != probe_val) {
+   printk(KERN_INFO Using NULL legacy PIC\n);
+   legacy_pic = null_legacy_pic;
+   raw_spin_unlock_irqrestore(i8259A_lock, flags);
+   return;
+   }
+
+   outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */
 
/*
 * outb_pic - this has to work on a wide range of PC hardware.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[tip:x86/hyperv] x86, hyperv: When on Hyper-v use NULL legacy PIC

2014-04-03 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  8df28b82ff0649dd293f0469b97792cfb9ed10ab
Gitweb: http://git.kernel.org/tip/8df28b82ff0649dd293f0469b97792cfb9ed10ab
Author: K. Y. Srinivasan 
AuthorDate: Thu, 3 Apr 2014 18:16:33 -0700
Committer:  H. Peter Anvin 
CommitDate: Thu, 3 Apr 2014 22:00:13 -0700

x86, hyperv: When on Hyper-v use NULL legacy PIC

Use the NULL legacy PIC when on Hyper-V. With this change we can support kexec
even when booting on EFI firmware. This patch has been tested on both EFI as
well as non-EFI firmware stacks on Hyper-V.

This patch is required to support kexec on EFI firmware on Hyper-V. Please
apply.

[ hpa: HyperV in EFI mode doesn't include a legacy PIC, and apparently
doesn't stub it out in a meaningful way.  This becomes an issue
after kexec if the second kernel doesn't know it is EFI-booted.
Since HyperV presumably never actually *needs* the legacy PIC, we
can just disable it. ]

Signed-off-by: K. Y. Srinivasan 
Link: 
http://lkml.kernel.org/r/1396574193-12043-1-git-send-email-...@microsoft.com
Cc: [3.13+]
Signed-off-by: H. Peter Anvin 
---
 arch/x86/kernel/cpu/mshyperv.c | 10 ++
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 832d05a..b7d82c7 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -93,14 +93,8 @@ static void __init ms_hyperv_init_platform(void)
printk(KERN_INFO "HyperV: LAPIC Timer Frequency: %#x\n",
lapic_timer_frequency);
 
-   /*
-* On Hyper-V, when we are booting off an EFI firmware stack,
-* we do not have many legacy devices including PIC, PIT etc.
-*/
-   if (efi_enabled(EFI_BOOT)) {
-   printk(KERN_INFO "HyperV: Using null_legacy_pic\n");
-   legacy_pic = _legacy_pic;
-   }
+   printk(KERN_INFO "HyperV: Using null_legacy_pic\n");
+   legacy_pic = _legacy_pic;
}
 #endif
 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[tip:x86/hyperv] x86, hyperv: When on Hyper-v use NULL legacy PIC

2014-04-03 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  8df28b82ff0649dd293f0469b97792cfb9ed10ab
Gitweb: http://git.kernel.org/tip/8df28b82ff0649dd293f0469b97792cfb9ed10ab
Author: K. Y. Srinivasan k...@microsoft.com
AuthorDate: Thu, 3 Apr 2014 18:16:33 -0700
Committer:  H. Peter Anvin h...@linux.intel.com
CommitDate: Thu, 3 Apr 2014 22:00:13 -0700

x86, hyperv: When on Hyper-v use NULL legacy PIC

Use the NULL legacy PIC when on Hyper-V. With this change we can support kexec
even when booting on EFI firmware. This patch has been tested on both EFI as
well as non-EFI firmware stacks on Hyper-V.

This patch is required to support kexec on EFI firmware on Hyper-V. Please
apply.

[ hpa: HyperV in EFI mode doesn't include a legacy PIC, and apparently
doesn't stub it out in a meaningful way.  This becomes an issue
after kexec if the second kernel doesn't know it is EFI-booted.
Since HyperV presumably never actually *needs* the legacy PIC, we
can just disable it. ]

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Link: 
http://lkml.kernel.org/r/1396574193-12043-1-git-send-email-...@microsoft.com
Cc: sta...@vger.kernel.org[3.13+]
Signed-off-by: H. Peter Anvin h...@linux.intel.com
---
 arch/x86/kernel/cpu/mshyperv.c | 10 ++
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 832d05a..b7d82c7 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -93,14 +93,8 @@ static void __init ms_hyperv_init_platform(void)
printk(KERN_INFO HyperV: LAPIC Timer Frequency: %#x\n,
lapic_timer_frequency);
 
-   /*
-* On Hyper-V, when we are booting off an EFI firmware stack,
-* we do not have many legacy devices including PIC, PIT etc.
-*/
-   if (efi_enabled(EFI_BOOT)) {
-   printk(KERN_INFO HyperV: Using null_legacy_pic\n);
-   legacy_pic = null_legacy_pic;
-   }
+   printk(KERN_INFO HyperV: Using null_legacy_pic\n);
+   legacy_pic = null_legacy_pic;
}
 #endif
 
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[tip:x86/urgent] x86/platform/hyperv: Handle VMBUS driver being a module

2014-04-02 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  f704a7d7f1d815621cb4c47f7a94787e1bd7c27c
Gitweb: http://git.kernel.org/tip/f704a7d7f1d815621cb4c47f7a94787e1bd7c27c
Author: K. Y. Srinivasan 
AuthorDate: Tue, 1 Apr 2014 23:51:42 -0700
Committer:  Ingo Molnar 
CommitDate: Wed, 2 Apr 2014 09:49:47 +0200

x86/platform/hyperv: Handle VMBUS driver being a module

Hyper-V VMBUS driver can be a module; handle this case
correctly. Please apply.

Signed-off-by: K. Y. Srinivasan 
Cc: o...@aepfle.de
Cc: a...@canonical.com
Cc: jasow...@redhat.com
Link: 
http://lkml.kernel.org/r/1396421502-23222-1-git-send-email-...@microsoft.com
Signed-off-by: Ingo Molnar 
---
 arch/x86/kernel/irq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 42805fa..283a76a 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -125,7 +125,7 @@ int arch_show_interrupts(struct seq_file *p, int prec)
seq_printf(p, "%10u ", per_cpu(mce_poll_count, j));
seq_printf(p, "  Machine check polls\n");
 #endif
-#if defined(CONFIG_HYPERV) || defined(CONFIG_XEN)
+#if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN)
seq_printf(p, "%*s: ", prec, "THR");
for_each_online_cpu(j)
seq_printf(p, "%10u ", irq_stats(j)->irq_hv_callback_count);
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[tip:x86/urgent] x86/platform/hyperv: Handle VMBUS driver being a module

2014-04-02 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  f704a7d7f1d815621cb4c47f7a94787e1bd7c27c
Gitweb: http://git.kernel.org/tip/f704a7d7f1d815621cb4c47f7a94787e1bd7c27c
Author: K. Y. Srinivasan k...@microsoft.com
AuthorDate: Tue, 1 Apr 2014 23:51:42 -0700
Committer:  Ingo Molnar mi...@kernel.org
CommitDate: Wed, 2 Apr 2014 09:49:47 +0200

x86/platform/hyperv: Handle VMBUS driver being a module

Hyper-V VMBUS driver can be a module; handle this case
correctly. Please apply.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Cc: o...@aepfle.de
Cc: a...@canonical.com
Cc: jasow...@redhat.com
Link: 
http://lkml.kernel.org/r/1396421502-23222-1-git-send-email-...@microsoft.com
Signed-off-by: Ingo Molnar mi...@kernel.org
---
 arch/x86/kernel/irq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 42805fa..283a76a 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -125,7 +125,7 @@ int arch_show_interrupts(struct seq_file *p, int prec)
seq_printf(p, %10u , per_cpu(mce_poll_count, j));
seq_printf(p,   Machine check polls\n);
 #endif
-#if defined(CONFIG_HYPERV) || defined(CONFIG_XEN)
+#if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN)
seq_printf(p, %*s: , prec, THR);
for_each_online_cpu(j)
seq_printf(p, %10u , irq_stats(j)-irq_hv_callback_count);
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[tip:x86/hyperv] x86, hyperv: Correctly guard the local APIC calibration code

2013-10-10 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  90ab9d5510932e146a9443bf5a591f95d5b5ada8
Gitweb: http://git.kernel.org/tip/90ab9d5510932e146a9443bf5a591f95d5b5ada8
Author: K. Y. Srinivasan 
AuthorDate: Thu, 10 Oct 2013 15:30:24 -0700
Committer:  H. Peter Anvin 
CommitDate: Thu, 10 Oct 2013 15:21:38 -0700

x86, hyperv: Correctly guard the local APIC calibration code

The code that gets the local APIC timer frequency from the hypervisor
rather depends on there being a local APIC.

Signed-off-by: K. Y. Srinivasan 
Link: 
http://lkml.kernel.org/r/1381444224-3303-1-git-send-email-...@microsoft.com
Signed-off-by: H. Peter Anvin 
---
 arch/x86/kernel/cpu/mshyperv.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 0a490ca..628ff50 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -80,6 +80,7 @@ static void __init ms_hyperv_init_platform(void)
printk(KERN_INFO "HyperV: features 0x%x, hints 0x%x\n",
   ms_hyperv.features, ms_hyperv.hints);
 
+#ifdef CONFIG_X86_LOCAL_APIC
if (ms_hyperv.features & HV_X64_MSR_APIC_FREQUENCY_AVAILABLE) {
/*
 * Get the APIC frequency.
@@ -99,6 +100,7 @@ static void __init ms_hyperv_init_platform(void)
legacy_pic = _legacy_pic;
}
}
+#endif
 
if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE)
clocksource_register_hz(_cs, NSEC_PER_SEC/100);
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[tip:x86/hyperv] x86, hyperv: Get the local APIC timer frequency from the hypervisor

2013-10-10 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  9e7827b5ea4ca93b4d864bc07c0fafb838d496b1
Gitweb: http://git.kernel.org/tip/9e7827b5ea4ca93b4d864bc07c0fafb838d496b1
Author: K. Y. Srinivasan 
AuthorDate: Mon, 30 Sep 2013 17:28:52 +0200
Committer:  H. Peter Anvin 
CommitDate: Thu, 10 Oct 2013 11:44:12 -0700

x86, hyperv: Get the local APIC timer frequency from the hypervisor

Hyper-V supports a mechanism for retrieving the local APIC frequency.
Use this and bypass the calibration code in the kernel . This would
allow us to boot the Linux kernel as a "modern VM" on Hyper-V where
many of the legacy devices (such as PIT) are not emulated.

I would like to thank Olaf Hering , Jan Beulich 
 and
H. Peter Anvin  for their help in this effort.

In this version of the patch, I have addressed Jan's comments.

Signed-off-by: K. Y. Srinivasan 
Link: http://lkml.kernel.org/r/1380554932-9888-1-git-send-email-o...@aepfle.de
Tested-by: Olaf Hering 
Signed-off-by: H. Peter Anvin 
---
 arch/x86/include/uapi/asm/hyperv.h | 19 +++
 arch/x86/kernel/cpu/mshyperv.c | 24 
 2 files changed, 43 insertions(+)

diff --git a/arch/x86/include/uapi/asm/hyperv.h 
b/arch/x86/include/uapi/asm/hyperv.h
index b80420b..b8f1c01 100644
--- a/arch/x86/include/uapi/asm/hyperv.h
+++ b/arch/x86/include/uapi/asm/hyperv.h
@@ -27,6 +27,19 @@
 #define HV_X64_MSR_VP_RUNTIME_AVAILABLE(1 << 0)
 /* Partition Reference Counter (HV_X64_MSR_TIME_REF_COUNT) available*/
 #define HV_X64_MSR_TIME_REF_COUNT_AVAILABLE(1 << 1)
+
+/*
+ * There is a single feature flag that signifies the presence of the MSR
+ * that can be used to retrieve both the local APIC Timer frequency as
+ * well as the TSC frequency.
+ */
+
+/* Local APIC timer frequency MSR (HV_X64_MSR_APIC_FREQUENCY) is available */
+#define HV_X64_MSR_APIC_FREQUENCY_AVAILABLE (1 << 11)
+
+/* TSC frequency MSR (HV_X64_MSR_TSC_FREQUENCY) is available */
+#define HV_X64_MSR_TSC_FREQUENCY_AVAILABLE (1 << 11)
+
 /*
  * Basic SynIC MSRs (HV_X64_MSR_SCONTROL through HV_X64_MSR_EOM
  * and HV_X64_MSR_SINT0 through HV_X64_MSR_SINT15) available
@@ -136,6 +149,12 @@
 /* MSR used to read the per-partition time reference counter */
 #define HV_X64_MSR_TIME_REF_COUNT  0x4020
 
+/* MSR used to retrieve the TSC frequency */
+#define HV_X64_MSR_TSC_FREQUENCY   0x4022
+
+/* MSR used to retrieve the local APIC timer frequency */
+#define HV_X64_MSR_APIC_FREQUENCY  0x4023
+
 /* Define the virtual APIC registers */
 #define HV_X64_MSR_EOI 0x4070
 #define HV_X64_MSR_ICR 0x4071
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 71a39f3..0a490ca 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -23,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 
 
 struct ms_hyperv_info ms_hyperv;
 EXPORT_SYMBOL_GPL(ms_hyperv);
@@ -67,6 +69,8 @@ static struct clocksource hyperv_cs = {
 
 static void __init ms_hyperv_init_platform(void)
 {
+   u64 hv_lapic_frequency;
+
/*
 * Extract the features and hints
 */
@@ -76,6 +80,26 @@ static void __init ms_hyperv_init_platform(void)
printk(KERN_INFO "HyperV: features 0x%x, hints 0x%x\n",
   ms_hyperv.features, ms_hyperv.hints);
 
+   if (ms_hyperv.features & HV_X64_MSR_APIC_FREQUENCY_AVAILABLE) {
+   /*
+* Get the APIC frequency.
+*/
+   rdmsrl(HV_X64_MSR_APIC_FREQUENCY, hv_lapic_frequency);
+   hv_lapic_frequency = div_u64(hv_lapic_frequency, HZ);
+   lapic_timer_frequency = hv_lapic_frequency;
+   printk(KERN_INFO "HyperV: LAPIC Timer Frequency: %#x\n",
+   lapic_timer_frequency);
+
+   /*
+* On Hyper-V, when we are booting off an EFI firmware stack,
+* we do not have many legacy devices including PIC, PIT etc.
+*/
+   if (efi_enabled(EFI_BOOT)) {
+   printk(KERN_INFO "HyperV: Using null_legacy_pic\n");
+   legacy_pic = _legacy_pic;
+   }
+   }
+
if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE)
clocksource_register_hz(_cs, NSEC_PER_SEC/100);
 }
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[tip:x86/hyperv] x86, hyperv: Get the local APIC timer frequency from the hypervisor

2013-10-10 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  9e7827b5ea4ca93b4d864bc07c0fafb838d496b1
Gitweb: http://git.kernel.org/tip/9e7827b5ea4ca93b4d864bc07c0fafb838d496b1
Author: K. Y. Srinivasan k...@microsoft.com
AuthorDate: Mon, 30 Sep 2013 17:28:52 +0200
Committer:  H. Peter Anvin h...@linux.intel.com
CommitDate: Thu, 10 Oct 2013 11:44:12 -0700

x86, hyperv: Get the local APIC timer frequency from the hypervisor

Hyper-V supports a mechanism for retrieving the local APIC frequency.
Use this and bypass the calibration code in the kernel . This would
allow us to boot the Linux kernel as a modern VM on Hyper-V where
many of the legacy devices (such as PIT) are not emulated.

I would like to thank Olaf Hering o...@aepfle.de, Jan Beulich 
jbeul...@suse.com and
H. Peter Anvin h.peter.an...@intel.com for their help in this effort.

In this version of the patch, I have addressed Jan's comments.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Link: http://lkml.kernel.org/r/1380554932-9888-1-git-send-email-o...@aepfle.de
Tested-by: Olaf Hering o...@aepfle.de
Signed-off-by: H. Peter Anvin h...@linux.intel.com
---
 arch/x86/include/uapi/asm/hyperv.h | 19 +++
 arch/x86/kernel/cpu/mshyperv.c | 24 
 2 files changed, 43 insertions(+)

diff --git a/arch/x86/include/uapi/asm/hyperv.h 
b/arch/x86/include/uapi/asm/hyperv.h
index b80420b..b8f1c01 100644
--- a/arch/x86/include/uapi/asm/hyperv.h
+++ b/arch/x86/include/uapi/asm/hyperv.h
@@ -27,6 +27,19 @@
 #define HV_X64_MSR_VP_RUNTIME_AVAILABLE(1  0)
 /* Partition Reference Counter (HV_X64_MSR_TIME_REF_COUNT) available*/
 #define HV_X64_MSR_TIME_REF_COUNT_AVAILABLE(1  1)
+
+/*
+ * There is a single feature flag that signifies the presence of the MSR
+ * that can be used to retrieve both the local APIC Timer frequency as
+ * well as the TSC frequency.
+ */
+
+/* Local APIC timer frequency MSR (HV_X64_MSR_APIC_FREQUENCY) is available */
+#define HV_X64_MSR_APIC_FREQUENCY_AVAILABLE (1  11)
+
+/* TSC frequency MSR (HV_X64_MSR_TSC_FREQUENCY) is available */
+#define HV_X64_MSR_TSC_FREQUENCY_AVAILABLE (1  11)
+
 /*
  * Basic SynIC MSRs (HV_X64_MSR_SCONTROL through HV_X64_MSR_EOM
  * and HV_X64_MSR_SINT0 through HV_X64_MSR_SINT15) available
@@ -136,6 +149,12 @@
 /* MSR used to read the per-partition time reference counter */
 #define HV_X64_MSR_TIME_REF_COUNT  0x4020
 
+/* MSR used to retrieve the TSC frequency */
+#define HV_X64_MSR_TSC_FREQUENCY   0x4022
+
+/* MSR used to retrieve the local APIC timer frequency */
+#define HV_X64_MSR_APIC_FREQUENCY  0x4023
+
 /* Define the virtual APIC registers */
 #define HV_X64_MSR_EOI 0x4070
 #define HV_X64_MSR_ICR 0x4071
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 71a39f3..0a490ca 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -15,6 +15,7 @@
 #include linux/clocksource.h
 #include linux/module.h
 #include linux/hardirq.h
+#include linux/efi.h
 #include linux/interrupt.h
 #include asm/processor.h
 #include asm/hypervisor.h
@@ -23,6 +24,7 @@
 #include asm/desc.h
 #include asm/idle.h
 #include asm/irq_regs.h
+#include asm/i8259.h
 
 struct ms_hyperv_info ms_hyperv;
 EXPORT_SYMBOL_GPL(ms_hyperv);
@@ -67,6 +69,8 @@ static struct clocksource hyperv_cs = {
 
 static void __init ms_hyperv_init_platform(void)
 {
+   u64 hv_lapic_frequency;
+
/*
 * Extract the features and hints
 */
@@ -76,6 +80,26 @@ static void __init ms_hyperv_init_platform(void)
printk(KERN_INFO HyperV: features 0x%x, hints 0x%x\n,
   ms_hyperv.features, ms_hyperv.hints);
 
+   if (ms_hyperv.features  HV_X64_MSR_APIC_FREQUENCY_AVAILABLE) {
+   /*
+* Get the APIC frequency.
+*/
+   rdmsrl(HV_X64_MSR_APIC_FREQUENCY, hv_lapic_frequency);
+   hv_lapic_frequency = div_u64(hv_lapic_frequency, HZ);
+   lapic_timer_frequency = hv_lapic_frequency;
+   printk(KERN_INFO HyperV: LAPIC Timer Frequency: %#x\n,
+   lapic_timer_frequency);
+
+   /*
+* On Hyper-V, when we are booting off an EFI firmware stack,
+* we do not have many legacy devices including PIC, PIT etc.
+*/
+   if (efi_enabled(EFI_BOOT)) {
+   printk(KERN_INFO HyperV: Using null_legacy_pic\n);
+   legacy_pic = null_legacy_pic;
+   }
+   }
+
if (ms_hyperv.features  HV_X64_MSR_TIME_REF_COUNT_AVAILABLE)
clocksource_register_hz(hyperv_cs, NSEC_PER_SEC/100);
 }
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[tip:x86/hyperv] x86, hyperv: Correctly guard the local APIC calibration code

2013-10-10 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  90ab9d5510932e146a9443bf5a591f95d5b5ada8
Gitweb: http://git.kernel.org/tip/90ab9d5510932e146a9443bf5a591f95d5b5ada8
Author: K. Y. Srinivasan k...@microsoft.com
AuthorDate: Thu, 10 Oct 2013 15:30:24 -0700
Committer:  H. Peter Anvin h...@linux.intel.com
CommitDate: Thu, 10 Oct 2013 15:21:38 -0700

x86, hyperv: Correctly guard the local APIC calibration code

The code that gets the local APIC timer frequency from the hypervisor
rather depends on there being a local APIC.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Link: 
http://lkml.kernel.org/r/1381444224-3303-1-git-send-email-...@microsoft.com
Signed-off-by: H. Peter Anvin h...@linux.intel.com
---
 arch/x86/kernel/cpu/mshyperv.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 0a490ca..628ff50 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -80,6 +80,7 @@ static void __init ms_hyperv_init_platform(void)
printk(KERN_INFO HyperV: features 0x%x, hints 0x%x\n,
   ms_hyperv.features, ms_hyperv.hints);
 
+#ifdef CONFIG_X86_LOCAL_APIC
if (ms_hyperv.features  HV_X64_MSR_APIC_FREQUENCY_AVAILABLE) {
/*
 * Get the APIC frequency.
@@ -99,6 +100,7 @@ static void __init ms_hyperv_init_platform(void)
legacy_pic = null_legacy_pic;
}
}
+#endif
 
if (ms_hyperv.features  HV_X64_MSR_TIME_REF_COUNT_AVAILABLE)
clocksource_register_hz(hyperv_cs, NSEC_PER_SEC/100);
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[tip:x86/urgent] x86, hyperv: Handle Xen emulation of Hyper-V more gracefully

2013-04-18 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  7eff7ded02d1b15ba8321664839b353fa6c0c1e4
Gitweb: http://git.kernel.org/tip/7eff7ded02d1b15ba8321664839b353fa6c0c1e4
Author: K. Y. Srinivasan 
AuthorDate: Thu, 18 Apr 2013 08:44:46 -0700
Committer:  H. Peter Anvin 
CommitDate: Thu, 18 Apr 2013 08:59:20 -0700

x86, hyperv: Handle Xen emulation of Hyper-V more gracefully

Install the Hyper-V specific interrupt handler only when needed. This would
permit us to get rid of the Xen check. Note that when the vmbus drivers invokes
the call to register its handler, we are sure to be running on Hyper-V.

Signed-off-by: K. Y. Srinivasan 
Link: 
http://lkml.kernel.org/r/1366299886-6399-1-git-send-email-...@microsoft.com
Acked-by: Michael S. Tsirkin 
Signed-off-by: H. Peter Anvin 
---
 arch/x86/kernel/cpu/mshyperv.c | 18 +-
 1 file changed, 5 insertions(+), 13 deletions(-)

diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index a7d26d8..8f4be53 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -35,13 +35,6 @@ static bool __init ms_hyperv_platform(void)
if (!boot_cpu_has(X86_FEATURE_HYPERVISOR))
return false;
 
-   /*
-* Xen emulates Hyper-V to support enlightened Windows.
-* Check to see first if we are on a Xen Hypervisor.
-*/
-   if (xen_cpuid_base())
-   return false;
-
cpuid(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS,
  , _signature[0], _signature[1], _signature[2]);
 
@@ -82,12 +75,6 @@ static void __init ms_hyperv_init_platform(void)
 
if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE)
clocksource_register_hz(_cs, NSEC_PER_SEC/100);
-#if IS_ENABLED(CONFIG_HYPERV)
-   /*
-* Setup the IDT for hypervisor callback.
-*/
-   alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector);
-#endif
 }
 
 const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = {
@@ -103,6 +90,11 @@ static irq_handler_t vmbus_isr;
 
 void hv_register_vmbus_handler(int irq, irq_handler_t handler)
 {
+   /*
+* Setup the IDT for hypervisor callback.
+*/
+   alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector);
+
vmbus_irq = irq;
vmbus_isr = handler;
 }
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[tip:x86/urgent] x86, hyperv: Handle Xen emulation of Hyper-V more gracefully

2013-04-18 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  7eff7ded02d1b15ba8321664839b353fa6c0c1e4
Gitweb: http://git.kernel.org/tip/7eff7ded02d1b15ba8321664839b353fa6c0c1e4
Author: K. Y. Srinivasan k...@microsoft.com
AuthorDate: Thu, 18 Apr 2013 08:44:46 -0700
Committer:  H. Peter Anvin h...@linux.intel.com
CommitDate: Thu, 18 Apr 2013 08:59:20 -0700

x86, hyperv: Handle Xen emulation of Hyper-V more gracefully

Install the Hyper-V specific interrupt handler only when needed. This would
permit us to get rid of the Xen check. Note that when the vmbus drivers invokes
the call to register its handler, we are sure to be running on Hyper-V.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Link: 
http://lkml.kernel.org/r/1366299886-6399-1-git-send-email-...@microsoft.com
Acked-by: Michael S. Tsirkin m...@redhat.com
Signed-off-by: H. Peter Anvin h...@linux.intel.com
---
 arch/x86/kernel/cpu/mshyperv.c | 18 +-
 1 file changed, 5 insertions(+), 13 deletions(-)

diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index a7d26d8..8f4be53 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -35,13 +35,6 @@ static bool __init ms_hyperv_platform(void)
if (!boot_cpu_has(X86_FEATURE_HYPERVISOR))
return false;
 
-   /*
-* Xen emulates Hyper-V to support enlightened Windows.
-* Check to see first if we are on a Xen Hypervisor.
-*/
-   if (xen_cpuid_base())
-   return false;
-
cpuid(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS,
  eax, hyp_signature[0], hyp_signature[1], hyp_signature[2]);
 
@@ -82,12 +75,6 @@ static void __init ms_hyperv_init_platform(void)
 
if (ms_hyperv.features  HV_X64_MSR_TIME_REF_COUNT_AVAILABLE)
clocksource_register_hz(hyperv_cs, NSEC_PER_SEC/100);
-#if IS_ENABLED(CONFIG_HYPERV)
-   /*
-* Setup the IDT for hypervisor callback.
-*/
-   alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector);
-#endif
 }
 
 const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = {
@@ -103,6 +90,11 @@ static irq_handler_t vmbus_isr;
 
 void hv_register_vmbus_handler(int irq, irq_handler_t handler)
 {
+   /*
+* Setup the IDT for hypervisor callback.
+*/
+   alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector);
+
vmbus_irq = irq;
vmbus_isr = handler;
 }
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[tip:x86/hyperv] X86: Handle Hyper-V vmbus interrupts as special hypervisor interrupts

2013-02-12 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  bc2b0331e077f576369a2b6c75d15ed4de4ef91f
Gitweb: http://git.kernel.org/tip/bc2b0331e077f576369a2b6c75d15ed4de4ef91f
Author: K. Y. Srinivasan 
AuthorDate: Sun, 3 Feb 2013 17:22:39 -0800
Committer:  H. Peter Anvin 
CommitDate: Tue, 12 Feb 2013 16:27:15 -0800

X86: Handle Hyper-V vmbus interrupts as special hypervisor interrupts

Starting with win8, vmbus interrupts can be delivered on any VCPU in the guest
and furthermore can be concurrently active on multiple VCPUs. Support this
interrupt delivery model by setting up a separate IDT entry for Hyper-V vmbus.
interrupts. I would like to thank Jan Beulich  and
Thomas Gleixner , for their help.

In this version of the patch, based on the feedback, I have merged the IDT
vector for Xen and Hyper-V and made the necessary adjustments. Furhermore,
based on Jan's feedback I have added the necessary compilation switches.

Signed-off-by: K. Y. Srinivasan 
Link: 
http://lkml.kernel.org/r/1359940959-32168-3-git-send-email-...@microsoft.com
Signed-off-by: H. Peter Anvin 
---
 arch/x86/include/asm/irq_vectors.h |  4 ++--
 arch/x86/include/asm/mshyperv.h|  4 
 arch/x86/kernel/cpu/mshyperv.c | 44 ++
 arch/x86/kernel/entry_32.S |  9 +++-
 arch/x86/kernel/entry_64.S |  7 +-
 drivers/xen/events.c   |  7 +++---
 6 files changed, 68 insertions(+), 7 deletions(-)

diff --git a/arch/x86/include/asm/irq_vectors.h 
b/arch/x86/include/asm/irq_vectors.h
index 1508e51..aac5fa6 100644
--- a/arch/x86/include/asm/irq_vectors.h
+++ b/arch/x86/include/asm/irq_vectors.h
@@ -109,8 +109,8 @@
 
 #define UV_BAU_MESSAGE 0xf5
 
-/* Xen vector callback to receive events in a HVM domain */
-#define XEN_HVM_EVTCHN_CALLBACK0xf3
+/* Vector on which hypervisor callbacks will be delivered */
+#define HYPERVISOR_CALLBACK_VECTOR 0xf3
 
 /*
  * Local APIC timer IRQ vector is on a different priority level,
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 79ce568..c2934be 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -11,4 +11,8 @@ struct ms_hyperv_info {
 
 extern struct ms_hyperv_info ms_hyperv;
 
+void hyperv_callback_vector(void);
+void hyperv_vector_handler(struct pt_regs *regs);
+void hv_register_vmbus_handler(int irq, irq_handler_t handler);
+
 #endif
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 4dab317..a7d26d8 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -14,10 +14,15 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 
 struct ms_hyperv_info ms_hyperv;
 EXPORT_SYMBOL_GPL(ms_hyperv);
@@ -77,6 +82,12 @@ static void __init ms_hyperv_init_platform(void)
 
if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE)
clocksource_register_hz(_cs, NSEC_PER_SEC/100);
+#if IS_ENABLED(CONFIG_HYPERV)
+   /*
+* Setup the IDT for hypervisor callback.
+*/
+   alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector);
+#endif
 }
 
 const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = {
@@ -85,3 +96,36 @@ const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = 
{
.init_platform  = ms_hyperv_init_platform,
 };
 EXPORT_SYMBOL(x86_hyper_ms_hyperv);
+
+#if IS_ENABLED(CONFIG_HYPERV)
+static int vmbus_irq = -1;
+static irq_handler_t vmbus_isr;
+
+void hv_register_vmbus_handler(int irq, irq_handler_t handler)
+{
+   vmbus_irq = irq;
+   vmbus_isr = handler;
+}
+
+void hyperv_vector_handler(struct pt_regs *regs)
+{
+   struct pt_regs *old_regs = set_irq_regs(regs);
+   struct irq_desc *desc;
+
+   irq_enter();
+   exit_idle();
+
+   desc = irq_to_desc(vmbus_irq);
+
+   if (desc)
+   generic_handle_irq_desc(vmbus_irq, desc);
+
+   irq_exit();
+   set_irq_regs(old_regs);
+}
+#else
+void hv_register_vmbus_handler(int irq, irq_handler_t handler)
+{
+}
+#endif
+EXPORT_SYMBOL_GPL(hv_register_vmbus_handler);
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index 6ed91d9..8831176 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -1091,11 +1091,18 @@ ENTRY(xen_failsafe_callback)
_ASM_EXTABLE(4b,9b)
 ENDPROC(xen_failsafe_callback)
 
-BUILD_INTERRUPT3(xen_hvm_callback_vector, XEN_HVM_EVTCHN_CALLBACK,
+BUILD_INTERRUPT3(xen_hvm_callback_vector, HYPERVISOR_CALLBACK_VECTOR,
xen_evtchn_do_upcall)
 
 #endif /* CONFIG_XEN */
 
+#if IS_ENABLED(CONFIG_HYPERV)
+
+BUILD_INTERRUPT3(hyperv_callback_vector, HYPERVISOR_CALLBACK_VECTOR,
+   hyperv_vector_handler)
+
+#endif /* CONFIG_HYPERV */
+
 #ifdef CONFIG_FUNCTION_TRACER
 #ifdef CONFIG_DYNAMIC_FTRACE
 
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index cb3c591..048f224 100644
--- 

[tip:x86/hyperv] X86: Add a check to catch Xen emulation of Hyper-V

2013-02-12 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  db34bbb767bdfa1ebed7214b876fe01c5b7ee457
Gitweb: http://git.kernel.org/tip/db34bbb767bdfa1ebed7214b876fe01c5b7ee457
Author: K. Y. Srinivasan 
AuthorDate: Sun, 3 Feb 2013 17:22:38 -0800
Committer:  H. Peter Anvin 
CommitDate: Tue, 12 Feb 2013 16:27:03 -0800

X86: Add a check to catch Xen emulation of Hyper-V

Xen emulates Hyper-V to host enlightened Windows. Looks like this
emulation may be turned on by default even for Linux guests. Check and
fail Hyper-V detection if we are on Xen.

[ hpa: the problem here is that Xen doesn't emulate Hyper-V well
  enough, and if the Xen support isn't compiled in, we end up stubling
  over the Hyper-V emulation and try to activate it -- and it fails. ]

Signed-off-by: K. Y. Srinivasan 
Link: 
http://lkml.kernel.org/r/1359940959-32168-2-git-send-email-...@microsoft.com
Signed-off-by: H. Peter Anvin 
---
 arch/x86/kernel/cpu/mshyperv.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 646d192..4dab317 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -30,6 +30,13 @@ static bool __init ms_hyperv_platform(void)
if (!boot_cpu_has(X86_FEATURE_HYPERVISOR))
return false;
 
+   /*
+* Xen emulates Hyper-V to support enlightened Windows.
+* Check to see first if we are on a Xen Hypervisor.
+*/
+   if (xen_cpuid_base())
+   return false;
+
cpuid(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS,
  , _signature[0], _signature[1], _signature[2]);
 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[tip:x86/hyperv] X86: Add a check to catch Xen emulation of Hyper-V

2013-02-12 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  db34bbb767bdfa1ebed7214b876fe01c5b7ee457
Gitweb: http://git.kernel.org/tip/db34bbb767bdfa1ebed7214b876fe01c5b7ee457
Author: K. Y. Srinivasan k...@microsoft.com
AuthorDate: Sun, 3 Feb 2013 17:22:38 -0800
Committer:  H. Peter Anvin h...@linux.intel.com
CommitDate: Tue, 12 Feb 2013 16:27:03 -0800

X86: Add a check to catch Xen emulation of Hyper-V

Xen emulates Hyper-V to host enlightened Windows. Looks like this
emulation may be turned on by default even for Linux guests. Check and
fail Hyper-V detection if we are on Xen.

[ hpa: the problem here is that Xen doesn't emulate Hyper-V well
  enough, and if the Xen support isn't compiled in, we end up stubling
  over the Hyper-V emulation and try to activate it -- and it fails. ]

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Link: 
http://lkml.kernel.org/r/1359940959-32168-2-git-send-email-...@microsoft.com
Signed-off-by: H. Peter Anvin h...@linux.intel.com
---
 arch/x86/kernel/cpu/mshyperv.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 646d192..4dab317 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -30,6 +30,13 @@ static bool __init ms_hyperv_platform(void)
if (!boot_cpu_has(X86_FEATURE_HYPERVISOR))
return false;
 
+   /*
+* Xen emulates Hyper-V to support enlightened Windows.
+* Check to see first if we are on a Xen Hypervisor.
+*/
+   if (xen_cpuid_base())
+   return false;
+
cpuid(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS,
  eax, hyp_signature[0], hyp_signature[1], hyp_signature[2]);
 
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[tip:x86/hyperv] X86: Handle Hyper-V vmbus interrupts as special hypervisor interrupts

2013-02-12 Thread tip-bot for K. Y. Srinivasan
Commit-ID:  bc2b0331e077f576369a2b6c75d15ed4de4ef91f
Gitweb: http://git.kernel.org/tip/bc2b0331e077f576369a2b6c75d15ed4de4ef91f
Author: K. Y. Srinivasan k...@microsoft.com
AuthorDate: Sun, 3 Feb 2013 17:22:39 -0800
Committer:  H. Peter Anvin h...@linux.intel.com
CommitDate: Tue, 12 Feb 2013 16:27:15 -0800

X86: Handle Hyper-V vmbus interrupts as special hypervisor interrupts

Starting with win8, vmbus interrupts can be delivered on any VCPU in the guest
and furthermore can be concurrently active on multiple VCPUs. Support this
interrupt delivery model by setting up a separate IDT entry for Hyper-V vmbus.
interrupts. I would like to thank Jan Beulich jbeul...@suse.com and
Thomas Gleixner t...@linutronix.de, for their help.

In this version of the patch, based on the feedback, I have merged the IDT
vector for Xen and Hyper-V and made the necessary adjustments. Furhermore,
based on Jan's feedback I have added the necessary compilation switches.

Signed-off-by: K. Y. Srinivasan k...@microsoft.com
Link: 
http://lkml.kernel.org/r/1359940959-32168-3-git-send-email-...@microsoft.com
Signed-off-by: H. Peter Anvin h...@linux.intel.com
---
 arch/x86/include/asm/irq_vectors.h |  4 ++--
 arch/x86/include/asm/mshyperv.h|  4 
 arch/x86/kernel/cpu/mshyperv.c | 44 ++
 arch/x86/kernel/entry_32.S |  9 +++-
 arch/x86/kernel/entry_64.S |  7 +-
 drivers/xen/events.c   |  7 +++---
 6 files changed, 68 insertions(+), 7 deletions(-)

diff --git a/arch/x86/include/asm/irq_vectors.h 
b/arch/x86/include/asm/irq_vectors.h
index 1508e51..aac5fa6 100644
--- a/arch/x86/include/asm/irq_vectors.h
+++ b/arch/x86/include/asm/irq_vectors.h
@@ -109,8 +109,8 @@
 
 #define UV_BAU_MESSAGE 0xf5
 
-/* Xen vector callback to receive events in a HVM domain */
-#define XEN_HVM_EVTCHN_CALLBACK0xf3
+/* Vector on which hypervisor callbacks will be delivered */
+#define HYPERVISOR_CALLBACK_VECTOR 0xf3
 
 /*
  * Local APIC timer IRQ vector is on a different priority level,
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 79ce568..c2934be 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -11,4 +11,8 @@ struct ms_hyperv_info {
 
 extern struct ms_hyperv_info ms_hyperv;
 
+void hyperv_callback_vector(void);
+void hyperv_vector_handler(struct pt_regs *regs);
+void hv_register_vmbus_handler(int irq, irq_handler_t handler);
+
 #endif
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 4dab317..a7d26d8 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -14,10 +14,15 @@
 #include linux/time.h
 #include linux/clocksource.h
 #include linux/module.h
+#include linux/hardirq.h
+#include linux/interrupt.h
 #include asm/processor.h
 #include asm/hypervisor.h
 #include asm/hyperv.h
 #include asm/mshyperv.h
+#include asm/desc.h
+#include asm/idle.h
+#include asm/irq_regs.h
 
 struct ms_hyperv_info ms_hyperv;
 EXPORT_SYMBOL_GPL(ms_hyperv);
@@ -77,6 +82,12 @@ static void __init ms_hyperv_init_platform(void)
 
if (ms_hyperv.features  HV_X64_MSR_TIME_REF_COUNT_AVAILABLE)
clocksource_register_hz(hyperv_cs, NSEC_PER_SEC/100);
+#if IS_ENABLED(CONFIG_HYPERV)
+   /*
+* Setup the IDT for hypervisor callback.
+*/
+   alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector);
+#endif
 }
 
 const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = {
@@ -85,3 +96,36 @@ const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = 
{
.init_platform  = ms_hyperv_init_platform,
 };
 EXPORT_SYMBOL(x86_hyper_ms_hyperv);
+
+#if IS_ENABLED(CONFIG_HYPERV)
+static int vmbus_irq = -1;
+static irq_handler_t vmbus_isr;
+
+void hv_register_vmbus_handler(int irq, irq_handler_t handler)
+{
+   vmbus_irq = irq;
+   vmbus_isr = handler;
+}
+
+void hyperv_vector_handler(struct pt_regs *regs)
+{
+   struct pt_regs *old_regs = set_irq_regs(regs);
+   struct irq_desc *desc;
+
+   irq_enter();
+   exit_idle();
+
+   desc = irq_to_desc(vmbus_irq);
+
+   if (desc)
+   generic_handle_irq_desc(vmbus_irq, desc);
+
+   irq_exit();
+   set_irq_regs(old_regs);
+}
+#else
+void hv_register_vmbus_handler(int irq, irq_handler_t handler)
+{
+}
+#endif
+EXPORT_SYMBOL_GPL(hv_register_vmbus_handler);
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index 6ed91d9..8831176 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -1091,11 +1091,18 @@ ENTRY(xen_failsafe_callback)
_ASM_EXTABLE(4b,9b)
 ENDPROC(xen_failsafe_callback)
 
-BUILD_INTERRUPT3(xen_hvm_callback_vector, XEN_HVM_EVTCHN_CALLBACK,
+BUILD_INTERRUPT3(xen_hvm_callback_vector, HYPERVISOR_CALLBACK_VECTOR,
xen_evtchn_do_upcall)
 
 #endif /* CONFIG_XEN */
 
+#if IS_ENABLED(CONFIG_HYPERV)
+