aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2016-01-28 11:46:33 +0000
committerPeter Maydell <peter.maydell@linaro.org>2016-01-28 11:46:34 +0000
commit357e81c7e880f868833edf9f53cce1f3b09ea8ec (patch)
treecf82332ce2788845f63c24db676407f949b5ea38
parent8fd9dece6599eb3fbd2cdd3e7fbdd4e575e33911 (diff)
parent234779a2b9141d9386289ba5ed86c9d617567646 (diff)
Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20160128' into staging
Mostly bugfixes and small improvements; and the gdb target.xml patch. # gpg: Signature made Thu 28 Jan 2016 11:02:14 GMT using RSA key ID C6F02FAF # gpg: Good signature from "Cornelia Huck <huckc@linux.vnet.ibm.com>" # gpg: aka "Cornelia Huck <cornelia.huck@de.ibm.com>" * remotes/cohuck/tags/s390x-20160128: s390x: s390_cpu_get_phys_page_debug has to return -1 gdb: provide the name of the architecture in the target.xml s390x/css: fix control flags during csch watchdog/diag288: don't reset for action=none|debug|pause watchdog: introduction of get_watchdog_action s390x: fix generation of event information crw s390x/ioinst: set type and len for SEI response s390x/sclp: add device to the sysbus in sclp_realize s390x/machine: make addon register fields static s390x/skeys: Fix instance and class size Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--gdbstub.c21
-rw-r--r--hw/s390x/css.c15
-rw-r--r--hw/s390x/css.h1
-rw-r--r--hw/s390x/s390-skeys.c2
-rw-r--r--hw/s390x/sclp.c8
-rw-r--r--hw/watchdog/watchdog.c14
-rw-r--r--hw/watchdog/wdt_diag288.c7
-rw-r--r--include/qom/cpu.h3
-rw-r--r--include/sysemu/watchdog.h10
-rw-r--r--target-arm/cpu.c12
-rw-r--r--target-arm/cpu64.c6
-rw-r--r--target-ppc/translate_init.c10
-rw-r--r--target-s390x/cpu.c6
-rw-r--r--target-s390x/helper.c5
-rw-r--r--target-s390x/ioinst.c4
-rw-r--r--target-s390x/machine.c4
16 files changed, 102 insertions, 26 deletions
diff --git a/gdbstub.c b/gdbstub.c
index 1a84c1a746..59d16506c5 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -540,13 +540,20 @@ static const char *get_feature_xml(const char *p, const char **newp,
GDBRegisterState *r;
CPUState *cpu = first_cpu;
- snprintf(target_xml, sizeof(target_xml),
- "<?xml version=\"1.0\"?>"
- "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
- "<target>"
- "<xi:include href=\"%s\"/>",
- cc->gdb_core_xml_file);
-
+ pstrcat(target_xml, sizeof(target_xml),
+ "<?xml version=\"1.0\"?>"
+ "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
+ "<target>");
+ if (cc->gdb_arch_name) {
+ gchar *arch = cc->gdb_arch_name(cpu);
+ pstrcat(target_xml, sizeof(target_xml), "<architecture>");
+ pstrcat(target_xml, sizeof(target_xml), arch);
+ pstrcat(target_xml, sizeof(target_xml), "</architecture>");
+ g_free(arch);
+ }
+ pstrcat(target_xml, sizeof(target_xml), "<xi:include href=\"");
+ pstrcat(target_xml, sizeof(target_xml), cc->gdb_core_xml_file);
+ pstrcat(target_xml, sizeof(target_xml), "\"/>");
for (r = cpu->gdb_regs; r; r = r->next) {
pstrcat(target_xml, sizeof(target_xml), "<xi:include href=\"");
pstrcat(target_xml, sizeof(target_xml), r->xml);
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index 343c3520de..e83bf60a74 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -49,6 +49,7 @@ typedef struct IoAdapter {
typedef struct ChannelSubSys {
QTAILQ_HEAD(, CrwContainer) pending_crws;
+ bool sei_pending;
bool do_crw_mchk;
bool crws_lost;
uint8_t max_cssid;
@@ -701,7 +702,7 @@ int css_do_csch(SubchDev *sch)
/* Trigger the clear function. */
s->ctrl &= ~(SCSW_CTRL_MASK_FCTL | SCSW_CTRL_MASK_ACTL);
- s->ctrl |= SCSW_FCTL_CLEAR_FUNC | SCSW_FCTL_CLEAR_FUNC;
+ s->ctrl |= SCSW_FCTL_CLEAR_FUNC | SCSW_ACTL_CLEAR_PEND;
do_subchannel_work(sch, NULL);
ret = 0;
@@ -1359,7 +1360,15 @@ void css_generate_chp_crws(uint8_t cssid, uint8_t chpid)
void css_generate_css_crws(uint8_t cssid)
{
- css_queue_crw(CRW_RSC_CSS, 0, 0, cssid);
+ if (!channel_subsys->sei_pending) {
+ css_queue_crw(CRW_RSC_CSS, 0, 0, cssid);
+ }
+ channel_subsys->sei_pending = true;
+}
+
+void css_clear_sei_pending(void)
+{
+ channel_subsys->sei_pending = false;
}
int css_enable_mcsse(void)
@@ -1509,6 +1518,7 @@ static void css_init(void)
{
channel_subsys = g_malloc0(sizeof(*channel_subsys));
QTAILQ_INIT(&channel_subsys->pending_crws);
+ channel_subsys->sei_pending = false;
channel_subsys->do_crw_mchk = true;
channel_subsys->crws_lost = false;
channel_subsys->chnmon_active = false;
@@ -1561,6 +1571,7 @@ void css_reset(void)
QTAILQ_REMOVE(&channel_subsys->pending_crws, crw_cont, sibling);
g_free(crw_cont);
}
+ channel_subsys->sei_pending = false;
channel_subsys->do_crw_mchk = true;
channel_subsys->crws_lost = false;
diff --git a/hw/s390x/css.h b/hw/s390x/css.h
index a09bb1f87c..a47937dee5 100644
--- a/hw/s390x/css.h
+++ b/hw/s390x/css.h
@@ -103,6 +103,7 @@ void css_generate_sch_crws(uint8_t cssid, uint8_t ssid, uint16_t schid,
int hotplugged, int add);
void css_generate_chp_crws(uint8_t cssid, uint8_t chpid);
void css_generate_css_crws(uint8_t cssid);
+void css_clear_sei_pending(void);
void css_adapter_interrupt(uint8_t isc);
#define CSS_IO_ADAPTER_VIRTIO 1
diff --git a/hw/s390x/s390-skeys.c b/hw/s390x/s390-skeys.c
index f2b732e300..0cd340747d 100644
--- a/hw/s390x/s390-skeys.c
+++ b/hw/s390x/s390-skeys.c
@@ -237,7 +237,7 @@ static const TypeInfo qemu_s390_skeys_info = {
.instance_init = qemu_s390_skeys_init,
.instance_size = sizeof(QEMUS390SKeysState),
.class_init = qemu_s390_skeys_class_init,
- .instance_size = sizeof(S390SKeysClass),
+ .class_size = sizeof(S390SKeysClass),
};
static void s390_storage_keys_save(QEMUFile *f, void *opaque)
diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index 74f2b40154..23dee88dd9 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -465,6 +465,12 @@ static void sclp_realize(DeviceState *dev, Error **errp)
if (err) {
goto out;
}
+ /*
+ * qdev_device_add searches the sysbus for TYPE_SCLP_EVENTS_BUS. As long
+ * as we can't find a fitting bus via the qom tree, we have to add the
+ * event facility to the sysbus, so e.g. a sclp console can be created.
+ */
+ qdev_set_parent_bus(DEVICE(sclp->event_facility), sysbus_get_default());
ret = s390_set_memory_limit(machine->maxram_size, &hw_limit);
if (ret == -E2BIG) {
@@ -533,8 +539,6 @@ static void sclp_init(Object *obj)
new = object_new(TYPE_SCLP_EVENT_FACILITY);
object_property_add_child(obj, TYPE_SCLP_EVENT_FACILITY, new, NULL);
- /* qdev_device_add searches the sysbus for TYPE_SCLP_EVENTS_BUS */
- qdev_set_parent_bus(DEVICE(new), sysbus_get_default());
object_unref(new);
sclp->event_facility = EVENT_FACILITY(new);
diff --git a/hw/watchdog/watchdog.c b/hw/watchdog/watchdog.c
index 8d4b0eeeb0..81de0e50b1 100644
--- a/hw/watchdog/watchdog.c
+++ b/hw/watchdog/watchdog.c
@@ -29,15 +29,6 @@
#include "qapi-event.h"
#include "hw/nmi.h"
-/* Possible values for action parameter. */
-#define WDT_RESET 1 /* Hard reset. */
-#define WDT_SHUTDOWN 2 /* Shutdown. */
-#define WDT_POWEROFF 3 /* Quit. */
-#define WDT_PAUSE 4 /* Pause. */
-#define WDT_DEBUG 5 /* Prints a message and continues running. */
-#define WDT_NONE 6 /* Do nothing. */
-#define WDT_NMI 7 /* Inject nmi into the guest */
-
static int watchdog_action = WDT_RESET;
static QLIST_HEAD(watchdog_list, WatchdogTimerModel) watchdog_list;
@@ -105,6 +96,11 @@ int select_watchdog_action(const char *p)
return 0;
}
+int get_watchdog_action(void)
+{
+ return watchdog_action;
+}
+
/* This actually performs the "action" once a watchdog has expired,
* ie. reboot, shutdown, exit, etc.
*/
diff --git a/hw/watchdog/wdt_diag288.c b/hw/watchdog/wdt_diag288.c
index 2a885a447c..ddda723906 100644
--- a/hw/watchdog/wdt_diag288.c
+++ b/hw/watchdog/wdt_diag288.c
@@ -51,6 +51,13 @@ static void diag288_timer_expired(void *dev)
{
qemu_log_mask(CPU_LOG_RESET, "Watchdog timer expired.\n");
watchdog_perform_action();
+ /* Reset the watchdog only if the guest was notified about expiry. */
+ switch (get_watchdog_action()) {
+ case WDT_DEBUG:
+ case WDT_NONE:
+ case WDT_PAUSE:
+ return;
+ }
wdt_diag288_reset(dev);
}
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 2e5229d280..035179c09c 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -120,6 +120,8 @@ struct TranslationBlock;
* @gdb_core_xml_file: File name for core registers GDB XML description.
* @gdb_stop_before_watchpoint: Indicates whether GDB expects the CPU to stop
* before the insn which triggers a watchpoint rather than after it.
+ * @gdb_arch_name: Optional callback that returns the architecture name known
+ * to GDB. The caller must free the returned string with g_free.
* @cpu_exec_enter: Callback for cpu_exec preparation.
* @cpu_exec_exit: Callback for cpu_exec cleanup.
* @cpu_exec_interrupt: Callback for processing interrupts in cpu_exec.
@@ -177,6 +179,7 @@ typedef struct CPUClass {
const struct VMStateDescription *vmsd;
int gdb_num_core_regs;
const char *gdb_core_xml_file;
+ gchar * (*gdb_arch_name)(CPUState *cpu);
bool gdb_stop_before_watchpoint;
void (*cpu_exec_enter)(CPUState *cpu);
diff --git a/include/sysemu/watchdog.h b/include/sysemu/watchdog.h
index 3e9a970686..72a4da07a6 100644
--- a/include/sysemu/watchdog.h
+++ b/include/sysemu/watchdog.h
@@ -24,6 +24,15 @@
#include "qemu/queue.h"
+/* Possible values for action parameter. */
+#define WDT_RESET 1 /* Hard reset. */
+#define WDT_SHUTDOWN 2 /* Shutdown. */
+#define WDT_POWEROFF 3 /* Quit. */
+#define WDT_PAUSE 4 /* Pause. */
+#define WDT_DEBUG 5 /* Prints a message and continues running. */
+#define WDT_NONE 6 /* Do nothing. */
+#define WDT_NMI 7 /* Inject nmi into the guest. */
+
struct WatchdogTimerModel {
QLIST_ENTRY(WatchdogTimerModel) entry;
@@ -37,6 +46,7 @@ typedef struct WatchdogTimerModel WatchdogTimerModel;
/* in hw/watchdog.c */
int select_watchdog(const char *p);
int select_watchdog_action(const char *action);
+int get_watchdog_action(void);
void watchdog_add_model(WatchdogTimerModel *model);
void watchdog_perform_action(void);
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 6c34476a3d..0e582c4410 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -1426,6 +1426,17 @@ static int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
}
#endif
+static gchar *arm_gdb_arch_name(CPUState *cs)
+{
+ ARMCPU *cpu = ARM_CPU(cs);
+ CPUARMState *env = &cpu->env;
+
+ if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
+ return g_strdup("iwmmxt");
+ }
+ return g_strdup("arm");
+}
+
static void arm_cpu_class_init(ObjectClass *oc, void *data)
{
ARMCPUClass *acc = ARM_CPU_CLASS(oc);
@@ -1460,6 +1471,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
#endif
cc->gdb_num_core_regs = 26;
cc->gdb_core_xml_file = "arm-core.xml";
+ cc->gdb_arch_name = arm_gdb_arch_name;
cc->gdb_stop_before_watchpoint = true;
cc->debug_excp_handler = arm_debug_excp_handler;
diff --git a/target-arm/cpu64.c b/target-arm/cpu64.c
index cc177bb9f6..c847513b25 100644
--- a/target-arm/cpu64.c
+++ b/target-arm/cpu64.c
@@ -287,6 +287,11 @@ static void aarch64_cpu_set_pc(CPUState *cs, vaddr value)
}
}
+static gchar *aarch64_gdb_arch_name(CPUState *cs)
+{
+ return g_strdup("aarch64");
+}
+
static void aarch64_cpu_class_init(ObjectClass *oc, void *data)
{
CPUClass *cc = CPU_CLASS(oc);
@@ -297,6 +302,7 @@ static void aarch64_cpu_class_init(ObjectClass *oc, void *data)
cc->gdb_write_register = aarch64_cpu_gdb_write_register;
cc->gdb_num_core_regs = 34;
cc->gdb_core_xml_file = "aarch64-core.xml";
+ cc->gdb_arch_name = aarch64_gdb_arch_name;
}
static void aarch64_cpu_register(const ARMCPUInfo *info)
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 4ab2d927b0..d7e1a4e1c8 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -9681,6 +9681,15 @@ static bool ppc_pvr_match_default(PowerPCCPUClass *pcc, uint32_t pvr)
return pcc->pvr == pvr;
}
+static gchar *ppc_gdb_arch_name(CPUState *cs)
+{
+#if defined(TARGET_PPC64)
+ return g_strdup("powerpc:common64");
+#else
+ return g_strdup("powerpc:common");
+#endif
+}
+
static void ppc_cpu_class_init(ObjectClass *oc, void *data)
{
PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
@@ -9724,6 +9733,7 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
cc->gdb_num_core_regs = 71 + 32;
#endif
+ cc->gdb_arch_name = ppc_gdb_arch_name;
#if defined(TARGET_PPC64)
cc->gdb_core_xml_file = "power64-core.xml";
#else
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index e5a3f65029..792310e50d 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -325,6 +325,11 @@ unsigned int s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu)
}
#endif
+static gchar *s390_gdb_arch_name(CPUState *cs)
+{
+ return g_strdup("s390:64-bit");
+}
+
static void s390_cpu_class_init(ObjectClass *oc, void *data)
{
S390CPUClass *scc = S390_CPU_CLASS(oc);
@@ -360,6 +365,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
cc->gdb_num_core_regs = S390_NUM_CORE_REGS;
cc->gdb_core_xml_file = "s390x-core64.xml";
+ cc->gdb_arch_name = s390_gdb_arch_name;
/*
* Reason: s390_cpu_initfn() calls cpu_exec_init(), which saves
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index e541d69724..1231e586a4 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -162,8 +162,9 @@ hwaddr s390_cpu_get_phys_page_debug(CPUState *cs, vaddr vaddr)
vaddr &= 0x7fffffff;
}
- mmu_translate(env, vaddr, MMU_INST_FETCH, asc, &raddr, &prot, false);
-
+ if (mmu_translate(env, vaddr, MMU_INST_FETCH, asc, &raddr, &prot, false)) {
+ return -1;
+ }
return raddr;
}
diff --git a/target-s390x/ioinst.c b/target-s390x/ioinst.c
index 77f2a1fb96..9a8de6d122 100644
--- a/target-s390x/ioinst.c
+++ b/target-s390x/ioinst.c
@@ -614,9 +614,11 @@ static void ioinst_handle_chsc_sei(ChscReq *req, ChscResp *res)
(*res_flags) |= 0x80;
} else {
(*res_flags) &= ~0x80;
+ css_clear_sei_pending();
}
} else {
- res->code = cpu_to_be16(0x0004);
+ res->code = cpu_to_be16(0x0005);
+ res->len = cpu_to_be16(CHSC_MIN_RESP_LEN);
}
}
diff --git a/target-s390x/machine.c b/target-s390x/machine.c
index b76fb08319..96ad0a9d4f 100644
--- a/target-s390x/machine.c
+++ b/target-s390x/machine.c
@@ -48,7 +48,7 @@ static inline bool fpu_needed(void *opaque)
return true;
}
-const VMStateDescription vmstate_fpu = {
+static const VMStateDescription vmstate_fpu = {
.name = "cpu/fpu",
.version_id = 1,
.minimum_version_id = 1,
@@ -75,7 +75,7 @@ const VMStateDescription vmstate_fpu = {
}
};
-const VMStateDescription vmstate_vregs = {
+static const VMStateDescription vmstate_vregs = {
.name = "cpu/vregs",
.version_id = 1,
.minimum_version_id = 1,