mapping memory in 0xb space
Igor Grobman
igor at cs.wisc.edu
Wed Sep 29 15:14:08 EST 2004
On Wed, 29 Sep 2004, David Gibson wrote:
> On Tue, Sep 28, 2004 at 01:52:16PM -0500, Igor Grobman wrote:
> > On Tue, 28 Sep 2004, David Gibson wrote:
> >
> > > 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.
>From the description I read, I might be better off using 0xfff.. addresses
with that algorithm. Not a big deal.
>
> > 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).
In my 2.4.21 source, do_slb_bolted does get called for 0xb addresses.
And thanks for letting me know about power4 being SLB. I was clueless on
the issue.
>
> > 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.
Or is it?
>
>
> > 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.
>
>
> > > 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.
And this is why I avoided explaining fully in my first email :-). I'd
like to solve one problem at a time. What I said in my initial email
is accurate. Even within the valid VSID range, if the highest 5 bits of
the page index are not zero, I get a crash on access (e.g.
0xb00001FFFFF00000, but works on 0xb00001FFF0000000).
As for why I thought 0xbff would work, I reasoned that
since the highest bits are masked out in get_kernel_vsid(), and since
nobody else is using the 0xb region, it doesn't matter if I get a VSID
that is the same as some other VSID in 0xb region. However, I did not
consider the bug in do_slb_bolted that you describe below.
>
> 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.
This must be happening, although I would still like to know why it
misbehaves even within the valid VSID range.
>
> 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.
No, it's not close enough--I really must have that very last segment.
It sounds like I was simply getting lucky on the power3 machine.
Without the mask, I must have been getting random pages, and
happily overwriting them.
Any ideas on how I might map that very last segment of 0xb, or for
that matter the very last segment of 0xf ? It need not be pretty,
but it cannot involve modifying the kernel source, though it can rely on
whatever dirty tricks a kernel module might get away with. I don't
want to modify the source, because I would like the tool to work on
unmodified kernels.
It's starting to sound like an impossible task (at least on non-recent
kernels). I think I might go with a backup suboptimal solution, which
involves extra jumps, but at least it might work.
Thanks again,
Igor
>
> > > 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.
> >
>
>
More information about the Linuxppc64-dev
mailing list