mirror of https://github.com/xqemu/xqemu.git
ppc patch queue for 2017-03-06
Looks like my previous batch wasn't quite the last before hard freeze. This has a handful of bugfixes to go in. They're all genuine bugfixes, though not regressions in some cases. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCAAGBQJYvOCUAAoJEGw4ysog2bOSQWgQAKzPeIqz8I/1eXL+zmZCUaiU J2gyjzfaKkQ/AVGPtT45ZjJsihxSFbZT6koxXtEaxwq5DD87yXQOqA/d+BH7jr5d 75FGjVzKOA0IKQymySztwoC2j/ftWmmSx0N6YUmL0QcXCISS1YHRvdQkdXf6j4I/ XtK1FA34wmCsTK1AgZ9WDxjABdkHP+7FDRBpVmr01Nv1TeK2Xms2MqJ5Wku/lOX/ 6bg1KbC8pVHy5YZhIpRFzgGxaMr2UcJ0Q3YR9fD/4UW/k518sJk+i2xlagVsFxyG gqfPolv0wjwuGpYt42UyFG4IouCbKN+MChU5MBIaqU10VouOw+0/W+p+1ZOHgdB8 GoaBGyfuJ6/i4EQL0/+FL4hPOI5vHLliWxPfMJxDL5ujP0cFaPm2XbK5Yqxksu3m uYp3yYIbiSaF8QUxbBjAAoKPdVpP5dsgHjAlxecwCUGlIo0Ur3uphnU5lPoNlvS4 5ZcDDlMGjPb0oIHfdPt2ai8g+32uAsD7X7pi+qI0x+srSnjisRpOT2wKv0otMbGx U4j01/Na2DjFjhGW+vNm9UYsE/QgKr6pU9z3jUXOIplX1HBXirtfv5C/OypCN7Zj LgqsmiMWMJFjSLk8N8cxeM1w839B3wEM+2+46su7/qpW9sd0jKvHk0cJDyZPzn29 zQ52CbQQiewXM8y+mffe =/RZL -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-2.9-20170306' into staging ppc patch queue for 2017-03-06 Looks like my previous batch wasn't quite the last before hard freeze. This has a handful of bugfixes to go in. They're all genuine bugfixes, though not regressions in some cases. # gpg: Signature made Mon 06 Mar 2017 04:07:48 GMT # gpg: using RSA key 0x6C38CACA20D9B392 # gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>" # gpg: aka "David Gibson (Red Hat) <dgibson@redhat.com>" # gpg: aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>" # gpg: aka "David Gibson (kernel.org) <dwg@kernel.org>" # Primary key fingerprint: 75F4 6586 AE61 A66C C44E 87DC 6C38 CACA 20D9 B392 * remotes/dgibson/tags/ppc-for-2.9-20170306: target/ppc: use helper for excp handling target/ppc: fmadd: add macro for updating flags target/ppc: fmadd check for excp independently spapr: ensure that all threads within core are on the same NUMA node ppc/xics: register reset handlers for the ICP and ICS objects Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
56b51708e9
|
@ -333,7 +333,7 @@ static const VMStateDescription vmstate_icp_server = {
|
|||
},
|
||||
};
|
||||
|
||||
static void icp_reset(DeviceState *dev)
|
||||
static void icp_reset(void *dev)
|
||||
{
|
||||
ICPState *icp = ICP(dev);
|
||||
|
||||
|
@ -359,6 +359,8 @@ static void icp_realize(DeviceState *dev, Error **errp)
|
|||
}
|
||||
|
||||
icp->xics = XICS_FABRIC(obj);
|
||||
|
||||
qemu_register_reset(icp_reset, dev);
|
||||
}
|
||||
|
||||
|
||||
|
@ -366,7 +368,6 @@ static void icp_class_init(ObjectClass *klass, void *data)
|
|||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
dc->reset = icp_reset;
|
||||
dc->vmsd = &vmstate_icp_server;
|
||||
dc->realize = icp_realize;
|
||||
}
|
||||
|
@ -522,7 +523,7 @@ static void ics_simple_eoi(ICSState *ics, uint32_t nr)
|
|||
}
|
||||
}
|
||||
|
||||
static void ics_simple_reset(DeviceState *dev)
|
||||
static void ics_simple_reset(void *dev)
|
||||
{
|
||||
ICSState *ics = ICS_SIMPLE(dev);
|
||||
int i;
|
||||
|
@ -611,6 +612,8 @@ static void ics_simple_realize(DeviceState *dev, Error **errp)
|
|||
}
|
||||
ics->irqs = g_malloc0(ics->nr_irqs * sizeof(ICSIRQState));
|
||||
ics->qirqs = qemu_allocate_irqs(ics_simple_set_irq, ics, ics->nr_irqs);
|
||||
|
||||
qemu_register_reset(ics_simple_reset, dev);
|
||||
}
|
||||
|
||||
static Property ics_simple_properties[] = {
|
||||
|
@ -626,7 +629,6 @@ static void ics_simple_class_init(ObjectClass *klass, void *data)
|
|||
isc->realize = ics_simple_realize;
|
||||
dc->props = ics_simple_properties;
|
||||
dc->vmsd = &vmstate_ics_simple;
|
||||
dc->reset = ics_simple_reset;
|
||||
isc->reject = ics_simple_reject;
|
||||
isc->resend = ics_simple_resend;
|
||||
isc->eoi = ics_simple_eoi;
|
||||
|
|
|
@ -102,7 +102,7 @@ static int icp_set_kvm_state(ICPState *icp, int version_id)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void icp_kvm_reset(DeviceState *dev)
|
||||
static void icp_kvm_reset(void *dev)
|
||||
{
|
||||
ICPState *icp = ICP(dev);
|
||||
|
||||
|
@ -146,12 +146,17 @@ static void icp_kvm_cpu_setup(ICPState *icp, PowerPCCPU *cpu)
|
|||
icp->cap_irq_xics_enabled = true;
|
||||
}
|
||||
|
||||
static void icp_kvm_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
qemu_register_reset(icp_kvm_reset, dev);
|
||||
}
|
||||
|
||||
static void icp_kvm_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
ICPStateClass *icpc = ICP_CLASS(klass);
|
||||
|
||||
dc->reset = icp_kvm_reset;
|
||||
dc->realize = icp_kvm_realize;
|
||||
icpc->pre_save = icp_get_kvm_state;
|
||||
icpc->post_load = icp_set_kvm_state;
|
||||
icpc->cpu_setup = icp_kvm_cpu_setup;
|
||||
|
@ -293,7 +298,7 @@ static void ics_kvm_set_irq(void *opaque, int srcno, int val)
|
|||
}
|
||||
}
|
||||
|
||||
static void ics_kvm_reset(DeviceState *dev)
|
||||
static void ics_kvm_reset(void *dev)
|
||||
{
|
||||
ICSState *ics = ICS_SIMPLE(dev);
|
||||
int i;
|
||||
|
@ -324,15 +329,15 @@ static void ics_kvm_realize(DeviceState *dev, Error **errp)
|
|||
}
|
||||
ics->irqs = g_malloc0(ics->nr_irqs * sizeof(ICSIRQState));
|
||||
ics->qirqs = qemu_allocate_irqs(ics_kvm_set_irq, ics, ics->nr_irqs);
|
||||
|
||||
qemu_register_reset(ics_kvm_reset, dev);
|
||||
}
|
||||
|
||||
static void ics_kvm_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
ICSStateClass *icsc = ICS_BASE_CLASS(klass);
|
||||
|
||||
icsc->realize = ics_kvm_realize;
|
||||
dc->reset = ics_kvm_reset;
|
||||
icsc->pre_save = ics_get_kvm_state;
|
||||
icsc->post_load = ics_set_kvm_state;
|
||||
}
|
||||
|
|
|
@ -106,7 +106,6 @@ static int try_create_xics(sPAPRMachineState *spapr, const char *type_ics,
|
|||
int i;
|
||||
|
||||
ics = ICS_SIMPLE(object_new(type_ics));
|
||||
qdev_set_parent_bus(DEVICE(ics), sysbus_get_default());
|
||||
object_property_add_child(OBJECT(spapr), "ics", OBJECT(ics), NULL);
|
||||
object_property_set_int(OBJECT(ics), nr_irqs, "nr-irqs", &err);
|
||||
object_property_add_const_link(OBJECT(ics), "xics", OBJECT(xi), NULL);
|
||||
|
@ -123,7 +122,6 @@ static int try_create_xics(sPAPRMachineState *spapr, const char *type_ics,
|
|||
ICPState *icp = &spapr->icps[i];
|
||||
|
||||
object_initialize(icp, sizeof(*icp), type_icp);
|
||||
qdev_set_parent_bus(DEVICE(icp), sysbus_get_default());
|
||||
object_property_add_child(OBJECT(spapr), "icp[*]", OBJECT(icp), NULL);
|
||||
object_property_add_const_link(OBJECT(icp), "xics", OBJECT(xi), NULL);
|
||||
object_property_set_bool(OBJECT(icp), true, "realized", &err);
|
||||
|
|
|
@ -63,8 +63,6 @@ static void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu,
|
|||
Error **errp)
|
||||
{
|
||||
CPUPPCState *env = &cpu->env;
|
||||
CPUState *cs = CPU(cpu);
|
||||
int i;
|
||||
|
||||
/* Set time-base frequency to 512 MHz */
|
||||
cpu_ppc_tb_init(env, SPAPR_TIMEBASE_FREQ);
|
||||
|
@ -82,12 +80,6 @@ static void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu,
|
|||
}
|
||||
}
|
||||
|
||||
/* Set NUMA node for the added CPUs */
|
||||
i = numa_get_node_for_cpu(cs->cpu_index);
|
||||
if (i < nb_numa_nodes) {
|
||||
cs->numa_node = i;
|
||||
}
|
||||
|
||||
xics_cpu_setup(XICS_FABRIC(spapr), cpu);
|
||||
|
||||
qemu_register_reset(spapr_cpu_reset, cpu);
|
||||
|
@ -171,11 +163,13 @@ static void spapr_cpu_core_realize(DeviceState *dev, Error **errp)
|
|||
const char *typename = object_class_get_name(scc->cpu_class);
|
||||
size_t size = object_type_get_instance_size(typename);
|
||||
Error *local_err = NULL;
|
||||
int core_node_id = numa_get_node_for_cpu(cc->core_id);;
|
||||
void *obj;
|
||||
int i, j;
|
||||
|
||||
sc->threads = g_malloc0(size * cc->nr_threads);
|
||||
for (i = 0; i < cc->nr_threads; i++) {
|
||||
int node_id;
|
||||
char id[32];
|
||||
CPUState *cs;
|
||||
|
||||
|
@ -184,6 +178,19 @@ static void spapr_cpu_core_realize(DeviceState *dev, Error **errp)
|
|||
object_initialize(obj, size, typename);
|
||||
cs = CPU(obj);
|
||||
cs->cpu_index = cc->core_id + i;
|
||||
|
||||
/* Set NUMA node for the added CPUs */
|
||||
node_id = numa_get_node_for_cpu(cs->cpu_index);
|
||||
if (node_id != core_node_id) {
|
||||
error_setg(&local_err, "Invalid node-id=%d of thread[cpu-index: %d]"
|
||||
" on CPU[core-id: %d, node-id: %d], node-id must be the same",
|
||||
node_id, cs->cpu_index, cc->core_id, core_node_id);
|
||||
goto err;
|
||||
}
|
||||
if (node_id < nb_numa_nodes) {
|
||||
cs->numa_node = node_id;
|
||||
}
|
||||
|
||||
snprintf(id, sizeof(id), "thread[%d]", i);
|
||||
object_property_add_child(OBJECT(sc), id, obj, &local_err);
|
||||
if (local_err) {
|
||||
|
|
|
@ -743,34 +743,38 @@ uint64_t helper_frim(CPUPPCState *env, uint64_t arg)
|
|||
return do_fri(env, arg, float_round_down);
|
||||
}
|
||||
|
||||
static void float64_maddsub_update_excp(CPUPPCState *env, float64 arg1,
|
||||
float64 arg2, float64 arg3,
|
||||
unsigned int madd_flags)
|
||||
{
|
||||
if (unlikely((float64_is_infinity(arg1) && float64_is_zero(arg2)) ||
|
||||
(float64_is_zero(arg1) && float64_is_infinity(arg2)))) {
|
||||
/* Multiplication of zero by infinity */
|
||||
arg1 = float_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1);
|
||||
} else if (unlikely(float64_is_signaling_nan(arg1, &env->fp_status) ||
|
||||
float64_is_signaling_nan(arg2, &env->fp_status) ||
|
||||
float64_is_signaling_nan(arg3, &env->fp_status))) {
|
||||
/* sNaN operation */
|
||||
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
|
||||
} else if ((float64_is_infinity(arg1) || float64_is_infinity(arg2)) &&
|
||||
float64_is_infinity(arg3)) {
|
||||
uint8_t aSign, bSign, cSign;
|
||||
|
||||
aSign = float64_is_neg(arg1);
|
||||
bSign = float64_is_neg(arg2);
|
||||
cSign = float64_is_neg(arg3);
|
||||
if (madd_flags & float_muladd_negate_c) {
|
||||
cSign ^= 1;
|
||||
}
|
||||
if (aSign ^ bSign ^ cSign) {
|
||||
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1);
|
||||
}
|
||||
}
|
||||
#define FPU_MADDSUB_UPDATE(NAME, TP) \
|
||||
static void NAME(CPUPPCState *env, TP arg1, TP arg2, TP arg3, \
|
||||
unsigned int madd_flags) \
|
||||
{ \
|
||||
if (TP##_is_signaling_nan(arg1, &env->fp_status) || \
|
||||
TP##_is_signaling_nan(arg2, &env->fp_status) || \
|
||||
TP##_is_signaling_nan(arg3, &env->fp_status)) { \
|
||||
/* sNaN operation */ \
|
||||
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); \
|
||||
} \
|
||||
if ((TP##_is_infinity(arg1) && TP##_is_zero(arg2)) || \
|
||||
(TP##_is_zero(arg1) && TP##_is_infinity(arg2))) { \
|
||||
/* Multiplication of zero by infinity */ \
|
||||
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1); \
|
||||
} \
|
||||
if ((TP##_is_infinity(arg1) || TP##_is_infinity(arg2)) && \
|
||||
TP##_is_infinity(arg3)) { \
|
||||
uint8_t aSign, bSign, cSign; \
|
||||
\
|
||||
aSign = TP##_is_neg(arg1); \
|
||||
bSign = TP##_is_neg(arg2); \
|
||||
cSign = TP##_is_neg(arg3); \
|
||||
if (madd_flags & float_muladd_negate_c) { \
|
||||
cSign ^= 1; \
|
||||
} \
|
||||
if (aSign ^ bSign ^ cSign) { \
|
||||
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
FPU_MADDSUB_UPDATE(float32_maddsub_update_excp, float32)
|
||||
FPU_MADDSUB_UPDATE(float64_maddsub_update_excp, float64)
|
||||
|
||||
#define FPU_FMADD(op, madd_flags) \
|
||||
uint64_t helper_##op(CPUPPCState *env, uint64_t arg1, \
|
||||
|
@ -2236,24 +2240,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \
|
|||
env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
|
||||
\
|
||||
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \
|
||||
if (tp##_is_signaling_nan(xa.fld, &tstat) || \
|
||||
tp##_is_signaling_nan(b->fld, &tstat) || \
|
||||
tp##_is_signaling_nan(c->fld, &tstat)) { \
|
||||
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \
|
||||
tstat.float_exception_flags &= ~float_flag_invalid; \
|
||||
} \
|
||||
if ((tp##_is_infinity(xa.fld) && tp##_is_zero(b->fld)) || \
|
||||
(tp##_is_zero(xa.fld) && tp##_is_infinity(b->fld))) { \
|
||||
xt_out.fld = float64_to_##tp(float_invalid_op_excp(env, \
|
||||
POWERPC_EXCP_FP_VXIMZ, sfprf), &env->fp_status); \
|
||||
tstat.float_exception_flags &= ~float_flag_invalid; \
|
||||
} \
|
||||
if ((tstat.float_exception_flags & float_flag_invalid) && \
|
||||
((tp##_is_infinity(xa.fld) || \
|
||||
tp##_is_infinity(b->fld)) && \
|
||||
tp##_is_infinity(c->fld))) { \
|
||||
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, sfprf); \
|
||||
} \
|
||||
tp##_maddsub_update_excp(env, xa.fld, b->fld, c->fld, maddflgs); \
|
||||
} \
|
||||
\
|
||||
if (r2sp) { \
|
||||
|
|
Loading…
Reference in New Issue