Merge branch 'upstream/xen-settime' of git://git.kernel.org/pub/scm/linux/kernel...
Linus Torvalds [Mon, 7 Nov 2011 04:15:05 +0000 (20:15 -0800)]
* 'upstream/xen-settime' of git://git.kernel.org/pub/scm/linux/kernel/git/jeremy/xen:
  xen/dom0: set wallclock time in Xen
  xen: add dom0_op hypercall
  xen/acpi: Domain0 acpi parser related platform hypercall

1  2 
arch/x86/include/asm/xen/hypercall.h
arch/x86/xen/time.c
include/xen/interface/xen.h

  #include <linux/string.h>
  #include <linux/types.h>
  
 +#include <trace/events/xen.h>
 +
  #include <asm/page.h>
  #include <asm/pgtable.h>
  
  #include <xen/interface/xen.h>
  #include <xen/interface/sched.h>
  #include <xen/interface/physdev.h>
+ #include <xen/interface/platform.h>
  
  /*
   * The hypercall asms have to meet several constraints:
@@@ -301,6 -300,13 +302,13 @@@ HYPERVISOR_set_timer_op(u64 timeout
  }
  
  static inline int
+ HYPERVISOR_dom0_op(struct xen_platform_op *platform_op)
+ {
+       platform_op->interface_version = XENPF_INTERFACE_VERSION;
+       return _hypercall1(int, dom0_op, platform_op);
+ }
+ static inline int
  HYPERVISOR_set_debugreg(int reg, unsigned long value)
  {
        return _hypercall2(int, set_debugreg, reg, value);
@@@ -461,8 -467,6 +469,8 @@@ MULTI_fpu_taskswitch(struct multicall_e
  {
        mcl->op = __HYPERVISOR_fpu_taskswitch;
        mcl->args[0] = set;
 +
 +      trace_xen_mc_entry(mcl, 1);
  }
  
  static inline void
@@@ -479,8 -483,6 +487,8 @@@ MULTI_update_va_mapping(struct multical
                mcl->args[2] = new_val.pte >> 32;
                mcl->args[3] = flags;
        }
 +
 +      trace_xen_mc_entry(mcl, sizeof(new_val) == sizeof(long) ? 3 : 4);
  }
  
  static inline void
@@@ -491,8 -493,6 +499,8 @@@ MULTI_grant_table_op(struct multicall_e
        mcl->args[0] = cmd;
        mcl->args[1] = (unsigned long)uop;
        mcl->args[2] = count;
 +
 +      trace_xen_mc_entry(mcl, 3);
  }
  
  static inline void
@@@ -512,8 -512,6 +520,8 @@@ MULTI_update_va_mapping_otherdomain(str
                mcl->args[3] = flags;
                mcl->args[4] = domid;
        }
 +
 +      trace_xen_mc_entry(mcl, sizeof(new_val) == sizeof(long) ? 4 : 5);
  }
  
  static inline void
@@@ -530,8 -528,6 +538,8 @@@ MULTI_update_descriptor(struct multical
                mcl->args[2] = desc.a;
                mcl->args[3] = desc.b;
        }
 +
 +      trace_xen_mc_entry(mcl, sizeof(maddr) == sizeof(long) ? 2 : 4);
  }
  
  static inline void
@@@ -540,8 -536,6 +548,8 @@@ MULTI_memory_op(struct multicall_entry 
        mcl->op = __HYPERVISOR_memory_op;
        mcl->args[0] = cmd;
        mcl->args[1] = (unsigned long)arg;
 +
 +      trace_xen_mc_entry(mcl, 2);
  }
  
  static inline void
@@@ -553,8 -547,6 +561,8 @@@ MULTI_mmu_update(struct multicall_entr
        mcl->args[1] = count;
        mcl->args[2] = (unsigned long)success_count;
        mcl->args[3] = domid;
 +
 +      trace_xen_mc_entry(mcl, 4);
  }
  
  static inline void
@@@ -566,8 -558,6 +574,8 @@@ MULTI_mmuext_op(struct multicall_entry 
        mcl->args[1] = count;
        mcl->args[2] = (unsigned long)success_count;
        mcl->args[3] = domid;
 +
 +      trace_xen_mc_entry(mcl, 4);
  }
  
  static inline void
@@@ -576,8 -566,6 +584,8 @@@ MULTI_set_gdt(struct multicall_entry *m
        mcl->op = __HYPERVISOR_set_gdt;
        mcl->args[0] = (unsigned long)frames;
        mcl->args[1] = entries;
 +
 +      trace_xen_mc_entry(mcl, 2);
  }
  
  static inline void
@@@ -587,8 -575,6 +595,8 @@@ MULTI_stack_switch(struct multicall_ent
        mcl->op = __HYPERVISOR_stack_switch;
        mcl->args[0] = ss;
        mcl->args[1] = esp;
 +
 +      trace_xen_mc_entry(mcl, 2);
  }
  
  #endif /* _ASM_X86_XEN_HYPERCALL_H */
