diff options
author | gibbs <gibbs@FreeBSD.org> | 2013-08-29 23:11:58 +0000 |
---|---|---|
committer | gibbs <gibbs@FreeBSD.org> | 2013-08-29 23:11:58 +0000 |
commit | f5ff33730e4d7c8ed7baf90dfb75a20ee45fdfd0 (patch) | |
tree | d3a1d0f880bba269983f967cc4477ca719a19d07 /sys/i386/xen/xen_clock_util.c | |
parent | 76248c6467c383919f68dde031fabc532f64d2f0 (diff) | |
download | FreeBSD-src-f5ff33730e4d7c8ed7baf90dfb75a20ee45fdfd0.zip FreeBSD-src-f5ff33730e4d7c8ed7baf90dfb75a20ee45fdfd0.tar.gz |
Introduce a new, HVM compatible, paravirtualized timer driver for Xen.
Use this new driver for both PV and HVM instances.
This driver requires a Xen hypervisor that supports vector callbacks,
VCPUOP hypercalls, and reports that it has a "safe PV clock".
New timer driver:
Submitted by: will
Sponsored by: Spectra Logic Corporation
PV port to new driver, and bug fixes:
Submitted by: Roger Pau Monné
Sponsored by: Citrix Systems R&D
sys/dev/xen/timer/timer.c:
- Register a PV timer device driver which (currently)
implements device_{identify,probe,attach} and stubs
device_detach. The detach routine requires functionality
not provided by timecounters(4). The suspend and resume
routines need additional work (due to Xen requiring that
the hypercalls be executed on the target VCPU), and aren't
needed for our purposes.
- Make sure there can only be one device instance of this
driver, and that it only registers one eventtimers(4) and
one timecounters(4) device interface. Make both interfaces
use PCPU data as needed.
- Match, with a few style cleanups & API differences, the
Xen versions of the "fetch time" functions.
- Document the magic scale_delta() better for the i386 version.
- When registering the event timer, bind a separate event
channel for the timer VIRQ to the device's event timer
interrupt handler for each active VCPU. Describe each
interrupt as "xen_et:c%d", so they can be identified per
CPU in "vmstat -i" or "show intrcnt" in KDB.
- When scheduling a timer into the hypervisor, try up to
60 times if the hypervisor rejects the time as being in
the past. In the common case, this retry shouldn't happen,
and if it does, it should only happen once. This is
because the event timer advertises a minimum period of
100usec, which is only less than the usual hypercall round
trip time about 1 out of every 100 tries. (Unlike other
similar drivers, this one actually checks whether the
hypervisor accepted the singleshot timer set hypercall.)
- Implement a RTC PV clock based on the hypervisor wallclock.
sys/conf/files:
- Add dev/xen/timer/timer.c if the kernel configuration
includes either the XEN or XENHVM options.
sys/conf/files.i386:
sys/i386/include/xen/xen_clock_util.h:
sys/i386/xen/clock.c:
sys/i386/xen/xen_clock_util.c:
sys/i386/xen/mp_machdep.c:
sys/i386/xen/xen_rtc.c:
- Remove previous PV timer used in i386 XEN PV kernels, the
new timer introduced in this change is used instead (so
we share the same code between PVHVM and PV).
MFC after: 2 weeks
Diffstat (limited to 'sys/i386/xen/xen_clock_util.c')
-rw-r--r-- | sys/i386/xen/xen_clock_util.c | 102 |
1 files changed, 0 insertions, 102 deletions
diff --git a/sys/i386/xen/xen_clock_util.c b/sys/i386/xen/xen_clock_util.c deleted file mode 100644 index c124515..0000000 --- a/sys/i386/xen/xen_clock_util.c +++ /dev/null @@ -1,102 +0,0 @@ -/*- - * Copyright (c) 2009 Adrian Chadd - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/bus.h> -#include <sys/clock.h> -#include <sys/lock.h> -#include <sys/mutex.h> -#include <sys/kernel.h> -#include <sys/module.h> -#include <sys/time.h> - -#include <xen/xen-os.h> -#include <xen/xen_intr.h> - -#include <vm/vm.h> -#include <vm/pmap.h> -#include <machine/pmap.h> -#include <xen/hypervisor.h> -#include <machine/xen/xenfunc.h> -#include <xen/interface/io/xenbus.h> -#include <xen/interface/vcpu.h> -#include <machine/cpu.h> - -#include <machine/xen/xen_clock_util.h> - -/* - * Read the current hypervisor start time (wall clock) from Xen. - */ -void -xen_fetch_wallclock(struct timespec *ts) -{ - shared_info_t *s = HYPERVISOR_shared_info; - uint32_t ts_version; - - do { - ts_version = s->wc_version; - rmb(); - ts->tv_sec = s->wc_sec; - ts->tv_nsec = s->wc_nsec; - rmb(); - } - while ((s->wc_version & 1) | (ts_version ^ s->wc_version)); -} - -/* - * Read the current hypervisor system uptime value from Xen. - */ -void -xen_fetch_uptime(struct timespec *ts) -{ - shared_info_t *s = HYPERVISOR_shared_info; - struct vcpu_time_info *src; - struct shadow_time_info dst; - uint32_t pre_version, post_version; - - src = &s->vcpu_info[smp_processor_id()].time; - - spinlock_enter(); - do { - pre_version = dst.version = src->version; - rmb(); - dst.system_timestamp = src->system_time; - rmb(); - post_version = src->version; - } - while ((pre_version & 1) | (pre_version ^ post_version)); - - spinlock_exit(); - - ts->tv_sec = dst.system_timestamp / 1000000000; - ts->tv_nsec = dst.system_timestamp % 1000000000; -} |