Page MenuHomeFreeBSD

Make powerpc64 kernel position-independent

Authored by nwhitehorn on Jan 19 2015, 6:29 AM.


Group Reviewers

The 64-bit PowerPC GENERIC kernel boots on a wide variety of firmwares. The current fixed load address is a best-guess that is supposed to work everywhere. The impending addition of OPAL support for bare-metal POWER8 narrows the parameter space that works everywhere to zero, so we need a new system.

The attached changes make the kernel position-independent, loadable and executable from any fixed address accessible in real mode. This is a relatively small set of changes since powerpc64 ABI is essentially always position-independent unless you deliberately thwart that (which we had done in a few places). Major highlights:

  1. Modify loader to accept dynamic ELF images as kernels. These are distinguished from modules by their entry point being non-zero; changes to to enforce this are included. The changes there are protected by checks for powerpc64, but I believe they should be harmless on all architectures. Feedback or tests on this point would be appreciated.
  2. Code in locore64.S and elf64_machdep.c to perform relocations at kernel start.
  3. Code for the trap handlers to make them position-independent.
  4. Makefile.powerpc bits to tell the compiler and linker to generate position-independent code.
Test Plan

Testing on both UP and SMP ppc64 systems would be much appreciated, as would tests of the loader changes with the if (powerpc64) removed.

Diff Detail

Lint Skipped
Unit Tests Skipped

Event Timeline

nwhitehorn retitled this revision from to Make powerpc64 kernel position-independent.
nwhitehorn updated this object.
nwhitehorn edited the test plan for this revision. (Show Details)
nwhitehorn added reviewers: jhibbits, PowerPC, andreast.

Looks fine, except the one comment.


swtch64.S uses syntax 'mfsprg %rN,{sprgnum}'. Can that be used here? It'll keep things consistent.

nwhitehorn edited edge metadata.

Updated to not __CONCAT for the SPRG instructions. Additionally, since ABSOLUTE_JUMP was only being used in one place, I just expanded it in-place.

UP boots fine. SMP hangs on ichb and uhub attach.

Andreas: which version of the patch did you try? It seems to work OK on my SMP hardware here.

I'm on 277392 now and I tried to create a patch between 3241 and 3254. This is not my tool.

nwhitehorn edited edge metadata.

I think I found the SMP issue, which was actually a CPUTYPE issue. There was an extremely subtle problem in the trap code that would cause a double fault on the first altivec instruction issued from userland. Fixing it is horrible, as it requires that trapcode be at most 8 instructions, which it now is. This comes up successfully on my hardware now. A retest on yours would be much appreciated.

Messed up the last diff. This should fix the SMP/Altivec issue in any case.

Nathan, hm. Do I do it right? I do 'Download Raw Diff', latest revision against base. Apply it to current and it still hangs after the second CPU got activated. uhub and iichb errors.
Current svn revision is: 277423

That should be right. You should be able to apply just the machdep.c, trap.h, and trap_subr64.S parts of the patch to see if the problem is there. Each section of trap_subr64.S is also independent if you have the time to bisect. I'm very confused about why your hardware and mine are different. You see the AP #1 launched message OK?

Ok, good. Then I did it right. I was confused why it still hangs. Thought it was my patch apply procedure. But this is ok I guess.

Yes, I see the AP#1 launched ok. But right afterwards uhub timeouts appear and also iichb read errors.
'Trying to mount root from nfs[]' is about the last I see. It doesn't work because the nic seems to be dead. Additionally I see lots of ata hard resets when bootverbose is on.

I guess I have much older hw than you :) It's a 7,2 or 7,3.

Could you try again post r277468? There was a bad interaction between some of the changed compiler flags and the hacked-together HID register restore sequence in mp_cpudep.c that I just fixed. I hadn't noticed the problem earlier since I wasn't using 970 based hardware. My G5 powermac now runs fine with a dynamic kernel.

Now both, UP and SMP are working. Against -CURRENT after 277468 with diff 4, ID 3258.

Thanks a lot.

I owe you the POWER5+ test, but I lack some time now.

I'm reasonably satisfied that it won't cause regressions now, since we've tested on UP and SMP 970, Cell, and the POWER simulator. If you won't have time to test on POWER hardware in the near future, and you think the approach here is reasonable, could you mark this "Approved"?

andreast edited edge metadata.

Okey. POWER5+ is also happy. Awesome! Thanks

This revision is now accepted and ready to land.Jan 21 2015, 6:55 PM

Committed in stages to HEAD.