return do_dom0_op(xc_handle, &op);
}
+int xc_domain_set_time_offset(int xc_handle,
+ uint32_t domid,
+ int32_t time_offset_seconds)
+{
+ DECLARE_DOM0_OP;
+ op.cmd = DOM0_SETTIMEOFFSET;
+ op.u.settimeoffset.domain = (domid_t)domid;
+ op.u.settimeoffset.time_offset_seconds = time_offset_seconds;
+ return do_dom0_op(xc_handle, &op);
+}
+
int xc_domain_memory_increase_reservation(int xc_handle,
uint32_t domid,
unsigned long nr_extents,
uint32_t domid,
unsigned int max_memkb);
+int xc_domain_set_time_offset(int xc_handle,
+ uint32_t domid,
+ int32_t time_offset_seconds);
+
int xc_domain_memory_increase_reservation(int xc_handle,
uint32_t domid,
unsigned long nr_extents,
return zero;
}
+static PyObject *pyxc_domain_set_time_offset(XcObject *self, PyObject *args)
+{
+ uint32_t dom;
+ int32_t time_offset_seconds;
+ time_t calendar_time;
+ struct tm local_time;
+ struct tm utc_time;
+
+ if (!PyArg_ParseTuple(args, "i", &dom))
+ return NULL;
+
+ calendar_time = time(NULL);
+ localtime_r(&calendar_time, &local_time);
+ gmtime_r(&calendar_time, &utc_time);
+ /* set up to get calendar time based on utc_time, with local dst setting */
+ utc_time.tm_isdst = local_time.tm_isdst;
+ time_offset_seconds = (int32_t)difftime(calendar_time, mktime(&utc_time));
+
+ if (xc_domain_set_time_offset(self->xc_handle, dom, time_offset_seconds) != 0)
+ return NULL;
+
+ Py_INCREF(zero);
+ return zero;
+}
static PyObject *dom_op(XcObject *self, PyObject *args,
int (*fn)(int, uint32_t))
"Returns: [int]: The size in KiB of memory spanning the given number "
"of pages.\n" },
+ { "domain_set_time_offset",
+ (PyCFunction)pyxc_domain_set_time_offset,
+ METH_VARARGS, "\n"
+ "Set a domain's time offset to Dom0's localtime\n"
+ " dom [int]: Domain whose time offset is being set.\n"
+ "Returns: [int] 0 on success; -1 on error.\n" },
+
{ NULL, NULL, 0, NULL }
};
('bootloader', str),
('bootloader_args', str),
('features', str),
+ ('localtime', int),
]
ROUNDTRIPPING_CONFIG_ENTRIES += VM_CONFIG_PARAMS
self.info['image'],
self.info['device'])
+ localtime = self.info['localtime']
+ if localtime is not None and localtime == 1:
+ xc.domain_set_time_offset(self.domid)
+
xc.domain_setcpuweight(self.domid, self.info['cpu_weight'])
# repin domain vcpus if a restricted cpus list is provided
config.append(['backend', ['netif']])
if vals.tpmif:
config.append(['backend', ['tpmif']])
+ if vals.localtime:
+ config.append(['localtime', vals.localtime])
config_image = configure_image(vals)
if vals.bootloader:
{
spin_lock(&wc_lock);
version_update_begin(&d->shared_info->wc_version);
- d->shared_info->wc_sec = wc_sec;
+ d->shared_info->wc_sec = wc_sec + d->time_offset_seconds;
d->shared_info->wc_nsec = wc_nsec;
version_update_end(&d->shared_info->wc_version);
spin_unlock(&wc_lock);
break;
#endif
+ case DOM0_SETTIMEOFFSET:
+ {
+ struct domain *d;
+
+ ret = -ESRCH;
+ d = find_domain_by_id(op->u.settimeoffset.domain);
+ if ( d != NULL )
+ {
+ d->time_offset_seconds = op->u.settimeoffset.time_offset_seconds;
+ put_domain(d);
+ ret = 0;
+ }
+ }
+ break;
+
default:
ret = arch_do_dom0_op(op, u_dom0_op);
break;
} dom0_domain_setup_t;
DEFINE_XEN_GUEST_HANDLE(dom0_domain_setup_t);
+#define DOM0_SETTIMEOFFSET 50
+struct dom0_settimeoffset {
+ domid_t domain;
+ int32_t time_offset_seconds; /* applied to domain wallclock time */
+};
+typedef struct dom0_settimeoffset dom0_settimeoffset_t;
+DEFINE_XEN_GUEST_HANDLE(dom0_settimeoffset_t);
+
struct dom0_op {
uint32_t cmd;
uint32_t interface_version; /* DOM0_INTERFACE_VERSION */
struct dom0_iomem_permission iomem_permission;
struct dom0_hypercall_init hypercall_init;
struct dom0_domain_setup domain_setup;
+ struct dom0_settimeoffset settimeoffset;
uint8_t pad[128];
} u;
};
/* OProfile support. */
struct xenoprof *xenoprof;
+ int32_t time_offset_seconds;
};
struct domain_setup_info