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:
Peter Maydell 2017-03-06 13:06:30 +00:00
commit 56b51708e9
5 changed files with 63 additions and 64 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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) {

View File

@ -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) { \