Skip to content

Commit

Permalink
Merge pull request #3 from adamfenn/user/afenn/update-to-current-2021…
Browse files Browse the repository at this point in the history
…1007

Update to landed version
  • Loading branch information
allanjude authored Oct 20, 2021
2 parents b7c9d4c + 90a5bb8 commit 6c1fc7c
Show file tree
Hide file tree
Showing 6 changed files with 207 additions and 271 deletions.
131 changes: 0 additions & 131 deletions include/x86/_rdtsc_ordered.h

This file was deleted.

38 changes: 7 additions & 31 deletions include/x86/pvclock.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@
#define X86_PVCLOCK

#include <sys/types.h>
#include <machine/atomic.h>
#include <x86/rdtsc_ordered.h>

#ifdef _KERNEL
#include <sys/timetc.h>
Expand Down Expand Up @@ -104,33 +102,8 @@ pvclock_scale_delta(uint64_t delta, uint32_t mul_frac, int shift)
return (product);
}

static inline uint64_t
pvclock_get_nsec_offset(struct pvclock_vcpu_time_info *ti)
{
uint64_t delta;

delta = rdtsc_ordered() - ti->tsc_timestamp;
return (pvclock_scale_delta(delta, ti->tsc_to_system_mul,
ti->tsc_shift));
}

static inline void
pvclock_read_time_info(struct pvclock_vcpu_time_info *ti,
uint64_t *ns, uint8_t *flags)
{
uint32_t version;

do {
version = atomic_load_acq_32(&ti->version);
*ns = ti->system_time + pvclock_get_nsec_offset(ti);
*flags = ti->flags;
atomic_thread_fence_acq();
} while ((ti->version & 1) != 0 || ti->version != version);
}

#ifdef _KERNEL

typedef struct pvclock_vcpu_time_info *pvclock_get_curcpu_timeinfo_t(void *arg);
typedef struct pvclock_wall_clock *pvclock_get_wallclock_t(void *arg);