diff --combined arch/x86/xen/time.c
@@@ -168,10 -168,9 +168,10 @@@ cycle_t xen_clocksource_read(void
          struct pvclock_vcpu_time_info *src;
        cycle_t ret;
  
 -      src = &get_cpu_var(xen_vcpu)->time;
 +      preempt_disable_notrace();
 +      src = &__get_cpu_var(xen_vcpu)->time;
        ret = pvclock_clocksource_read(src);
 -      put_cpu_var(xen_vcpu);
 +      preempt_enable_notrace();
        return ret;
  }
  
@@@ -201,8 -200,22 +201,22 @@@ static unsigned long xen_get_wallclock(
  
  static int xen_set_wallclock(unsigned long now)
  {
+       struct xen_platform_op op;
+       int rc;
        /* do nothing for domU */
-       return -1;
+       if (!xen_initial_domain())
+               return -1;
+       op.cmd = XENPF_settime;
+       op.u.settime.secs = now;
+       op.u.settime.nsecs = 0;
+       op.u.settime.system_time = xen_clocksource_read();
+       rc = HYPERVISOR_dom0_op(&op);
+       WARN(rc != 0, "XENPF_settime failed: now=%ld\n", now);
+       return rc;
  }
  
  static struct clocksource xen_clocksource __read_mostly = {
@@@ -450,48 -450,10 +450,49 @@@ struct start_info 
        int8_t cmd_line[MAX_GUEST_CMDLINE];
  };
  
 +struct dom0_vga_console_info {
 +      uint8_t video_type;
 +#define XEN_VGATYPE_TEXT_MODE_3 0x03
 +#define XEN_VGATYPE_VESA_LFB    0x23
 +
 +      union {
 +              struct {
 +                      /* Font height, in pixels. */
 +                      uint16_t font_height;
 +                      /* Cursor location (column, row). */
 +                      uint16_t cursor_x, cursor_y;
 +                      /* Number of rows and columns (dimensions in characters). */
 +                      uint16_t rows, columns;
 +              } text_mode_3;
 +
 +              struct {
 +                      /* Width and height, in pixels. */
 +                      uint16_t width, height;
 +                      /* Bytes per scan line. */
 +                      uint16_t bytes_per_line;
 +                      /* Bits per pixel. */
 +                      uint16_t bits_per_pixel;
 +                      /* LFB physical address, and size (in units of 64kB). */
 +                      uint32_t lfb_base;
 +                      uint32_t lfb_size;
 +                      /* RGB mask offsets and sizes, as defined by VBE 1.2+ */
 +                      uint8_t  red_pos, red_size;
 +                      uint8_t  green_pos, green_size;
 +                      uint8_t  blue_pos, blue_size;
 +                      uint8_t  rsvd_pos, rsvd_size;
 +
 +                      /* VESA capabilities (offset 0xa, VESA command 0x4f00). */
 +                      uint32_t gbl_caps;
 +                      /* Mode attributes (offset 0x0, VESA command 0x4f01). */
 +                      uint16_t mode_attrs;
 +              } vesa_lfb;
 +      } u;
 +};
 +
  /* These flags are passed in the 'flags' field of start_info_t. */
  #define SIF_PRIVILEGED    (1<<0)  /* Is the domain privileged? */
  #define SIF_INITDOMAIN    (1<<1)  /* Is this the initial control domain? */
+ #define SIF_PM_MASK       (0xFF<<8) /* reserve 1 byte for xen-pm options */
  
  typedef uint64_t cpumap_t;