diff options
author | marcel <marcel@FreeBSD.org> | 2007-05-21 05:11:43 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 2007-05-21 05:11:43 +0000 |
commit | 4e45a73058fb6a7791362a77bf844a3c8f8c0fff (patch) | |
tree | beed16268e947daecff3f90938c227058a5d1217 /sys/ia64 | |
parent | f0e9277351d131ebcb8cf08cb5acffe41a1ac16a (diff) | |
download | FreeBSD-src-4e45a73058fb6a7791362a77bf844a3c8f8c0fff.zip FreeBSD-src-4e45a73058fb6a7791362a77bf844a3c8f8c0fff.tar.gz |
When speculation fails (as determined by the chk instruction) the
processor is to jump to recovery code. This branching behaviour
may not be implemented by the processor and a Speculative Operation
fault is raised. The OS is responsible to emulate the branch.
Implement this, because GCC 4.2 uses advanced loads regularly.
Diffstat (limited to 'sys/ia64')
-rw-r--r-- | sys/ia64/ia64/trap.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/sys/ia64/ia64/trap.c b/sys/ia64/ia64/trap.c index 6a66361..77b5009 100644 --- a/sys/ia64/ia64/trap.c +++ b/sys/ia64/ia64/trap.c @@ -629,8 +629,20 @@ trap(int vector, struct trapframe *tf) break; } - case IA64_VEC_NAT_CONSUMPTION: case IA64_VEC_SPECULATION: + /* + * The branching behaviour of the chk instruction is not + * implemented by the processor. All we need to do is + * compute the target address of the branch and make sure + * that control is transfered to that address. + * We should do this in the IVT table and not by entring + * the kernel... + */ + tf->tf_special.iip += tf->tf_special.ifa << 4; + tf->tf_special.psr &= ~IA64_PSR_RI; + goto out; + + case IA64_VEC_NAT_CONSUMPTION: case IA64_VEC_UNSUPP_DATA_REFERENCE: if (user) { ucode = vector; |