diff mbox

[v3,3/7] x86/hyper-v: reenlightenment notifications support

Message ID 20180116182700.1042-4-vkuznets@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Vitaly Kuznetsov Jan. 16, 2018, 6:26 p.m. UTC
Hyper-V supports Live Migration notification. This is supposed to be used
in conjunction with TSC emulation: when we are migrated to a host with
different TSC frequency for some short period host emulates our accesses
to TSC and sends us an interrupt to notify about the event. When we're
done updating everything we can disable TSC emulation and everything will
start working fast again.

We didn't need these notifications before as Hyper-V guests are not
supposed to use TSC as a clocksource: in Linux we even mark it as unstable
on boot. Guests normally use 'tsc page' clocksouce and host updates its
values on migrations automatically.

Things change when we want to run nested virtualization: even when we pass
through PV clocksources (kvm-clock or tsc page) to our guests we need to
know TSC frequency and when it changes.

Hyper-V Top Level Functional Specification (as of v5.0b) wrongly specifies
EAX:BIT(12) of CPUID:0x40000009 as the feature identification bit. The
right one to check is EAX:BIT(13) of CPUID:0x40000003. I was assured that
the fix in on the way.

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
v2 -> v3:
- add __visible and __irq_entry [Thomas Gleixner]
---
 arch/x86/entry/entry_32.S          |  3 ++
 arch/x86/entry/entry_64.S          |  3 ++
 arch/x86/hyperv/hv_init.c          | 89 ++++++++++++++++++++++++++++++++++++++
 arch/x86/include/asm/irq_vectors.h |  7 ++-
 arch/x86/include/asm/mshyperv.h    | 10 +++++
 arch/x86/include/uapi/asm/hyperv.h | 27 ++++++++++++
 arch/x86/kernel/cpu/mshyperv.c     |  6 +++
 7 files changed, 144 insertions(+), 1 deletion(-)

Comments

Thomas Gleixner Jan. 16, 2018, 6:33 p.m. UTC | #1
On Tue, 16 Jan 2018, Vitaly Kuznetsov wrote:
> Hyper-V supports Live Migration notification. This is supposed to be used
> in conjunction with TSC emulation: when we are migrated to a host with
> different TSC frequency for some short period host emulates our accesses
> to TSC and sends us an interrupt to notify about the event. When we're
> done updating everything we can disable TSC emulation and everything will
> start working fast again.
> 
> We didn't need these notifications before as Hyper-V guests are not
> supposed to use TSC as a clocksource: in Linux we even mark it as unstable
> on boot. Guests normally use 'tsc page' clocksouce and host updates its
> values on migrations automatically.
> 
> Things change when we want to run nested virtualization: even when we pass
> through PV clocksources (kvm-clock or tsc page) to our guests we need to
> know TSC frequency and when it changes.
> 
> Hyper-V Top Level Functional Specification (as of v5.0b) wrongly specifies
> EAX:BIT(12) of CPUID:0x40000009 as the feature identification bit. The
> right one to check is EAX:BIT(13) of CPUID:0x40000003. I was assured that
> the fix in on the way.
> 
> Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Vitaly Kuznetsov Jan. 19, 2018, 10:47 a.m. UTC | #2
kbuild test robot <lkp@intel.com> writes:

