[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.