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); ICPState *icp = ICP(dev);
@ -359,6 +359,8 @@ static void icp_realize(DeviceState *dev, Error **errp)
} }
icp->xics = XICS_FABRIC(obj); 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); DeviceClass *dc = DEVICE_CLASS(klass);
dc->reset = icp_reset;
dc->vmsd = &vmstate_icp_server; dc->vmsd = &vmstate_icp_server;
dc->realize = icp_realize; 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); ICSState *ics = ICS_SIMPLE(dev);
int i; 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->irqs = g_malloc0(ics->nr_irqs * sizeof(ICSIRQState));
ics->qirqs = qemu_allocate_irqs(ics_simple_set_irq, ics, ics->nr_irqs); 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[] = { static Property ics_simple_properties[] = {
@ -626,7 +629,6 @@ static void ics_simple_class_init(ObjectClass *klass, void *data)
isc->realize = ics_simple_realize; isc->realize = ics_simple_realize;
dc->props = ics_simple_properties; dc->props = ics_simple_properties;
dc->vmsd = &vmstate_ics_simple; dc->vmsd = &vmstate_ics_simple;
dc->reset = ics_simple_reset;
isc->reject = ics_simple_reject; isc->reject = ics_simple_reject;
isc->resend = ics_simple_resend; isc->resend = ics_simple_resend;
isc->eoi = ics_simple_eoi; isc->eoi = ics_simple_eoi;

View file

@ -102,7 +102,7 @@ static int icp_set_kvm_state(ICPState *icp, int version_id)
return 0; return 0;
} }
static void icp_kvm_reset(DeviceState *dev) static void icp_kvm_reset(void *dev)
{ {
ICPState *icp = ICP(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; 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) static void icp_kvm_class_init(ObjectClass *klass, void *data)
{ {
DeviceClass *dc = DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass);
ICPStateClass *icpc = ICP_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->pre_save = icp_get_kvm_state;
icpc->post_load = icp_set_kvm_state; icpc->post_load = icp_set_kvm_state;
icpc->cpu_setup = icp_kvm_cpu_setup; 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); ICSState *ics = ICS_SIMPLE(dev);
int i; 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->irqs = g_malloc0(ics->nr_irqs * sizeof(ICSIRQState));
ics->qirqs = qemu_allocate_irqs(ics_kvm_set_irq, ics, ics->nr_irqs); 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) static void ics_kvm_class_init(ObjectClass *klass, void *data)
{ {
DeviceClass *dc = DEVICE_CLASS(klass);
ICSStateClass *icsc = ICS_BASE_CLASS(klass); ICSStateClass *icsc = ICS_BASE_CLASS(klass);
icsc->realize = ics_kvm_realize; icsc->realize = ics_kvm_realize;
dc->reset = ics_kvm_reset;
icsc->pre_save = ics_get_kvm_state; icsc->pre_save = ics_get_kvm_state;
icsc->post_load = ics_set_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; int i;
ics = ICS_SIMPLE(object_new(type_ics)); 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_add_child(OBJECT(spapr), "ics", OBJECT(ics), NULL);
object_property_set_int(OBJECT(ics), nr_irqs, "nr-irqs", &err); object_property_set_int(OBJECT(ics), nr_irqs, "nr-irqs", &err);
object_property_add_const_link(OBJECT(ics), "xics", OBJECT(xi), NULL); 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]; ICPState *icp = &spapr->icps[i];
object_initialize(icp, sizeof(*icp), type_icp); 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_child(OBJECT(spapr), "icp[*]", OBJECT(icp), NULL);
object_property_add_const_link(OBJECT(icp), "xics", OBJECT(xi), NULL); object_property_add_const_link(OBJECT(icp), "xics", OBJECT(xi), NULL);
object_property_set_bool(OBJECT(icp), true, "realized", &err); 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) Error **errp)
{ {
CPUPPCState *env = &cpu->env; CPUPPCState *env = &cpu->env;
CPUState *cs = CPU(cpu);
int i;
/* Set time-base frequency to 512 MHz */ /* Set time-base frequency to 512 MHz */
cpu_ppc_tb_init(env, SPAPR_TIMEBASE_FREQ); 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); xics_cpu_setup(XICS_FABRIC(spapr), cpu);
qemu_register_reset(spapr_cpu_reset, 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); const char *typename = object_class_get_name(scc->cpu_class);
size_t size = object_type_get_instance_size(typename); size_t size = object_type_get_instance_size(typename);
Error *local_err = NULL; Error *local_err = NULL;
int core_node_id = numa_get_node_for_cpu(cc->core_id);;
void *obj; void *obj;
int i, j; int i, j;
sc->threads = g_malloc0(size * cc->nr_threads); sc->threads = g_malloc0(size * cc->nr_threads);
for (i = 0; i < cc->nr_threads; i++) { for (i = 0; i < cc->nr_threads; i++) {
int node_id;
char id[32]; char id[32];
CPUState *cs; CPUState *cs;
@ -184,6 +178,19 @@ static void spapr_cpu_core_realize(DeviceState *dev, Error **errp)
object_initialize(obj, size, typename); object_initialize(obj, size, typename);
cs = CPU(obj); cs = CPU(obj);
cs->cpu_index = cc->core_id + i; 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); snprintf(id, sizeof(id), "thread[%d]", i);
object_property_add_child(OBJECT(sc), id, obj, &local_err); object_property_add_child(OBJECT(sc), id, obj, &local_err);
if (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); return do_fri(env, arg, float_round_down);
} }
static void float64_maddsub_update_excp(CPUPPCState *env, float64 arg1, #define FPU_MADDSUB_UPDATE(NAME, TP) \
float64 arg2, float64 arg3, static void NAME(CPUPPCState *env, TP arg1, TP arg2, TP arg3, \
unsigned int madd_flags) unsigned int madd_flags) \
{ { \
if (unlikely((float64_is_infinity(arg1) && float64_is_zero(arg2)) || if (TP##_is_signaling_nan(arg1, &env->fp_status) || \
(float64_is_zero(arg1) && float64_is_infinity(arg2)))) { TP##_is_signaling_nan(arg2, &env->fp_status) || \
/* Multiplication of zero by infinity */ TP##_is_signaling_nan(arg3, &env->fp_status)) { \
arg1 = float_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1); /* sNaN operation */ \
} else if (unlikely(float64_is_signaling_nan(arg1, &env->fp_status) || float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); \
float64_is_signaling_nan(arg2, &env->fp_status) || } \
float64_is_signaling_nan(arg3, &env->fp_status))) { if ((TP##_is_infinity(arg1) && TP##_is_zero(arg2)) || \
/* sNaN operation */ (TP##_is_zero(arg1) && TP##_is_infinity(arg2))) { \
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); /* Multiplication of zero by infinity */ \
} else if ((float64_is_infinity(arg1) || float64_is_infinity(arg2)) && float_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1); \
float64_is_infinity(arg3)) { } \
uint8_t aSign, bSign, cSign; if ((TP##_is_infinity(arg1) || TP##_is_infinity(arg2)) && \
TP##_is_infinity(arg3)) { \
aSign = float64_is_neg(arg1); uint8_t aSign, bSign, cSign; \
bSign = float64_is_neg(arg2); \
cSign = float64_is_neg(arg3); aSign = TP##_is_neg(arg1); \
if (madd_flags & float_muladd_negate_c) { bSign = TP##_is_neg(arg2); \
cSign ^= 1; cSign = TP##_is_neg(arg3); \
} if (madd_flags & float_muladd_negate_c) { \
if (aSign ^ bSign ^ cSign) { cSign ^= 1; \
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 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) \ #define FPU_FMADD(op, madd_flags) \
uint64_t helper_##op(CPUPPCState *env, uint64_t arg1, \ 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; \ env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
\ \
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \ if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \
if (tp##_is_signaling_nan(xa.fld, &tstat) || \ tp##_maddsub_update_excp(env, xa.fld, b->fld, c->fld, maddflgs); \
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); \
} \
} \ } \
\ \
if (r2sp) { \ if (r2sp) { \