On Sat, Apr 03, 2021 at 10:21:02PM -0500, Scott Cheloha wrote:
> On Fri, Apr 02, 2021 at 10:37:36AM -0700, Mike Larkin wrote:
> > On Thu, Apr 01, 2021 at 06:43:30PM -0500, Scott Cheloha wrote:
> > >
> > > [...]
> > >
> > > Hmmm.  Being able to work around this would be nice.
> > >
> > > FreeBSD has code that uses WRMSR to synchronize the TSC:
> > >
> > > https://cgit.freebsd.org/src/commit/sys/x86/x86/tsc.c?id=b2c63698d4b81576e0c8842263ee86e86cd34e76
> > >
> > > My guess is that support for writing the TSC is not implemented by
> > > every hypervisor, so we would need to be very careful in deciding when
> > > to try it.  Otherwise we end up with protection faults and other crap
> > > we don't want.
> > >
> >
> > We implemented rdmsr_safe for things like this. We could probably do the 
> > same
> > for wrmsr.
>
> Like this?
>
> Sorry if this is not idiomatic.  I don't write much assembly.
>
> I tested this a bit on my laptop.  Stuff like:
>
>       wrmsr_safe(MSR_TSC, rdtsc() + 100);
>
> Which seems to desync the normally synchronized TSCs here.
>
> Unclear what the rules are for RETGUARD.  I just copied what was in
> rdmsr_safe().  We're not using R10 so we can use R10?
>
> -Scott
>
> Index: include/cpufunc.h
> ===================================================================
> RCS file: /cvs/src/sys/arch/amd64/include/cpufunc.h,v
> retrieving revision 1.36
> diff -u -p -r1.36 cpufunc.h
> --- include/cpufunc.h 13 Sep 2020 11:53:16 -0000      1.36
> +++ include/cpufunc.h 4 Apr 2021 03:16:48 -0000
> @@ -398,6 +398,7 @@ struct cpu_info_full;
>  void cpu_enter_pages(struct cpu_info_full *);
>
>  int rdmsr_safe(u_int msr, uint64_t *);
> +int wrmsr_safe(uint32_t msr, uint64_t);
>
>  #endif /* _KERNEL */
>
> Index: amd64/locore.S
> ===================================================================
> RCS file: /cvs/src/sys/arch/amd64/amd64/locore.S,v
> retrieving revision 1.122
> diff -u -p -r1.122 locore.S
> --- amd64/locore.S    3 Nov 2020 18:19:31 -0000       1.122
> +++ amd64/locore.S    4 Apr 2021 03:16:48 -0000
> @@ -1154,6 +1154,30 @@ NENTRY(rdmsr_resume)
>       ret
>  END(rdmsr_safe)
>
> +/* int wrmsr_safe(uint32_t msr, uint64_t val) */
> +ENTRY(wrmsr_safe)
> +     RETGUARD_SETUP(wrmsr_safe, r10)
> +
> +     movl    %edi,   %ecx    /* uint32_t msr */
> +
> +     movl    %esi,   %eax    /* uint64_t val */
> +     sarq    $32,    %rsi
> +     movl    %esi,   %edx
> +
> +     .globl  wrmsr_safe_fault
> +wrmsr_safe_fault:
> +     wrmsr
> +
> +     xorq    %rax,   %rax
> +     RETGUARD_CHECK(rdmsr_safe, r10)
> +     ret
> +
> +NENTRY(wrmsr_resume)
> +     movq    $0x1,   %rax
> +     RETGUARD_CHECK(wrmsr_safe, r10)
> +     ret
> +END(wrmsr_safe)
> +
>  #if NXEN > 0
>       /* Hypercall page needs to be page aligned */
>       .text
>

You will need the handler case in vector.S also (like we did for rdmsr_safe).

(Sorry if this reply hits the list twice; mailer error on previous attempt).

-ml

Reply via email to