Commit a64319bf authored by Laurent Dufour's avatar Laurent Dufour Committed by Pavel Emelyanov

ppc64: rely on NVRREG define

When dealing with the number of Altivec registers (VR), we should use
the NVRREG constant defined in system file
/usr/include/powerpc64le-linux-gnu/sys/ucontext.h.

However this constant take in account the extra quad word containing
vrsave in split vectors so we must remove 1 to get the exact number of
registers VR.
Signed-off-by: 's avatarLaurent Dufour <ldufour@linux.vnet.ibm.com>
Reviewed-by: 's avatarDmitry Safonov <dsafonov@virtuozzo.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent 187fb297
...@@ -168,7 +168,7 @@ static int get_altivec_regs(pid_t pid, CoreEntry *core) ...@@ -168,7 +168,7 @@ static int get_altivec_regs(pid_t pid, CoreEntry *core)
* "Userland shall check AT_HWCAP to know whether it can rely on the * "Userland shall check AT_HWCAP to know whether it can rely on the
* v_regs pointer or not" * v_regs pointer or not"
*/ */
unsigned char vrregs[33 * 16 + 4]; unsigned char vrregs[(NVRREG-1) * 16 + 4];
UserPpc64VrstateEntry *vse; UserPpc64VrstateEntry *vse;
uint64_t *p64; uint64_t *p64;
uint32_t *p32; uint32_t *p32;
...@@ -192,7 +192,8 @@ static int get_altivec_regs(pid_t pid, CoreEntry *core) ...@@ -192,7 +192,8 @@ static int get_altivec_regs(pid_t pid, CoreEntry *core)
return -1; return -1;
user_ppc64_vrstate_entry__init(vse); user_ppc64_vrstate_entry__init(vse);
vse->n_vrregs = 33 * 2; /* protocol buffer store 64bit entries */ /* protocol buffer store only 64bit entries and we need 128bit */
vse->n_vrregs = (NVRREG-1) * 2;
vse->vrregs = xmalloc(vse->n_vrregs * sizeof(vse->vrregs[0])); vse->vrregs = xmalloc(vse->n_vrregs * sizeof(vse->vrregs[0]));
if (!vse->vrregs) { if (!vse->vrregs) {
xfree(vse); xfree(vse);
...@@ -200,13 +201,13 @@ static int get_altivec_regs(pid_t pid, CoreEntry *core) ...@@ -200,13 +201,13 @@ static int get_altivec_regs(pid_t pid, CoreEntry *core)
} }
/* Vectors are 2*64bits entries */ /* Vectors are 2*64bits entries */
for (i = 0; i < 33; i++) { for (i = 0; i < (NVRREG-1); i++) {
p64 = (uint64_t*) &vrregs[i * 2 * sizeof(uint64_t)]; p64 = (uint64_t*) &vrregs[i * 2 * sizeof(uint64_t)];
vse->vrregs[i*2] = p64[0]; vse->vrregs[i*2] = p64[0];
vse->vrregs[i*2 + 1] = p64[1]; vse->vrregs[i*2 + 1] = p64[1];
} }
p32 = (uint32_t*) &vrregs[33 * 2 * sizeof(uint64_t)]; p32 = (uint32_t*) &vrregs[(NVRREG-1) * 2 * sizeof(uint64_t)];
vse->vrsave = *p32; vse->vrsave = *p32;
core->ti_ppc64->vrstate = vse; core->ti_ppc64->vrstate = vse;
...@@ -226,7 +227,7 @@ static int put_altivec_regs(mcontext_t *mc, UserPpc64VrstateEntry *vse) ...@@ -226,7 +227,7 @@ static int put_altivec_regs(mcontext_t *mc, UserPpc64VrstateEntry *vse)
pr_debug("Restoring Altivec registers\n"); pr_debug("Restoring Altivec registers\n");
if (vse->n_vrregs != 33*2) { if (vse->n_vrregs != (NVRREG-1)*2) {
pr_err("Corrupted Altivec dump data\n"); pr_err("Corrupted Altivec dump data\n");
return -1; return -1;
} }
...@@ -234,7 +235,8 @@ static int put_altivec_regs(mcontext_t *mc, UserPpc64VrstateEntry *vse) ...@@ -234,7 +235,8 @@ static int put_altivec_regs(mcontext_t *mc, UserPpc64VrstateEntry *vse)
/* Note that this should only be done in the case MSR_VEC is set but /* Note that this should only be done in the case MSR_VEC is set but
* this is not a big deal to do that in all cases. * this is not a big deal to do that in all cases.
*/ */
memcpy(&v_regs->vrregs[0][0], vse->vrregs, sizeof(uint64_t) * 2 * 33); memcpy(&v_regs->vrregs[0][0], vse->vrregs,
sizeof(uint64_t) * 2 * (NVRREG-1));
/* vscr has been restored with the previous memcpy which copied 32 /* vscr has been restored with the previous memcpy which copied 32
* 128bits registers + a 128bits field containing the vscr value in * 128bits registers + a 128bits field containing the vscr value in
* the low part. * the low part.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment