[PATCH] Retrieval of TLS pointer via RDHWR

Jayachandran C. c.jayachandran at gmail.com
Mon Jan 10 06:18:36 UTC 2011


On Sun, Jan 2, 2011 at 1:09 PM, Jayachandran C.
<c.jayachandran at gmail.com> wrote:
> On Fri, Dec 31, 2010 at 8:36 PM, Robert Millan <rmh at debian.org> wrote:
>> 2010/12/28 Warner Losh <imp at bsdimp.com>:
>>> I reviewed the patch, and I liked it.  Couldn't find anything wrong with it
>>> when I first looked at it.  Would be nice if things were more flexible, but
>>> since generalizing from a sample size of one can be hard, I totally agree.
>>
>> Great.  So will someone commit this? :-)
>
> I will look at committing this.
>
> BTW, The netlogic(RMI) contributed code had a different implementation
> for this. The User Reserved Instruction exception had a fast path for
> RDHWR which used k0/k1 and returned the value without taking the full
> trap.   I hadn't looked at adding that either (mostly because I did
> not see an immediate requirement).
>
> Another emulation missing in the kernel is for floating point...

Finally got some time to test and commit this patch.  Looking thru the
patch again, I have a couple of comments:

| 	case T_RES_INST + T_USER:
|-		log_illegal_instruction("RES_INST", trapframe);
|-		i = SIGILL;
|-		addr = trapframe->pc;
|+		{
|+			register_t inst = *((register_t *) trapframe->pc);

fuword32() should be used here, since it is fetching the value from userspace.

|+			switch (MIPS_INST_OPCODE(inst)) {
|+			case OP_SPECIAL3:
|+				switch (MIPS_INST_FUNC(inst)) {
|+				case OP_RDHWR:
|+					/* Register 29 used for TLS */
|+					if (MIPS_INST_RD(inst) == 29) {
|+						((register_t *) trapframe)[MIPS_INST_RT(inst)] = td->td_md.md_tls;
|+						trapframe->pc += sizeof(int);

This will mis-behave if the rdhwr is in a branch delay slot. You
should either signal 'SIGILL' in this case or do an emulate branch (if
the rdhwr is can be used in a branch delay slot).

|+						goto out;
|+					}
|+				break;
|+				}
|+			break;
|+			}
|+			log_illegal_instruction("RES_INST", trapframe);
|+			i = SIGILL;
|+			addr = trapframe->pc;
|+		}

Sorry for the delay,
JC.


More information about the freebsd-mips mailing list