From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from web63006.mail.re1.yahoo.com (web63006.mail.re1.yahoo.com [69.147.96.217]) by ozlabs.org (Postfix) with SMTP id 1A42FB7D45 for ; Wed, 28 Apr 2010 18:27:34 +1000 (EST) Message-ID: <193202.72183.qm@web63006.mail.re1.yahoo.com> Date: Wed, 28 Apr 2010 01:27:32 -0700 (PDT) From: Maindoor Subject: change_page_attr support on ppc, patch discussion To: linuxppc-dev@lists.ozlabs.org MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="0-1068691629-1272443252=:72183" List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , --0-1068691629-1272443252=:72183 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable Hi, I am trying to set a page of my data-structure as read-only on a USI MPC834= 7E. This is primarily to figure a data structure corruption issue. Added small support as follows: ppc/mm/init.c:MMU_setup =A0=A0=A0 __map_without_bats =3D 1; =A0=A0=A0 __map_without_ltlbs =3D 1; ppc/mm/pgtable.c static int __change_page_attr(struct page *page, pgprot_t prot) { =A0=A0=A0 pte_t *kpte; =A0=A0=A0 pmd_t *kpmd; =A0=A0=A0 unsigned long address; =A0=A0=A0 BUG_ON(PageHighMem(page)); =A0=A0=A0 address =3D (unsigned long)page_address(page); =A0=A0=A0 if (v_mapped_by_bats(address) || v_mapped_by_tlbcam(address)) =A0=A0=A0=A0=A0=A0=A0 return 0; =A0=A0=A0 if (!get_pteptr(&init_mm, address, &kpte, &kpmd)) =A0=A0=A0=A0=A0=A0=A0 return -EINVAL; =A0=A0=A0 set_pte_at(&init_mm, address, kpte, mk_pte(page, prot)); =A0=A0=A0 wmb(); =A0=A0=A0 flush_HPTE(0, address, pmd_val(*kpmd)); =A0=A0=A0 pte_unmap(kpte); =A0=A0=A0 mb(); =A0=A0=A0 return 0; } /* =A0* Change the page attributes of an page in the linear mapping. */ int change_page_attr(struct page *page, int numpages, pgprot_t prot) { =A0=A0=A0 int i, err =3D 0; =A0=A0=A0 unsigned long flags; =A0=A0=A0 local_irq_save(flags); =A0=A0=A0 for (i =3D 0; i < numpages; i++, page++) { =A0=A0=A0=A0=A0=A0=A0 err =3D __change_page_attr(page, prot); =A0=A0=A0=A0=A0=A0=A0 if (err) =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 break; =A0=A0=A0 } =A0=A0=A0 local_irq_restore(flags); =A0=A0=A0 return err; } EXPORT_SYMBOL(change_page_attr); After allocation of my data structure, when I mark the page readonly like t= his: change_page_attr(virt_to_page(dat_str), 1, PAGE_READONLY); it works (throws Oops) but only for the first time, but subsequent writes are going through. I expect even the subsequent writes to fail. One more quirkiness to this is, after changing the page attribute I need to read the element at least once for this to work. Have I written the supportive api's (above ) correctly ? This is on 2.6.18 = kernel. If there is any other way to catch this corruption please let me know. kgdb and bdi won't help me as it is a dynamically created data-structure an= d I have timing constraints. Regards, Maindoor. =0A=0A=0A --0-1068691629-1272443252=:72183 Content-Type: text/html; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable
Hi,
I am trying to set a page of my data-s= tructure as read-only on a USI MPC8347E.
This is primarily to figure a d= ata structure corruption issue.
Added small support as follows:
ppc/m= m/init.c:MMU_setup

    __map_without_bats =3D 1;
&= nbsp;   __map_without_ltlbs =3D 1;


ppc/mm/pgtable.c
static int __change_page_attr(struct page *page, pgprot_t prot)
{    pte_t *kpte;
    pmd_t *kpmd;
&nb= sp;   unsigned long address;

    BUG_ON(Pag= eHighMem(page));
    address =3D (unsigned long)page_addr= ess(page);

    if (v_mapped_by_bats(address) || v_map= ped_by_tlbcam(address))
        retur= n 0;
    if (!get_pteptr(&init_mm, address, &kpte= , &kpmd))
        return -EINVAL;<= br>    set_pte_at(&init_mm, address, kpte, mk_pte(page, = prot));
    wmb();
    flush_HPTE(0, ad= dress, pmd_val(*kpmd));
    pte_unmap(kpte);
 &nb= sp;  mb();
    return 0;
}

/*
 * C= hange the page attributes of an page in the linear mapping.
*/
int ch= ange_page_attr(struct page *page, int numpages, pgprot_t prot)
{
&nbs= p;   int i, err =3D 0;
    unsigned long flags;=

    local_irq_save(flags);
    for= (i =3D 0; i < numpages; i++, page++) {
     = ;   err =3D __change_page_attr(page, prot);
   =      if (err)
      &n= bsp;     break;
    }
    local_irq_restore(flags);
    re= turn err;
}
EXPORT_SYMBOL(change_page_attr);

After allocation = of my data structure, when I mark the page readonly like this:
change_pa= ge_attr(virt_to_page(dat_str), 1, PAGE_READONLY);

it works (throws O= ops) but only for the first time, but subsequent writes
are going throug= h. I expect even the subsequent writes to fail.

One more quirkiness = to this is, after changing the page attribute I need to
read the element= at least once for this to work.

Have I written the supportive api's= (above ) correctly ? This is on 2.6.18 kernel.
If there is any other wa= y to catch this corruption please let me know.
kgdb and bdi won't help m= e as it is a dynamically created data-structure and I
have timing constr= aints.

Regards,
Maindoor.


=0A=0A=0A= =0A=0A=0A=0A=0A --0-1068691629-1272443252=:72183--