mapping memory in 0xb space

David Gibson david at gibson.dropbear.id.au
Wed Sep 29 11:40:17 EST 2004


On Tue, Sep 28, 2004 at 01:52:16PM -0500, Igor Grobman wrote:
> On Tue, 28 Sep 2004, David Gibson wrote:
> >
> > Err... this seems likely to cause trouble.
> 
> So it has :-)
> 
> >  Recent kernels don't even
> > have VSIDs allocated for the 0xb... region.
> 
> Looking at both 2.6.8 and 2.4.21, I don't see a difference in
> get_kernel_vsid() code.

Ok, *very* recent kernels.  The new VSID algorithm has gone into the
BK tree since 2.6.8.

> >  2.4.21 will have some
> > kernel VSIDs there, but there will probably be a bunch of places that
> > assume addresses below 0xc... are user addresses and compute the vsids
> > accordingly.
> 
> Note that since I put in a bolted entry into the HPT, I assume I don't
> have to worry about page fault handling code.  

That sounds correct.

> This leaves segments.  Both
> DataAccess_common and DataAccessSLB_common call
> do_stab_bolted/do_slb_bolted when confronted with an address in 0xb
> region.

Oh, so it does.  That, I think is a 2.4 thing, long gone in 2.6 (even
before the SLB rewrite, I'm pretty sure do_slb_bolted was only called
for 0xc addresses).

> Presumably, this will fault in the segments I am interested in.

Yes, actually, it should.  Ok, I guess the problem is deeper than I
thought.

> > Differences in the code for segment table and SLB
> > machines are probably why it works (or seems to) on power3 but not
> > power4.
> 
> SLB machines are LPAR machines, correct?

Not necessarily.

> In that case, neither the power3
> nor the power4 I am using are SLB machines.  

No, power4 is definitely SLB.

> Also, I narrowed it down to
> working (or appearing to work) as long as the highest 5 bits of the page
> index (those that end up as partial index in the HPTE) are zero.  This may
> just be a weird coincidence.

Could be.

> > Also, unless you've created a new set, there are no Linux page tables
> > for the 0xb region - the only linux page tables for the kernel are for
> > the vmalloc (0xd) and ioremap (0xe) regions.
> 
> I am building page tables off the bolted_dir, which does exist in 2.4.21
> for the 0xb region.  But again, assuming I insert a bolted entry in HPT,
> do I even need to worry about linux page tables as such?

Oh, so they do.  But yes, you shouldn't need to worry about them.

> > Why on earth do you want to do this?
> 
> Good question ;-).  A long long time ago, I posted on this list and
> explained.  Since then, I found what appeared to be a solution, except
> that it appears power4 breaks it.  I am building a tool that allows
> dynamic splicing of code into a running kernel (see
> http://www.paradyn.org/html/kerninst.html).  In order for this to work, I
> need to be able to overwrite a single instruction with a jump to
> spliced-in code.  The target of the jump needs to be within the range (26
> bits).  Therefore, I have a choice of 0xbfff.. addresses with backward
> jumps from 0xc region, or the 0xff.. addresses for absolute jumps.  I
> chose 0xbff.., because I found already-working code, originally written
> for the performance counter interface.  Am I making more sense now?

Aha!  But this does actually explain the problem - there are only
VSIDs assigned for the first 2^41 bits of each region - so although
there are vsids for 0xb000000000000000-0xb00001ffffffffff, there
aren't any for 0xbff... addresses.  Likewise the Linux pagetables only
cover a 41-bit address range, but that won't matter if you're creating
HPTEs directly.

You may have seen the comment in do_slb_bolted which claims to permit
a full 32-bits of ESID - it's wrong.  The code doesn't mask the ESID
down to 13 bits as get_kernel_vsid() does, but it probably should - an
overlarge ESID will cause collisions with VSIDs from entirely
different address places, which would be a Bad Thing.

Actually, you should be able to allow ESIDs of up to 21 bits there (36
bit VSID - 15 bits of "context").  But you will need to make sure
get_kernel_vsid(), or whatever you're using to calculate the VAs for
the hash HPTEs is updated to match - at the moment I think it will
mask down to 13 bits.  I'm not sure if that will get you sufficiently
close to 0xc0... for your purposes.

> > On Mon, Sep 27, 2004 at 02:47:15PM -0500, Igor Grobman wrote:
> > > I would like to be able to remap memory into 0xb space with 2.4.21
> kernel.
> > > I have code that works fine on power3 box, but fails miserably on my
> dual
> > > power4+ box.  I am using btmalloc() from pmc.c with a modified range.
> > > Normal btmalloc() allocation works fine, but if I change the range to
> > > start with, e.g. 0xb00001FFFFF00000 (instead of 0xb00..), the kernel
> > > crashes when accessing the allocated page.
> > >
> > > For those of you unfamiliar with btmalloc() code, it finds a physical
> page
> > > using get_free_pages(), subtracts PAGE_OFFSET (i.e. 0xc00...) to form
> a
> > > physical address, then inserts the page into linux page tables, using
> the
> > > VSID calculated with get_kernel_vsid() and the physical address
> > > calculated above.  It also inserts an HPTE into the hardware page
> table.
> > > It doesn't do anything with regards to allocating segments.  I
> understand
> > > the segments should be faulted in.  I looked at the code in head.S,
> and it
> > > appears that do_stab_bolted should be doing this.  Yet, I am missing
> someth$
> > > because the btmalloc() code does not in fact work for pages in the
> range I
> > > specified above.
> > >
> > > I am running this on 7029-6E3 (p615?) machine with two power4+
> processors.
> > > I am using the kernel from Suse's 2.4.21-215 source package.
> > >
> > > Any ideas and attempts to un-confuse me are welcome.
> 

-- 
David Gibson			| For every complex problem there is a
david AT gibson.dropbear.id.au	| solution which is simple, neat and
				| wrong.
http://www.ozlabs.org/people/dgibson



More information about the Linuxppc64-dev mailing list