IBM SA14-2339-04 Personal Computer User Manual


 
Programming Model 2-29
To understand the implications of this situation, consider the code sequence:
handler: aaa
bbb
rfi
subroutine: bctr
When executing the interrupt handler, the fetcher does not recognize the rfi as a break in the program
flow, and speculatively fetches the target of the bctr, which is really the first instruction of a subroutine
that has not been called. Therefore, the CTR might contain an invalid pointer.
To protect against such a prefetch, the software must insert an unconditional branch hang (b $) just
after the rfi. This prevents the hardware from prefetching the invalid target address used by bctr.
Consider also the above code sequence, with the rfi instruction replaced by an sc instruction used to
initialize the CTR with the appropriate value for the bctr to branch to, upon return from the system
call. The sc handler returns to the instruction following the sc, which can’t be a branch hang. Instead,
software could put a mtctr just before the sc to load a non-sensitive address into the CTR. This
address will be used as the prediction address before the sc executes. An alternative would be to put
a mfctr or mtctr between the sc and the bctr; the mtctr prevents the fetcher from speculatively
accessing the address contained in the CTR before initialization.
2.8.2.2 Fetching Past tw or twi Instructions
The interrupt-causing instructions, tw and twi, do not require the special handling described in
“Fetching Past an Interrupt-Causing or Interrupt-Returning Instruction” on page 2-28. These
instructions are typically used by debuggers, which implement software breakpoints by substituting a
trap instruction for the instruction originally at the breakpoint address. In a code sequence mtlr
followed by blr (or mtctr followed by bctr), replacement of mtlr/mtctr by tw or twi leaves the LR/CTR
uninitialized. It would be inappropriate to fetch from the blr/bctr target address. This situation is
common, and the fetcher is designed to prevent the problem.
2.8.2.3 Fetching Past an Unconditional Branch
When an unconditional branch is in DCD in the instruction queue, the fetcher recognizes that the
sequential instructions following the branch are unnecessary. These sequential addresses are not
accessed. Addresses at the branch target are accessed instead.
Therefore, placing an unconditional branch just before the start of a sensitive address space (for
example, at the “end” of a memory area that borders an I/O device) guarantees that addresses in the
sensitive area will not be speculatively fetched.
2.8.2.4 Suggested Locations of Memory-Mapped Hardware
The preferred method of protecting memory-mapped hardware from inadvertent access is to use
address translation, with hardware isolated to guarded pages (the G storage attribute in the
associated TLB entry is set to 1.) The pages can be as small as 1KB. Code should never be stored in
such pages.
If address translation is disabled, the preferred protection method is to isolate memory-mapped
hardware into regions guarded using the SGR. Code should never be stored in such regions. The
disadvantage of this method, compared to the preferred method, is that each region guarded by the
SGR consumes 128MB of the address space.