struct pvclock_wall_clock {
Expand All @@ -141,20 +114,23 @@ struct pvclock_wall_clock {

struct pvclock {
/* Public; initialized by the caller of 'pvclock_init()': */
pvclock_get_curcpu_timeinfo_t *get_curcpu_ti;
void *get_curcpu_ti_arg;
pvclock_get_wallclock_t *get_wallclock;
void *get_wallclock_arg;
struct pvclock_vcpu_time_info *ti_vcpu0_page;
struct pvclock_vcpu_time_info *timeinfos;
bool stable_flag_supported;

/* Private; initialized by the 'pvclock' API: */
bool vdso_force_unstable;
struct timecounter tc;
struct cdev *cdev;
};

/*
* NOTE: 'pvclock_get_timecount()' and 'pvclock_get_wallclock()' are purely
* transitional; they should be removed after 'dev/xen/timer/timer.c' has been
* migrated to the 'struct pvclock' API.
*/
void pvclock_resume(void);
uint64_t pvclock_get_last_cycles(void);
uint64_t pvclock_tsc_freq(struct pvclock_vcpu_time_info *ti);
uint64_t pvclock_get_timecount(struct pvclock_vcpu_time_info *ti);
void pvclock_get_wallclock(struct pvclock_wall_clock *wc,
Expand Down
4 changes: 3 additions & 1 deletion include/x86/vdso.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@
#define VDSO_TIMEHANDS_MD \
uint32_t th_x86_shift; \
uint32_t th_x86_hpet_idx; \
uint32_t th_res[6];
uint64_t th_x86_pvc_last_systime;\
uint8_t th_x86_pvc_stable_mask; \
uint8_t th_res[15];

#define VDSO_TH_ALGO_X86_TSC VDSO_TH_ALGO_1
#define VDSO_TH_ALGO_X86_HPET VDSO_TH_ALGO_2
Expand Down
66 changes: 12 additions & 54 deletions kvm_clock.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");

#include <vm/vm.h>
#include <vm/pmap.h>
#include <vm/vm_extern.h>

#include <machine/pvclock.h>
#include <x86/kvm.h>
Expand All @@ -73,19 +74,10 @@ struct kvm_clock_softc {

static devclass_t kvm_clock_devclass;

static struct pvclock_vcpu_time_info *kvm_clock_get_curcpu_timeinfo(void *arg);
static struct pvclock_wall_clock *kvm_clock_get_wallclock(void *arg);
static void kvm_clock_system_time_enable(struct kvm_clock_softc *sc);
static void kvm_clock_system_time_enable_pcpu(void *arg);

static struct pvclock_vcpu_time_info *
kvm_clock_get_curcpu_timeinfo(void *arg)
{
struct pvclock_vcpu_time_info *timeinfos = arg;

return (&timeinfos[curcpu]);
}

static struct pvclock_wall_clock *
kvm_clock_get_wallclock(void *arg)
{
Expand Down Expand Up @@ -118,8 +110,8 @@ kvm_clock_identify(driver_t *driver, device_t parent)
u_int regs[4];

kvm_cpuid_get_features(regs);
if ((regs[0] & KVM_FEATURE_CLOCKSOURCE2) == 0 &&
(regs[0] & KVM_FEATURE_CLOCKSOURCE) == 0)
if ((regs[0] &
(KVM_FEATURE_CLOCKSOURCE2 | KVM_FEATURE_CLOCKSOURCE)) == 0)
return;
if (device_find_child(parent, KVM_CLOCK_DEVNAME, -1))
return;
Expand All @@ -133,39 +125,6 @@ kvm_clock_probe(device_t dev)
return (BUS_PROBE_DEFAULT);
}

#if __FreeBSD_version <= 1202000
static void *
malloc_domainset_aligned(size_t size, size_t align,
struct malloc_type *mtp, struct domainset *ds, int flags)
{
void *res;
size_t asize;

KASSERT(align != 0 && powerof2(align),
("malloc_domainset_aligned: wrong align %#zx size %#zx",
align, size));
KASSERT(align <= PAGE_SIZE,
("malloc_domainset_aligned: align %#zx (size %#zx) too large",
align, size));

/*
* Round the allocation size up to the next power of 2,
* because we can only guarantee alignment for
* power-of-2-sized allocations. Further increase the
* allocation size to align if the rounded size is less than
* align, since malloc zones provide alignment equal to their
* size.
*/
asize = size <= align ? align : 1UL << flsl(size - 1);

res = malloc_domainset(asize, mtp, ds, flags);
KASSERT(res == NULL || ((uintptr_t)res & (align - 1)) == 0,
("malloc_domainset_aligned: result not aligned %p size %#zx "
"allocsize %#zx align %#zx", res, size, asize, align));
return (res);
}
#endif

static int
kvm_clock_attach(device_t dev)
{
Expand All @@ -178,18 +137,19 @@ kvm_clock_attach(device_t dev)
if ((regs[0] & KVM_FEATURE_CLOCKSOURCE2) != 0) {
sc->msr_tc = KVM_MSR_SYSTEM_TIME_NEW;
sc->msr_wc = KVM_MSR_WALL_CLOCK_NEW;
} else if ((regs[0] & KVM_FEATURE_CLOCKSOURCE) != 0) {
} else {
KASSERT((regs[0] & KVM_FEATURE_CLOCKSOURCE) != 0,
("Clocksource feature flags disappeared since "
"kvm_clock_identify: regs[0] %#0x.", regs[0]));
sc->msr_tc = KVM_MSR_SYSTEM_TIME;
sc->msr_wc = KVM_MSR_WALL_CLOCK;
} else
return (ENXIO);
}
stable_flag_supported =
((regs[0] & KVM_FEATURE_CLOCKSOURCE_STABLE_BIT) != 0);
(regs[0] & KVM_FEATURE_CLOCKSOURCE_STABLE_BIT) != 0;

/* Set up 'struct pvclock_vcpu_time_info' page(s): */
sc->timeinfos = malloc_domainset_aligned(round_page(mp_ncpus *
sizeof(struct pvclock_vcpu_time_info)), PAGE_SIZE, M_DEVBUF,
DOMAINSET_RR(), M_WAITOK | M_ZERO);
sc->timeinfos = (struct pvclock_vcpu_time_info *)kmem_malloc(mp_ncpus *
sizeof(struct pvclock_vcpu_time_info), M_WAITOK | M_ZERO);
kvm_clock_system_time_enable(sc);

/*
Expand All @@ -201,11 +161,9 @@ kvm_clock_attach(device_t dev)
* leave 'TC_FLAGS_SUSPEND_SAFE' cleared and assume that the system
* time must be re-inited in such cases.
*/
sc->pvc.get_curcpu_ti = kvm_clock_get_curcpu_timeinfo;
sc->pvc.get_curcpu_ti_arg = sc->timeinfos;
sc->pvc.get_wallclock = kvm_clock_get_wallclock;
sc->pvc.get_wallclock_arg = sc;
sc->pvc.ti_vcpu0_page = sc->timeinfos;
sc->pvc.timeinfos = sc->timeinfos;
sc->pvc.stable_flag_supported = stable_flag_supported;
pvclock_init(&sc->pvc, dev, KVM_CLOCK_DEVNAME, KVM_CLOCK_TC_QUALITY, 0);
return (0);
Expand Down
Loading

0 comments on commit 6c1fc7c

Please sign in to comment.