> Hi Vitaly,
>
> Thank you for the patch! Perhaps something to improve:
>
> [auto build test WARNING on tip/auto-latest]
> [also build test WARNING on v4.15-rc8 next-20180118]
> [cannot apply to tip/x86/core kvm/linux-next]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>
> url:    https://github.com/0day-ci/linux/commits/Vitaly-Kuznetsov/x86-kvm-hyperv-stable-clocksorce-for-L2-guests-when-running-nested-KVM-on-Hyper-V/20180119-160814
> config: x86_64-allmodconfig (attached as .config)
> compiler: gcc-7 (Debian 7.2.0-12) 7.2.1 20171025
> reproduce:
>         # save the attached .config to linux build tree
>         make ARCH=x86_64 
>
> All warnings (new ones prefixed by >>):
>
>    In file included from include/linux/kasan.h:17:0,
>                     from include/linux/slab.h:129,
>                     from include/linux/irq.h:26,
>                     from arch/x86/include/asm/hardirq.h:6,
>                     from include/linux/hardirq.h:9,
>                     from include/linux/interrupt.h:13,
>                     from arch/x86/include/asm/mshyperv.h:8,
>                     from arch/x86//entry/vdso/vdso32/../vclock_gettime.c:20,
>                     from arch/x86//entry/vdso/vdso32/vclock_gettime.c:33:
>    arch/x86/include/asm/pgtable.h: In function 'clone_pgd_range':
>    arch/x86/include/asm/pgtable.h:1129:9: error: implicit declaration of function 'kernel_to_user_pgdp'; did you mean 'u64_to_user_ptr'? [-Werror=implicit-function-declaration]
>      memcpy(kernel_to_user_pgdp(dst), kernel_to_user_pgdp(src),
>             ^~~~~~~~~~~~~~~~~~~

Sorry but I'm failing to see how this (and all the rest) is related to
my patch ...

[snip]
kernel test robot Jan. 19, 2018, 11:11 a.m. UTC | #3
Hi Vitaly,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on tip/auto-latest]
[also build test WARNING on v4.15-rc8 next-20180118]
[cannot apply to tip/x86/core kvm/linux-next]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Vitaly-Kuznetsov/x86-kvm-hyperv-stable-clocksorce-for-L2-guests-when-running-nested-KVM-on-Hyper-V/20180119-160814
config: x86_64-randconfig-s5-01191733 (attached as .config)
compiler: gcc-7 (Debian 7.2.0-12) 7.2.1 20171025
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All warnings (new ones prefixed by >>):

   In file included from arch/x86/include/asm/string.h:3:0,
                    from include/linux/string.h:19,
                    from arch/x86/include/asm/page_32.h:35,
                    from arch/x86/include/asm/page.h:14,
                    from arch/x86/include/asm/thread_info.h:12,
                    from include/linux/thread_info.h:38,
                    from arch/x86/include/asm/preempt.h:7,
                    from include/linux/preempt.h:81,
                    from include/linux/spinlock.h:51,
                    from include/linux/seqlock.h:36,
                    from include/linux/time.h:6,
                    from include/uapi/linux/timex.h:56,
                    from include/linux/timex.h:56,
                    from include/linux/clocksource.h:13,
                    from arch/x86/include/asm/vgtod.h:6,
                    from arch/x86//entry/vdso/vdso32/../vclock_gettime.c:15,
                    from arch/x86//entry/vdso/vdso32/vclock_gettime.c:33:
   arch/x86/include/asm/pgtable.h: In function 'clone_pgd_range':
   arch/x86/include/asm/pgtable.h:1129:9: error: implicit declaration of function 'kernel_to_user_pgdp'; did you mean 'u64_to_user_ptr'? [-Werror=implicit-function-declaration]
     memcpy(kernel_to_user_pgdp(dst), kernel_to_user_pgdp(src),
            ^
   arch/x86/include/asm/string_32.h:183:42: note: in definition of macro 'memcpy'
    #define memcpy(t, f, n) __builtin_memcpy(t, f, n)
                                             ^
>> arch/x86/include/asm/pgtable.h:1129:9: warning: passing argument 1 of '__builtin_memcpy' makes pointer from integer without a cast [-Wint-conversion]
     memcpy(kernel_to_user_pgdp(dst), kernel_to_user_pgdp(src),
            ^
   arch/x86/include/asm/string_32.h:183:42: note: in definition of macro 'memcpy'
    #define memcpy(t, f, n) __builtin_memcpy(t, f, n)
                                             ^
   arch/x86/include/asm/pgtable.h:1129:9: note: expected 'void *' but argument is of type 'int'
     memcpy(kernel_to_user_pgdp(dst), kernel_to_user_pgdp(src),
            ^
   arch/x86/include/asm/string_32.h:183:42: note: in definition of macro 'memcpy'
    #define memcpy(t, f, n) __builtin_memcpy(t, f, n)
                                             ^
   arch/x86/include/asm/pgtable.h:1129:35: warning: passing argument 2 of '__builtin_memcpy' makes pointer from integer without a cast [-Wint-conversion]
     memcpy(kernel_to_user_pgdp(dst), kernel_to_user_pgdp(src),
                                      ^
   arch/x86/include/asm/string_32.h:183:45: note: in definition of macro 'memcpy'
    #define memcpy(t, f, n) __builtin_memcpy(t, f, n)
                                                ^
   arch/x86/include/asm/pgtable.h:1129:35: note: expected 'const void *' but argument is of type 'int'
     memcpy(kernel_to_user_pgdp(dst), kernel_to_user_pgdp(src),
                                      ^
   arch/x86/include/asm/string_32.h:183:45: note: in definition of macro 'memcpy'
    #define memcpy(t, f, n) __builtin_memcpy(t, f, n)
                                                ^
   cc1: some warnings being treated as errors

vim +/__builtin_memcpy +1129 arch/x86/include/asm/pgtable.h

1501899a arch/x86/include/asm/pgtable.h Dan Williams        2017-11-29  1111  
85958b46 include/asm-x86/pgtable.h      Jeremy Fitzhardinge 2008-03-17  1112  /*
85958b46 include/asm-x86/pgtable.h      Jeremy Fitzhardinge 2008-03-17  1113   * clone_pgd_range(pgd_t *dst, pgd_t *src, int count);
85958b46 include/asm-x86/pgtable.h      Jeremy Fitzhardinge 2008-03-17  1114   *
85958b46 include/asm-x86/pgtable.h      Jeremy Fitzhardinge 2008-03-17  1115   *  dst - pointer to pgd range anwhere on a pgd page
85958b46 include/asm-x86/pgtable.h      Jeremy Fitzhardinge 2008-03-17  1116   *  src - ""
85958b46 include/asm-x86/pgtable.h      Jeremy Fitzhardinge 2008-03-17  1117   *  count - the number of pgds to copy.
85958b46 include/asm-x86/pgtable.h      Jeremy Fitzhardinge 2008-03-17  1118   *
85958b46 include/asm-x86/pgtable.h      Jeremy Fitzhardinge 2008-03-17  1119   * dst and src can be on the same page, but the range must not overlap,
85958b46 include/asm-x86/pgtable.h      Jeremy Fitzhardinge 2008-03-17  1120   * and must not cross a page boundary.
85958b46 include/asm-x86/pgtable.h      Jeremy Fitzhardinge 2008-03-17  1121   */
85958b46 include/asm-x86/pgtable.h      Jeremy Fitzhardinge 2008-03-17  1122  static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
85958b46 include/asm-x86/pgtable.h      Jeremy Fitzhardinge 2008-03-17  1123  {
85958b46 include/asm-x86/pgtable.h      Jeremy Fitzhardinge 2008-03-17  1124  	memcpy(dst, src, count * sizeof(pgd_t));
fc2fbc85 arch/x86/include/asm/pgtable.h Dave Hansen         2017-12-04  1125  #ifdef CONFIG_PAGE_TABLE_ISOLATION
fc2fbc85 arch/x86/include/asm/pgtable.h Dave Hansen         2017-12-04  1126  	if (!static_cpu_has(X86_FEATURE_PTI))
fc2fbc85 arch/x86/include/asm/pgtable.h Dave Hansen         2017-12-04  1127  		return;
fc2fbc85 arch/x86/include/asm/pgtable.h Dave Hansen         2017-12-04  1128  	/* Clone the user space pgd as well */
fc2fbc85 arch/x86/include/asm/pgtable.h Dave Hansen         2017-12-04 @1129  	memcpy(kernel_to_user_pgdp(dst), kernel_to_user_pgdp(src),
fc2fbc85 arch/x86/include/asm/pgtable.h Dave Hansen         2017-12-04  1130  	       count * sizeof(pgd_t));
fc2fbc85 arch/x86/include/asm/pgtable.h Dave Hansen         2017-12-04  1131  #endif
85958b46 include/asm-x86/pgtable.h      Jeremy Fitzhardinge 2008-03-17  1132  }
85958b46 include/asm-x86/pgtable.h      Jeremy Fitzhardinge 2008-03-17  1133  

:::::: The code at line 1129 was first introduced by commit
:::::: fc2fbc8512ed08d1de7720936fd7d2e4ce02c3a2 x86/mm/pti: Populate user PGD

:::::: TO: Dave Hansen <dave.hansen@linux.intel.com>
:::::: CC: Ingo Molnar <mingo@kernel.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
Thomas Gleixner Jan. 20, 2018, 7:48 a.m. UTC | #4
On Fri, 19 Jan 2018, Vitaly Kuznetsov wrote:
> kbuild test robot <lkp@intel.com> writes:
> 
> > Hi Vitaly,
> >
> > Thank you for the patch! Perhaps something to improve:
> >
> > [auto build test WARNING on tip/auto-latest]
> > [also build test WARNING on v4.15-rc8 next-20180118]
> > [cannot apply to tip/x86/core kvm/linux-next]
> > [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
> >
> > url:    https://github.com/0day-ci/linux/commits/Vitaly-Kuznetsov/x86-kvm-hyperv-stable-clocksorce-for-L2-guests-when-running-nested-KVM-on-Hyper-V/20180119-160814
> > config: x86_64-allmodconfig (attached as .config)
> > compiler: gcc-7 (Debian 7.2.0-12) 7.2.1 20171025
> > reproduce:
> >         # save the attached .config to linux build tree
> >         make ARCH=x86_64 
> >
> > All warnings (new ones prefixed by >>):
> >
> >    In file included from include/linux/kasan.h:17:0,
> >                     from include/linux/slab.h:129,
> >                     from include/linux/irq.h:26,
> >                     from arch/x86/include/asm/hardirq.h:6,
> >                     from include/linux/hardirq.h:9,
> >                     from include/linux/interrupt.h:13,
> >                     from arch/x86/include/asm/mshyperv.h:8,
> >                     from arch/x86//entry/vdso/vdso32/../vclock_gettime.c:20,
> >                     from arch/x86//entry/vdso/vdso32/vclock_gettime.c:33:
> >    arch/x86/include/asm/pgtable.h: In function 'clone_pgd_range':
> >    arch/x86/include/asm/pgtable.h:1129:9: error: implicit declaration of function 'kernel_to_user_pgdp'; did you mean 'u64_to_user_ptr'? [-Werror=implicit-function-declaration]
> >      memcpy(kernel_to_user_pgdp(dst), kernel_to_user_pgdp(src),
> >             ^~~~~~~~~~~~~~~~~~~
> 
> Sorry but I'm failing to see how this (and all the rest) is related to
> my patch ...

You added '#include <linux/interrupt.h>' to mshyperv.h which is included in
vclock_gettime.c and pulls in other stuff which fails to expand....

Thanks,

	tglx
Michael Kelley (EOSG) Jan. 22, 2018, 1:22 a.m. UTC | #5
On Fri, 19 Jan 2018, Thomas Gleixner wrote:

> -----Original Message-----
> From: Thomas Gleixner [mailto:tglx@linutronix.de]
> Sent: Friday, January 19, 2018 11:48 PM
> To: Vitaly Kuznetsov <vkuznets@redhat.com>
> Cc: kbuild test robot <lkp@intel.com>; kbuild-all@01.org; kvm@vger.kernel.org;
> x86@kernel.org; Stephen Hemminger <sthemmin@microsoft.com>; Radim Krčmář
> <rkrcmar@redhat.com>; Haiyang Zhang <haiyangz@microsoft.com>; linux-
> kernel@vger.kernel.org; devel@linuxdriverproject.org; Michael Kelley (EOSG)
> <Michael.H.Kelley@microsoft.com>; Ingo Molnar <mingo@redhat.com>; Roman Kagan
> <rkagan@virtuozzo.com>; Andy Lutomirski <luto@kernel.org>; H. Peter Anvin
> <hpa@zytor.com>; Paolo Bonzini <pbonzini@redhat.com>; Mohammed Gamal
> <mmorsy@redhat.com>
> Subject: Re: [PATCH v3 3/7] x86/hyper-v: reenlightenment notifications support
> 
> On Fri, 19 Jan 2018, Vitaly Kuznetsov wrote:
> > kbuild test robot <lkp@intel.com> writes:
> >
> > > Hi Vitaly,
> > >
> > > Thank you for the patch! Perhaps something to improve:
> > >
> > > [auto build test WARNING on tip/auto-latest]
> > > [also build test WARNING on v4.15-rc8 next-20180118]
> > > [cannot apply to tip/x86/core kvm/linux-next]
> > > [if your patch is applied to the wrong git tree, please drop us a note to help improve the
> system]
> > >
> > > url:
> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2F0day-
> ci%2Flinux%2Fcommits%2FVitaly-Kuznetsov%2Fx86-kvm-hyperv-stable-clocksorce-for-L2-
> guests-when-running-nested-KVM-on-Hyper-V%2F20180119-
> 160814&data=02%7C01%7CMichael.H.Kelley%40microsoft.com%7Ce95c66107da6446826830
> 8d55fda2c2b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636520313062777623&s
> data=kAXl3mLVUdJi%2BsB4Ub0fmUHQfl6NuUDjW%2FAY9%2BFLZE4%3D&reserved=0
> > > config: x86_64-allmodconfig (attached as .config)
> > > compiler: gcc-7 (Debian 7.2.0-12) 7.2.1 20171025
> > > reproduce:
> > >         # save the attached .config to linux build tree
> > >         make ARCH=x86_64
> > >
> > > All warnings (new ones prefixed by >>):
> > >
> > >    In file included from include/linux/kasan.h:17:0,
> > >                     from include/linux/slab.h:129,
> > >                     from include/linux/irq.h:26,
> > >                     from arch/x86/include/asm/hardirq.h:6,
> > >                     from include/linux/hardirq.h:9,
> > >                     from include/linux/interrupt.h:13,
> > >                     from arch/x86/include/asm/mshyperv.h:8,
> > >                     from arch/x86//entry/vdso/vdso32/../vclock_gettime.c:20,
> > >                     from arch/x86//entry/vdso/vdso32/vclock_gettime.c:33:
> > >    arch/x86/include/asm/pgtable.h: In function 'clone_pgd_range':
> > >    arch/x86/include/asm/pgtable.h:1129:9: error: implicit declaration of function
> 'kernel_to_user_pgdp'; did you mean 'u64_to_user_ptr'? [-Werror=implicit-function-
> declaration]
> > >      memcpy(kernel_to_user_pgdp(dst), kernel_to_user_pgdp(src),
> > >             ^~~~~~~~~~~~~~~~~~~
> >
> > Sorry but I'm failing to see how this (and all the rest) is related to
> > my patch ...
> 
> You added '#include <linux/interrupt.h>' to mshyperv.h which is included in
> vclock_gettime.c and pulls in other stuff which fails to expand....

Is the declaration of hyperv_reenlightenment_intr() even needed in
mshyperv.h?  The '#include <linux/interrupt.h>' is there for the __irq_entry
annotation on that declaration.   There's a declaration of the parallel (and
unannotated) hyperv_vector_handler(), but that looks like a fossil that
isn't needed either.

Michael

> 
> Thanks,
> 
> 	tglx
Vitaly Kuznetsov Jan. 22, 2018, 10:41 a.m. UTC | #6
Thomas Gleixner <tglx@linutronix.de> writes:

> On Fri, 19 Jan 2018, Vitaly Kuznetsov wrote:
>> kbuild test robot <lkp@intel.com> writes:
>> 
>> > Hi Vitaly,
>> >
>> > Thank you for the patch! Perhaps something to improve:
>> >
>> > [auto build test WARNING on tip/auto-latest]
>> > [also build test WARNING on v4.15-rc8 next-20180118]
>> > [cannot apply to tip/x86/core kvm/linux-next]
>> > [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>> >
>> > url:    https://github.com/0day-ci/linux/commits/Vitaly-Kuznetsov/x86-kvm-hyperv-stable-clocksorce-for-L2-guests-when-running-nested-KVM-on-Hyper-V/20180119-160814
>> > config: x86_64-allmodconfig (attached as .config)
>> > compiler: gcc-7 (Debian 7.2.0-12) 7.2.1 20171025
>> > reproduce:
>> >         # save the attached .config to linux build tree
>> >         make ARCH=x86_64 
>> >
>> > All warnings (new ones prefixed by >>):
>> >
>> >    In file included from include/linux/kasan.h:17:0,
>> >                     from include/linux/slab.h:129,
>> >                     from include/linux/irq.h:26,
>> >                     from arch/x86/include/asm/hardirq.h:6,
>> >                     from include/linux/hardirq.h:9,
>> >                     from include/linux/interrupt.h:13,
>> >                     from arch/x86/include/asm/mshyperv.h:8,
>> >                     from arch/x86//entry/vdso/vdso32/../vclock_gettime.c:20,
>> >                     from arch/x86//entry/vdso/vdso32/vclock_gettime.c:33:
>> >    arch/x86/include/asm/pgtable.h: In function 'clone_pgd_range':
>> >    arch/x86/include/asm/pgtable.h:1129:9: error: implicit declaration of function 'kernel_to_user_pgdp'; did you mean 'u64_to_user_ptr'? [-Werror=implicit-function-declaration]
>> >      memcpy(kernel_to_user_pgdp(dst), kernel_to_user_pgdp(src),
>> >             ^~~~~~~~~~~~~~~~~~~
>> 
>> Sorry but I'm failing to see how this (and all the rest) is related to
>> my patch ...
>
> You added '#include <linux/interrupt.h>' to mshyperv.h which is included in
> vclock_gettime.c and pulls in other stuff which fails to expand....
>

Oh, right, thanks! I'll see what can be done.
Vitaly Kuznetsov Jan. 22, 2018, 12:06 p.m. UTC | #7
"Michael Kelley (EOSG)" <Michael.H.Kelley@microsoft.com> writes:

> On Fri, 19 Jan 2018, Thomas Gleixner wrote:
>
>> -----Original Message-----
>> From: Thomas Gleixner [mailto:tglx@linutronix.de]
>> Sent: Friday, January 19, 2018 11:48 PM
>> To: Vitaly Kuznetsov <vkuznets@redhat.com>
>> Cc: kbuild test robot <lkp@intel.com>; kbuild-all@01.org; kvm@vger.kernel.org;
>> x86@kernel.org; Stephen Hemminger <sthemmin@microsoft.com>; Radim Krčmář
>> <rkrcmar@redhat.com>; Haiyang Zhang <haiyangz@microsoft.com>; linux-
>> kernel@vger.kernel.org; devel@linuxdriverproject.org; Michael Kelley (EOSG)
>> <Michael.H.Kelley@microsoft.com>; Ingo Molnar <mingo@redhat.com>; Roman Kagan
>> <rkagan@virtuozzo.com>; Andy Lutomirski <luto@kernel.org>; H. Peter Anvin
>> <hpa@zytor.com>; Paolo Bonzini <pbonzini@redhat.com>; Mohammed Gamal
>> <mmorsy@redhat.com>
>> Subject: Re: [PATCH v3 3/7] x86/hyper-v: reenlightenment notifications support
>> 
>> On Fri, 19 Jan 2018, Vitaly Kuznetsov wrote:
>> > kbuild test robot <lkp@intel.com> writes:
>> >
>> > > Hi Vitaly,
>> > >
>> > > Thank you for the patch! Perhaps something to improve:
>> > >
>> > > [auto build test WARNING on tip/auto-latest]
>> > > [also build test WARNING on v4.15-rc8 next-20180118]
>> > > [cannot apply to tip/x86/core kvm/linux-next]
>> > > [if your patch is applied to the wrong git tree, please drop us a note to help improve the
>> system]
>> > >
>> > > url:
>> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2F0day-
>> ci%2Flinux%2Fcommits%2FVitaly-Kuznetsov%2Fx86-kvm-hyperv-stable-clocksorce-for-L2-
>> guests-when-running-nested-KVM-on-Hyper-V%2F20180119-
>> 160814&data=02%7C01%7CMichael.H.Kelley%40microsoft.com%7Ce95c66107da6446826830
>> 8d55fda2c2b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636520313062777623&s
>> data=kAXl3mLVUdJi%2BsB4Ub0fmUHQfl6NuUDjW%2FAY9%2BFLZE4%3D&reserved=0
>> > > config: x86_64-allmodconfig (attached as .config)
>> > > compiler: gcc-7 (Debian 7.2.0-12) 7.2.1 20171025
>> > > reproduce:
>> > >         # save the attached .config to linux build tree
>> > >         make ARCH=x86_64
>> > >
>> > > All warnings (new ones prefixed by >>):
>> > >
>> > >    In file included from include/linux/kasan.h:17:0,
>> > >                     from include/linux/slab.h:129,
>> > >                     from include/linux/irq.h:26,
>> > >                     from arch/x86/include/asm/hardirq.h:6,
>> > >                     from include/linux/hardirq.h:9,
>> > >                     from include/linux/interrupt.h:13,
>> > >                     from arch/x86/include/asm/mshyperv.h:8,
>> > >                     from arch/x86//entry/vdso/vdso32/../vclock_gettime.c:20,
>> > >                     from arch/x86//entry/vdso/vdso32/vclock_gettime.c:33:
>> > >    arch/x86/include/asm/pgtable.h: In function 'clone_pgd_range':
>> > >    arch/x86/include/asm/pgtable.h:1129:9: error: implicit declaration of function
>> 'kernel_to_user_pgdp'; did you mean 'u64_to_user_ptr'? [-Werror=implicit-function-
>> declaration]
>> > >      memcpy(kernel_to_user_pgdp(dst), kernel_to_user_pgdp(src),
>> > >             ^~~~~~~~~~~~~~~~~~~
>> >
>> > Sorry but I'm failing to see how this (and all the rest) is related to
>> > my patch ...
>> 
>> You added '#include <linux/interrupt.h>' to mshyperv.h which is included in
>> vclock_gettime.c and pulls in other stuff which fails to expand....
>
> Is the declaration of hyperv_reenlightenment_intr() even needed in
> mshyperv.h?  The '#include <linux/interrupt.h>' is there for the __irq_entry
> annotation on that declaration.   There's a declaration of the parallel (and
> unannotated) hyperv_vector_handler(), but that looks like a fossil that
> isn't needed either.
>

True,

the only need for the declaration in mshyperv.h is to silence "warning:
no previous prototype for ‘hyperv_reenlightenment_intr’"; I'm not sure
if this actually needs fixing.
Vitaly Kuznetsov Jan. 23, 2018, 1:41 p.m. UTC | #8
Vitaly Kuznetsov <vkuznets@redhat.com> writes:

> "Michael Kelley (EOSG)" <Michael.H.Kelley@microsoft.com> writes:
>
>> On Fri, 19 Jan 2018, Thomas Gleixner wrote:
>>
>>> 
>>> You added '#include <linux/interrupt.h>' to mshyperv.h which is included in
>>> vclock_gettime.c and pulls in other stuff which fails to expand....
>>
>> Is the declaration of hyperv_reenlightenment_intr() even needed in
>> mshyperv.h?  The '#include <linux/interrupt.h>' is there for the __irq_entry
>> annotation on that declaration.   There's a declaration of the parallel (and
>> unannotated) hyperv_vector_handler(), but that looks like a fossil that
>> isn't needed either.
>>
>
> True,
>
> the only need for the declaration in mshyperv.h is to silence "warning:
> no previous prototype for ‘hyperv_reenlightenment_intr’"; I'm not sure
> if this actually needs fixing.

It seems we can get away with dropping '__visible' and '__irq_entry'
qualifiers from 'hyperv_reenlightenment_intr' declaration in mshyperv.h
while keeping them in hv_init.c for the implementation. This way we can
avoid the nasty 'no previous prototype' warning and not have to add
'#include <linux/interrupt.h>' to mshyperv.h breaking vdso.

I'm inclined to go ahead with this in v4 if nobody objects.
Michael Kelley (EOSG) Jan. 23, 2018, 2:02 p.m. UTC | #9
Vitaly Kuznetsov <vkuznets@redhat.com> writes:
> 

> > "Michael Kelley (EOSG)" <Michael.H.Kelley@microsoft.com> writes:

> >

> >> On Fri, 19 Jan 2018, Thomas Gleixner wrote:

> >>

> >>>

> >>> You added '#include <linux/interrupt.h>' to mshyperv.h which is included in

> >>> vclock_gettime.c and pulls in other stuff which fails to expand....

> >>

> >> Is the declaration of hyperv_reenlightenment_intr() even needed in

> >> mshyperv.h?  The '#include <linux/interrupt.h>' is there for the __irq_entry

> >> annotation on that declaration.   There's a declaration of the parallel (and

> >> unannotated) hyperv_vector_handler(), but that looks like a fossil that

> >> isn't needed either.

> >>

> >

> > True,

> >

> > the only need for the declaration in mshyperv.h is to silence "warning:

> > no previous prototype for ‘hyperv_reenlightenment_intr’"; I'm not sure

> > if this actually needs fixing.

> 

> It seems we can get away with dropping '__visible' and '__irq_entry'

> qualifiers from 'hyperv_reenlightenment_intr' declaration in mshyperv.h

> while keeping them in hv_init.c for the implementation. This way we can

> avoid the nasty 'no previous prototype' warning and not have to add

> '#include <linux/interrupt.h>' to mshyperv.h breaking vdso.


Where exactly is the 'no previous prototype' warning being generated?
I was thinking the only references to hyperv_reenlightenment_intr()
would be in entry_32.S and entry_64.S, but maybe there's another one
I missed.

Michael

> 

> I'm inclined to go ahead with this in v4 if nobody objects.

> 

> --

>   Vitaly
Vitaly Kuznetsov Jan. 23, 2018, 2:07 p.m. UTC | #10
"Michael Kelley (EOSG)" <Michael.H.Kelley@microsoft.com> writes:

> Vitaly Kuznetsov <vkuznets@redhat.com> writes:
>> 
>> > "Michael Kelley (EOSG)" <Michael.H.Kelley@microsoft.com> writes:
>> >
>> >> On Fri, 19 Jan 2018, Thomas Gleixner wrote:
>> >>
>> >>>
>> >>> You added '#include <linux/interrupt.h>' to mshyperv.h which is included in
>> >>> vclock_gettime.c and pulls in other stuff which fails to expand....
>> >>
>> >> Is the declaration of hyperv_reenlightenment_intr() even needed in
>> >> mshyperv.h?  The '#include <linux/interrupt.h>' is there for the __irq_entry
>> >> annotation on that declaration.   There's a declaration of the parallel (and
>> >> unannotated) hyperv_vector_handler(), but that looks like a fossil that
>> >> isn't needed either.
>> >>
>> >
>> > True,
>> >
>> > the only need for the declaration in mshyperv.h is to silence "warning:
>> > no previous prototype for ‘hyperv_reenlightenment_intr’"; I'm not sure
>> > if this actually needs fixing.
>> 
>> It seems we can get away with dropping '__visible' and '__irq_entry'
>> qualifiers from 'hyperv_reenlightenment_intr' declaration in mshyperv.h
>> while keeping them in hv_init.c for the implementation. This way we can
>> avoid the nasty 'no previous prototype' warning and not have to add
>> '#include <linux/interrupt.h>' to mshyperv.h breaking vdso.
>
> Where exactly is the 'no previous prototype' warning being generated?

It is generated while compiling the implementation in hv_init.c, every
non-static function needs a previously defined prototype.
diff mbox

Patch

diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
index a1f28a54f23a..4041608cd208 100644
--- a/arch/x86/entry/entry_32.S
+++ b/arch/x86/entry/entry_32.S
@@ -883,6 +883,9 @@  BUILD_INTERRUPT3(xen_hvm_callback_vector, HYPERVISOR_CALLBACK_VECTOR,
 BUILD_INTERRUPT3(hyperv_callback_vector, HYPERVISOR_CALLBACK_VECTOR,
 		 hyperv_vector_handler)
 
+BUILD_INTERRUPT3(hyperv_reenlightenment_vector, HYPERV_REENLIGHTENMENT_VECTOR,
+		 hyperv_reenlightenment_intr)
+
 #endif /* CONFIG_HYPERV */
 
 ENTRY(page_fault)
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 4f8e1d35a97c..7da977b8d1dd 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -1233,6 +1233,9 @@  apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \
 #if IS_ENABLED(CONFIG_HYPERV)
 apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \
 	hyperv_callback_vector hyperv_vector_handler
+
+apicinterrupt3 HYPERV_REENLIGHTENMENT_VECTOR \
+	hyperv_reenlightenment_vector hyperv_reenlightenment_intr
 #endif /* CONFIG_HYPERV */
 
 idtentry debug			do_debug		has_error_code=0	paranoid=1 shift_ist=DEBUG_STACK
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 1a6c63f721bc..712ac40081f7 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -18,6 +18,8 @@ 
  */
 
 #include <linux/types.h>
+#include <asm/apic.h>
+#include <asm/desc.h>
 #include <asm/hypervisor.h>
 #include <asm/hyperv.h>
 #include <asm/mshyperv.h>
@@ -102,6 +104,93 @@  static int hv_cpu_init(unsigned int cpu)
 	return 0;
 }
 
+static void (*hv_reenlightenment_cb)(void);
+
+static void hv_reenlightenment_notify(struct work_struct *dummy)
+{
+	struct hv_tsc_emulation_status emu_status;
+
+	rdmsrl(HV_X64_MSR_TSC_EMULATION_STATUS, *(u64 *)&emu_status);
+
+	/* Don't issue the callback if TSC accesses are not emulated */
+	if (hv_reenlightenment_cb && emu_status.inprogress)
+		hv_reenlightenment_cb();
+}
+static DECLARE_DELAYED_WORK(hv_reenlightenment_work, hv_reenlightenment_notify);
+
+void hyperv_stop_tsc_emulation(void)
+{
+	u64 freq;
+	struct hv_tsc_emulation_status emu_status;
+
+	rdmsrl(HV_X64_MSR_TSC_EMULATION_STATUS, *(u64 *)&emu_status);
+	emu_status.inprogress = 0;
+	wrmsrl(HV_X64_MSR_TSC_EMULATION_STATUS, *(u64 *)&emu_status);
+
+	rdmsrl(HV_X64_MSR_TSC_FREQUENCY, freq);
+	tsc_khz = div64_u64(freq, 1000);
+}
+EXPORT_SYMBOL_GPL(hyperv_stop_tsc_emulation);
+
+static inline bool hv_reenlightenment_available(void)
+{
+	/*
+	 * Check for required features and priviliges to make TSC frequency
+	 * change notifications work.
+	 */
+	return ms_hyperv.features & HV_X64_ACCESS_FREQUENCY_MSRS &&
+		ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE &&
+		ms_hyperv.features & HV_X64_ACCESS_REENLIGHTENMENT;
+}
+
+__visible void __irq_entry hyperv_reenlightenment_intr(struct pt_regs *regs)
+{
+	entering_ack_irq();
+
+	schedule_delayed_work(&hv_reenlightenment_work, HZ/10);
+
+	exiting_irq();
+}
+
+void set_hv_tscchange_cb(void (*cb)(void))
+{
+	struct hv_reenlightenment_control re_ctrl = {
+		.vector = HYPERV_REENLIGHTENMENT_VECTOR,
+		.enabled = 1,
+		.target_vp = hv_vp_index[smp_processor_id()]
+	};
+	struct hv_tsc_emulation_control emu_ctrl = {.enabled = 1};
+
+	if (!hv_reenlightenment_available()) {
+		pr_warn("Hyper-V: reenlightenment support is unavailable\n");
+		return;
+	}
+
+	hv_reenlightenment_cb = cb;
+
+	/* Make sure callback is registered before we write to MSRs */
+	wmb();
+
+	wrmsrl(HV_X64_MSR_REENLIGHTENMENT_CONTROL, *((u64 *)&re_ctrl));
+	wrmsrl(HV_X64_MSR_TSC_EMULATION_CONTROL, *((u64 *)&emu_ctrl));
+}
+EXPORT_SYMBOL_GPL(set_hv_tscchange_cb);
+
+void clear_hv_tscchange_cb(void)
+{
+	struct hv_reenlightenment_control re_ctrl;
+
+	if (!hv_reenlightenment_available())
+		return;
+
+	rdmsrl(HV_X64_MSR_REENLIGHTENMENT_CONTROL, *(u64 *)&re_ctrl);
+	re_ctrl.enabled = 0;
+	wrmsrl(HV_X64_MSR_REENLIGHTENMENT_CONTROL, *(u64 *)&re_ctrl);
+
+	hv_reenlightenment_cb = NULL;
+}
+EXPORT_SYMBOL_GPL(clear_hv_tscchange_cb);
+
 /*
  * This function is to be invoked early in the boot sequence after the
  * hypervisor has been detected.
diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h
index 67421f649cfa..e71c1120426b 100644
--- a/arch/x86/include/asm/irq_vectors.h
+++ b/arch/x86/include/asm/irq_vectors.h
@@ -103,7 +103,12 @@ 
 #endif
 
 #define MANAGED_IRQ_SHUTDOWN_VECTOR	0xef
-#define LOCAL_TIMER_VECTOR		0xee
+
+#if IS_ENABLED(CONFIG_HYPERV)
+#define HYPERV_REENLIGHTENMENT_VECTOR	0xee
+#endif
+
+#define LOCAL_TIMER_VECTOR		0xed
 
 #define NR_VECTORS			 256
 
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 6b1d4ea78270..96c96f8e570c 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -5,6 +5,7 @@ 
 #include <linux/types.h>
 #include <linux/atomic.h>
 #include <linux/nmi.h>
+#include <linux/interrupt.h>
 #include <asm/io.h>
 #include <asm/hyperv.h>
 #include <asm/nospec-branch.h>
@@ -160,6 +161,7 @@  static inline void vmbus_signal_eom(struct hv_message *msg, u32 old_msg_type)
 #define hv_set_synint_state(int_num, val) wrmsrl(int_num, val)
 
 void hyperv_callback_vector(void);
+void hyperv_reenlightenment_vector(void);
 #ifdef CONFIG_TRACING
 #define trace_hyperv_callback_vector hyperv_callback_vector
 #endif
@@ -316,11 +318,19 @@  void hyper_alloc_mmu(void);
 void hyperv_report_panic(struct pt_regs *regs, long err);
 bool hv_is_hypercall_page_setup(void);
 void hyperv_cleanup(void);
+
+__visible void __irq_entry hyperv_reenlightenment_intr(struct pt_regs *regs);
+void set_hv_tscchange_cb(void (*cb)(void));
+void clear_hv_tscchange_cb(void);
+void hyperv_stop_tsc_emulation(void);
 #else /* CONFIG_HYPERV */
 static inline void hyperv_init(void) {}
 static inline bool hv_is_hypercall_page_setup(void) { return false; }
 static inline void hyperv_cleanup(void) {}
 static inline void hyperv_setup_mmu_ops(void) {}
+static inline void set_hv_tscchange_cb(void (*cb)(void)) {}
+static inline void clear_hv_tscchange_cb(void) {}
+static inline void hyperv_stop_tsc_emulation(void) {};
 #endif /* CONFIG_HYPERV */
 
 #ifdef CONFIG_HYPERV_TSCPAGE
diff --git a/arch/x86/include/uapi/asm/hyperv.h b/arch/x86/include/uapi/asm/hyperv.h
index 1a5bfead93b4..197c2e6c7376 100644
--- a/arch/x86/include/uapi/asm/hyperv.h
+++ b/arch/x86/include/uapi/asm/hyperv.h
@@ -40,6 +40,9 @@ 
  */
 #define HV_X64_ACCESS_FREQUENCY_MSRS		(1 << 11)
 
+/* AccessReenlightenmentControls privilege */
+#define HV_X64_ACCESS_REENLIGHTENMENT		BIT(13)
+
 /*
  * Basic SynIC MSRs (HV_X64_MSR_SCONTROL through HV_X64_MSR_EOM
  * and HV_X64_MSR_SINT0 through HV_X64_MSR_SINT15) available
@@ -234,6 +237,30 @@ 
 #define HV_X64_MSR_CRASH_PARAMS		\
 		(1 + (HV_X64_MSR_CRASH_P4 - HV_X64_MSR_CRASH_P0))
 
+/* TSC emulation after migration */
+#define HV_X64_MSR_REENLIGHTENMENT_CONTROL	0x40000106
+
+struct hv_reenlightenment_control {
+	u64 vector:8;
+	u64 reserved1:8;
+	u64 enabled:1;
+	u64 reserved2:15;
+	u64 target_vp:32;
+};
+
+#define HV_X64_MSR_TSC_EMULATION_CONTROL	0x40000107
+#define HV_X64_MSR_TSC_EMULATION_STATUS		0x40000108
+
+struct hv_tsc_emulation_control {
+	u64 enabled:1;
+	u64 reserved:63;
+};
+
+struct hv_tsc_emulation_status {
+	u64 inprogress:1;
+	u64 reserved:63;
+};
+
 #define HV_X64_MSR_HYPERCALL_ENABLE		0x00000001
 #define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT	12
 #define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_MASK	\
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 85eb5fc180c8..9340f41ce8d3 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -251,6 +251,12 @@  static void __init ms_hyperv_init_platform(void)
 	hyperv_setup_mmu_ops();
 	/* Setup the IDT for hypervisor callback */
 	alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector);
+
+	/* Setup the IDT for reenlightenment notifications */
+	if (ms_hyperv.features & HV_X64_ACCESS_REENLIGHTENMENT)
+		alloc_intr_gate(HYPERV_REENLIGHTENMENT_VECTOR,
+				hyperv_reenlightenment_vector);
+
 #endif
 }