[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Minios-devel] [UNIKRAFT PATCH 3/3] plat/kvm: Add KVM (x86_64) timer support
Hi Wei, On 05/09/2018 08:32 AM, Wei Chen wrote: > Hi Costin, > >> -----Original Message----- >> From: Minios-devel <minios-devel-bounces@xxxxxxxxxxxxxxxxxxxx> On Behalf Of >> Costin Lupu >> Sent: 2018年5月1日 7:55 >> To: Simon Kuenzer <simon.kuenzer@xxxxxxxxx>; minios-devel@xxxxxxxxxxxxx >> Subject: Re: [Minios-devel] [UNIKRAFT PATCH 3/3] plat/kvm: Add KVM (x86_64) >> timer support >> >> On 04/30/2018 03:44 PM, Simon Kuenzer wrote: >>> See my comments inline. >>> >>> On 05.04.2018 17:21, Costin Lupu wrote: >>>> We are using TSC clock as main timer on KVM. >>>> >>>> Signed-off-by: Costin Lupu <costin.lupu@xxxxxxxxx> >>>> --- >>>> plat/kvm/Makefile.uk | 3 + >>>> plat/kvm/clock_subr.c | 226 ++++++++++++++++++++++++ >>>> plat/kvm/include/kvm/clock_subr.h | 83 +++++++++ >>>> plat/kvm/include/kvm/tscclock.h | 42 +++++ >>>> plat/kvm/irq.c | 10 ++ >>>> plat/kvm/time.c | 62 +++++++ >>>> plat/kvm/tscclock.c | 356 > > > [...] trimming for easy reading > >>>> +/* >>>> + * Calibrate TSC and initialise TSC clock. >>>> + */ >>>> +int tscclock_init(void) >>>> +{ >>>> + __u64 tsc_freq, rtc_boot; >>>> + >>>> + /* Initialise i8254 timer channel 0 to mode 2 at 100 Hz */ >>>> + outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); >>>> + outb(TIMER_CNTR, (TIMER_HZ / 100) & 0xff); >>>> + outb(TIMER_CNTR, (TIMER_HZ / 100) >> 8); >>>> + >>>> + /* >>>> + * Read RTC "time at boot". This must be done just before >>>> tsc_base is >>>> + * initialised in order to get a correct offset below. >>>> + */ >>>> + rtc_boot = rtc_gettimeofday(); >>>> + >>>> + /* >>>> + * Calculate TSC frequency by calibrating against an 0.1s delay >>>> + * using the i8254 timer. >>>> + */ >>> >>> Wow, this is adds a 100ms boot delay to the Unikernels on KVM. Can you >>> put an TODO comment for revisiting this later? Maybe we can find a >>> different method to get the correct value for the TSC frequency. >> >> Right. >> > > It seems that QEMU-KVM publish TSC frequency to the guest OS in CPUID page > 0x40000010. Can we read the tsc_freq from CPUID just like VMWare does? Thanks for the heads-up. I've tried it, but I don't have a CPUID page 0x40000010. Using the base leaf (0x40000000) to get the maximum page number gives me only a maximum value of 0x40000001. Can you please indicate a reference where you got this information from? Historically speaking, TSCs needed a calibration phase, thus it's part of the classic boot process. Providing the frequency directly must be a PV trick provided by the hypervisor. My guess is there should be some special parameter for it when running QEMU. The timer code for KVM is ported from Solo5 which has 2 timer sources: pvclock and TSC. Most of the existing documentation recommends using the pvclock. I chose TSC because I needed a source for timer interrupts that should also be configurable (for pvclock the frequency is fixed). So maybe a cleaner solution would be either: - using a different timer for generating interrupts and keeping the wall clock time, or - keeping TSC as source for timer interrupts and using pvclock for wall clock time >>>> + tsc_base = rdtsc(); >>>> + i8254_delay(100000); >>>> + tsc_freq = (rdtsc() - tsc_base) * 10; >>>> + uk_printd(DLVL_INFO, >>>> + "Clock source: TSC, frequency estimate is %llu Hz\n", >>>> + (unsigned long long) tsc_freq); //TODO >>>> + >>>> + /* >>>> + * Calculate TSC scaling multiplier. >>>> + * >>>> + * (0.32) tsc_mult = NSEC_PER_SEC (32.32) / tsc_freq (32.0) >>>> + */ >>>> + tsc_mult = (NSEC_PER_SEC << 32) / tsc_freq; >>>> + >>>> + /* >>>> + * Monotonic time begins at tsc_base (first read of TSC before >>>> + * calibration). >>>> + */ >>>> + time_base = mul64_32(tsc_base, tsc_mult); >>>> + >>>> + /* >>>> + * Compute RTC epoch offset by subtracting monotonic time_base >>>> from RTC >>>> + * time at boot. >>>> + */ >>>> + rtc_epochoffset = rtc_boot - time_base; >>>> + >>>> + /* >>>> + * Initialise i8254 timer channel 0 to mode 4 (one shot). >>>> + */ >>>> + outb(TIMER_MODE, TIMER_SEL0 | TIMER_ONESHOT | TIMER_16BIT); >>>> + >>>> + return 0; >>>> +} > > _______________________________________________ > Minios-devel mailing list > Minios-devel@xxxxxxxxxxxxxxxxxxxx > https://lists.xenproject.org/mailman/listinfo/minios-devel > _______________________________________________ Minios-devel mailing list Minios-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/minios-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |