Mostly bugfixes and small improvements; and the gdb target.xml

patch.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.11 (GNU/Linux)
 
 iQIcBAABAgAGBQJWqfU2AAoJEN7Pa5PG8C+vxhQQAIYOS/ipBececOJv/nMGBDVH
 nXZs7T/QPV0b0cYeqb4r0g+Dbg4bywdbF7/bdULJtOsygK7Y9U4FlL+S1wL7D3x1
 YcqrXCwX8xSqqd51wzYshIwbRO/22G/7pyGa2jSvHTiPJlLJUsPF09z5otSZ3p8g
 4JW2Xmfx3MF20IBMQgazB4dd/Lz6EKy8MJbqrcQUc9+mpsstL3I4L5AUF59jlARY
 0e73OYbBRUZaHmGpI24uRO2OLhYWKwmVkaUo8FfZB3W94k0PXcsQ/Kg8UJbqlwY/
 PTYDhhSm6JycLyLp/0MnlHuyHiKtCnQyl+4O27lWOiQWUzKELiereO9MFlUwRg5L
 N6f4IwpDqTGU2tmj1ujLbzI2kaVEuVu++gIaBe+LL8BYNtcf25/3eVQ71WL1ioQV
 YRooC3eWAVQtLgjM04+F5fiMgxXSklowb29ONwm/M6dfYl0mXhKoPuE9rkRSUKfZ
 jPsK7HM4hHM2nHY+JQZnoAWV0DMBT0d4Ehe1pDrQ2lu5XDMNYip3buW/VEzqZTzF
 Buk2tIhJFA6EriU2OAj+6+ENqia/7PMWpPry/0wi2Tmgt1ksu8DFyfati4PP31Or
 A/jYo10mzn4cZtrgI9kavg1Ij5c8Ij9h3oNg2pVDZfXKQmIxIqxgPq8/puwK3ywU
 DOBAAglu8nLgHv+EJTNz
 =lF/D
 -----END PGP SIGNATURE-----

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>
This commit is contained in:
Peter Maydell 2016-01-28 11:46:33 +00:00
commit 357e81c7e8
16 changed files with 102 additions and 26 deletions

View File

@ -540,13 +540,20 @@ static const char *get_feature_xml(const char *p, const char **newp,
GDBRegisterState *r; GDBRegisterState *r;
CPUState *cpu = first_cpu; CPUState *cpu = first_cpu;
snprintf(target_xml, sizeof(target_xml), pstrcat(target_xml, sizeof(target_xml),
"<?xml version=\"1.0\"?>" "<?xml version=\"1.0\"?>"
"<!DOCTYPE target SYSTEM \"gdb-target.dtd\">" "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
"<target>" "<target>");
"<xi:include href=\"%s\"/>", if (cc->gdb_arch_name) {
cc->gdb_core_xml_file); 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) { for (r = cpu->gdb_regs; r; r = r->next) {
pstrcat(target_xml, sizeof(target_xml), "<xi:include href=\""); pstrcat(target_xml, sizeof(target_xml), "<xi:include href=\"");
pstrcat(target_xml, sizeof(target_xml), r->xml); pstrcat(target_xml, sizeof(target_xml), r->xml);

View File

@ -49,6 +49,7 @@ typedef struct IoAdapter {
typedef struct ChannelSubSys { typedef struct ChannelSubSys {
QTAILQ_HEAD(, CrwContainer) pending_crws; QTAILQ_HEAD(, CrwContainer) pending_crws;
bool sei_pending;
bool do_crw_mchk; bool do_crw_mchk;
bool crws_lost; bool crws_lost;
uint8_t max_cssid; uint8_t max_cssid;
@ -701,7 +702,7 @@ int css_do_csch(SubchDev *sch)
/* Trigger the clear function. */ /* Trigger the clear function. */
s->ctrl &= ~(SCSW_CTRL_MASK_FCTL | SCSW_CTRL_MASK_ACTL); 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); do_subchannel_work(sch, NULL);
ret = 0; 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) 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) int css_enable_mcsse(void)
@ -1509,6 +1518,7 @@ static void css_init(void)
{ {
channel_subsys = g_malloc0(sizeof(*channel_subsys)); channel_subsys = g_malloc0(sizeof(*channel_subsys));
QTAILQ_INIT(&channel_subsys->pending_crws); QTAILQ_INIT(&channel_subsys->pending_crws);
channel_subsys->sei_pending = false;
channel_subsys->do_crw_mchk = true; channel_subsys->do_crw_mchk = true;
channel_subsys->crws_lost = false; channel_subsys->crws_lost = false;
channel_subsys->chnmon_active = false; channel_subsys->chnmon_active = false;
@ -1561,6 +1571,7 @@ void css_reset(void)
QTAILQ_REMOVE(&channel_subsys->pending_crws, crw_cont, sibling); QTAILQ_REMOVE(&channel_subsys->pending_crws, crw_cont, sibling);
g_free(crw_cont); g_free(crw_cont);
} }
channel_subsys->sei_pending = false;
channel_subsys->do_crw_mchk = true; channel_subsys->do_crw_mchk = true;
channel_subsys->crws_lost = false; channel_subsys->crws_lost = false;

View File

@ -103,6 +103,7 @@ void css_generate_sch_crws(uint8_t cssid, uint8_t ssid, uint16_t schid,
int hotplugged, int add); int hotplugged, int add);
void css_generate_chp_crws(uint8_t cssid, uint8_t chpid); void css_generate_chp_crws(uint8_t cssid, uint8_t chpid);
void css_generate_css_crws(uint8_t cssid); void css_generate_css_crws(uint8_t cssid);
void css_clear_sei_pending(void);
void css_adapter_interrupt(uint8_t isc); void css_adapter_interrupt(uint8_t isc);
#define CSS_IO_ADAPTER_VIRTIO 1 #define CSS_IO_ADAPTER_VIRTIO 1

View File

@ -237,7 +237,7 @@ static const TypeInfo qemu_s390_skeys_info = {
.instance_init = qemu_s390_skeys_init, .instance_init = qemu_s390_skeys_init,
.instance_size = sizeof(QEMUS390SKeysState), .instance_size = sizeof(QEMUS390SKeysState),
.class_init = qemu_s390_skeys_class_init, .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) static void s390_storage_keys_save(QEMUFile *f, void *opaque)

View File

@ -465,6 +465,12 @@ static void sclp_realize(DeviceState *dev, Error **errp)
if (err) { if (err) {
goto out; 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); ret = s390_set_memory_limit(machine->maxram_size, &hw_limit);
if (ret == -E2BIG) { if (ret == -E2BIG) {
@ -533,8 +539,6 @@ static void sclp_init(Object *obj)
new = object_new(TYPE_SCLP_EVENT_FACILITY); new = object_new(TYPE_SCLP_EVENT_FACILITY);
object_property_add_child(obj, TYPE_SCLP_EVENT_FACILITY, new, NULL); 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); object_unref(new);
sclp->event_facility = EVENT_FACILITY(new); sclp->event_facility = EVENT_FACILITY(new);

View File

@ -29,15 +29,6 @@
#include "qapi-event.h" #include "qapi-event.h"
#include "hw/nmi.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 int watchdog_action = WDT_RESET;
static QLIST_HEAD(watchdog_list, WatchdogTimerModel) watchdog_list; static QLIST_HEAD(watchdog_list, WatchdogTimerModel) watchdog_list;
@ -105,6 +96,11 @@ int select_watchdog_action(const char *p)
return 0; return 0;
} }
int get_watchdog_action(void)
{
return watchdog_action;
}
/* This actually performs the "action" once a watchdog has expired, /* This actually performs the "action" once a watchdog has expired,
* ie. reboot, shutdown, exit, etc. * ie. reboot, shutdown, exit, etc.
*/ */

View File

@ -51,6 +51,13 @@ static void diag288_timer_expired(void *dev)
{ {
qemu_log_mask(CPU_LOG_RESET, "Watchdog timer expired.\n"); qemu_log_mask(CPU_LOG_RESET, "Watchdog timer expired.\n");
watchdog_perform_action(); 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); wdt_diag288_reset(dev);
} }

View File

@ -120,6 +120,8 @@ struct TranslationBlock;
* @gdb_core_xml_file: File name for core registers GDB XML description. * @gdb_core_xml_file: File name for core registers GDB XML description.
* @gdb_stop_before_watchpoint: Indicates whether GDB expects the CPU to stop * @gdb_stop_before_watchpoint: Indicates whether GDB expects the CPU to stop
* before the insn which triggers a watchpoint rather than after it. * 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_enter: Callback for cpu_exec preparation.
* @cpu_exec_exit: Callback for cpu_exec cleanup. * @cpu_exec_exit: Callback for cpu_exec cleanup.
* @cpu_exec_interrupt: Callback for processing interrupts in cpu_exec. * @cpu_exec_interrupt: Callback for processing interrupts in cpu_exec.
@ -177,6 +179,7 @@ typedef struct CPUClass {
const struct VMStateDescription *vmsd; const struct VMStateDescription *vmsd;
int gdb_num_core_regs; int gdb_num_core_regs;
const char *gdb_core_xml_file; const char *gdb_core_xml_file;
gchar * (*gdb_arch_name)(CPUState *cpu);
bool gdb_stop_before_watchpoint; bool gdb_stop_before_watchpoint;
void (*cpu_exec_enter)(CPUState *cpu); void (*cpu_exec_enter)(CPUState *cpu);

View File

@ -24,6 +24,15 @@
#include "qemu/queue.h" #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 { struct WatchdogTimerModel {
QLIST_ENTRY(WatchdogTimerModel) entry; QLIST_ENTRY(WatchdogTimerModel) entry;
@ -37,6 +46,7 @@ typedef struct WatchdogTimerModel WatchdogTimerModel;
/* in hw/watchdog.c */ /* in hw/watchdog.c */
int select_watchdog(const char *p); int select_watchdog(const char *p);
int select_watchdog_action(const char *action); int select_watchdog_action(const char *action);
int get_watchdog_action(void);
void watchdog_add_model(WatchdogTimerModel *model); void watchdog_add_model(WatchdogTimerModel *model);
void watchdog_perform_action(void); void watchdog_perform_action(void);

View File

@ -1426,6 +1426,17 @@ static int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
} }
#endif #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) static void arm_cpu_class_init(ObjectClass *oc, void *data)
{ {
ARMCPUClass *acc = ARM_CPU_CLASS(oc); ARMCPUClass *acc = ARM_CPU_CLASS(oc);
@ -1460,6 +1471,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
#endif #endif
cc->gdb_num_core_regs = 26; cc->gdb_num_core_regs = 26;
cc->gdb_core_xml_file = "arm-core.xml"; cc->gdb_core_xml_file = "arm-core.xml";
cc->gdb_arch_name = arm_gdb_arch_name;
cc->gdb_stop_before_watchpoint = true; cc->gdb_stop_before_watchpoint = true;
cc->debug_excp_handler = arm_debug_excp_handler; cc->debug_excp_handler = arm_debug_excp_handler;

View File

@ -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) static void aarch64_cpu_class_init(ObjectClass *oc, void *data)
{ {
CPUClass *cc = CPU_CLASS(oc); 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_write_register = aarch64_cpu_gdb_write_register;
cc->gdb_num_core_regs = 34; cc->gdb_num_core_regs = 34;
cc->gdb_core_xml_file = "aarch64-core.xml"; cc->gdb_core_xml_file = "aarch64-core.xml";
cc->gdb_arch_name = aarch64_gdb_arch_name;
} }
static void aarch64_cpu_register(const ARMCPUInfo *info) static void aarch64_cpu_register(const ARMCPUInfo *info)

View File

@ -9681,6 +9681,15 @@ static bool ppc_pvr_match_default(PowerPCCPUClass *pcc, uint32_t pvr)
return pcc->pvr == 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) static void ppc_cpu_class_init(ObjectClass *oc, void *data)
{ {
PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); 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; cc->gdb_num_core_regs = 71 + 32;
#endif #endif
cc->gdb_arch_name = ppc_gdb_arch_name;
#if defined(TARGET_PPC64) #if defined(TARGET_PPC64)
cc->gdb_core_xml_file = "power64-core.xml"; cc->gdb_core_xml_file = "power64-core.xml";
#else #else

View File

@ -325,6 +325,11 @@ unsigned int s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu)
} }
#endif #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) static void s390_cpu_class_init(ObjectClass *oc, void *data)
{ {
S390CPUClass *scc = S390_CPU_CLASS(oc); 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_num_core_regs = S390_NUM_CORE_REGS;
cc->gdb_core_xml_file = "s390x-core64.xml"; 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 * Reason: s390_cpu_initfn() calls cpu_exec_init(), which saves

View File

@ -162,8 +162,9 @@ hwaddr s390_cpu_get_phys_page_debug(CPUState *cs, vaddr vaddr)
vaddr &= 0x7fffffff; 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; return raddr;
} }

View File

@ -614,9 +614,11 @@ static void ioinst_handle_chsc_sei(ChscReq *req, ChscResp *res)
(*res_flags) |= 0x80; (*res_flags) |= 0x80;
} else { } else {
(*res_flags) &= ~0x80; (*res_flags) &= ~0x80;
css_clear_sei_pending();
} }
} else { } else {
res->code = cpu_to_be16(0x0004); res->code = cpu_to_be16(0x0005);
res->len = cpu_to_be16(CHSC_MIN_RESP_LEN);
} }
} }

View File

@ -48,7 +48,7 @@ static inline bool fpu_needed(void *opaque)
return true; return true;
} }
const VMStateDescription vmstate_fpu = { static const VMStateDescription vmstate_fpu = {
.name = "cpu/fpu", .name = "cpu/fpu",
.version_id = 1, .version_id = 1,
.minimum_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", .name = "cpu/vregs",
.version_id = 1, .version_id = 1,
.minimum_version_id = 1, .minimum_version_id = 1,