* RTC fixes (Artem)

* icount fixes (Artem)
 * rr fixes (Pavel, myself)
 * hotplug cleanup (Igor)
 * SCSI fixes (myself)
 * 4.20-rc1 KVM header update (myself)
 * coalesced PIO support (Peng Hao)
 * HVF fixes (Roman B.)
 * Hyper-V refactoring (Roman K.)
 * Support for Hyper-V IPI (Vitaly)
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQEcBAABAgAGBQJbycRuAAoJEL/70l94x66DGL4H/00Gu/+0dNlpxt6hYVaJ30jX
 vFCsZoglBJ060M8m0C9roTF7zdIgI/X0oxJKWNaxqCDD0GSL5oM1AfG0DCsEBq6X
 ApHYfBOh6mMWuB2qzV9QkK0b2u7+g9J8pQQYfZlU+QNtmUUmbzBxV4h7oqOoedJZ
 nTJrkYzBg88bLDXUAuFrnMhaktqzPvyhdD36vUX5Kc9Hk9R3krtEenc/XKfEJg+o
 n1DX9QeAWgi3MdhkhXSaNSnAu2k2+/qJDmOPk1r63ft5ZfaUKOaVecU06ioiEmrc
 KJd6EYeRvh2eIpbOCGSEVDrieGVBOPvqYg0ryWroxSveoPqJZh5ys9MdIjD+8zg=
 =4XhC
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging

* RTC fixes (Artem)
* icount fixes (Artem)
* rr fixes (Pavel, myself)
* hotplug cleanup (Igor)
* SCSI fixes (myself)
* 4.20-rc1 KVM header update (myself)
* coalesced PIO support (Peng Hao)
* HVF fixes (Roman B.)
* Hyper-V refactoring (Roman K.)
* Support for Hyper-V IPI (Vitaly)

# gpg: Signature made Fri 19 Oct 2018 12:47:58 BST
# gpg:                using RSA key BFFBD25F78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>"
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>"
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* remotes/bonzini/tags/for-upstream: (47 commits)
  replay: pass raw icount value to replay_save_clock
  target/i386: kvm: just return after migrate_add_blocker failed
  hyperv_testdev: add SynIC message and event testmodes
  hyperv: process POST_MESSAGE hypercall
  hyperv: add support for KVM_HYPERV_EVENTFD
  hyperv: process SIGNAL_EVENT hypercall
  hyperv: add synic event flag signaling
  hyperv: add synic message delivery
  hyperv: make overlay pages for SynIC
  hyperv: only add SynIC in compatible configurations
  hyperv: qom-ify SynIC
  hyperv:synic: split capability testing and setting
  i386: add hyperv-stub for CONFIG_HYPERV=n
  default-configs: collect CONFIG_HYPERV* in hyperv.mak
  hyperv: factor out arch-independent API into hw/hyperv
  hyperv: make hyperv_vp_index inline
  hyperv: split hyperv-proto.h into x86 and arch-independent parts
  hyperv: rename kvm_hv_sint_route_set_sint
  hyperv: make HvSintRoute reference-counted
  hyperv: address HvSintRoute by X86CPU pointer
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2018-10-19 19:01:07 +01:00
commit b312532fd0
58 changed files with 1876 additions and 688 deletions

110
vl.c
View file

@ -147,8 +147,15 @@ bool enable_cpu_pm = false;
int nb_nics;
NICInfo nd_table[MAX_NICS];
int autostart;
static int rtc_utc = 1;
static int rtc_date_offset = -1; /* -1 means no change */
static enum {
RTC_BASE_UTC,
RTC_BASE_LOCALTIME,
RTC_BASE_DATETIME,
} rtc_base_type = RTC_BASE_UTC;
static time_t rtc_ref_start_datetime;
static int rtc_realtime_clock_offset; /* used only with QEMU_CLOCK_REALTIME */
static int rtc_host_datetime_offset = -1; /* valid & used only with
RTC_BASE_DATETIME */
QEMUClockType rtc_clock;
int vga_interface_type = VGA_NONE;
static DisplayOptions dpy;
@ -242,6 +249,7 @@ static struct {
static QemuOptsList qemu_rtc_opts = {
.name = "rtc",
.head = QTAILQ_HEAD_INITIALIZER(qemu_rtc_opts.head),
.merge_lists = true,
.desc = {
{
.name = "base",
@ -780,28 +788,42 @@ void qemu_system_vmstop_request(RunState state)
}
/***********************************************************/
/* real time host monotonic timer */
static time_t qemu_time(void)
/* RTC reference time/date access */
static time_t qemu_ref_timedate(QEMUClockType clock)
{
return qemu_clock_get_ms(QEMU_CLOCK_HOST) / 1000;
time_t value = qemu_clock_get_ms(clock) / 1000;
switch (clock) {
case QEMU_CLOCK_REALTIME:
value -= rtc_realtime_clock_offset;
/* no break */
case QEMU_CLOCK_VIRTUAL:
value += rtc_ref_start_datetime;
break;
case QEMU_CLOCK_HOST:
if (rtc_base_type == RTC_BASE_DATETIME) {
value -= rtc_host_datetime_offset;
}
break;
default:
assert(0);
}
return value;
}
/***********************************************************/
/* host time/date access */
void qemu_get_timedate(struct tm *tm, int offset)
{
time_t ti = qemu_time();
time_t ti = qemu_ref_timedate(rtc_clock);
ti += offset;
if (rtc_date_offset == -1) {
if (rtc_utc)
gmtime_r(&ti, tm);
else
localtime_r(&ti, tm);
} else {
ti -= rtc_date_offset;
switch (rtc_base_type) {
case RTC_BASE_DATETIME:
case RTC_BASE_UTC:
gmtime_r(&ti, tm);
break;
case RTC_BASE_LOCALTIME:
localtime_r(&ti, tm);
break;
}
}
@ -809,23 +831,28 @@ int qemu_timedate_diff(struct tm *tm)
{
time_t seconds;
if (rtc_date_offset == -1)
if (rtc_utc)
seconds = mktimegm(tm);
else {
struct tm tmp = *tm;
tmp.tm_isdst = -1; /* use timezone to figure it out */
seconds = mktime(&tmp);
}
else
seconds = mktimegm(tm) + rtc_date_offset;
switch (rtc_base_type) {
case RTC_BASE_DATETIME:
case RTC_BASE_UTC:
seconds = mktimegm(tm);
break;
case RTC_BASE_LOCALTIME:
{
struct tm tmp = *tm;
tmp.tm_isdst = -1; /* use timezone to figure it out */
seconds = mktime(&tmp);
break;
}
default:
abort();
}
return seconds - qemu_time();
return seconds - qemu_ref_timedate(QEMU_CLOCK_HOST);
}
static void configure_rtc_date_offset(const char *startdate)
static void configure_rtc_base_datetime(const char *startdate)
{
time_t rtc_start_date;
time_t rtc_start_datetime;
struct tm tm;
if (sscanf(startdate, "%d-%d-%dT%d:%d:%d", &tm.tm_year, &tm.tm_mon,
@ -841,33 +868,40 @@ static void configure_rtc_date_offset(const char *startdate)
}
tm.tm_year -= 1900;
tm.tm_mon--;
rtc_start_date = mktimegm(&tm);
if (rtc_start_date == -1) {
rtc_start_datetime = mktimegm(&tm);
if (rtc_start_datetime == -1) {
date_fail:
error_report("invalid date format");
error_report("invalid datetime format");
error_printf("valid formats: "
"'2006-06-17T16:01:21' or '2006-06-17'\n");
exit(1);
}
rtc_date_offset = qemu_time() - rtc_start_date;
rtc_host_datetime_offset = rtc_ref_start_datetime - rtc_start_datetime;
rtc_ref_start_datetime = rtc_start_datetime;
}
static void configure_rtc(QemuOpts *opts)
{
const char *value;
/* Set defaults */
rtc_clock = QEMU_CLOCK_HOST;
rtc_ref_start_datetime = qemu_clock_get_ms(QEMU_CLOCK_HOST) / 1000;
rtc_realtime_clock_offset = qemu_clock_get_ms(QEMU_CLOCK_REALTIME) / 1000;
value = qemu_opt_get(opts, "base");
if (value) {
if (!strcmp(value, "utc")) {
rtc_utc = 1;
rtc_base_type = RTC_BASE_UTC;
} else if (!strcmp(value, "localtime")) {
Error *blocker = NULL;
rtc_utc = 0;
rtc_base_type = RTC_BASE_LOCALTIME;
error_setg(&blocker, QERR_REPLAY_NOT_SUPPORTED,
"-rtc base=localtime");
replay_add_blocker(blocker);
} else {
configure_rtc_date_offset(value);
rtc_base_type = RTC_BASE_DATETIME;
configure_rtc_base_datetime(value);
}
}
value = qemu_opt_get(opts, "clock");
@ -3017,7 +3051,6 @@ int main(int argc, char **argv, char **envp)
error_reportf_err(err, "cannot initialize crypto: ");
exit(1);
}
rtc_clock = QEMU_CLOCK_HOST;
QLIST_INIT (&vm_change_state_head);
os_setup_early_signal_handling();
@ -3737,7 +3770,6 @@ int main(int argc, char **argv, char **envp)
if (!opts) {
exit(1);
}
configure_rtc(opts);
break;
case QEMU_OPTION_tb_size:
#ifndef CONFIG_TCG
@ -3955,6 +3987,8 @@ int main(int argc, char **argv, char **envp)
exit(EXIT_FAILURE);
}
configure_rtc(qemu_find_opts_singleton("rtc"));
machine_class = select_machine();
set_memory_options(&ram_slots, &maxram_size, machine_class);