[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH] time: widen wallclock seconds to 64 bits
On 29/01/15 15:39, Jan Beulich wrote: > Linux is in the process of converting their seconds representation to > 64 bits, so in order to support it consistently we should follow suit > (which at some point in quite a few years we'd have to do anyway). To > represent this in struct shared_info we leverage a 32-bit hole in > x86-64's and arm's variant of the structure; for x86-32 guests the only > (reasonable) choice we have is to put the extension in struct > arch_shared_info. > > A note on the conditional suppressing the xen_wc_sec_hi helper macro > definition in the ix86 case for hypervisor and tools: Neither of the > two actually need this, and its presence causes the tools to fail to > build (due to the inclusion of both the x86-64 and x86-32 variants of > the header). > > As a secondary change, x86's do_platform_op() gets a pointless > initializer as well as a pointless assignment of that same variable > dropped. > > Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> > > --- a/tools/include/xen-foreign/Makefile > +++ b/tools/include/xen-foreign/Makefile > @@ -17,7 +17,7 @@ clean: > distclean: clean > > checker: checker.c $(headers) > - $(HOSTCC) $(HOSTCFLAGS) -o $@ $< > + $(HOSTCC) $(HOSTCFLAGS) -D__XEN_TOOLS__ -o $@ $< > > check-headers: checker > ./checker > tmp.size > --- a/tools/include/xen-foreign/reference.size > +++ b/tools/include/xen-foreign/reference.size > @@ -9,6 +9,6 @@ vcpu_guest_context | 344 > arch_vcpu_info | 0 0 24 16 > vcpu_time_info | 32 32 32 32 > vcpu_info | 48 48 64 64 > -arch_shared_info | 0 0 24 48 > -shared_info | 1088 1088 2340 3136 > +arch_shared_info | 0 0 28 48 > +shared_info | 1088 1088 2344 3136 > > --- a/xen/arch/arm/time.c > +++ b/xen/arch/arm/time.c > @@ -239,7 +239,7 @@ void update_vcpu_system_time(struct vcpu > /* XXX update shared_info->wc_* */ > } > > -void domain_set_time_offset(struct domain *d, int32_t time_offset_seconds) > +void domain_set_time_offset(struct domain *d, int64_t time_offset_seconds) > { > d->time_offset_seconds = time_offset_seconds; > /* XXX update guest visible wallclock time */ > --- a/xen/arch/x86/platform_hypercall.c > +++ b/xen/arch/x86/platform_hypercall.c > @@ -187,7 +187,7 @@ static void resource_access(void *info) > > ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) > { > - ret_t ret = 0; > + ret_t ret; > struct xen_platform_op curop, *op = &curop; > > if ( copy_from_guest(op, u_xenpf_op, 1) ) > @@ -212,14 +212,20 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PA > > switch ( op->cmd ) > { > - case XENPF_settime: > - { > - do_settime(op->u.settime.secs, > - op->u.settime.nsecs, > - op->u.settime.system_time); > - ret = 0; > - } > - break; > + case XENPF_settime32: > + do_settime(op->u.settime32.secs, > + op->u.settime32.nsecs, > + op->u.settime32.system_time); > + break; > + > + case XENPF_settime64: > + if ( likely(!op->u.settime64.mbz) ) > + do_settime(op->u.settime64.secs, > + op->u.settime64.nsecs, > + op->u.settime64.system_time); > + else > + ret = -EINVAL; > + break; > > case XENPF_add_memtype: > { > --- a/xen/arch/x86/time.c > +++ b/xen/arch/x86/time.c > @@ -47,7 +47,8 @@ string_param("clocksource", opt_clocksou > unsigned long __read_mostly cpu_khz; /* CPU clock frequency in kHz. */ > DEFINE_SPINLOCK(rtc_lock); > unsigned long pit0_ticks; > -static u32 wc_sec, wc_nsec; /* UTC time at last 'time update'. */ > +static unsigned long wc_sec; /* UTC time at last 'time update'. */ > +static unsigned int wc_nsec; > static DEFINE_SPINLOCK(wc_lock); > > struct cpu_time { > @@ -902,6 +903,7 @@ void force_update_vcpu_system_time(struc > void update_domain_wallclock_time(struct domain *d) > { > uint32_t *wc_version; > + unsigned long sec; > > spin_lock(&wc_lock); > > @@ -909,8 +911,19 @@ void update_domain_wallclock_time(struct > *wc_version = version_update_begin(*wc_version); > wmb(); > > - shared_info(d, wc_sec) = wc_sec + d->time_offset_seconds; > - shared_info(d, wc_nsec) = wc_nsec; > + sec = wc_sec + d->time_offset_seconds; > + if ( likely(!has_32bit_shinfo(d)) ) > + { > + d->shared_info->native.wc_sec = sec; > + d->shared_info->native.wc_nsec = wc_nsec; > + d->shared_info->native.wc_sec_hi = sec >> 32; > + } > + else > + { > + d->shared_info->compat.wc_sec = sec; > + d->shared_info->compat.wc_nsec = wc_nsec; > + d->shared_info->compat.arch.wc_sec_hi = sec >> 32; > + } > > wmb(); > *wc_version = version_update_end(*wc_version); > @@ -931,7 +944,7 @@ static void update_domain_rtc(void) > rcu_read_unlock(&domlist_read_lock); > } > > -void domain_set_time_offset(struct domain *d, int32_t time_offset_seconds) > +void domain_set_time_offset(struct domain *d, int64_t time_offset_seconds) > { > d->time_offset_seconds = time_offset_seconds; > if ( is_hvm_domain(d) ) > @@ -976,13 +989,13 @@ int cpu_frequency_change(u64 freq) > } > > /* Set clock to <secs,usecs> after 00:00:00 UTC, 1 January, 1970. */ > -void do_settime(unsigned long secs, unsigned long nsecs, u64 > system_time_base) > +void do_settime(unsigned long secs, unsigned int nsecs, u64 system_time_base) > { > u64 x; > u32 y; > struct domain *d; > > - x = SECONDS(secs) + (u64)nsecs - system_time_base; > + x = SECONDS(secs) + nsecs - system_time_base; > y = do_div(x, 1000000000); > > spin_lock(&wc_lock); > --- a/xen/include/public/arch-arm.h > +++ b/xen/include/public/arch-arm.h > @@ -165,6 +165,7 @@ > > #define XEN_HYPERCALL_TAG 0XEA1 > > +#define int64_aligned_t int64_t __attribute__((aligned(8))) > #define uint64_aligned_t uint64_t __attribute__((aligned(8))) > > #ifndef __ASSEMBLY__ > --- a/xen/include/public/arch-x86/xen.h > +++ b/xen/include/public/arch-x86/xen.h > @@ -255,6 +255,10 @@ struct arch_shared_info { > unsigned long p2m_cr3; /* cr3 value of the p2m address space */ > unsigned long p2m_vaddr; /* virtual address of the p2m list */ > unsigned long p2m_generation; /* generation count of p2m mapping */ > +#ifdef __i386__ > + /* There's no room for this field in the generic structure. */ > + uint32_t wc_sec_hi; > +#endif > }; > typedef struct arch_shared_info arch_shared_info_t; > > --- a/xen/include/public/arch-x86/xen-x86_32.h > +++ b/xen/include/public/arch-x86/xen-x86_32.h > @@ -104,6 +104,7 @@ > do { if ( sizeof(hnd) == 8 ) *(uint64_t *)&(hnd) = 0; \ > (hnd).p = val; \ > } while ( 0 ) > +#define int64_aligned_t int64_t __attribute__((aligned(8))) > #define uint64_aligned_t uint64_t __attribute__((aligned(8))) > #define __XEN_GUEST_HANDLE_64(name) __guest_handle_64_ ## name > #define XEN_GUEST_HANDLE_64(name) __XEN_GUEST_HANDLE_64(name) > --- a/xen/include/public/domctl.h > +++ b/xen/include/public/domctl.h > @@ -37,7 +37,7 @@ > #include "hvm/save.h" > #include "memory.h" > > -#define XEN_DOMCTL_INTERFACE_VERSION 0x0000000a > +#define XEN_DOMCTL_INTERFACE_VERSION 0x0000000b > > /* > * NB. xen_domctl.domain is an IN/OUT parameter for this operation. > @@ -449,7 +449,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_hyper > > /* XEN_DOMCTL_settimeoffset */ > struct xen_domctl_settimeoffset { > - int32_t time_offset_seconds; /* applied to domain wallclock time */ > + int64_aligned_t time_offset_seconds; /* applied to domain wallclock time > */ > }; > typedef struct xen_domctl_settimeoffset xen_domctl_settimeoffset_t; > DEFINE_XEN_GUEST_HANDLE(xen_domctl_settimeoffset_t); > --- a/xen/include/public/platform.h > +++ b/xen/include/public/platform.h > @@ -35,13 +35,28 @@ > * Set clock such that it would read <secs,nsecs> after 00:00:00 UTC, > * 1 January, 1970 if the current system time was <system_time>. > */ > -#define XENPF_settime 17 > -struct xenpf_settime { > +#define XENPF_settime32 17 > +struct xenpf_settime32 { > /* IN variables. */ > uint32_t secs; > uint32_t nsecs; > uint64_t system_time; > }; > +#define XENPF_settime64 62 > +struct xenpf_settime64 { > + /* IN variables. */ > + uint64_t secs; > + uint32_t nsecs; > + uint32_t mbz; > + uint64_t system_time; > +}; > +#if __XEN_INTERFACE_VERSION__ < 0x00040600 > +#define XENPF_settime XENPF_settime32 > +#define xenpf_settime xenpf_settime32 > +#else > +#define XENPF_settime XENPF_settime64 > +#define xenpf_settime xenpf_settime64 > +#endif > typedef struct xenpf_settime xenpf_settime_t; > DEFINE_XEN_GUEST_HANDLE(xenpf_settime_t); > > @@ -579,6 +594,8 @@ struct xen_platform_op { > uint32_t interface_version; /* XENPF_INTERFACE_VERSION */ > union { > struct xenpf_settime settime; > + struct xenpf_settime32 settime32; > + struct xenpf_settime64 settime64; > struct xenpf_add_memtype add_memtype; > struct xenpf_del_memtype del_memtype; > struct xenpf_read_memtype read_memtype; > --- a/xen/include/public/xen.h > +++ b/xen/include/public/xen.h > @@ -682,6 +682,12 @@ struct shared_info { > uint32_t wc_version; /* Version counter: see vcpu_time_info_t. */ > uint32_t wc_sec; /* Secs 00:00:00 UTC, Jan 1, 1970. */ > uint32_t wc_nsec; /* Nsecs 00:00:00 UTC, Jan 1, 1970. */ > +#if !defined(__i386__) > + uint32_t wc_sec_hi; > +# define xen_wc_sec_hi wc_sec_hi > +#elif !defined(__XEN__) && !defined(__XEN_TOOLS__) > +# define xen_wc_sec_hi arch.wc_sec_hi > +#endif > > struct arch_shared_info arch; > > @@ -870,6 +876,9 @@ __DEFINE_XEN_GUEST_HANDLE(uint64, uint64 > /* Default definitions for macros used by domctl/sysctl. */ > #if defined(__XEN__) || defined(__XEN_TOOLS__) > > +#ifndef int64_aligned_t > +#define int64_aligned_t int64_t > +#endif > #ifndef uint64_aligned_t > #define uint64_aligned_t uint64_t > #endif > --- a/xen/include/xen/sched.h > +++ b/xen/include/xen/sched.h > @@ -359,7 +359,7 @@ struct domain > /* Domain is paused by controller software? */ > int controller_pause_count; > > - int32_t time_offset_seconds; > + int64_t time_offset_seconds; > > #ifdef HAS_PASSTHROUGH > /* Does this guest need iommu mappings (-1 meaning "being set up")? */ > --- a/xen/include/xen/time.h > +++ b/xen/include/xen/time.h > @@ -65,11 +65,11 @@ extern void update_vcpu_system_time(stru > extern void update_domain_wallclock_time(struct domain *d); > > extern void do_settime( > - unsigned long secs, unsigned long nsecs, u64 system_time_base); > + unsigned long secs, unsigned int nsecs, u64 system_time_base); > > extern void send_timer_event(struct vcpu *v); > > -void domain_set_time_offset(struct domain *d, int32_t time_offset_seconds); > +void domain_set_time_offset(struct domain *d, int64_t time_offset_seconds); > > #include <asm/time.h> > > --- a/xen/xsm/flask/hooks.c > +++ b/xen/xsm/flask/hooks.c > @@ -1365,7 +1365,8 @@ static int flask_platform_op(uint32_t op > return 0; > #endif > > - case XENPF_settime: > + case XENPF_settime32: > + case XENPF_settime64: > return domain_has_xen(current->domain, XEN__SETTIME); > > case XENPF_add_memtype: > --- a/xen/xsm/flask/policy/access_vectors > +++ b/xen/xsm/flask/policy/access_vectors > @@ -8,7 +8,8 @@ > # executing the hypercall, and the target is the xen initial sid (type > xen_t). > class xen > { > -# XENPF_settime > +# XENPF_settime32 > +# XENPF_settime64 > settime > # XEN_SYSCTL_tbuf_op > tbufcontrol > > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |