Example #1
0
static UserPpc64VrstateEntry *copy_altivec_regs(__vector128 *vrregs)
{
	UserPpc64VrstateEntry *vse;
	uint64_t *p64;
	uint32_t *p32;
	int i;

	vse = xmalloc(sizeof(*vse));
	if (!vse)
		return NULL;
	user_ppc64_vrstate_entry__init(vse);

	/* 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]));
	if (!vse->vrregs) {
		xfree(vse);
		return NULL;
	}

	/* Vectors are 2*64bits entries */
	for (i = 0; i < (NVRREG-1); i++) {
		p64 = (uint64_t*) &vrregs[i];
		vse->vrregs[i*2] =  p64[0];
		vse->vrregs[i*2 + 1] = p64[1];
	}

	p32 = (uint32_t*) &vrregs[NVRREG-1];
	vse->vrsave = *p32;

	return vse;
}
Example #2
0
static int get_altivec_regs(pid_t pid, CoreEntry *core)
{
	/* The kernel returns :
	 *   32 Vector registers (128bit)
	 *   VSCR (32bit) stored in a 128bit entry (odd)
	 *   VRSAVE (32bit) store at the end.
	 *
	 * Kernel setup_sigcontext's comment mentions:
	 * "Userland shall check AT_HWCAP to know whether it can rely on the
	 * v_regs pointer or not"
	 */
	unsigned char vrregs[33 * 16 + 4];
	UserPpc64VrstateEntry *vse;
	uint64_t *p64;
	uint32_t *p32;
	int i;

	if (ptrace(PTRACE_GETVRREGS, pid, 0, (void*)&vrregs) < 0) {
		/* PTRACE_GETVRREGS returns EIO if Altivec is not supported.
		 * This should not happen if msr_vec is set. */
		if (errno != EIO) {
			pr_perror("Couldn't get Altivec registers");
			return -1;
		}
		pr_debug("Altivec not supported\n");
		return 0;
	}

	pr_debug("Dumping Altivec registers\n");

	vse = xmalloc(sizeof(*vse));
	if (!vse)
		return -1;
	user_ppc64_vrstate_entry__init(vse);

	vse->n_vrregs = 33 * 2; /* protocol buffer store 64bit entries */
	vse->vrregs = xmalloc(vse->n_vrregs * sizeof(vse->vrregs[0]));
	if (!vse->vrregs) {
		xfree(vse);
		return -1;
	}

	/* Vectors are 2*64bits entries */
	for (i = 0; i < 33; i++) {
		p64 = (uint64_t*) &vrregs[i * 2 * sizeof(uint64_t)];
		vse->vrregs[i*2] =  p64[0];
		vse->vrregs[i*2 + 1] = p64[1];
	}

	p32 = (uint32_t*) &vrregs[33 * 2 * sizeof(uint64_t)];
	vse->vrsave = *p32;

	core->ti_ppc64->vrstate = vse;

	/*
	 * Force the MSR_VEC bit of the restored MSR otherwise the kernel
	 * will not restore them from the signal frame.
	 */
	core->ti_ppc64->gpregs->msr |= MSR_VEC;

	return 0;
}