diff --git a/SOURCES/kvm-hw-s390x-Fix-bad-mask-in-time2tod.patch b/SOURCES/kvm-hw-s390x-Fix-bad-mask-in-time2tod.patch new file mode 100644 index 0000000..9a175ad --- /dev/null +++ b/SOURCES/kvm-hw-s390x-Fix-bad-mask-in-time2tod.patch @@ -0,0 +1,50 @@ +From 6e5f084a9839a417aaea25371af9dfe9c108cf65 Mon Sep 17 00:00:00 2001 +From: David Hildenbrand +Date: Fri, 21 Dec 2018 15:39:57 +0100 +Subject: [PATCH 13/14] hw/s390x: Fix bad mask in time2tod() + +RH-Author: David Hildenbrand +Message-id: <20181221153957.28183-13-david@redhat.com> +Patchwork-id: 83766 +O-Subject: [RHEL-7.6.z qemu-kvm-ma PATCH 12/12] hw/s390x: Fix bad mask in time2tod() +Bugzilla: 1672920 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Thomas Huth +RH-Acked-by: Laurent Vivier + +Since "s390x/tcg: avoid overflows in time2tod/tod2time", the +time2tod() function tries to deal with the 9 uppermost bits in the +time value, but uses the wrong mask for this: 0xff80000000000000 should +be used instead of 0xff10000000000000 here. + +Fixes: 14055ce53c2d901d826ffad7fb7d6bb8ab46bdfd +Cc: qemu-stable@nongnu.org +Signed-off-by: Thomas Huth +Message-Id: <1544792887-14575-1-git-send-email-thuth@redhat.com> +Reviewed-by: David Hildenbrand +[CH: tweaked commit message] +Signed-off-by: Cornelia Huck +(cherry picked from commit aba7a5a2de3dba5917024df25441f715b9249e31) +Signed-off-by: David Hildenbrand + +Signed-off-by: Miroslav Rezanina +--- + include/hw/s390x/tod.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/hw/s390x/tod.h b/include/hw/s390x/tod.h +index cbd7552..47ef9de 100644 +--- a/include/hw/s390x/tod.h ++++ b/include/hw/s390x/tod.h +@@ -56,7 +56,7 @@ typedef struct S390TODClass { + /* Converts ns to s390's clock format */ + static inline uint64_t time2tod(uint64_t ns) + { +- return (ns << 9) / 125 + (((ns & 0xff10000000000000ull) / 125) << 9); ++ return (ns << 9) / 125 + (((ns & 0xff80000000000000ull) / 125) << 9); + } + + /* Converts s390's clock format to ns */ +-- +1.8.3.1 + diff --git a/SOURCES/kvm-hw-s390x-Include-the-tod-qemu-also-for-builds-with-d.patch b/SOURCES/kvm-hw-s390x-Include-the-tod-qemu-also-for-builds-with-d.patch new file mode 100644 index 0000000..54f1392 --- /dev/null +++ b/SOURCES/kvm-hw-s390x-Include-the-tod-qemu-also-for-builds-with-d.patch @@ -0,0 +1,61 @@ +From abe7d93a04b4291bdcd406d180271143b16f2896 Mon Sep 17 00:00:00 2001 +From: David Hildenbrand +Date: Fri, 21 Dec 2018 15:39:55 +0100 +Subject: [PATCH 11/14] hw/s390x: Include the tod-qemu also for builds with + --disable-tcg + +RH-Author: David Hildenbrand +Message-id: <20181221153957.28183-11-david@redhat.com> +Patchwork-id: 83764 +O-Subject: [RHEL-7.6.z qemu-kvm-ma PATCH 10/12] hw/s390x: Include the tod-qemu also for builds with --disable-tcg +Bugzilla: 1672920 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Thomas Huth +RH-Acked-by: Laurent Vivier + +The device is required for running qtests, see hw/s390x/tod.c: + +void s390_init_tod(void) +{ + Object *obj; + + if (kvm_enabled()) { + obj = object_new(TYPE_KVM_S390_TOD); + } else { + obj = object_new(TYPE_QEMU_S390_TOD); + } + [...] + } + +During qtests, we're running without kvm, so TYPE_QEMU_S390_TOD is +required to avoid that QEMU aborts here. + +Fixes: 8046f374a6 ("s390x/tod: factor out TOD into separate device") +Signed-off-by: Thomas Huth +Message-Id: <1539264723-741-1-git-send-email-thuth@redhat.com> +Reviewed-by: David Hildenbrand +Signed-off-by: Cornelia Huck +(cherry picked from commit 0161215d435ef5680c4623bcbdfe89ce5b35cf42) +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + hw/s390x/Makefile.objs | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs +index 93282f7..58b1866 100644 +--- a/hw/s390x/Makefile.objs ++++ b/hw/s390x/Makefile.objs +@@ -15,8 +15,8 @@ obj-$(call lnot,$(CONFIG_PCI)) += s390-pci-stub.o + obj-y += s390-skeys.o + obj-y += s390-stattrib.o + obj-y += tod.o ++obj-y += tod-qemu.o + obj-$(CONFIG_KVM) += tod-kvm.o +-obj-$(CONFIG_TCG) += tod-qemu.o + obj-$(CONFIG_KVM) += s390-skeys-kvm.o + obj-$(CONFIG_KVM) += s390-stattrib-kvm.o + obj-y += s390-ccw.o +-- +1.8.3.1 + diff --git a/SOURCES/kvm-s390x-Return-specification-exception-for-unimplement.patch b/SOURCES/kvm-s390x-Return-specification-exception-for-unimplement.patch new file mode 100644 index 0000000..b29f78f --- /dev/null +++ b/SOURCES/kvm-s390x-Return-specification-exception-for-unimplement.patch @@ -0,0 +1,54 @@ +From f6f56692227952864edcb0dc841cde6238470cf8 Mon Sep 17 00:00:00 2001 +From: Cornelia Huck +Date: Mon, 21 Jan 2019 17:05:59 +0100 +Subject: [PATCH 14/14] s390x: Return specification exception for unimplemented + diag 308 subcodes + +RH-Author: Cornelia Huck +Message-id: <20190121170559.19471-1-cohuck@redhat.com> +Patchwork-id: 84074 +O-Subject: [RHEL-7.6.z qemu-kvm-ma PATCH] s390x: Return specification exception for unimplemented diag 308 subcodes +Bugzilla: 1668424 +RH-Acked-by: Thomas Huth +RH-Acked-by: David Hildenbrand +RH-Acked-by: John Snow + +From: Janosch Frank + +The architecture specifies specification exceptions for all +unavailable subcodes. + +The presence of subcodes is indicated by checking some query subcode. +For example 6 will indicate that 3-6 are available. So future systems +might call new subcodes to check for new features. This should not +trigger a hw error, instead we return the architectured specification +exception. + +Signed-off-by: Janosch Frank +Cc: qemu-stable@nongnu.org +Message-Id: <20190111113657.66195-3-frankja@linux.ibm.com> +Reviewed-by: Christian Borntraeger +Reviewed-by: David Hildenbrand +Signed-off-by: Cornelia Huck +(cherry picked from commit 37dbd1f4d4805edcd18d94eb202bb3461b3cd52d) +Signed-off-by: Miroslav Rezanina +--- + target/s390x/diag.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/target/s390x/diag.c b/target/s390x/diag.c +index a755837..50b58df 100644 +--- a/target/s390x/diag.c ++++ b/target/s390x/diag.c +@@ -182,7 +182,7 @@ out: + } + return; + default: +- hw_error("Unhandled diag308 subcode %" PRIx64, subcode); ++ s390_program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO, ra); + break; + } + } +-- +1.8.3.1 + diff --git a/SOURCES/kvm-s390x-kvm-pass-values-instead-of-pointers-to-kvm_s39.patch b/SOURCES/kvm-s390x-kvm-pass-values-instead-of-pointers-to-kvm_s39.patch new file mode 100644 index 0000000..6fbf7b2 --- /dev/null +++ b/SOURCES/kvm-s390x-kvm-pass-values-instead-of-pointers-to-kvm_s39.patch @@ -0,0 +1,129 @@ +From d8ea4acd4f566899da1ba6def05c5dca4217fd52 Mon Sep 17 00:00:00 2001 +From: David Hildenbrand +Date: Fri, 21 Dec 2018 15:39:47 +0100 +Subject: [PATCH 03/14] s390x/kvm: pass values instead of pointers to + kvm_s390_set_clock_*() + +RH-Author: David Hildenbrand +Message-id: <20181221153957.28183-3-david@redhat.com> +Patchwork-id: 83759 +O-Subject: [RHEL-7.6.z qemu-kvm-ma PATCH 02/12] s390x/kvm: pass values instead of pointers to kvm_s390_set_clock_*() +Bugzilla: 1672920 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Thomas Huth +RH-Acked-by: Laurent Vivier + +We are going to factor out the TOD into a separate device and use const +pointers for device class functions where possible. We are passing right +now ordinary pointers that should never be touched when setting the TOD. +Let's just pass the values directly. + +Note that s390_set_clock() will be removed in a follow-on patch and +therefore its calling convention is not changed. + +Signed-off-by: David Hildenbrand +Message-Id: <20180627134410.4901-3-david@redhat.com> +Signed-off-by: Cornelia Huck +(cherry picked from commit 4ab6a1feac0a142045d3b7bdbb8182a99c0b8980) +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + target/s390x/cpu.c | 4 ++-- + target/s390x/kvm-stub.c | 4 ++-- + target/s390x/kvm.c | 12 ++++++------ + target/s390x/kvm_s390x.h | 4 ++-- + 4 files changed, 12 insertions(+), 12 deletions(-) + +diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c +index c2b775f..1f590d1 100644 +--- a/target/s390x/cpu.c ++++ b/target/s390x/cpu.c +@@ -414,9 +414,9 @@ int s390_set_clock(uint8_t *tod_high, uint64_t *tod_low) + int r = 0; + + if (kvm_enabled()) { +- r = kvm_s390_set_clock_ext(tod_high, tod_low); ++ r = kvm_s390_set_clock_ext(*tod_high, *tod_low); + if (r == -ENXIO) { +- return kvm_s390_set_clock(tod_high, tod_low); ++ return kvm_s390_set_clock(*tod_high, *tod_low); + } + } + /* Fixme TCG */ +diff --git a/target/s390x/kvm-stub.c b/target/s390x/kvm-stub.c +index 29b1054..bf7795e 100644 +--- a/target/s390x/kvm-stub.c ++++ b/target/s390x/kvm-stub.c +@@ -60,12 +60,12 @@ int kvm_s390_get_clock_ext(uint8_t *tod_high, uint64_t *tod_low) + return -ENOSYS; + } + +-int kvm_s390_set_clock(uint8_t *tod_high, uint64_t *tod_low) ++int kvm_s390_set_clock(uint8_t tod_high, uint64_t tod_low) + { + return -ENOSYS; + } + +-int kvm_s390_set_clock_ext(uint8_t *tod_high, uint64_t *tod_low) ++int kvm_s390_set_clock_ext(uint8_t tod_high, uint64_t tod_low) + { + return -ENOSYS; + } +diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c +index c27e628..009902e 100644 +--- a/target/s390x/kvm.c ++++ b/target/s390x/kvm.c +@@ -696,13 +696,13 @@ int kvm_s390_get_clock_ext(uint8_t *tod_high, uint64_t *tod_low) + return r; + } + +-int kvm_s390_set_clock(uint8_t *tod_high, uint64_t *tod_low) ++int kvm_s390_set_clock(uint8_t tod_high, uint64_t tod_low) + { + int r; + struct kvm_device_attr attr = { + .group = KVM_S390_VM_TOD, + .attr = KVM_S390_VM_TOD_LOW, +- .addr = (uint64_t)tod_low, ++ .addr = (uint64_t)&tod_low, + }; + + r = kvm_vm_ioctl(kvm_state, KVM_SET_DEVICE_ATTR, &attr); +@@ -711,15 +711,15 @@ int kvm_s390_set_clock(uint8_t *tod_high, uint64_t *tod_low) + } + + attr.attr = KVM_S390_VM_TOD_HIGH; +- attr.addr = (uint64_t)tod_high; ++ attr.addr = (uint64_t)&tod_high; + return kvm_vm_ioctl(kvm_state, KVM_SET_DEVICE_ATTR, &attr); + } + +-int kvm_s390_set_clock_ext(uint8_t *tod_high, uint64_t *tod_low) ++int kvm_s390_set_clock_ext(uint8_t tod_high, uint64_t tod_low) + { + struct kvm_s390_vm_tod_clock gtod = { +- .epoch_idx = *tod_high, +- .tod = *tod_low, ++ .epoch_idx = tod_high, ++ .tod = tod_low, + }; + struct kvm_device_attr attr = { + .group = KVM_S390_VM_TOD, +diff --git a/target/s390x/kvm_s390x.h b/target/s390x/kvm_s390x.h +index c383bf4..36eb34b 100644 +--- a/target/s390x/kvm_s390x.h ++++ b/target/s390x/kvm_s390x.h +@@ -25,8 +25,8 @@ int kvm_s390_get_ri(void); + int kvm_s390_get_gs(void); + int kvm_s390_get_clock(uint8_t *tod_high, uint64_t *tod_clock); + int kvm_s390_get_clock_ext(uint8_t *tod_high, uint64_t *tod_clock); +-int kvm_s390_set_clock(uint8_t *tod_high, uint64_t *tod_clock); +-int kvm_s390_set_clock_ext(uint8_t *tod_high, uint64_t *tod_clock); ++int kvm_s390_set_clock(uint8_t tod_high, uint64_t tod_clock); ++int kvm_s390_set_clock_ext(uint8_t tod_high, uint64_t tod_clock); + void kvm_s390_enable_css_support(S390CPU *cpu); + int kvm_s390_assign_subch_ioeventfd(EventNotifier *notifier, uint32_t sch, + int vq, bool assign); +-- +1.8.3.1 + diff --git a/SOURCES/kvm-s390x-refuse-to-start-guests-backed-by-hugetlbfs.patch b/SOURCES/kvm-s390x-refuse-to-start-guests-backed-by-hugetlbfs.patch new file mode 100644 index 0000000..8c73926 --- /dev/null +++ b/SOURCES/kvm-s390x-refuse-to-start-guests-backed-by-hugetlbfs.patch @@ -0,0 +1,74 @@ +From 92fc5d11a4501a3734acc77b7d6a57190bd56154 Mon Sep 17 00:00:00 2001 +From: Cornelia Huck +Date: Wed, 21 Nov 2018 10:17:06 +0100 +Subject: [PATCH 01/14] s390x: refuse to start guests backed by hugetlbfs + +RH-Author: Cornelia Huck +Message-id: <20181121101706.17562-1-cohuck@redhat.com> +Patchwork-id: 83089 +O-Subject: [PATCH RHEL-7.6.z qemu-kvm-ma BZ1650580] s390x: refuse to start guests backed by hugetlbfs +Bugzilla: 1672919 +RH-Acked-by: David Hildenbrand +RH-Acked-by: Thomas Huth +RH-Acked-by: Dr. David Alan Gilbert + +In RHEL-ALT 7.x, running s390x guests with hugetlbfs backing +will not work due to missing support in the kernel. Unfortunately, +the guest will try to start and only then crash. This will lead +to problems when e.g. migrating a hugetlbfs backed guest from +RHEL 8 (where this is supported, but no new machine type has +been introduced.) + +Fix this by bailing out with an error message immediately. This +way, an incoming migration of a hugetlbfs backed guest will fail +immediately and properly fall back to the source. + +Signed-off-by: Cornelia Huck +Signed-off-by: Miroslav Rezanina +--- + target/s390x/kvm.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c +index ca8c32e..c27e628 100644 +--- a/target/s390x/kvm.c ++++ b/target/s390x/kvm.c +@@ -34,6 +34,7 @@ + #include "qapi/error.h" + #include "qemu/error-report.h" + #include "qemu/timer.h" ++#include "qemu/mmap-alloc.h" + #include "sysemu/sysemu.h" + #include "sysemu/hw_accel.h" + #include "hw/hw.h" +@@ -282,10 +283,27 @@ void kvm_s390_crypto_reset(void) + } + } + ++static int kvm_s390_configure_mempath_backing(KVMState *s) ++{ ++ size_t path_psize = qemu_mempath_getpagesize(mem_path); ++ ++ if (path_psize == 4096) { ++ return 0; ++ } ++ ++ /* Disabled in Red Hat Enterprise Linux 7 (KVM support missing) */ ++ error_report("This QEMU does not support huge page mappings"); ++ return -EINVAL; ++} ++ + int kvm_arch_init(MachineState *ms, KVMState *s) + { + MachineClass *mc = MACHINE_GET_CLASS(ms); + ++ if (mem_path && kvm_s390_configure_mempath_backing(s)) { ++ return -EINVAL; ++ } ++ + mc->default_cpu_type = S390_CPU_TYPE_NAME("host"); + cap_sync_regs = kvm_check_extension(s, KVM_CAP_SYNC_REGS); + cap_async_pf = kvm_check_extension(s, KVM_CAP_ASYNC_PF); +-- +1.8.3.1 + diff --git a/SOURCES/kvm-s390x-tcg-SET-CLOCK-COMPARATOR-can-clear-CKC-interru.patch b/SOURCES/kvm-s390x-tcg-SET-CLOCK-COMPARATOR-can-clear-CKC-interru.patch new file mode 100644 index 0000000..6dbde57 --- /dev/null +++ b/SOURCES/kvm-s390x-tcg-SET-CLOCK-COMPARATOR-can-clear-CKC-interru.patch @@ -0,0 +1,52 @@ +From afe233642d38207ddb34da8bac4507d88c4c3422 Mon Sep 17 00:00:00 2001 +From: David Hildenbrand +Date: Fri, 21 Dec 2018 15:39:51 +0100 +Subject: [PATCH 07/14] s390x/tcg: SET CLOCK COMPARATOR can clear CKC + interrupts + +RH-Author: David Hildenbrand +Message-id: <20181221153957.28183-7-david@redhat.com> +Patchwork-id: 83769 +O-Subject: [RHEL-7.6.z qemu-kvm-ma PATCH 06/12] s390x/tcg: SET CLOCK COMPARATOR can clear CKC interrupts +Bugzilla: 1672920 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Thomas Huth +RH-Acked-by: Laurent Vivier + +Let's stop the timer and delete any pending CKC IRQ before doing +anything else. + +While at it, add a comment why the check for ckc == -1ULL is needed. + +Reviewed-by: Thomas Huth +Signed-off-by: David Hildenbrand +Message-Id: <20180627134410.4901-7-david@redhat.com> +Signed-off-by: Cornelia Huck +(cherry picked from commit 345f1ab96e8279a537f32ae7447296d23308c7d1) +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + target/s390x/misc_helper.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/target/s390x/misc_helper.c b/target/s390x/misc_helper.c +index 4f675c7..cada7af 100644 +--- a/target/s390x/misc_helper.c ++++ b/target/s390x/misc_helper.c +@@ -155,6 +155,13 @@ void HELPER(sckc)(CPUS390XState *env, uint64_t time) + { + S390TODState *td = s390_get_todstate(); + ++ /* stop the timer and remove pending CKC IRQs */ ++ timer_del(env->tod_timer); ++ qemu_mutex_lock_iothread(); ++ env->pending_int &= ~INTERRUPT_EXT_CLOCK_COMPARATOR; ++ qemu_mutex_unlock_iothread(); ++ ++ /* the tod has to exceed the ckc, this can never happen if ckc is all 1's */ + if (time == -1ULL) { + return; + } +-- +1.8.3.1 + diff --git a/SOURCES/kvm-s390x-tcg-avoid-overflows-in-time2tod-tod2time.patch b/SOURCES/kvm-s390x-tcg-avoid-overflows-in-time2tod-tod2time.patch new file mode 100644 index 0000000..386290d --- /dev/null +++ b/SOURCES/kvm-s390x-tcg-avoid-overflows-in-time2tod-tod2time.patch @@ -0,0 +1,57 @@ +From 6a97308e4496bf7d387198ae77cb501bc67145f8 Mon Sep 17 00:00:00 2001 +From: David Hildenbrand +Date: Fri, 21 Dec 2018 15:39:46 +0100 +Subject: [PATCH 02/14] s390x/tcg: avoid overflows in time2tod/tod2time + +RH-Author: David Hildenbrand +Message-id: <20181221153957.28183-2-david@redhat.com> +Patchwork-id: 83757 +O-Subject: [RHEL-7.6.z qemu-kvm-ma PATCH 01/12] s390x/tcg: avoid overflows in time2tod/tod2time +Bugzilla: 1672920 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Thomas Huth +RH-Acked-by: Laurent Vivier + +Big values for the TOD/ns clock can result in some overflows that can be +avoided. Not all overflows can be handled however, as the conversion either +multiplies by 4.096 or divided by 4.096. + +Apply the trick used in the Linux kernel in arch/s390/include/asm/timex.h +for tod_to_ns() and use the same trick also for the conversion in the +other direction. + +Reviewed-by: Thomas Huth +Signed-off-by: David Hildenbrand +Message-Id: <20180627134410.4901-2-david@redhat.com> +Signed-off-by: Cornelia Huck +(cherry picked from commit 14055ce53c2d901d826ffad7fb7d6bb8ab46bdfd) +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + target/s390x/internal.h | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/target/s390x/internal.h b/target/s390x/internal.h +index d911e84..d1ed06f 100644 +--- a/target/s390x/internal.h ++++ b/target/s390x/internal.h +@@ -243,13 +243,14 @@ enum cc_op { + /* Converts ns to s390's clock format */ + static inline uint64_t time2tod(uint64_t ns) + { +- return (ns << 9) / 125; ++ return (ns << 9) / 125 + (((ns & 0xff10000000000000ull) / 125) << 9); ++ + } + + /* Converts s390's clock format to ns */ + static inline uint64_t tod2time(uint64_t t) + { +- return (t * 125) >> 9; ++ return ((t >> 9) * 125) + (((t & 0x1ff) * 125) >> 9); + } + + static inline hwaddr decode_basedisp_s(CPUS390XState *env, uint32_t ipb, +-- +1.8.3.1 + diff --git a/SOURCES/kvm-s390x-tcg-drop-tod_basetime.patch b/SOURCES/kvm-s390x-tcg-drop-tod_basetime.patch new file mode 100644 index 0000000..7477ac1 --- /dev/null +++ b/SOURCES/kvm-s390x-tcg-drop-tod_basetime.patch @@ -0,0 +1,78 @@ +From 7e7cd720a64754c0ebe4b38b310ceef2fc839c64 Mon Sep 17 00:00:00 2001 +From: David Hildenbrand +Date: Fri, 21 Dec 2018 15:39:49 +0100 +Subject: [PATCH 05/14] s390x/tcg: drop tod_basetime + +RH-Author: David Hildenbrand +Message-id: <20181221153957.28183-5-david@redhat.com> +Patchwork-id: 83768 +O-Subject: [RHEL-7.6.z qemu-kvm-ma PATCH 04/12] s390x/tcg: drop tod_basetime +Bugzilla: 1672920 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Thomas Huth +RH-Acked-by: Laurent Vivier + +Never set to anything but 0. + +Reviewed-by: Thomas Huth +Signed-off-by: David Hildenbrand +Message-Id: <20180627134410.4901-5-david@redhat.com> +Signed-off-by: Cornelia Huck +(cherry picked from commit f777b20544fe5db3de179a83374cbf9f1e454427) +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + target/s390x/cpu.c | 1 - + target/s390x/cpu.h | 1 - + target/s390x/misc_helper.c | 4 ++-- + 3 files changed, 2 insertions(+), 4 deletions(-) + +diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c +index 167d089..5570741 100644 +--- a/target/s390x/cpu.c ++++ b/target/s390x/cpu.c +@@ -290,7 +290,6 @@ static void s390_cpu_initfn(Object *obj) + qemu_get_timedate(&tm, 0); + env->tod_offset = TOD_UNIX_EPOCH + + (time2tod(mktimegm(&tm)) * 1000000000ULL); +- env->tod_basetime = 0; + env->tod_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, s390x_tod_timer, cpu); + env->cpu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, s390x_cpu_timer, cpu); + s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu); +diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h +index 67118c8..04f9adf 100644 +--- a/target/s390x/cpu.h ++++ b/target/s390x/cpu.h +@@ -134,7 +134,6 @@ struct CPUS390XState { + #endif + + uint64_t tod_offset; +- uint64_t tod_basetime; + QEMUTimer *tod_timer; + + QEMUTimer *cpu_timer; +diff --git a/target/s390x/misc_helper.c b/target/s390x/misc_helper.c +index e0b23c1..8b3b040 100644 +--- a/target/s390x/misc_helper.c ++++ b/target/s390x/misc_helper.c +@@ -142,7 +142,7 @@ uint64_t HELPER(stck)(CPUS390XState *env) + uint64_t time; + + time = env->tod_offset + +- time2tod(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - env->tod_basetime); ++ time2tod(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); + + return time; + } +@@ -162,7 +162,7 @@ void HELPER(sckc)(CPUS390XState *env, uint64_t time) + /* nanoseconds */ + time = tod2time(time); + +- timer_mod(env->tod_timer, env->tod_basetime + time); ++ timer_mod(env->tod_timer, time); + } + + /* Set Tod Programmable Field */ +-- +1.8.3.1 + diff --git a/SOURCES/kvm-s390x-tcg-fix-locking-problem-with-tcg_s390_tod_upda.patch b/SOURCES/kvm-s390x-tcg-fix-locking-problem-with-tcg_s390_tod_upda.patch new file mode 100644 index 0000000..a7fefaf --- /dev/null +++ b/SOURCES/kvm-s390x-tcg-fix-locking-problem-with-tcg_s390_tod_upda.patch @@ -0,0 +1,100 @@ +From 76a996b5b9cc079655bde96db67b785db2094b98 Mon Sep 17 00:00:00 2001 +From: David Hildenbrand +Date: Fri, 21 Dec 2018 15:39:54 +0100 +Subject: [PATCH 10/14] s390x/tcg: fix locking problem with + tcg_s390_tod_updated + +RH-Author: David Hildenbrand +Message-id: <20181221153957.28183-10-david@redhat.com> +Patchwork-id: 83763 +O-Subject: [RHEL-7.6.z qemu-kvm-ma PATCH 09/12] s390x/tcg: fix locking problem with tcg_s390_tod_updated +Bugzilla: 1672920 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Thomas Huth +RH-Acked-by: Laurent Vivier + +tcg_s390_tod_updated() is always called with the iothread being locked +(e.g. from S390TODClass->set() e.g. via HELPER(sck) or on incoming +migration). The helper we call takes the lock itself - bad. + +Let's change that by factoring out updating the ckc timer. This now looks +much nicer than having to call a helper from another function. + +While touching it we also make sure that env->ckc is updated even if the +new value is -1ULL, for now it would not have been modified in that case. + +Reported-by: Christian Borntraeger +Signed-off-by: David Hildenbrand +Message-Id: <20180629170520.13671-1-david@redhat.com> +Reviewed-by: Richard Henderson +Signed-off-by: Cornelia Huck +(cherry picked from commit 30c8db0e219a3c1d8b39c19e8b858830cb141738) +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + target/s390x/misc_helper.c | 26 ++++++++++++++++---------- + 1 file changed, 16 insertions(+), 10 deletions(-) + +diff --git a/target/s390x/misc_helper.c b/target/s390x/misc_helper.c +index d629b2f..ffb9f6c 100644 +--- a/target/s390x/misc_helper.c ++++ b/target/s390x/misc_helper.c +@@ -150,26 +150,23 @@ uint64_t HELPER(stck)(CPUS390XState *env) + return tod.low; + } + +-/* Set Clock Comparator */ +-void HELPER(sckc)(CPUS390XState *env, uint64_t time) ++static void update_ckc_timer(CPUS390XState *env) + { + S390TODState *td = s390_get_todstate(); ++ uint64_t time; + + /* stop the timer and remove pending CKC IRQs */ + timer_del(env->tod_timer); +- qemu_mutex_lock_iothread(); ++ g_assert(qemu_mutex_iothread_locked()); + env->pending_int &= ~INTERRUPT_EXT_CLOCK_COMPARATOR; +- qemu_mutex_unlock_iothread(); + + /* the tod has to exceed the ckc, this can never happen if ckc is all 1's */ +- if (time == -1ULL) { ++ if (env->ckc == -1ULL) { + return; + } + +- env->ckc = time; +- + /* difference between origins */ +- time -= td->base.low; ++ time = env->ckc - td->base.low; + + /* nanoseconds */ + time = tod2time(time); +@@ -177,12 +174,21 @@ void HELPER(sckc)(CPUS390XState *env, uint64_t time) + timer_mod(env->tod_timer, time); + } + ++/* Set Clock Comparator */ ++void HELPER(sckc)(CPUS390XState *env, uint64_t ckc) ++{ ++ env->ckc = ckc; ++ ++ qemu_mutex_lock_iothread(); ++ update_ckc_timer(env); ++ qemu_mutex_unlock_iothread(); ++} ++ + void tcg_s390_tod_updated(CPUState *cs, run_on_cpu_data opaque) + { + S390CPU *cpu = S390_CPU(cs); +- CPUS390XState *env = &cpu->env; + +- helper_sckc(env, env->ckc); ++ update_ckc_timer(&cpu->env); + } + + /* Set Clock */ +-- +1.8.3.1 + diff --git a/SOURCES/kvm-s390x-tcg-implement-SET-CLOCK.patch b/SOURCES/kvm-s390x-tcg-implement-SET-CLOCK.patch new file mode 100644 index 0000000..2352da0 --- /dev/null +++ b/SOURCES/kvm-s390x-tcg-implement-SET-CLOCK.patch @@ -0,0 +1,113 @@ +From 79880b67f42bad47d885722d58abcedc53986759 Mon Sep 17 00:00:00 2001 +From: David Hildenbrand +Date: Fri, 21 Dec 2018 15:39:52 +0100 +Subject: [PATCH 08/14] s390x/tcg: implement SET CLOCK + +RH-Author: David Hildenbrand +Message-id: <20181221153957.28183-8-david@redhat.com> +Patchwork-id: 83762 +O-Subject: [RHEL-7.6.z qemu-kvm-ma PATCH 07/12] s390x/tcg: implement SET CLOCK +Bugzilla: 1672920 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Thomas Huth +RH-Acked-by: Laurent Vivier +Signed-off-by: Miroslav Rezanina + +Conflicts: + target/s390x/translate.c: ExitStatus vs. DisasJumpType + +This allows a guest to change its TOD. We already take care of updating +all CKC timers from within S390TODClass. + +Use MO_ALIGN to load the operand manually - this will properly trigger a +SPECIFICATION exception. + +Acked-by: Thomas Huth +Signed-off-by: David Hildenbrand +Message-Id: <20180627134410.4901-8-david@redhat.com> +Signed-off-by: Cornelia Huck +(cherry picked from commit 9dc6753718d4c0fe327729fea94e4d9f3f5a3d17) +Signed-off-by: David Hildenbrand +--- + target/s390x/helper.h | 1 + + target/s390x/insn-data.def | 3 +-- + target/s390x/misc_helper.c | 16 ++++++++++++++++ + target/s390x/translate.c | 9 +++++++++ + 4 files changed, 27 insertions(+), 2 deletions(-) + +diff --git a/target/s390x/helper.h b/target/s390x/helper.h +index 59cba86..97c60ca 100644 +--- a/target/s390x/helper.h ++++ b/target/s390x/helper.h +@@ -127,6 +127,7 @@ DEF_HELPER_4(diag, void, env, i32, i32, i32) + DEF_HELPER_3(load_psw, noreturn, env, i64, i64) + DEF_HELPER_FLAGS_2(spx, TCG_CALL_NO_RWG, void, env, i64) + DEF_HELPER_FLAGS_1(stck, TCG_CALL_NO_RWG_SE, i64, env) ++DEF_HELPER_FLAGS_2(sck, TCG_CALL_NO_RWG, i32, env, i64) + DEF_HELPER_FLAGS_2(sckc, TCG_CALL_NO_RWG, void, env, i64) + DEF_HELPER_FLAGS_2(sckpf, TCG_CALL_NO_RWG, void, env, i64) + DEF_HELPER_FLAGS_1(stckc, TCG_CALL_NO_RWG, i64, env) +diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def +index 1576194..5c6f33e 100644 +--- a/target/s390x/insn-data.def ++++ b/target/s390x/insn-data.def +@@ -997,8 +997,7 @@ + /* SET ADDRESS SPACE CONTROL FAST */ + C(0xb279, SACF, S, Z, 0, a2, 0, 0, sacf, 0) + /* SET CLOCK */ +- /* ??? Not implemented - is it necessary? */ +- C(0xb204, SCK, S, Z, 0, 0, 0, 0, 0, 0) ++ C(0xb204, SCK, S, Z, la2, 0, 0, 0, sck, 0) + /* SET CLOCK COMPARATOR */ + C(0xb206, SCKC, S, Z, 0, m2_64a, 0, 0, sckc, 0) + /* SET CLOCK PROGRAMMABLE FIELD */ +diff --git a/target/s390x/misc_helper.c b/target/s390x/misc_helper.c +index cada7af..d629b2f 100644 +--- a/target/s390x/misc_helper.c ++++ b/target/s390x/misc_helper.c +@@ -185,6 +185,22 @@ void tcg_s390_tod_updated(CPUState *cs, run_on_cpu_data opaque) + helper_sckc(env, env->ckc); + } + ++/* Set Clock */ ++uint32_t HELPER(sck)(CPUS390XState *env, uint64_t tod_low) ++{ ++ S390TODState *td = s390_get_todstate(); ++ S390TODClass *tdc = S390_TOD_GET_CLASS(td); ++ S390TOD tod = { ++ .high = 0, ++ .low = tod_low, ++ }; ++ ++ qemu_mutex_lock_iothread(); ++ tdc->set(td, &tod, &error_abort); ++ qemu_mutex_unlock_iothread(); ++ return 0; ++} ++ + /* Set Tod Programmable Field */ + void HELPER(sckpf)(CPUS390XState *env, uint64_t r0) + { +diff --git a/target/s390x/translate.c b/target/s390x/translate.c +index 7d39ab3..ed9aff4 100644 +--- a/target/s390x/translate.c ++++ b/target/s390x/translate.c +@@ -4015,6 +4015,15 @@ static ExitStatus op_stcke(DisasContext *s, DisasOps *o) + return NO_EXIT; + } + ++static ExitStatus op_sck(DisasContext *s, DisasOps *o) ++{ ++ check_privileged(s); ++ tcg_gen_qemu_ld_i64(o->in1, o->addr1, get_mem_index(s), MO_TEQ | MO_ALIGN); ++ gen_helper_sck(cc_op, cpu_env, o->in1); ++ set_cc_static(s); ++ return NO_EXIT; ++} ++ + static ExitStatus op_sckc(DisasContext *s, DisasOps *o) + { + check_privileged(s); +-- +1.8.3.1 + diff --git a/SOURCES/kvm-s390x-tcg-properly-implement-the-TOD.patch b/SOURCES/kvm-s390x-tcg-properly-implement-the-TOD.patch new file mode 100644 index 0000000..1d5c4e3 --- /dev/null +++ b/SOURCES/kvm-s390x-tcg-properly-implement-the-TOD.patch @@ -0,0 +1,350 @@ +From f87cbf4e70d1df758df90f56934a39a0a018e2cc Mon Sep 17 00:00:00 2001 +From: David Hildenbrand +Date: Fri, 21 Dec 2018 15:39:50 +0100 +Subject: [PATCH 06/14] s390x/tcg: properly implement the TOD + +RH-Author: David Hildenbrand +Message-id: <20181221153957.28183-6-david@redhat.com> +Patchwork-id: 83760 +O-Subject: [RHEL-7.6.z qemu-kvm-ma PATCH 05/12] s390x/tcg: properly implement the TOD +Bugzilla: 1672920 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Thomas Huth +RH-Acked-by: Laurent Vivier + +Right now, each CPU has its own TOD. Especially, the TOD will differ +based on creation time of a CPU - e.g. when hotplugging a CPU the times +will differ quite a lot, resulting in stall warnings in the guest. + +Let's use a single TOD by implementing our new TOD device. Prepare it +for TOD-clock epoch extension. + +Most importantly, whenever we set the TOD, we have to update the CKC +timer. + +Introduce "tcg_s390x.h" just like "kvm_s390x.h" for tcg specific +function declarations that should not go into cpu.h. + +Reviewed-by: Thomas Huth +Signed-off-by: David Hildenbrand +Message-Id: <20180627134410.4901-6-david@redhat.com> +Signed-off-by: Cornelia Huck +(cherry picked from commit 7de3b1cdc67dcb572c1761c2051252e91a438b22) +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + hw/s390x/tod-qemu.c | 46 ++++++++++++++++++++++++++++++++++++++++++---- + hw/s390x/tod.c | 11 +++++++++++ + include/hw/s390x/tod.h | 19 +++++++++++++++++++ + target/s390x/cpu.c | 7 ------- + target/s390x/cpu.h | 1 - + target/s390x/internal.h | 16 ---------------- + target/s390x/misc_helper.c | 25 +++++++++++++++++++------ + target/s390x/tcg_s390x.h | 18 ++++++++++++++++++ + 8 files changed, 109 insertions(+), 34 deletions(-) + create mode 100644 target/s390x/tcg_s390x.h + +diff --git a/hw/s390x/tod-qemu.c b/hw/s390x/tod-qemu.c +index 03ea1ce..59c015c 100644 +--- a/hw/s390x/tod-qemu.c ++++ b/hw/s390x/tod-qemu.c +@@ -11,19 +11,43 @@ + #include "qemu/osdep.h" + #include "qapi/error.h" + #include "hw/s390x/tod.h" ++#include "qemu/timer.h" ++#include "qemu/cutils.h" ++#include "cpu.h" ++#include "tcg_s390x.h" + + static void qemu_s390_tod_get(const S390TODState *td, S390TOD *tod, + Error **errp) + { +- /* FIXME */ +- tod->high = 0; +- tod->low = 0; ++ *tod = td->base; ++ ++ tod->low += time2tod(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); ++ if (tod->low < td->base.low) { ++ tod->high++; ++ } + } + + static void qemu_s390_tod_set(S390TODState *td, const S390TOD *tod, + Error **errp) + { +- /* FIXME */ ++ CPUState *cpu; ++ ++ td->base = *tod; ++ ++ td->base.low -= time2tod(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); ++ if (td->base.low > tod->low) { ++ td->base.high--; ++ } ++ ++ /* ++ * The TOD has been changed and we have to recalculate the CKC values ++ * for all CPUs. We do this asynchronously, as "SET CLOCK should be ++ * issued only while all other activity on all CPUs .. has been ++ * suspended". ++ */ ++ CPU_FOREACH(cpu) { ++ async_run_on_cpu(cpu, tcg_s390_tod_updated, RUN_ON_CPU_NULL); ++ } + } + + static void qemu_s390_tod_class_init(ObjectClass *oc, void *data) +@@ -34,10 +58,24 @@ static void qemu_s390_tod_class_init(ObjectClass *oc, void *data) + tdc->set = qemu_s390_tod_set; + } + ++static void qemu_s390_tod_init(Object *obj) ++{ ++ S390TODState *td = S390_TOD(obj); ++ struct tm tm; ++ ++ qemu_get_timedate(&tm, 0); ++ td->base.high = 0; ++ td->base.low = TOD_UNIX_EPOCH + (time2tod(mktimegm(&tm)) * 1000000000ULL); ++ if (td->base.low < TOD_UNIX_EPOCH) { ++ td->base.high += 1; ++ } ++} ++ + static TypeInfo qemu_s390_tod_info = { + .name = TYPE_QEMU_S390_TOD, + .parent = TYPE_S390_TOD, + .instance_size = sizeof(S390TODState), ++ .instance_init = qemu_s390_tod_init, + .class_init = qemu_s390_tod_class_init, + .class_size = sizeof(S390TODClass), + }; +diff --git a/hw/s390x/tod.c b/hw/s390x/tod.c +index 0501aff..1c63f41 100644 +--- a/hw/s390x/tod.c ++++ b/hw/s390x/tod.c +@@ -30,6 +30,17 @@ void s390_init_tod(void) + qdev_init_nofail(DEVICE(obj)); + } + ++S390TODState *s390_get_todstate(void) ++{ ++ static S390TODState *ts; ++ ++ if (!ts) { ++ ts = S390_TOD(object_resolve_path_type("", TYPE_S390_TOD, NULL)); ++ } ++ ++ return ts; ++} ++ + #define S390_TOD_CLOCK_VALUE_MISSING 0x00 + #define S390_TOD_CLOCK_VALUE_PRESENT 0x01 + +diff --git a/include/hw/s390x/tod.h b/include/hw/s390x/tod.h +index 7096b57..413c0d7 100644 +--- a/include/hw/s390x/tod.h ++++ b/include/hw/s390x/tod.h +@@ -30,6 +30,9 @@ typedef struct S390TOD { + typedef struct S390TODState { + /* private */ + DeviceState parent_obj; ++ ++ /* unused by KVM implementation */ ++ S390TOD base; + } S390TODState; + + typedef struct S390TODClass { +@@ -41,6 +44,22 @@ typedef struct S390TODClass { + void (*set)(S390TODState *td, const S390TOD *tod, Error **errp); + } S390TODClass; + ++/* The value of the TOD clock for 1.1.1970. */ ++#define TOD_UNIX_EPOCH 0x7d91048bca000000ULL ++ ++/* Converts ns to s390's clock format */ ++static inline uint64_t time2tod(uint64_t ns) ++{ ++ return (ns << 9) / 125 + (((ns & 0xff10000000000000ull) / 125) << 9); ++} ++ ++/* Converts s390's clock format to ns */ ++static inline uint64_t tod2time(uint64_t t) ++{ ++ return ((t >> 9) * 125) + (((t & 0x1ff) * 125) >> 9); ++} ++ + void s390_init_tod(void); ++S390TODState *s390_get_todstate(void); + + #endif +diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c +index 5570741..f74d2a3 100644 +--- a/target/s390x/cpu.c ++++ b/target/s390x/cpu.c +@@ -30,7 +30,6 @@ + #include "kvm_s390x.h" + #include "sysemu/kvm.h" + #include "qemu-common.h" +-#include "qemu/cutils.h" + #include "qemu/timer.h" + #include "qemu/error-report.h" + #include "trace.h" +@@ -276,9 +275,6 @@ static void s390_cpu_initfn(Object *obj) + CPUState *cs = CPU(obj); + S390CPU *cpu = S390_CPU(obj); + CPUS390XState *env = &cpu->env; +-#if !defined(CONFIG_USER_ONLY) +- struct tm tm; +-#endif + + cs->env_ptr = env; + cs->halted = 1; +@@ -287,9 +283,6 @@ static void s390_cpu_initfn(Object *obj) + s390_cpu_get_crash_info_qom, NULL, NULL, NULL, NULL); + s390_cpu_model_register_props(obj); + #if !defined(CONFIG_USER_ONLY) +- qemu_get_timedate(&tm, 0); +- env->tod_offset = TOD_UNIX_EPOCH + +- (time2tod(mktimegm(&tm)) * 1000000000ULL); + env->tod_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, s390x_tod_timer, cpu); + env->cpu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, s390x_cpu_timer, cpu); + s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu); +diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h +index 04f9adf..6500f42 100644 +--- a/target/s390x/cpu.h ++++ b/target/s390x/cpu.h +@@ -133,7 +133,6 @@ struct CPUS390XState { + uint64_t cpuid; + #endif + +- uint64_t tod_offset; + QEMUTimer *tod_timer; + + QEMUTimer *cpu_timer; +diff --git a/target/s390x/internal.h b/target/s390x/internal.h +index d1ed06f..61a509d 100644 +--- a/target/s390x/internal.h ++++ b/target/s390x/internal.h +@@ -237,22 +237,6 @@ enum cc_op { + CC_OP_MAX + }; + +-/* The value of the TOD clock for 1.1.1970. */ +-#define TOD_UNIX_EPOCH 0x7d91048bca000000ULL +- +-/* Converts ns to s390's clock format */ +-static inline uint64_t time2tod(uint64_t ns) +-{ +- return (ns << 9) / 125 + (((ns & 0xff10000000000000ull) / 125) << 9); +- +-} +- +-/* Converts s390's clock format to ns */ +-static inline uint64_t tod2time(uint64_t t) +-{ +- return ((t >> 9) * 125) + (((t & 0x1ff) * 125) >> 9); +-} +- + static inline hwaddr decode_basedisp_s(CPUS390XState *env, uint32_t ipb, + uint8_t *ar) + { +diff --git a/target/s390x/misc_helper.c b/target/s390x/misc_helper.c +index 8b3b040..4f675c7 100644 +--- a/target/s390x/misc_helper.c ++++ b/target/s390x/misc_helper.c +@@ -29,6 +29,8 @@ + #include "exec/address-spaces.h" + #include "exec/exec-all.h" + #include "exec/cpu_ldst.h" ++#include "qapi/error.h" ++#include "tcg_s390x.h" + + #if !defined(CONFIG_USER_ONLY) + #include "sysemu/cpus.h" +@@ -40,6 +42,7 @@ + #include "hw/s390x/ioinst.h" + #include "hw/s390x/s390-pci-inst.h" + #include "hw/boards.h" ++#include "hw/s390x/tod.h" + #endif + + /* #define DEBUG_HELPER */ +@@ -139,17 +142,19 @@ void HELPER(spx)(CPUS390XState *env, uint64_t a1) + /* Store Clock */ + uint64_t HELPER(stck)(CPUS390XState *env) + { +- uint64_t time; ++ S390TODState *td = s390_get_todstate(); ++ S390TODClass *tdc = S390_TOD_GET_CLASS(td); ++ S390TOD tod; + +- time = env->tod_offset + +- time2tod(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); +- +- return time; ++ tdc->get(td, &tod, &error_abort); ++ return tod.low; + } + + /* Set Clock Comparator */ + void HELPER(sckc)(CPUS390XState *env, uint64_t time) + { ++ S390TODState *td = s390_get_todstate(); ++ + if (time == -1ULL) { + return; + } +@@ -157,7 +162,7 @@ void HELPER(sckc)(CPUS390XState *env, uint64_t time) + env->ckc = time; + + /* difference between origins */ +- time -= env->tod_offset; ++ time -= td->base.low; + + /* nanoseconds */ + time = tod2time(time); +@@ -165,6 +170,14 @@ void HELPER(sckc)(CPUS390XState *env, uint64_t time) + timer_mod(env->tod_timer, time); + } + ++void tcg_s390_tod_updated(CPUState *cs, run_on_cpu_data opaque) ++{ ++ S390CPU *cpu = S390_CPU(cs); ++ CPUS390XState *env = &cpu->env; ++ ++ helper_sckc(env, env->ckc); ++} ++ + /* Set Tod Programmable Field */ + void HELPER(sckpf)(CPUS390XState *env, uint64_t r0) + { +diff --git a/target/s390x/tcg_s390x.h b/target/s390x/tcg_s390x.h +new file mode 100644 +index 0000000..4e308aa +--- /dev/null ++++ b/target/s390x/tcg_s390x.h +@@ -0,0 +1,18 @@ ++/* ++ * QEMU TCG support -- s390x specific functions. ++ * ++ * Copyright 2018 Red Hat, Inc. ++ * ++ * Authors: ++ * David Hildenbrand ++ * ++ * This work is licensed under the terms of the GNU GPL, version 2 or later. ++ * See the COPYING file in the top-level directory. ++ */ ++ ++#ifndef TCG_S390X_H ++#define TCG_S390X_H ++ ++void tcg_s390_tod_updated(CPUState *cs, run_on_cpu_data opaque); ++ ++#endif /* TCG_S390X_H */ +-- +1.8.3.1 + diff --git a/SOURCES/kvm-s390x-tcg-rearm-the-CKC-timer-during-migration.patch b/SOURCES/kvm-s390x-tcg-rearm-the-CKC-timer-during-migration.patch new file mode 100644 index 0000000..245eacc --- /dev/null +++ b/SOURCES/kvm-s390x-tcg-rearm-the-CKC-timer-during-migration.patch @@ -0,0 +1,98 @@ +From 0ae076c231b0b8096acf0103b559bc5d58c4fdcf Mon Sep 17 00:00:00 2001 +From: David Hildenbrand +Date: Fri, 21 Dec 2018 15:39:53 +0100 +Subject: [PATCH 09/14] s390x/tcg: rearm the CKC timer during migration + +RH-Author: David Hildenbrand +Message-id: <20181221153957.28183-9-david@redhat.com> +Patchwork-id: 83767 +O-Subject: [RHEL-7.6.z qemu-kvm-ma PATCH 08/12] s390x/tcg: rearm the CKC timer during migration +Bugzilla: 1672920 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Thomas Huth +RH-Acked-by: Laurent Vivier + +If the CPU data is migrated after the TOD clock, the CKC timer of a CPU +is not rearmed. Let's rearm it when loading the CPU state. + +Introduce tcg-stub.c just like kvm-stub.c for tcg specific stubs. + +Reviewed-by: Thomas Huth +Signed-off-by: David Hildenbrand +Message-Id: <20180627134410.4901-9-david@redhat.com> +Signed-off-by: Cornelia Huck +(cherry picked from commit 7c12f710bad60dc7e509da4e80c77e952ef0490c) +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + target/s390x/Makefile.objs | 1 + + target/s390x/machine.c | 6 ++++++ + target/s390x/tcg-stub.c | 20 ++++++++++++++++++++ + 3 files changed, 27 insertions(+) + create mode 100644 target/s390x/tcg-stub.c + +diff --git a/target/s390x/Makefile.objs b/target/s390x/Makefile.objs +index 31932de..22a9a99 100644 +--- a/target/s390x/Makefile.objs ++++ b/target/s390x/Makefile.objs +@@ -5,6 +5,7 @@ obj-$(CONFIG_SOFTMMU) += machine.o ioinst.o arch_dump.o mmu_helper.o diag.o + obj-$(CONFIG_SOFTMMU) += sigp.o + obj-$(CONFIG_KVM) += kvm.o + obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o ++obj-$(call lnot,$(CONFIG_TCG)) += tcg-stub.o + + # build and run feature list generator + feat-src = $(SRC_PATH)/target/$(TARGET_BASE_ARCH)/ +diff --git a/target/s390x/machine.c b/target/s390x/machine.c +index 8421deb..cb792aa 100644 +--- a/target/s390x/machine.c ++++ b/target/s390x/machine.c +@@ -19,6 +19,7 @@ + #include "cpu.h" + #include "internal.h" + #include "kvm_s390x.h" ++#include "tcg_s390x.h" + #include "sysemu/kvm.h" + + static int cpu_post_load(void *opaque, int version_id) +@@ -34,6 +35,11 @@ static int cpu_post_load(void *opaque, int version_id) + return kvm_s390_vcpu_interrupt_post_load(cpu); + } + ++ if (tcg_enabled()) { ++ /* Rearm the CKC timer if necessary */ ++ tcg_s390_tod_updated(CPU(cpu), RUN_ON_CPU_NULL); ++ } ++ + return 0; + } + +diff --git a/target/s390x/tcg-stub.c b/target/s390x/tcg-stub.c +new file mode 100644 +index 0000000..c93501d +--- /dev/null ++++ b/target/s390x/tcg-stub.c +@@ -0,0 +1,20 @@ ++/* ++ * QEMU TCG support -- s390x specific function stubs. ++ * ++ * Copyright (C) 2018 Red Hat Inc ++ * ++ * Authors: ++ * David Hildenbrand ++ * ++ * This work is licensed under the terms of the GNU GPL, version 2 or later. ++ * See the COPYING file in the top-level directory. ++ */ ++ ++#include "qemu/osdep.h" ++#include "qemu-common.h" ++#include "cpu.h" ++#include "tcg_s390x.h" ++ ++void tcg_s390_tod_updated(CPUState *cs, run_on_cpu_data opaque) ++{ ++} +-- +1.8.3.1 + diff --git a/SOURCES/kvm-s390x-tod-Properly-stop-the-KVM-TOD-while-the-guest-.patch b/SOURCES/kvm-s390x-tod-Properly-stop-the-KVM-TOD-while-the-guest-.patch new file mode 100644 index 0000000..64c88f5 --- /dev/null +++ b/SOURCES/kvm-s390x-tod-Properly-stop-the-KVM-TOD-while-the-guest-.patch @@ -0,0 +1,250 @@ +From f9494422b9c4abe8f7cfea0ecee729bbc618de02 Mon Sep 17 00:00:00 2001 +From: David Hildenbrand +Date: Fri, 21 Dec 2018 15:39:56 +0100 +Subject: [PATCH 12/14] s390x/tod: Properly stop the KVM TOD while the guest is + not running + +RH-Author: David Hildenbrand +Message-id: <20181221153957.28183-12-david@redhat.com> +Patchwork-id: 83765 +O-Subject: [RHEL-7.6.z qemu-kvm-ma PATCH 11/12] s390x/tod: Properly stop the KVM TOD while the guest is not running +Bugzilla: 1672920 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Thomas Huth +RH-Acked-by: Laurent Vivier + +Just like on other architectures, we should stop the clock while the guest +is not running. This is already properly done for TCG. Right now, doing an +offline migration (stop, migrate, cont) can easily trigger stalls in the +guest. + +Even doing a + (hmp) stop + ... wait 2 minutes ... + (hmp) cont +will already trigger stalls. + +So whenever the guest stops, backup the KVM TOD. When continuing to run +the guest, restore the KVM TOD. + +One special case is starting a simple VM: Reading the TOD from KVM to +stop it right away until the guest is actually started means that the +time of any simple VM will already differ to the host time. We can +simply leave the TOD running and the guest won't be able to recognize +it. + +For migration, we actually want to keep the TOD stopped until really +starting the guest. To be able to catch most errors, we should however +try to set the TOD in addition to simply storing it. So we can still +catch basic migration problems. + +If anything goes wrong while backing up/restoring the TOD, we have to +ignore it (but print a warning). This is then basically a fallback to +old behavior (TOD remains running). + +I tested this very basically with an initrd: + 1. Start a simple VM. Observed that the TOD is kept running. Old + behavior. + 2. Ordinary live migration. Observed that the TOD is temporarily + stopped on the destination when setting the new value and + correctly started when finally starting the guest. + 3. Offline live migration. (stop, migrate, cont). Observed that the + TOD will be stopped on the source with the "stop" command. On the + destination, the TOD is temporarily stopped when setting the new + value and correctly started when finally starting the guest via + "cont". + 4. Simple stop/cont correctly stops/starts the TOD. (multiple stops + or conts in a row have no effect, so works as expected) + +In the future, we might want to send the guest a special kind of time sync +interrupt under some conditions, so it can synchronize its tod to the +host tod. This is interesting for migration scenarios but also when we +get time sync interrupts ourselves. This however will most probably have +to be handled in KVM (e.g. when the tods differ too much) and is not +desired e.g. when debugging the guest (single stepping should not +result in permanent time syncs). I consider something like that an add-on +on top of this basic "don't break the guest" handling. + +Signed-off-by: David Hildenbrand +Message-Id: <20181130094957.4121-1-david@redhat.com> +Acked-by: Christian Borntraeger +Reviewed-by: Thomas Huth +Signed-off-by: Cornelia Huck +(cherry picked from commit 9bc9d3d1ae3bcd1caaad1946494726b52f58b291) +Signed-off-by: David Hildenbrand +Signed-off-by: Miroslav Rezanina +--- + hw/s390x/tod-kvm.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++- + include/hw/s390x/tod.h | 8 +++- + 2 files changed, 107 insertions(+), 3 deletions(-) + +diff --git a/hw/s390x/tod-kvm.c b/hw/s390x/tod-kvm.c +index df564ab..2456bf7 100644 +--- a/hw/s390x/tod-kvm.c ++++ b/hw/s390x/tod-kvm.c +@@ -10,10 +10,11 @@ + + #include "qemu/osdep.h" + #include "qapi/error.h" ++#include "sysemu/sysemu.h" + #include "hw/s390x/tod.h" + #include "kvm_s390x.h" + +-static void kvm_s390_tod_get(const S390TODState *td, S390TOD *tod, Error **errp) ++static void kvm_s390_get_tod_raw(S390TOD *tod, Error **errp) + { + int r; + +@@ -27,7 +28,17 @@ static void kvm_s390_tod_get(const S390TODState *td, S390TOD *tod, Error **errp) + } + } + +-static void kvm_s390_tod_set(S390TODState *td, const S390TOD *tod, Error **errp) ++static void kvm_s390_tod_get(const S390TODState *td, S390TOD *tod, Error **errp) ++{ ++ if (td->stopped) { ++ *tod = td->base; ++ return; ++ } ++ ++ kvm_s390_get_tod_raw(tod, errp); ++} ++ ++static void kvm_s390_set_tod_raw(const S390TOD *tod, Error **errp) + { + int r; + +@@ -41,18 +52,105 @@ static void kvm_s390_tod_set(S390TODState *td, const S390TOD *tod, Error **errp) + } + } + ++static void kvm_s390_tod_set(S390TODState *td, const S390TOD *tod, Error **errp) ++{ ++ Error *local_err = NULL; ++ ++ /* ++ * Somebody (e.g. migration) set the TOD. We'll store it into KVM to ++ * properly detect errors now but take a look at the runstate to decide ++ * whether really to keep the tod running. E.g. during migration, this ++ * is the point where we want to stop the initially running TOD to fire ++ * it back up when actually starting the migrated guest. ++ */ ++ kvm_s390_set_tod_raw(tod, &local_err); ++ if (local_err) { ++ error_propagate(errp, local_err); ++ return; ++ } ++ ++ if (runstate_is_running()) { ++ td->stopped = false; ++ } else { ++ td->stopped = true; ++ td->base = *tod; ++ } ++} ++ ++static void kvm_s390_tod_vm_state_change(void *opaque, int running, ++ RunState state) ++{ ++ S390TODState *td = opaque; ++ Error *local_err = NULL; ++ ++ if (running && td->stopped) { ++ /* Set the old TOD when running the VM - start the TOD clock. */ ++ kvm_s390_set_tod_raw(&td->base, &local_err); ++ if (local_err) { ++ warn_report_err(local_err); ++ } ++ /* Treat errors like the TOD was running all the time. */ ++ td->stopped = false; ++ } else if (!running && !td->stopped) { ++ /* Store the TOD when stopping the VM - stop the TOD clock. */ ++ kvm_s390_get_tod_raw(&td->base, &local_err); ++ if (local_err) { ++ /* Keep the TOD running in case we could not back it up. */ ++ warn_report_err(local_err); ++ } else { ++ td->stopped = true; ++ } ++ } ++} ++ ++static void kvm_s390_tod_realize(DeviceState *dev, Error **errp) ++{ ++ S390TODState *td = S390_TOD(dev); ++ S390TODClass *tdc = S390_TOD_GET_CLASS(td); ++ Error *local_err = NULL; ++ ++ tdc->parent_realize(dev, &local_err); ++ if (local_err) { ++ error_propagate(errp, local_err); ++ return; ++ } ++ ++ /* ++ * We need to know when the VM gets started/stopped to start/stop the TOD. ++ * As we can never have more than one TOD instance (and that will never be ++ * removed), registering here and never unregistering is good enough. ++ */ ++ qemu_add_vm_change_state_handler(kvm_s390_tod_vm_state_change, td); ++} ++ + static void kvm_s390_tod_class_init(ObjectClass *oc, void *data) + { + S390TODClass *tdc = S390_TOD_CLASS(oc); + ++ device_class_set_parent_realize(DEVICE_CLASS(oc), kvm_s390_tod_realize, ++ &tdc->parent_realize); + tdc->get = kvm_s390_tod_get; + tdc->set = kvm_s390_tod_set; + } + ++static void kvm_s390_tod_init(Object *obj) ++{ ++ S390TODState *td = S390_TOD(obj); ++ ++ /* ++ * The TOD is initially running (value stored in KVM). Avoid needless ++ * loading/storing of the TOD when starting a simple VM, so let it ++ * run although the (never started) VM is stopped. For migration, we ++ * will properly set the TOD later. ++ */ ++ td->stopped = false; ++} ++ + static TypeInfo kvm_s390_tod_info = { + .name = TYPE_KVM_S390_TOD, + .parent = TYPE_S390_TOD, + .instance_size = sizeof(S390TODState), ++ .instance_init = kvm_s390_tod_init, + .class_init = kvm_s390_tod_class_init, + .class_size = sizeof(S390TODClass), + }; +diff --git a/include/hw/s390x/tod.h b/include/hw/s390x/tod.h +index 413c0d7..cbd7552 100644 +--- a/include/hw/s390x/tod.h ++++ b/include/hw/s390x/tod.h +@@ -31,13 +31,19 @@ typedef struct S390TODState { + /* private */ + DeviceState parent_obj; + +- /* unused by KVM implementation */ ++ /* ++ * Used by TCG to remember the time base. Used by KVM to backup the TOD ++ * while the TOD is stopped. ++ */ + S390TOD base; ++ /* Used by KVM to remember if the TOD is stopped and base is valid. */ ++ bool stopped; + } S390TODState; + + typedef struct S390TODClass { + /* private */ + DeviceClass parent_class; ++ void (*parent_realize)(DeviceState *dev, Error **errp); + + /* public */ + void (*get)(const S390TODState *td, S390TOD *tod, Error **errp); +-- +1.8.3.1 + diff --git a/SOURCES/kvm-s390x-tod-factor-out-TOD-into-separate-device.patch b/SOURCES/kvm-s390x-tod-factor-out-TOD-into-separate-device.patch new file mode 100644 index 0000000..c294173 --- /dev/null +++ b/SOURCES/kvm-s390x-tod-factor-out-TOD-into-separate-device.patch @@ -0,0 +1,516 @@ +From eb4b0282363c6149a05d6b00b0b7d40535715598 Mon Sep 17 00:00:00 2001 +From: David Hildenbrand +Date: Fri, 21 Dec 2018 15:39:48 +0100 +Subject: [PATCH 04/14] s390x/tod: factor out TOD into separate device + +RH-Author: David Hildenbrand +Message-id: <20181221153957.28183-4-david@redhat.com> +Patchwork-id: 83761 +O-Subject: [RHEL-7.6.z qemu-kvm-ma PATCH 03/12] s390x/tod: factor out TOD into separate device +Bugzilla: 1672920 +RH-Acked-by: Cornelia Huck +RH-Acked-by: Thomas Huth +RH-Acked-by: Laurent Vivier +Signed-off-by: Miroslav Rezanina + +Conflicts: + hw/s390x/s390-virtio-ccw.c: contextual conflict (console init + rework) + +Let's treat this like a separate device. TCG will have to store the +actual state/time later on. + +Include cpu-qom.h in kvm_s390x.h (due to S390CPU) to compile tod-kvm.c. + +Reviewed-by: Thomas Huth +Signed-off-by: David Hildenbrand +Message-Id: <20180627134410.4901-4-david@redhat.com> +Signed-off-by: Cornelia Huck +(cherry picked from commit 8046f374a64b81fdf4f71f7a433bf4035d501521) +Signed-off-by: David Hildenbrand +--- + hw/s390x/Makefile.objs | 3 ++ + hw/s390x/s390-virtio-ccw.c | 57 ++-------------------- + hw/s390x/tod-kvm.c | 64 ++++++++++++++++++++++++ + hw/s390x/tod-qemu.c | 49 +++++++++++++++++++ + hw/s390x/tod.c | 119 +++++++++++++++++++++++++++++++++++++++++++++ + include/hw/s390x/tod.h | 46 ++++++++++++++++++ + target/s390x/cpu.c | 32 ------------ + target/s390x/cpu.h | 2 - + target/s390x/kvm_s390x.h | 2 + + 9 files changed, 286 insertions(+), 88 deletions(-) + create mode 100644 hw/s390x/tod-kvm.c + create mode 100644 hw/s390x/tod-qemu.c + create mode 100644 hw/s390x/tod.c + create mode 100644 include/hw/s390x/tod.h + +diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs +index dc704b5..93282f7 100644 +--- a/hw/s390x/Makefile.objs ++++ b/hw/s390x/Makefile.objs +@@ -14,6 +14,9 @@ obj-$(CONFIG_PCI) += s390-pci-bus.o s390-pci-inst.o + obj-$(call lnot,$(CONFIG_PCI)) += s390-pci-stub.o + obj-y += s390-skeys.o + obj-y += s390-stattrib.o ++obj-y += tod.o ++obj-$(CONFIG_KVM) += tod-kvm.o ++obj-$(CONFIG_TCG) += tod-qemu.o + obj-$(CONFIG_KVM) += s390-skeys-kvm.o + obj-$(CONFIG_KVM) += s390-stattrib-kvm.o + obj-y += s390-ccw.o +diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c +index bf039a1..3429e55 100644 +--- a/hw/s390x/s390-virtio-ccw.c ++++ b/hw/s390x/s390-virtio-ccw.c +@@ -35,6 +35,7 @@ + #include "migration/register.h" + #include "cpu_models.h" + #include "hw/nmi.h" ++#include "hw/s390x/tod.h" + + S390CPU *s390_cpu_addr2state(uint16_t cpu_addr) + { +@@ -187,58 +188,6 @@ static void s390_memory_init(ram_addr_t mem_size) + s390_stattrib_init(); + } + +-#define S390_TOD_CLOCK_VALUE_MISSING 0x00 +-#define S390_TOD_CLOCK_VALUE_PRESENT 0x01 +- +-static void gtod_save(QEMUFile *f, void *opaque) +-{ +- uint64_t tod_low; +- uint8_t tod_high; +- int r; +- +- r = s390_get_clock(&tod_high, &tod_low); +- if (r) { +- warn_report("Unable to get guest clock for migration: %s", +- strerror(-r)); +- error_printf("Guest clock will not be migrated " +- "which could cause the guest to hang."); +- qemu_put_byte(f, S390_TOD_CLOCK_VALUE_MISSING); +- return; +- } +- +- qemu_put_byte(f, S390_TOD_CLOCK_VALUE_PRESENT); +- qemu_put_byte(f, tod_high); +- qemu_put_be64(f, tod_low); +-} +- +-static int gtod_load(QEMUFile *f, void *opaque, int version_id) +-{ +- uint64_t tod_low; +- uint8_t tod_high; +- int r; +- +- if (qemu_get_byte(f) == S390_TOD_CLOCK_VALUE_MISSING) { +- warn_report("Guest clock was not migrated. This could " +- "cause the guest to hang."); +- return 0; +- } +- +- tod_high = qemu_get_byte(f); +- tod_low = qemu_get_be64(f); +- +- r = s390_set_clock(&tod_high, &tod_low); +- if (r) { +- error_report("Unable to set KVM guest TOD clock: %s", strerror(-r)); +- } +- +- return r; +-} +- +-static SaveVMHandlers savevm_gtod = { +- .save_state = gtod_save, +- .load_state = gtod_load, +-}; +- + static void s390_init_ipl_dev(const char *kernel_filename, + const char *kernel_cmdline, + const char *initrd_filename, const char *firmware, +@@ -346,8 +295,8 @@ static void ccw_init(MachineState *machine) + /* Create VirtIO network adapters */ + s390_create_virtio_net(BUS(css_bus), "virtio-net-ccw"); + +- /* Register savevm handler for guest TOD clock */ +- register_savevm_live(NULL, "todclock", 0, 1, &savevm_gtod, NULL); ++ /* init the TOD clock */ ++ s390_init_tod(); + } + + static void s390_cpu_plug(HotplugHandler *hotplug_dev, +diff --git a/hw/s390x/tod-kvm.c b/hw/s390x/tod-kvm.c +new file mode 100644 +index 0000000..df564ab +--- /dev/null ++++ b/hw/s390x/tod-kvm.c +@@ -0,0 +1,64 @@ ++/* ++ * TOD (Time Of Day) clock - KVM implementation ++ * ++ * Copyright 2018 Red Hat, Inc. ++ * Author(s): David Hildenbrand ++ * ++ * This work is licensed under the terms of the GNU GPL, version 2 or later. ++ * See the COPYING file in the top-level directory. ++ */ ++ ++#include "qemu/osdep.h" ++#include "qapi/error.h" ++#include "hw/s390x/tod.h" ++#include "kvm_s390x.h" ++ ++static void kvm_s390_tod_get(const S390TODState *td, S390TOD *tod, Error **errp) ++{ ++ int r; ++ ++ r = kvm_s390_get_clock_ext(&tod->high, &tod->low); ++ if (r == -ENXIO) { ++ r = kvm_s390_get_clock(&tod->high, &tod->low); ++ } ++ if (r) { ++ error_setg(errp, "Unable to get KVM guest TOD clock: %s", ++ strerror(-r)); ++ } ++} ++ ++static void kvm_s390_tod_set(S390TODState *td, const S390TOD *tod, Error **errp) ++{ ++ int r; ++ ++ r = kvm_s390_set_clock_ext(tod->high, tod->low); ++ if (r == -ENXIO) { ++ r = kvm_s390_set_clock(tod->high, tod->low); ++ } ++ if (r) { ++ error_setg(errp, "Unable to set KVM guest TOD clock: %s", ++ strerror(-r)); ++ } ++} ++ ++static void kvm_s390_tod_class_init(ObjectClass *oc, void *data) ++{ ++ S390TODClass *tdc = S390_TOD_CLASS(oc); ++ ++ tdc->get = kvm_s390_tod_get; ++ tdc->set = kvm_s390_tod_set; ++} ++ ++static TypeInfo kvm_s390_tod_info = { ++ .name = TYPE_KVM_S390_TOD, ++ .parent = TYPE_S390_TOD, ++ .instance_size = sizeof(S390TODState), ++ .class_init = kvm_s390_tod_class_init, ++ .class_size = sizeof(S390TODClass), ++}; ++ ++static void register_types(void) ++{ ++ type_register_static(&kvm_s390_tod_info); ++} ++type_init(register_types); +diff --git a/hw/s390x/tod-qemu.c b/hw/s390x/tod-qemu.c +new file mode 100644 +index 0000000..03ea1ce +--- /dev/null ++++ b/hw/s390x/tod-qemu.c +@@ -0,0 +1,49 @@ ++/* ++ * TOD (Time Of Day) clock - QEMU implementation ++ * ++ * Copyright 2018 Red Hat, Inc. ++ * Author(s): David Hildenbrand ++ * ++ * This work is licensed under the terms of the GNU GPL, version 2 or later. ++ * See the COPYING file in the top-level directory. ++ */ ++ ++#include "qemu/osdep.h" ++#include "qapi/error.h" ++#include "hw/s390x/tod.h" ++ ++static void qemu_s390_tod_get(const S390TODState *td, S390TOD *tod, ++ Error **errp) ++{ ++ /* FIXME */ ++ tod->high = 0; ++ tod->low = 0; ++} ++ ++static void qemu_s390_tod_set(S390TODState *td, const S390TOD *tod, ++ Error **errp) ++{ ++ /* FIXME */ ++} ++ ++static void qemu_s390_tod_class_init(ObjectClass *oc, void *data) ++{ ++ S390TODClass *tdc = S390_TOD_CLASS(oc); ++ ++ tdc->get = qemu_s390_tod_get; ++ tdc->set = qemu_s390_tod_set; ++} ++ ++static TypeInfo qemu_s390_tod_info = { ++ .name = TYPE_QEMU_S390_TOD, ++ .parent = TYPE_S390_TOD, ++ .instance_size = sizeof(S390TODState), ++ .class_init = qemu_s390_tod_class_init, ++ .class_size = sizeof(S390TODClass), ++}; ++ ++static void register_types(void) ++{ ++ type_register_static(&qemu_s390_tod_info); ++} ++type_init(register_types); +diff --git a/hw/s390x/tod.c b/hw/s390x/tod.c +new file mode 100644 +index 0000000..0501aff +--- /dev/null ++++ b/hw/s390x/tod.c +@@ -0,0 +1,119 @@ ++/* ++ * TOD (Time Of Day) clock ++ * ++ * Copyright 2018 Red Hat, Inc. ++ * Author(s): David Hildenbrand ++ * ++ * This work is licensed under the terms of the GNU GPL, version 2 or later. ++ * See the COPYING file in the top-level directory. ++ */ ++ ++#include "qemu/osdep.h" ++#include "hw/s390x/tod.h" ++#include "qapi/error.h" ++#include "qemu/error-report.h" ++#include "sysemu/kvm.h" ++#include "migration/register.h" ++ ++void s390_init_tod(void) ++{ ++ Object *obj; ++ ++ if (kvm_enabled()) { ++ obj = object_new(TYPE_KVM_S390_TOD); ++ } else { ++ obj = object_new(TYPE_QEMU_S390_TOD); ++ } ++ object_property_add_child(qdev_get_machine(), TYPE_S390_TOD, obj, NULL); ++ object_unref(obj); ++ ++ qdev_init_nofail(DEVICE(obj)); ++} ++ ++#define S390_TOD_CLOCK_VALUE_MISSING 0x00 ++#define S390_TOD_CLOCK_VALUE_PRESENT 0x01 ++ ++static void s390_tod_save(QEMUFile *f, void *opaque) ++{ ++ S390TODState *td = opaque; ++ S390TODClass *tdc = S390_TOD_GET_CLASS(td); ++ Error *err = NULL; ++ S390TOD tod; ++ ++ tdc->get(td, &tod, &err); ++ if (err) { ++ warn_report_err(err); ++ error_printf("Guest clock will not be migrated " ++ "which could cause the guest to hang."); ++ qemu_put_byte(f, S390_TOD_CLOCK_VALUE_MISSING); ++ return; ++ } ++ ++ qemu_put_byte(f, S390_TOD_CLOCK_VALUE_PRESENT); ++ qemu_put_byte(f, tod.high); ++ qemu_put_be64(f, tod.low); ++} ++ ++static int s390_tod_load(QEMUFile *f, void *opaque, int version_id) ++{ ++ S390TODState *td = opaque; ++ S390TODClass *tdc = S390_TOD_GET_CLASS(td); ++ Error *err = NULL; ++ S390TOD tod; ++ ++ if (qemu_get_byte(f) == S390_TOD_CLOCK_VALUE_MISSING) { ++ warn_report("Guest clock was not migrated. This could " ++ "cause the guest to hang."); ++ return 0; ++ } ++ ++ tod.high = qemu_get_byte(f); ++ tod.low = qemu_get_be64(f); ++ ++ tdc->set(td, &tod, &err); ++ if (err) { ++ error_report_err(err); ++ return -1; ++ } ++ return 0; ++} ++ ++static SaveVMHandlers savevm_tod = { ++ .save_state = s390_tod_save, ++ .load_state = s390_tod_load, ++}; ++ ++static void s390_tod_realize(DeviceState *dev, Error **errp) ++{ ++ S390TODState *td = S390_TOD(dev); ++ ++ /* Legacy migration interface */ ++ register_savevm_live(NULL, "todclock", 0, 1, &savevm_tod, td); ++} ++ ++static void s390_tod_class_init(ObjectClass *oc, void *data) ++{ ++ DeviceClass *dc = DEVICE_CLASS(oc); ++ ++ dc->desc = "TOD (Time Of Day) Clock"; ++ dc->realize = s390_tod_realize; ++ set_bit(DEVICE_CATEGORY_MISC, dc->categories); ++ ++ /* We only have one TOD clock in the system attached to the machine */ ++ dc->user_creatable = false; ++} ++ ++static TypeInfo s390_tod_info = { ++ .name = TYPE_S390_TOD, ++ .parent = TYPE_DEVICE, ++ .instance_size = sizeof(S390TODState), ++ .class_init = s390_tod_class_init, ++ .class_size = sizeof(S390TODClass), ++ .abstract = true, ++}; ++ ++static void register_types(void) ++{ ++ type_register_static(&s390_tod_info); ++} ++type_init(register_types); +diff --git a/include/hw/s390x/tod.h b/include/hw/s390x/tod.h +new file mode 100644 +index 0000000..7096b57 +--- /dev/null ++++ b/include/hw/s390x/tod.h +@@ -0,0 +1,46 @@ ++/* ++ * TOD (Time Of Day) clock ++ * ++ * Copyright 2018 Red Hat, Inc. ++ * Author(s): David Hildenbrand ++ * ++ * This work is licensed under the terms of the GNU GPL, version 2 or later. ++ * See the COPYING file in the top-level directory. ++ */ ++ ++#ifndef HW_S390_TOD_H ++#define HW_S390_TOD_H ++ ++#include "hw/qdev.h" ++ ++typedef struct S390TOD { ++ uint8_t high; ++ uint64_t low; ++} S390TOD; ++ ++#define TYPE_S390_TOD "s390-tod" ++#define S390_TOD(obj) OBJECT_CHECK(S390TODState, (obj), TYPE_S390_TOD) ++#define S390_TOD_CLASS(oc) OBJECT_CLASS_CHECK(S390TODClass, (oc), \ ++ TYPE_S390_TOD) ++#define S390_TOD_GET_CLASS(obj) OBJECT_GET_CLASS(S390TODClass, (obj), \ ++ TYPE_S390_TOD) ++#define TYPE_KVM_S390_TOD TYPE_S390_TOD "-kvm" ++#define TYPE_QEMU_S390_TOD TYPE_S390_TOD "-qemu" ++ ++typedef struct S390TODState { ++ /* private */ ++ DeviceState parent_obj; ++} S390TODState; ++ ++typedef struct S390TODClass { ++ /* private */ ++ DeviceClass parent_class; ++ ++ /* public */ ++ void (*get)(const S390TODState *td, S390TOD *tod, Error **errp); ++ void (*set)(S390TODState *td, const S390TOD *tod, Error **errp); ++} S390TODClass; ++ ++void s390_init_tod(void); ++ ++#endif +diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c +index 1f590d1..167d089 100644 +--- a/target/s390x/cpu.c ++++ b/target/s390x/cpu.c +@@ -391,38 +391,6 @@ unsigned int s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu) + return s390_count_running_cpus(); + } + +-int s390_get_clock(uint8_t *tod_high, uint64_t *tod_low) +-{ +- int r = 0; +- +- if (kvm_enabled()) { +- r = kvm_s390_get_clock_ext(tod_high, tod_low); +- if (r == -ENXIO) { +- return kvm_s390_get_clock(tod_high, tod_low); +- } +- } else { +- /* Fixme TCG */ +- *tod_high = 0; +- *tod_low = 0; +- } +- +- return r; +-} +- +-int s390_set_clock(uint8_t *tod_high, uint64_t *tod_low) +-{ +- int r = 0; +- +- if (kvm_enabled()) { +- r = kvm_s390_set_clock_ext(*tod_high, *tod_low); +- if (r == -ENXIO) { +- return kvm_s390_set_clock(*tod_high, *tod_low); +- } +- } +- /* Fixme TCG */ +- return r; +-} +- + int s390_set_memory_limit(uint64_t new_limit, uint64_t *hw_limit) + { + if (kvm_enabled()) { +diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h +index 86d08fa..67118c8 100644 +--- a/target/s390x/cpu.h ++++ b/target/s390x/cpu.h +@@ -691,8 +691,6 @@ static inline uint64_t s390_build_validity_mcic(void) + + + /* cpu.c */ +-int s390_get_clock(uint8_t *tod_high, uint64_t *tod_low); +-int s390_set_clock(uint8_t *tod_high, uint64_t *tod_low); + void s390_crypto_reset(void); + bool s390_get_squash_mcss(void); + int s390_set_memory_limit(uint64_t new_limit, uint64_t *hw_limit); +diff --git a/target/s390x/kvm_s390x.h b/target/s390x/kvm_s390x.h +index 36eb34b..6e52287 100644 +--- a/target/s390x/kvm_s390x.h ++++ b/target/s390x/kvm_s390x.h +@@ -10,6 +10,8 @@ + #ifndef KVM_S390X_H + #define KVM_S390X_H + ++#include "cpu-qom.h" ++ + struct kvm_s390_irq; + + void kvm_s390_floating_interrupt_legacy(struct kvm_s390_irq *irq); +-- +1.8.3.1 + diff --git a/SPECS/qemu-kvm.spec b/SPECS/qemu-kvm.spec index 339d16a..17976e3 100644 --- a/SPECS/qemu-kvm.spec +++ b/SPECS/qemu-kvm.spec @@ -108,7 +108,7 @@ Obsoletes: %1%{rhel_ma_suffix} < %{obsoletes_version2} \ Summary: QEMU is a machine emulator and virtualizer Name: %{pkgname}%{?pkgsuffix} Version: 2.12.0 -Release: 18%{?dist} +Release: 18%{?dist}.2 # Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped Epoch: 10 License: GPLv2 and GPLv2+ and CC-BY @@ -1114,6 +1114,35 @@ Patch478: kvm-test-bdrv-drain-Fix-outdated-comments.patch Patch479: kvm-block-Use-a-single-global-AioWait.patch # For bz#1618584 - block commit aborts with "Co-routine was already scheduled" Patch480: kvm-test-bdrv-drain-Test-draining-job-source-child-and-p.patch +# For bz#1672919 - Trying to start a guest with hugetlbfs backing does not bail out so providing saying that hugetlbfs is not supported before actually trying to start the guest. [rhel-7.6.z] +Patch481: kvm-s390x-refuse-to-start-guests-backed-by-hugetlbfs.patch +# For bz#1672920 - Stress guest and stop it, then do live migration, guest hit call trace on destination end [rhel-7.6.z] +Patch482: kvm-s390x-tcg-avoid-overflows-in-time2tod-tod2time.patch +# For bz#1672920 - Stress guest and stop it, then do live migration, guest hit call trace on destination end [rhel-7.6.z] +Patch483: kvm-s390x-kvm-pass-values-instead-of-pointers-to-kvm_s39.patch +# For bz#1672920 - Stress guest and stop it, then do live migration, guest hit call trace on destination end [rhel-7.6.z] +Patch484: kvm-s390x-tod-factor-out-TOD-into-separate-device.patch +# For bz#1672920 - Stress guest and stop it, then do live migration, guest hit call trace on destination end [rhel-7.6.z] +Patch485: kvm-s390x-tcg-drop-tod_basetime.patch +# For bz#1672920 - Stress guest and stop it, then do live migration, guest hit call trace on destination end [rhel-7.6.z] +Patch486: kvm-s390x-tcg-properly-implement-the-TOD.patch +# For bz#1672920 - Stress guest and stop it, then do live migration, guest hit call trace on destination end [rhel-7.6.z] +Patch487: kvm-s390x-tcg-SET-CLOCK-COMPARATOR-can-clear-CKC-interru.patch +# For bz#1672920 - Stress guest and stop it, then do live migration, guest hit call trace on destination end [rhel-7.6.z] +Patch488: kvm-s390x-tcg-implement-SET-CLOCK.patch +# For bz#1672920 - Stress guest and stop it, then do live migration, guest hit call trace on destination end [rhel-7.6.z] +Patch489: kvm-s390x-tcg-rearm-the-CKC-timer-during-migration.patch +# For bz#1672920 - Stress guest and stop it, then do live migration, guest hit call trace on destination end [rhel-7.6.z] +Patch490: kvm-s390x-tcg-fix-locking-problem-with-tcg_s390_tod_upda.patch +# For bz#1672920 - Stress guest and stop it, then do live migration, guest hit call trace on destination end [rhel-7.6.z] +Patch491: kvm-hw-s390x-Include-the-tod-qemu-also-for-builds-with-d.patch +# For bz#1672920 - Stress guest and stop it, then do live migration, guest hit call trace on destination end [rhel-7.6.z] +Patch492: kvm-s390x-tod-Properly-stop-the-KVM-TOD-while-the-guest-.patch +# For bz#1672920 - Stress guest and stop it, then do live migration, guest hit call trace on destination end [rhel-7.6.z] +Patch493: kvm-hw-s390x-Fix-bad-mask-in-time2tod.patch +# For bz#1667843 - RHEL-Alt-7.6 - Backport diag308 stable exception fix (qemu-kvm-ma) +# For bz#1668424 - RHEL-Alt-7.6 - Backport diag308 stable exception fix (qemu-kvm-ma) [rhel-7.6.z] +Patch494: kvm-s390x-Return-specification-exception-for-unimplement.patch BuildRequires: zlib-devel BuildRequires: glib2-devel @@ -1808,6 +1837,20 @@ ApplyOptionalPatch() %patch478 -p1 %patch479 -p1 %patch480 -p1 +%patch481 -p1 +%patch482 -p1 +%patch483 -p1 +%patch484 -p1 +%patch485 -p1 +%patch486 -p1 +%patch487 -p1 +%patch488 -p1 +%patch489 -p1 +%patch490 -p1 +%patch491 -p1 +%patch492 -p1 +%patch493 -p1 +%patch494 -p1 # Fix executable permission for iotests chmod 755 $(ls tests/qemu-iotests/???) @@ -2328,6 +2371,28 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %endif %changelog +* Wed Feb 06 2019 Miroslav Rezanina - ma-2.12.0-18.el7_6.2 +- kvm-s390x-refuse-to-start-guests-backed-by-hugetlbfs.patch [bz#1672919] +- kvm-s390x-tcg-avoid-overflows-in-time2tod-tod2time.patch [bz#1672920] +- kvm-s390x-kvm-pass-values-instead-of-pointers-to-kvm_s39.patch [bz#1672920] +- kvm-s390x-tod-factor-out-TOD-into-separate-device.patch [bz#1672920] +- kvm-s390x-tcg-drop-tod_basetime.patch [bz#1672920] +- kvm-s390x-tcg-properly-implement-the-TOD.patch [bz#1672920] +- kvm-s390x-tcg-SET-CLOCK-COMPARATOR-can-clear-CKC-interru.patch [bz#1672920] +- kvm-s390x-tcg-implement-SET-CLOCK.patch [bz#1672920] +- kvm-s390x-tcg-rearm-the-CKC-timer-during-migration.patch [bz#1672920] +- kvm-s390x-tcg-fix-locking-problem-with-tcg_s390_tod_upda.patch [bz#1672920] +- kvm-hw-s390x-Include-the-tod-qemu-also-for-builds-with-d.patch [bz#1672920] +- kvm-s390x-tod-Properly-stop-the-KVM-TOD-while-the-guest-.patch [bz#1672920] +- kvm-hw-s390x-Fix-bad-mask-in-time2tod.patch [bz#1672920] +- kvm-s390x-Return-specification-exception-for-unimplement.patch [bz#1668424] +- Resolves: bz#1668424 + (RHEL-Alt-7.6 - Backport diag308 stable exception fix (qemu-kvm-ma) [rhel-7.6.z]) +- Resolves: bz#1672919 + (Trying to start a guest with hugetlbfs backing does not bail out so providing saying that hugetlbfs is not supported before actually trying to start the guest. [rhel-7.6.z]) +- Resolves: bz#1672920 + (Stress guest and stop it, then do live migration, guest hit call trace on destination end [rhel-7.6.z]) + * Fri Sep 21 2018 Miroslav Rezanina - 2.12.0-18.el7 - kvm-test-bdrv-drain-Fix-outdated-comments.patch [bz#1618584] - kvm-block-Use-a-single-global-AioWait.patch [bz#1618584]