|
[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 |