* [Qemu-devel] [PULL 01/15] s390/ipl: fix ipl with -no-reboot
2018-07-02 11:17 [Qemu-devel] [PULL 00/15] s390x patches for 3.0 Cornelia Huck
@ 2018-07-02 11:17 ` Cornelia Huck
2018-07-02 11:17 ` [Qemu-devel] [PULL 02/15] loader: Check access size when calling rom_ptr() to avoid crashes Cornelia Huck
` (14 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Cornelia Huck @ 2018-07-02 11:17 UTC (permalink / raw)
To: Peter Maydell
Cc: Christian Borntraeger, Alexander Graf, Richard Henderson,
David Hildenbrand, Thomas Huth, qemu-s390x, qemu-devel,
Cornelia Huck
From: Christian Borntraeger <borntraeger@de.ibm.com>
kexec/kdump as well as the bootloader use a subcode of diagnose 308
that is supposed to reset the I/O subsystem but not comprise a full
"reboot". With the latest refactoring this is now broken when
-no-reboot is used or when libvirt acts on a reboot QMP event, for
example a virt-install from iso images.
We need to mark these "subsystem resets" as special.
Fixes: a30fb811cbe9 (s390x: refactor reset/reipl handling)
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Message-Id: <20180622102928.173420-1-borntraeger@de.ibm.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
hw/s390x/ipl.c | 8 +++++++-
include/sysemu/sysemu.h | 4 ++++
vl.c | 4 ++--
3 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index 0d67349004..f278036fa7 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -535,7 +535,13 @@ void s390_ipl_reset_request(CPUState *cs, enum s390_reset reset_type)
ipl->iplb_valid = s390_gen_initial_iplb(ipl);
}
}
- qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
+ if (reset_type == S390_RESET_MODIFIED_CLEAR ||
+ reset_type == S390_RESET_LOAD_NORMAL) {
+ /* ignore -no-reboot, send no event */
+ qemu_system_reset_request(SHUTDOWN_CAUSE_SUBSYSTEM_RESET);
+ } else {
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
+ }
/* as this is triggered by a CPU, make sure to exit the loop */
if (tcg_enabled()) {
cpu_loop_exit(cs);
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index b921c6f3b7..76ef6196a7 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -44,6 +44,10 @@ typedef enum ShutdownCause {
turns that into a shutdown */
SHUTDOWN_CAUSE_GUEST_PANIC, /* Guest panicked, and command line turns
that into a shutdown */
+ SHUTDOWN_CAUSE_SUBSYSTEM_RESET,/* Partial guest reset that does not trigger
+ QMP events and ignores --no-reboot. This
+ is useful for sanitize hypercalls on s390
+ that are used during kexec/kdump/boot */
SHUTDOWN_CAUSE__MAX,
} ShutdownCause;
diff --git a/vl.c b/vl.c
index ef6cfcec40..9442beee21 100644
--- a/vl.c
+++ b/vl.c
@@ -1645,7 +1645,7 @@ void qemu_system_reset(ShutdownCause reason)
} else {
qemu_devices_reset();
}
- if (reason) {
+ if (reason != SHUTDOWN_CAUSE_SUBSYSTEM_RESET) {
qapi_event_send_reset(shutdown_caused_by_guest(reason),
&error_abort);
}
@@ -1691,7 +1691,7 @@ void qemu_system_guest_panicked(GuestPanicInformation *info)
void qemu_system_reset_request(ShutdownCause reason)
{
- if (no_reboot) {
+ if (no_reboot && reason != SHUTDOWN_CAUSE_SUBSYSTEM_RESET) {
shutdown_requested = reason;
} else {
reset_requested = reason;
--
2.14.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [Qemu-devel] [PULL 02/15] loader: Check access size when calling rom_ptr() to avoid crashes
2018-07-02 11:17 [Qemu-devel] [PULL 00/15] s390x patches for 3.0 Cornelia Huck
2018-07-02 11:17 ` [Qemu-devel] [PULL 01/15] s390/ipl: fix ipl with -no-reboot Cornelia Huck
@ 2018-07-02 11:17 ` Cornelia Huck
2018-07-02 11:17 ` [Qemu-devel] [PULL 03/15] s390x/cpumodel: default enable bpb and ppa15 for z196 and later Cornelia Huck
` (13 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Cornelia Huck @ 2018-07-02 11:17 UTC (permalink / raw)
To: Peter Maydell
Cc: Christian Borntraeger, Alexander Graf, Richard Henderson,
David Hildenbrand, Thomas Huth, qemu-s390x, qemu-devel,
Cornelia Huck
From: Thomas Huth <thuth@redhat.com>
The rom_ptr() function allows direct access to the ROM blobs that we
load during startup. However, there are currently no checks for the
size of the accesses, so it's currently possible to crash QEMU for
example with:
$ echo "Insane in the mainframe" > /tmp/test.txt
$ s390x-softmmu/qemu-system-s390x -kernel /tmp/test.txt -append xyz
Segmentation fault (core dumped)
$ s390x-softmmu/qemu-system-s390x -kernel /tmp/test.txt -initrd /tmp/test.txt
Segmentation fault (core dumped)
$ echo -n HdrS > /tmp/hdr.txt
$ sparc64-softmmu/qemu-system-sparc64 -kernel /tmp/hdr.txt -initrd /tmp/hdr.txt
Segmentation fault (core dumped)
We need a possibility to check the size of the ROM area that we want
to access, thus let's add a size parameter to the rom_ptr() function
to avoid these problems.
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-Id: <1530005740-25254-1-git-send-email-thuth@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
hw/core/loader.c | 10 +++++-----
hw/mips/mips_malta.c | 6 ++++--
hw/s390x/ipl.c | 18 ++++++++++++------
hw/sparc/sun4m.c | 4 ++--
hw/sparc64/sun4u.c | 4 ++--
include/hw/loader.h | 2 +-
target/arm/cpu.c | 2 +-
7 files changed, 27 insertions(+), 19 deletions(-)
diff --git a/hw/core/loader.c b/hw/core/loader.c
index 06bdbca537..bbb6e65bb5 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -191,7 +191,7 @@ void pstrcpy_targphys(const char *name, hwaddr dest, int buf_size,
rom_add_blob_fixed(name, source, (nulp - source) + 1, dest);
} else {
rom_add_blob_fixed(name, source, buf_size, dest);
- ptr = rom_ptr(dest + buf_size - 1);
+ ptr = rom_ptr(dest + buf_size - 1, sizeof(*ptr));
*ptr = 0;
}
}
@@ -1165,7 +1165,7 @@ void rom_reset_order_override(void)
fw_cfg_reset_order_override(fw_cfg);
}
-static Rom *find_rom(hwaddr addr)
+static Rom *find_rom(hwaddr addr, size_t size)
{
Rom *rom;
@@ -1179,7 +1179,7 @@ static Rom *find_rom(hwaddr addr)
if (rom->addr > addr) {
continue;
}
- if (rom->addr + rom->romsize < addr) {
+ if (rom->addr + rom->romsize < addr + size) {
continue;
}
return rom;
@@ -1249,11 +1249,11 @@ int rom_copy(uint8_t *dest, hwaddr addr, size_t size)
return (d + l) - dest;
}
-void *rom_ptr(hwaddr addr)
+void *rom_ptr(hwaddr addr, size_t size)
{
Rom *rom;
- rom = find_rom(addr);
+ rom = find_rom(addr, size);
if (!rom || !rom->data)
return NULL;
return rom->data + (addr - rom->addr);
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index b9d92bf47e..1b4e32e58e 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -1133,11 +1133,13 @@ void mips_malta_init(MachineState *machine)
a neat trick which allows bi-endian firmware. */
#ifndef TARGET_WORDS_BIGENDIAN
{
- uint32_t *end, *addr = rom_ptr(FLASH_ADDRESS);
+ uint32_t *end, *addr;
+ const size_t swapsize = MIN(bios_size, 0x3e0000);
+ addr = rom_ptr(FLASH_ADDRESS, swapsize);
if (!addr) {
addr = memory_region_get_ram_ptr(bios);
}
- end = (void *)addr + MIN(bios_size, 0x3e0000);
+ end = (void *)addr + swapsize;
while (addr < end) {
bswap32s(addr);
addr++;
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index f278036fa7..21f64ad26a 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -33,7 +33,6 @@
#define KERN_PARM_AREA 0x010480UL
#define INITRD_START 0x800000UL
#define INITRD_PARM_START 0x010408UL
-#define INITRD_PARM_SIZE 0x010410UL
#define PARMFILE_START 0x001000UL
#define ZIPL_IMAGE_START 0x009000UL
#define IPL_PSW_MASK (PSW_MASK_32 | PSW_MASK_64)
@@ -165,12 +164,12 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp)
goto error;
}
/* if this is Linux use KERN_IMAGE_START */
- magic = rom_ptr(LINUX_MAGIC_ADDR);
+ magic = rom_ptr(LINUX_MAGIC_ADDR, 6);
if (magic && !memcmp(magic, "S390EP", 6)) {
pentry = KERN_IMAGE_START;
} else {
/* if not Linux load the address of the (short) IPL PSW */
- ipl_psw = rom_ptr(4);
+ ipl_psw = rom_ptr(4, 4);
if (ipl_psw) {
pentry = be32_to_cpu(*ipl_psw) & 0x7fffffffUL;
} else {
@@ -186,9 +185,12 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp)
* loader) and it won't work. For this case we force it to 0x10000, too.
*/
if (pentry == KERN_IMAGE_START || pentry == 0x800) {
+ char *parm_area = rom_ptr(KERN_PARM_AREA, strlen(ipl->cmdline) + 1);
ipl->start_addr = KERN_IMAGE_START;
/* Overwrite parameters in the kernel image, which are "rom" */
- strcpy(rom_ptr(KERN_PARM_AREA), ipl->cmdline);
+ if (parm_area) {
+ strcpy(parm_area, ipl->cmdline);
+ }
} else {
ipl->start_addr = pentry;
}
@@ -196,6 +198,7 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp)
if (ipl->initrd) {
ram_addr_t initrd_offset;
int initrd_size;
+ uint64_t *romptr;
initrd_offset = INITRD_START;
while (kernel_size + 0x100000 > initrd_offset) {
@@ -212,8 +215,11 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp)
* we have to overwrite values in the kernel image,
* which are "rom"
*/
- stq_p(rom_ptr(INITRD_PARM_START), initrd_offset);
- stq_p(rom_ptr(INITRD_PARM_SIZE), initrd_size);
+ romptr = rom_ptr(INITRD_PARM_START, 16);
+ if (romptr) {
+ stq_p(romptr, initrd_offset);
+ stq_p(romptr + 1, initrd_size);
+ }
}
}
/*
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index b984d2da0e..21078cc121 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -272,8 +272,8 @@ static unsigned long sun4m_load_kernel(const char *kernel_filename,
}
if (initrd_size > 0) {
for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
- ptr = rom_ptr(KERNEL_LOAD_ADDR + i);
- if (ldl_p(ptr) == 0x48647253) { // HdrS
+ ptr = rom_ptr(KERNEL_LOAD_ADDR + i, 24);
+ if (ptr && ldl_p(ptr) == 0x48647253) { /* HdrS */
stl_p(ptr + 16, INITRD_LOAD_ADDR);
stl_p(ptr + 20, initrd_size);
break;
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index 3975a7b65a..334dd7008e 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -186,8 +186,8 @@ static uint64_t sun4u_load_kernel(const char *kernel_filename,
}
if (*initrd_size > 0) {
for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
- ptr = rom_ptr(*kernel_addr + i);
- if (ldl_p(ptr + 8) == 0x48647253) { /* HdrS */
+ ptr = rom_ptr(*kernel_addr + i, 32);
+ if (ptr && ldl_p(ptr + 8) == 0x48647253) { /* HdrS */
stl_p(ptr + 24, *initrd_addr + *kernel_addr);
stl_p(ptr + 28, *initrd_size);
break;
diff --git a/include/hw/loader.h b/include/hw/loader.h
index 5ed3fd8ae6..e98b84b8f9 100644
--- a/include/hw/loader.h
+++ b/include/hw/loader.h
@@ -226,7 +226,7 @@ void rom_set_fw(FWCfgState *f);
void rom_set_order_override(int order);
void rom_reset_order_override(void);
int rom_copy(uint8_t *dest, hwaddr addr, size_t size);
-void *rom_ptr(hwaddr addr);
+void *rom_ptr(hwaddr addr, size_t size);
void hmp_info_roms(Monitor *mon, const QDict *qdict);
#define rom_add_file_fixed(_f, _a, _i) \
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 82ff450f9a..64a8005a4b 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -239,7 +239,7 @@ static void arm_cpu_reset(CPUState *s)
/* Load the initial SP and PC from offset 0 and 4 in the vector table */
vecbase = env->v7m.vecbase[env->v7m.secure];
- rom = rom_ptr(vecbase);
+ rom = rom_ptr(vecbase, 8);
if (rom) {
/* Address zero is covered by ROM which hasn't yet been
* copied into physical memory.
--
2.14.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [Qemu-devel] [PULL 03/15] s390x/cpumodel: default enable bpb and ppa15 for z196 and later
2018-07-02 11:17 [Qemu-devel] [PULL 00/15] s390x patches for 3.0 Cornelia Huck
2018-07-02 11:17 ` [Qemu-devel] [PULL 01/15] s390/ipl: fix ipl with -no-reboot Cornelia Huck
2018-07-02 11:17 ` [Qemu-devel] [PULL 02/15] loader: Check access size when calling rom_ptr() to avoid crashes Cornelia Huck
@ 2018-07-02 11:17 ` Cornelia Huck
2018-07-02 11:17 ` [Qemu-devel] [PULL 04/15] s390x/tcg: avoid overflows in time2tod/tod2time Cornelia Huck
` (12 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Cornelia Huck @ 2018-07-02 11:17 UTC (permalink / raw)
To: Peter Maydell
Cc: Christian Borntraeger, Alexander Graf, Richard Henderson,
David Hildenbrand, Thomas Huth, qemu-s390x, qemu-devel,
Cornelia Huck
From: Christian Borntraeger <borntraeger@de.ibm.com>
Most systems and host kernels provide the necessary building blocks for
bpb and ppa15. We can reverse the logic and default enable those
features, while still allowing to disable it via cpu model.
So let us add bpb and ppa15 to z196 and later default CPU model for the
qemu 3.0 machine. (like -cpu z13). Older machine types (e.g.
s390-ccw-virtio-2.12) will retain the old value and not provide those
bits in the default model.
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Message-Id: <20180626123830.18282-1-borntraeger@de.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
hw/s390x/s390-virtio-ccw.c | 2 ++
target/s390x/gen-features.c | 2 ++
2 files changed, 4 insertions(+)
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 7ae5fb38dd..f8f58c8acb 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -824,6 +824,8 @@ DEFINE_CCW_MACHINE(3_0, "3.0", true);
static void ccw_machine_2_12_instance_options(MachineState *machine)
{
ccw_machine_3_0_instance_options(machine);
+ s390_cpudef_featoff_greater(11, 1, S390_FEAT_PPA15);
+ s390_cpudef_featoff_greater(11, 1, S390_FEAT_BPB);
}
static void ccw_machine_2_12_class_options(MachineClass *mc)
diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c
index 0cdbc15378..6626b6f565 100644
--- a/target/s390x/gen-features.c
+++ b/target/s390x/gen-features.c
@@ -512,6 +512,8 @@ static uint16_t default_GEN11_GA1[] = {
S390_FEAT_IPTE_RANGE,
S390_FEAT_ACCESS_EXCEPTION_FS_INDICATION,
S390_FEAT_GROUP_MSA_EXT_4,
+ S390_FEAT_PPA15,
+ S390_FEAT_BPB,
};
#define default_GEN11_GA2 EmptyFeat
--
2.14.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [Qemu-devel] [PULL 04/15] s390x/tcg: avoid overflows in time2tod/tod2time
2018-07-02 11:17 [Qemu-devel] [PULL 00/15] s390x patches for 3.0 Cornelia Huck
` (2 preceding siblings ...)
2018-07-02 11:17 ` [Qemu-devel] [PULL 03/15] s390x/cpumodel: default enable bpb and ppa15 for z196 and later Cornelia Huck
@ 2018-07-02 11:17 ` Cornelia Huck
2018-07-02 11:17 ` [Qemu-devel] [PULL 05/15] s390x/kvm: pass values instead of pointers to kvm_s390_set_clock_*() Cornelia Huck
` (11 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Cornelia Huck @ 2018-07-02 11:17 UTC (permalink / raw)
To: Peter Maydell
Cc: Christian Borntraeger, Alexander Graf, Richard Henderson,
David Hildenbrand, Thomas Huth, qemu-s390x, qemu-devel,
Cornelia Huck
From: David Hildenbrand <david@redhat.com>
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 <thuth@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20180627134410.4901-2-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
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 e392a02d12..6cf63340bf 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,
--
2.14.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [Qemu-devel] [PULL 05/15] s390x/kvm: pass values instead of pointers to kvm_s390_set_clock_*()
2018-07-02 11:17 [Qemu-devel] [PULL 00/15] s390x patches for 3.0 Cornelia Huck
` (3 preceding siblings ...)
2018-07-02 11:17 ` [Qemu-devel] [PULL 04/15] s390x/tcg: avoid overflows in time2tod/tod2time Cornelia Huck
@ 2018-07-02 11:17 ` Cornelia Huck
2018-07-02 11:17 ` [Qemu-devel] [PULL 06/15] s390x/tod: factor out TOD into separate device Cornelia Huck
` (10 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Cornelia Huck @ 2018-07-02 11:17 UTC (permalink / raw)
To: Peter Maydell
Cc: Christian Borntraeger, Alexander Graf, Richard Henderson,
David Hildenbrand, Thomas Huth, qemu-s390x, qemu-devel,
Cornelia Huck
From: David Hildenbrand <david@redhat.com>
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 <david@redhat.com>
Message-Id: <20180627134410.4901-3-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
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 c268065887..68512e3e54 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -413,9 +413,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 29b10542cc..bf7795e47a 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 ac370da281..8bcd832123 100644
--- a/target/s390x/kvm.c
+++ b/target/s390x/kvm.c
@@ -666,13 +666,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);
@@ -681,15 +681,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 c383bf4ee9..36eb34bf99 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);
--
2.14.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [Qemu-devel] [PULL 06/15] s390x/tod: factor out TOD into separate device
2018-07-02 11:17 [Qemu-devel] [PULL 00/15] s390x patches for 3.0 Cornelia Huck
` (4 preceding siblings ...)
2018-07-02 11:17 ` [Qemu-devel] [PULL 05/15] s390x/kvm: pass values instead of pointers to kvm_s390_set_clock_*() Cornelia Huck
@ 2018-07-02 11:17 ` Cornelia Huck
2018-10-11 12:15 ` [Qemu-devel] [qemu-s390x] " Thomas Huth
2018-07-02 11:17 ` [Qemu-devel] [PULL 07/15] s390x/tcg: drop tod_basetime Cornelia Huck
` (9 subsequent siblings)
15 siblings, 1 reply; 20+ messages in thread
From: Cornelia Huck @ 2018-07-02 11:17 UTC (permalink / raw)
To: Peter Maydell
Cc: Christian Borntraeger, Alexander Graf, Richard Henderson,
David Hildenbrand, Thomas Huth, qemu-s390x, qemu-devel,
Cornelia Huck
From: David Hildenbrand <david@redhat.com>
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 <thuth@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20180627134410.4901-4-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
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 dc704b57d6..93282f7c59 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 f8f58c8acb..7983185d04 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,
@@ -363,8 +312,8 @@ static void ccw_init(MachineState *machine)
s390_create_sclpconsole("sclplmconsole", serial_hd(1));
}
- /* 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 0000000000..df564ab89c
--- /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 <david@redhat.com>
+ *
+ * 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 0000000000..03ea1ce4e8
--- /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 <david@redhat.com>
+ *
+ * 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 0000000000..0501affa7f
--- /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 <david@redhat.com>
+ *
+ * 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 0000000000..7096b574ae
--- /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 <david@redhat.com>
+ *
+ * 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 68512e3e54..03ea6eafa7 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -390,38 +390,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 6629a533f3..ac51c17fb4 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -714,8 +714,6 @@ static inline void s390_do_cpu_load_normal(CPUState *cs, run_on_cpu_data arg)
/* 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 36eb34bf99..6e52287da3 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);
--
2.14.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [Qemu-devel] [qemu-s390x] [PULL 06/15] s390x/tod: factor out TOD into separate device
2018-07-02 11:17 ` [Qemu-devel] [PULL 06/15] s390x/tod: factor out TOD into separate device Cornelia Huck
@ 2018-10-11 12:15 ` Thomas Huth
2018-10-11 12:32 ` Cornelia Huck
0 siblings, 1 reply; 20+ messages in thread
From: Thomas Huth @ 2018-10-11 12:15 UTC (permalink / raw)
To: Cornelia Huck, David Hildenbrand
Cc: qemu-devel, Christian Borntraeger, qemu-s390x
On 2018-07-02 13:17, Cornelia Huck wrote:
> From: David Hildenbrand <david@redhat.com>
>
> 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.
This patch breaks "make check" when QEMU has been compiled with
--disable-tcg on s390x:
$ gdb --args s390x-softmmu/qemu-system-s390x -nographic -accel qtest
[...]
ERROR:qom/object.c:549:object_new_with_type: assertion failed: (type != NULL)
Program received signal SIGABRT, Aborted.
[...]
(gdb) bt
#0 0x000003fffcac1220 in raise () from /lib64/libc.so.6
#1 0x000003fffcac2aa8 in abort () from /lib64/libc.so.6
#2 0x000003fffd0fdd5e in g_assertion_message () from /lib64/libglib-2.0.so.0
#3 0x000003fffd0fddc6 in g_assertion_message_expr () from /lib64/libglib-2.0.so.0
#4 0x00000001002d4bf2 in object_new_with_type (type=0x0)
qom/object.c:549
#5 0x00000001002d4d6e in object_new (typename=typename@entry=0x100490ce8 "s390-tod-qemu")
at qom/object.c:563
#6 0x00000001001c04ee in s390_init_tod () at hw/s390x/tod.c:25
#7 0x0000000100233d00 in machine_run_board_init (machine=0x1008f5510)
at hw/core/machine.c:834
#8 0x000000010012cb08 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>)
at vl.c:4489
> diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
> index dc704b57d6..93282f7c59 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
With --disable-tcg, tod-qemu.o is not included in the build.
[...]
> diff --git a/hw/s390x/tod.c b/hw/s390x/tod.c
> new file mode 100644
> index 0000000000..0501affa7f
> --- /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 <david@redhat.com>
> + *
> + * 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);
> + }
... but with "-accel qtest", QEMU tries to instantiate the object here.
I think we should maybe simply inclue tod-qemu.o unconditionally? Opinions?
Thomas
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [Qemu-devel] [qemu-s390x] [PULL 06/15] s390x/tod: factor out TOD into separate device
2018-10-11 12:15 ` [Qemu-devel] [qemu-s390x] " Thomas Huth
@ 2018-10-11 12:32 ` Cornelia Huck
2018-10-11 12:35 ` David Hildenbrand
0 siblings, 1 reply; 20+ messages in thread
From: Cornelia Huck @ 2018-10-11 12:32 UTC (permalink / raw)
To: Thomas Huth
Cc: David Hildenbrand, qemu-devel, Christian Borntraeger, qemu-s390x
On Thu, 11 Oct 2018 14:15:41 +0200
Thomas Huth <thuth@redhat.com> wrote:
> On 2018-07-02 13:17, Cornelia Huck wrote:
> > From: David Hildenbrand <david@redhat.com>
> >
> > 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.
>
> This patch breaks "make check" when QEMU has been compiled with
> --disable-tcg on s390x:
>
> $ gdb --args s390x-softmmu/qemu-system-s390x -nographic -accel qtest
> [...]
> ERROR:qom/object.c:549:object_new_with_type: assertion failed: (type != NULL)
>
> Program received signal SIGABRT, Aborted.
> [...]
> (gdb) bt
> #0 0x000003fffcac1220 in raise () from /lib64/libc.so.6
> #1 0x000003fffcac2aa8 in abort () from /lib64/libc.so.6
> #2 0x000003fffd0fdd5e in g_assertion_message () from /lib64/libglib-2.0.so.0
> #3 0x000003fffd0fddc6 in g_assertion_message_expr () from /lib64/libglib-2.0.so.0
> #4 0x00000001002d4bf2 in object_new_with_type (type=0x0)
> qom/object.c:549
> #5 0x00000001002d4d6e in object_new (typename=typename@entry=0x100490ce8 "s390-tod-qemu")
> at qom/object.c:563
> #6 0x00000001001c04ee in s390_init_tod () at hw/s390x/tod.c:25
> #7 0x0000000100233d00 in machine_run_board_init (machine=0x1008f5510)
> at hw/core/machine.c:834
> #8 0x000000010012cb08 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>)
> at vl.c:4489
>
> > diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
> > index dc704b57d6..93282f7c59 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
>
> With --disable-tcg, tod-qemu.o is not included in the build.
>
> [...]
> > diff --git a/hw/s390x/tod.c b/hw/s390x/tod.c
> > new file mode 100644
> > index 0000000000..0501affa7f
> > --- /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 <david@redhat.com>
> > + *
> > + * 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);
> > + }
>
> ... but with "-accel qtest", QEMU tries to instantiate the object here.
>
> I think we should maybe simply inclue tod-qemu.o unconditionally? Opinions?
If tod-qemu does not depend on tcg stuff, that sounds like the easiest
solution.
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [Qemu-devel] [qemu-s390x] [PULL 06/15] s390x/tod: factor out TOD into separate device
2018-10-11 12:32 ` Cornelia Huck
@ 2018-10-11 12:35 ` David Hildenbrand
0 siblings, 0 replies; 20+ messages in thread
From: David Hildenbrand @ 2018-10-11 12:35 UTC (permalink / raw)
To: Cornelia Huck, Thomas Huth; +Cc: qemu-devel, Christian Borntraeger, qemu-s390x
On 11/10/2018 14:32, Cornelia Huck wrote:
> On Thu, 11 Oct 2018 14:15:41 +0200
> Thomas Huth <thuth@redhat.com> wrote:
>
>> On 2018-07-02 13:17, Cornelia Huck wrote:
>>> From: David Hildenbrand <david@redhat.com>
>>>
>>> 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.
>>
>> This patch breaks "make check" when QEMU has been compiled with
>> --disable-tcg on s390x:
>>
>> $ gdb --args s390x-softmmu/qemu-system-s390x -nographic -accel qtest
>> [...]
>> ERROR:qom/object.c:549:object_new_with_type: assertion failed: (type != NULL)
>>
>> Program received signal SIGABRT, Aborted.
>> [...]
>> (gdb) bt
>> #0 0x000003fffcac1220 in raise () from /lib64/libc.so.6
>> #1 0x000003fffcac2aa8 in abort () from /lib64/libc.so.6
>> #2 0x000003fffd0fdd5e in g_assertion_message () from /lib64/libglib-2.0.so.0
>> #3 0x000003fffd0fddc6 in g_assertion_message_expr () from /lib64/libglib-2.0.so.0
>> #4 0x00000001002d4bf2 in object_new_with_type (type=0x0)
>> qom/object.c:549
>> #5 0x00000001002d4d6e in object_new (typename=typename@entry=0x100490ce8 "s390-tod-qemu")
>> at qom/object.c:563
>> #6 0x00000001001c04ee in s390_init_tod () at hw/s390x/tod.c:25
>> #7 0x0000000100233d00 in machine_run_board_init (machine=0x1008f5510)
>> at hw/core/machine.c:834
>> #8 0x000000010012cb08 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>)
>> at vl.c:4489
>>
>>> diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
>>> index dc704b57d6..93282f7c59 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
>>
>> With --disable-tcg, tod-qemu.o is not included in the build.
>>
>> [...]
>>> diff --git a/hw/s390x/tod.c b/hw/s390x/tod.c
>>> new file mode 100644
>>> index 0000000000..0501affa7f
>>> --- /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 <david@redhat.com>
>>> + *
>>> + * 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);
>>> + }
>>
>> ... but with "-accel qtest", QEMU tries to instantiate the object here.
>>
>> I think we should maybe simply inclue tod-qemu.o unconditionally? Opinions?
>
> If tod-qemu does not depend on tcg stuff, that sounds like the easiest
> solution.
>
Or include it also for the (fake?) accel qtest instead of always.
--
Thanks,
David / dhildenb
^ permalink raw reply [flat|nested] 20+ messages in thread
* [Qemu-devel] [PULL 07/15] s390x/tcg: drop tod_basetime
2018-07-02 11:17 [Qemu-devel] [PULL 00/15] s390x patches for 3.0 Cornelia Huck
` (5 preceding siblings ...)
2018-07-02 11:17 ` [Qemu-devel] [PULL 06/15] s390x/tod: factor out TOD into separate device Cornelia Huck
@ 2018-07-02 11:17 ` Cornelia Huck
2018-07-02 11:17 ` [Qemu-devel] [PULL 08/15] s390x/tcg: properly implement the TOD Cornelia Huck
` (8 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Cornelia Huck @ 2018-07-02 11:17 UTC (permalink / raw)
To: Peter Maydell
Cc: Christian Borntraeger, Alexander Graf, Richard Henderson,
David Hildenbrand, Thomas Huth, qemu-s390x, qemu-devel,
Cornelia Huck
From: David Hildenbrand <david@redhat.com>
Never set to anything but 0.
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20180627134410.4901-5-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
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 03ea6eafa7..a41b3f34ab 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -289,7 +289,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 ac51c17fb4..4abfe88a3d 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -131,7 +131,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 de1ced2082..dd5273949b 100644
--- a/target/s390x/misc_helper.c
+++ b/target/s390x/misc_helper.c
@@ -141,7 +141,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;
}
@@ -161,7 +161,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 */
--
2.14.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [Qemu-devel] [PULL 08/15] s390x/tcg: properly implement the TOD
2018-07-02 11:17 [Qemu-devel] [PULL 00/15] s390x patches for 3.0 Cornelia Huck
` (6 preceding siblings ...)
2018-07-02 11:17 ` [Qemu-devel] [PULL 07/15] s390x/tcg: drop tod_basetime Cornelia Huck
@ 2018-07-02 11:17 ` Cornelia Huck
2018-07-02 11:17 ` [Qemu-devel] [PULL 09/15] s390x/tcg: SET CLOCK COMPARATOR can clear CKC interrupts Cornelia Huck
` (7 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Cornelia Huck @ 2018-07-02 11:17 UTC (permalink / raw)
To: Peter Maydell
Cc: Christian Borntraeger, Alexander Graf, Richard Henderson,
David Hildenbrand, Thomas Huth, qemu-s390x, qemu-devel,
Cornelia Huck
From: David Hildenbrand <david@redhat.com>
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 <thuth@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20180627134410.4901-6-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
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 03ea1ce4e8..59c015c69d 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 0501affa7f..1c63f411e6 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 7096b574ae..413c0d7c02 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 a41b3f34ab..40d6980229 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"
@@ -275,9 +274,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;
@@ -286,9 +282,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 4abfe88a3d..2c3dd2d189 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -130,7 +130,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 6cf63340bf..f2a771e2b4 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 dd5273949b..229f14d3da 100644
--- a/target/s390x/misc_helper.c
+++ b/target/s390x/misc_helper.c
@@ -28,6 +28,8 @@
#include "qemu/timer.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"
@@ -39,6 +41,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 */
@@ -138,17 +141,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;
}
@@ -156,7 +161,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);
@@ -164,6 +169,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 0000000000..4e308aa0ce
--- /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 <david@redhat.com>
+ *
+ * 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 */
--
2.14.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [Qemu-devel] [PULL 09/15] s390x/tcg: SET CLOCK COMPARATOR can clear CKC interrupts
2018-07-02 11:17 [Qemu-devel] [PULL 00/15] s390x patches for 3.0 Cornelia Huck
` (7 preceding siblings ...)
2018-07-02 11:17 ` [Qemu-devel] [PULL 08/15] s390x/tcg: properly implement the TOD Cornelia Huck
@ 2018-07-02 11:17 ` Cornelia Huck
2018-07-02 11:17 ` [Qemu-devel] [PULL 10/15] s390x/tcg: implement SET CLOCK Cornelia Huck
` (6 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Cornelia Huck @ 2018-07-02 11:17 UTC (permalink / raw)
To: Peter Maydell
Cc: Christian Borntraeger, Alexander Graf, Richard Henderson,
David Hildenbrand, Thomas Huth, qemu-s390x, qemu-devel,
Cornelia Huck
From: David Hildenbrand <david@redhat.com>
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 <thuth@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20180627134410.4901-7-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
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 229f14d3da..e4c1522140 100644
--- a/target/s390x/misc_helper.c
+++ b/target/s390x/misc_helper.c
@@ -154,6 +154,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;
}
--
2.14.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [Qemu-devel] [PULL 10/15] s390x/tcg: implement SET CLOCK
2018-07-02 11:17 [Qemu-devel] [PULL 00/15] s390x patches for 3.0 Cornelia Huck
` (8 preceding siblings ...)
2018-07-02 11:17 ` [Qemu-devel] [PULL 09/15] s390x/tcg: SET CLOCK COMPARATOR can clear CKC interrupts Cornelia Huck
@ 2018-07-02 11:17 ` Cornelia Huck
2018-07-02 11:17 ` [Qemu-devel] [PULL 11/15] s390x/tcg: rearm the CKC timer during migration Cornelia Huck
` (5 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Cornelia Huck @ 2018-07-02 11:17 UTC (permalink / raw)
To: Peter Maydell
Cc: Christian Borntraeger, Alexander Graf, Richard Henderson,
David Hildenbrand, Thomas Huth, qemu-s390x, qemu-devel,
Cornelia Huck
From: David Hildenbrand <david@redhat.com>
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 <thuth@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20180627134410.4901-8-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
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 59cba86a27..97c60ca7bc 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 157619403d..5c6f33ed9c 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 e4c1522140..7656a9b90a 100644
--- a/target/s390x/misc_helper.c
+++ b/target/s390x/misc_helper.c
@@ -184,6 +184,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 fdfec7feba..57c03cbf58 100644
--- a/target/s390x/translate.c
+++ b/target/s390x/translate.c
@@ -4016,6 +4016,15 @@ static DisasJumpType op_stcke(DisasContext *s, DisasOps *o)
return DISAS_NEXT;
}
+static DisasJumpType 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 DISAS_NEXT;
+}
+
static DisasJumpType op_sckc(DisasContext *s, DisasOps *o)
{
check_privileged(s);
--
2.14.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [Qemu-devel] [PULL 11/15] s390x/tcg: rearm the CKC timer during migration
2018-07-02 11:17 [Qemu-devel] [PULL 00/15] s390x patches for 3.0 Cornelia Huck
` (9 preceding siblings ...)
2018-07-02 11:17 ` [Qemu-devel] [PULL 10/15] s390x/tcg: implement SET CLOCK Cornelia Huck
@ 2018-07-02 11:17 ` Cornelia Huck
2018-07-02 11:17 ` [Qemu-devel] [PULL 12/15] s390x/tcg: fix CPU hotplug with single-threaded TCG Cornelia Huck
` (4 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Cornelia Huck @ 2018-07-02 11:17 UTC (permalink / raw)
To: Peter Maydell
Cc: Christian Borntraeger, Alexander Graf, Richard Henderson,
David Hildenbrand, Thomas Huth, qemu-s390x, qemu-devel,
Cornelia Huck
From: David Hildenbrand <david@redhat.com>
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 <thuth@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20180627134410.4901-9-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
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 31932de9cf..22a9a9927a 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 84b4928755..bd3230d027 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 0000000000..c93501db0b
--- /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 <david@redhat.com>
+ *
+ * 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)
+{
+}
--
2.14.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [Qemu-devel] [PULL 12/15] s390x/tcg: fix CPU hotplug with single-threaded TCG
2018-07-02 11:17 [Qemu-devel] [PULL 00/15] s390x patches for 3.0 Cornelia Huck
` (10 preceding siblings ...)
2018-07-02 11:17 ` [Qemu-devel] [PULL 11/15] s390x/tcg: rearm the CKC timer during migration Cornelia Huck
@ 2018-07-02 11:17 ` Cornelia Huck
2018-07-02 11:17 ` [Qemu-devel] [PULL 13/15] s390x/kvm: legacy_s390_alloc() only supports one allocation Cornelia Huck
` (3 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Cornelia Huck @ 2018-07-02 11:17 UTC (permalink / raw)
To: Peter Maydell
Cc: Christian Borntraeger, Alexander Graf, Richard Henderson,
David Hildenbrand, Thomas Huth, qemu-s390x, qemu-devel,
Cornelia Huck
From: David Hildenbrand <david@redhat.com>
run_on_cpu() doesn't seem to work reliably until the CPU has been fully
created if the single-threaded TCG main loop is already running.
Therefore, hotplugging a CPU under single-threaded TCG does currently
not work. We should use the direct call instead of going via
run_on_cpu().
So let's use run_on_cpu() for KVM only - KVM requires it due to the initial
CPU reset ioctl. As a nice side effect, we get rid of the ifdef.
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20180627134410.4901-10-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
target/s390x/cpu.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index 40d6980229..271c5ce652 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -218,11 +218,18 @@ static void s390_cpu_realizefn(DeviceState *dev, Error **errp)
#endif
s390_cpu_gdb_init(cs);
qemu_init_vcpu(cs);
-#if !defined(CONFIG_USER_ONLY)
- run_on_cpu(cs, s390_do_cpu_full_reset, RUN_ON_CPU_NULL);
-#else
- cpu_reset(cs);
-#endif
+
+ /*
+ * KVM requires the initial CPU reset ioctl to be executed on the target
+ * CPU thread. CPU hotplug under single-threaded TCG will not work with
+ * run_on_cpu(), as run_on_cpu() will not work properly if called while
+ * the main thread is already running but the CPU hasn't been realized.
+ */
+ if (kvm_enabled()) {
+ run_on_cpu(cs, s390_do_cpu_full_reset, RUN_ON_CPU_NULL);
+ } else {
+ cpu_reset(cs);
+ }
scc->parent_realize(dev, &err);
out:
--
2.14.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [Qemu-devel] [PULL 13/15] s390x/kvm: legacy_s390_alloc() only supports one allocation
2018-07-02 11:17 [Qemu-devel] [PULL 00/15] s390x patches for 3.0 Cornelia Huck
` (11 preceding siblings ...)
2018-07-02 11:17 ` [Qemu-devel] [PULL 12/15] s390x/tcg: fix CPU hotplug with single-threaded TCG Cornelia Huck
@ 2018-07-02 11:17 ` Cornelia Huck
2018-07-02 11:17 ` [Qemu-devel] [PULL 14/15] s390x/kvm: indicate alignment in legacy_s390_alloc() Cornelia Huck
` (2 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Cornelia Huck @ 2018-07-02 11:17 UTC (permalink / raw)
To: Peter Maydell
Cc: Christian Borntraeger, Alexander Graf, Richard Henderson,
David Hildenbrand, Thomas Huth, qemu-s390x, qemu-devel,
Cornelia Huck
From: David Hildenbrand <david@redhat.com>
We always allocate at a fixed address, a second allocation can therefore
of course never work. We would simply overwrite mappings.
This can e.g. happen in s390_memory_init(), if trying to allocate more
than > 8TB. Let's just bail out, as there is no need for supporting it
(legacy handling for z/VM).
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20180628113817.30814-2-david@redhat.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
target/s390x/kvm.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
index 8bcd832123..a9d6d606df 100644
--- a/target/s390x/kvm.c
+++ b/target/s390x/kvm.c
@@ -752,12 +752,20 @@ int kvm_s390_mem_op(S390CPU *cpu, vaddr addr, uint8_t ar, void *hostbuf,
*/
static void *legacy_s390_alloc(size_t size, uint64_t *align, bool shared)
{
- void *mem;
+ static void *mem;
+
+ if (mem) {
+ /* we only support one allocation, which is enough for initial ram */
+ return NULL;
+ }
mem = mmap((void *) 0x800000000ULL, size,
PROT_EXEC|PROT_READ|PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
- return mem == MAP_FAILED ? NULL : mem;
+ if (mem == MAP_FAILED) {
+ mem = NULL;
+ }
+ return mem;
}
static uint8_t const *sw_bp_inst;
--
2.14.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [Qemu-devel] [PULL 14/15] s390x/kvm: indicate alignment in legacy_s390_alloc()
2018-07-02 11:17 [Qemu-devel] [PULL 00/15] s390x patches for 3.0 Cornelia Huck
` (12 preceding siblings ...)
2018-07-02 11:17 ` [Qemu-devel] [PULL 13/15] s390x/kvm: legacy_s390_alloc() only supports one allocation Cornelia Huck
@ 2018-07-02 11:17 ` Cornelia Huck
2018-07-02 11:17 ` [Qemu-devel] [PULL 15/15] s390x/tcg: fix locking problem with tcg_s390_tod_updated Cornelia Huck
2018-07-02 15:07 ` [Qemu-devel] [PULL 00/15] s390x patches for 3.0 Peter Maydell
15 siblings, 0 replies; 20+ messages in thread
From: Cornelia Huck @ 2018-07-02 11:17 UTC (permalink / raw)
To: Peter Maydell
Cc: Christian Borntraeger, Alexander Graf, Richard Henderson,
David Hildenbrand, Thomas Huth, qemu-s390x, qemu-devel,
Cornelia Huck
From: David Hildenbrand <david@redhat.com>
Let's do this for completeness reason, although we don't support e.g.
PCDIMM/NVDIMM, which would use the alignment for placing the memory
region in guest physical memory. But maybe someday we would want to
support something like this - then we don't forget about this if
allowing multiple allocations in legacy_s390_alloc().
Use the same alignment as we would set in qemu_anon_ram_alloc(). Our
fixed address satisfies this alignment (1MB). This implicitly sets the
alignment of the underlying memory region.
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20180628113817.30814-3-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
target/s390x/kvm.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
index a9d6d606df..d923cf4240 100644
--- a/target/s390x/kvm.c
+++ b/target/s390x/kvm.c
@@ -765,6 +765,9 @@ static void *legacy_s390_alloc(size_t size, uint64_t *align, bool shared)
if (mem == MAP_FAILED) {
mem = NULL;
}
+ if (mem && align) {
+ *align = QEMU_VMALLOC_ALIGN;
+ }
return mem;
}
--
2.14.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [Qemu-devel] [PULL 15/15] s390x/tcg: fix locking problem with tcg_s390_tod_updated
2018-07-02 11:17 [Qemu-devel] [PULL 00/15] s390x patches for 3.0 Cornelia Huck
` (13 preceding siblings ...)
2018-07-02 11:17 ` [Qemu-devel] [PULL 14/15] s390x/kvm: indicate alignment in legacy_s390_alloc() Cornelia Huck
@ 2018-07-02 11:17 ` Cornelia Huck
2018-07-02 15:07 ` [Qemu-devel] [PULL 00/15] s390x patches for 3.0 Peter Maydell
15 siblings, 0 replies; 20+ messages in thread
From: Cornelia Huck @ 2018-07-02 11:17 UTC (permalink / raw)
To: Peter Maydell
Cc: Christian Borntraeger, Alexander Graf, Richard Henderson,
David Hildenbrand, Thomas Huth, qemu-s390x, qemu-devel,
Cornelia Huck
From: David Hildenbrand <david@redhat.com>
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 <borntraeger@de.ibm.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20180629170520.13671-1-david@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
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 7656a9b90a..3f91579570 100644
--- a/target/s390x/misc_helper.c
+++ b/target/s390x/misc_helper.c
@@ -149,26 +149,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);
@@ -176,12 +173,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 */
--
2.14.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [Qemu-devel] [PULL 00/15] s390x patches for 3.0
2018-07-02 11:17 [Qemu-devel] [PULL 00/15] s390x patches for 3.0 Cornelia Huck
` (14 preceding siblings ...)
2018-07-02 11:17 ` [Qemu-devel] [PULL 15/15] s390x/tcg: fix locking problem with tcg_s390_tod_updated Cornelia Huck
@ 2018-07-02 15:07 ` Peter Maydell
15 siblings, 0 replies; 20+ messages in thread
From: Peter Maydell @ 2018-07-02 15:07 UTC (permalink / raw)
To: Cornelia Huck
Cc: Christian Borntraeger, Alexander Graf, Richard Henderson,
David Hildenbrand, Thomas Huth, qemu-s390x, QEMU Developers
On 2 July 2018 at 12:17, Cornelia Huck <cohuck@redhat.com> wrote:
> The following changes since commit 281bd281222776229d5dbf84d1a5c6d8d9d2a34b:
>
> Merge remote-tracking branch 'remotes/xtensa/tags/20180630-xtensa' into staging (2018-06-30 22:23:51 +0100)
>
> are available in the Git repository at:
>
> git://github.com/cohuck/qemu tags/s390x-20180702
>
> for you to fetch changes up to 30c8db0e219a3c1d8b39c19e8b858830cb141738:
>
> s390x/tcg: fix locking problem with tcg_s390_tod_updated (2018-07-02 10:37:38 +0200)
>
> ----------------------------------------------------------------
> s390x updates:
> - add bpb/ppa15 features to default cpu model for z196 and later
> - rework TOD handling and fix cpu hotplug under tcg
> - various fixes
>
Applied, thanks.
-- PMM
^ permalink raw reply [flat|nested] 20+ messages in thread