linux-mips-fnet
[Top] [All Lists]

Re: Linux support for R[34]000-series computers

To: Vladimir Roganov <roganov@niisi.msk.ru>, linux-mips@fnet.fr
Subject: Re: Linux support for R[34]000-series computers
From: ralf@uni-koblenz.de
Date: Tue, 13 Oct 1998 03:11:26 +0200
In-reply-to: <36221D8F.F5B81197@niisi.msk.ru>; from Vladimir Roganov on Mon, Oct 12, 1998 at 07:17:35PM +0400
References: <36221D8F.F5B81197@niisi.msk.ru>
On Mon, Oct 12, 1998 at 07:17:35PM +0400, Vladimir Roganov wrote:

> o  Strange code detected in 'asm-mips/mmu_context.h' file:
> 
> extern inline void get_new_mmu_context(struct mm_struct *mm, unsigned
> long asid)

[...]

> The first 'if' condition will never succeed for both R3000/R4000.
> 
> 
> Yet another problem can (theoretically) lead to security hole:
> the version counter is only 16-bits long.  
> If we will start a lot of processes, it is possible to obtain same
> versions
> for old (long time sleeping) and new process, so we can exchange mapping
> for
> some addresses.

This version does not have any of the mentioned problems.

#define MAX_ASID 0x0fc0

#define ASID_VERSION_SHIFT 16
#define ASID_VERSION_MASK  ((~0UL) << ASID_VERSION_SHIFT)
#define ASID_VERSION_INC 0x40
#define ASID_FIRST_VERSION (1UL << ASID_VERSION_SHIFT)

extern inline void get_new_mmu_context(struct mm_struct *mm, unsigned long asid)
{
        /* check if it's legal.. */
        if ((asid & ~ASID_VERSION_MASK) > MAX_ASID) {
                /* start a new version, invalidate all old asid's */
                flush_tlb_all();
                asid = (asid & ASID_VERSION_MASK) + ASID_FIRST_VERSION;
                if (!asid)
                        asid = ASID_FIRST_VERSION;
        }
        asid_cache = asid + ASID_VERSION_INC;
        mm->context = asid;                      /* full version + asid */
}

Note that it's just a little bit different from what is shipping in my
sources.  The whole difference are the values for MAX_ASID and the new
definition for ASID_VERSION_INC.  Unlike your version this code doesn't
have a second if which kills performance.

With a little bit of code patching on startup this routine can stay the
same for R3000 and R4000 series.

> We do not reproduce it now, but remember about problem with one-byte
> counter
> of active I/O requests in RSX-11M system, where after 256 QIO$
> directives
> executive regards task able to swap... :-)

Heh, I guess most people don't even know what RSX was.

> It is also looks strange that function 'get_new_mmu_context' takes asid
> as 
> parameter, due it must be only 'asid_cache' -- all other values can lead
> to problems. Really, both `r4xx0.c` and `r2300.c` use it only with 
> 'asid_cache' parameter, so may be we eliminate second parameter at all
> ?  

Look at the assembler code generated from this routine by gcc.  That's
actually quite often the explanation for strange looking Linux code :-)

[memcpy ...]
> So, best check should be:  src + len < dst
> 
> The result is not a bug, but a feature -- in a half of cases use
> 4-slower code.

The 4 times slower code is actually only being used because there seems to
be some capital bug in the code for backward copying which I glued this
really _bad_ way.

  Ralf

<Prev in Thread] Current Thread [Next in Thread>