Re: Interrupt and spin_lock

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



As far as I could understand your code, you are maintaining two data
structure, one to represent the list of vma's and another to maintain
the list of pages. List of pages is attached to each vma data strucure
in vma list.

Well the probable error might be as follows, in the function in which
you are filling the lists, you are first creating the vma structure to
be added to list, in this i think you just set the start and end
address of the structe elements, but the do not initliaze the list and
page_list elements of vma structure. After this you are adding this
structure to the global list of vma's under the protection of
spinlocks. After adding it to list you are initializing the page_list
element of just added vma, i think the better approach wud be to first
fill up the whole vma structure including the page list to be attached
to it  and start and end address elements and then attach that vma
structure to the global list.

As you must have got the hint, the problem in your code is that you
have added the structure to the global list without initiliazing all
the elementts of it, so any other code (code which scans the list) can
crash on this because the elements are not initialized properly.

It would be better if you first create the page list, attach that list
to vma structure, set the start and end address of vma strucuture and
then finally add the vma structure to list of vma structures, in this
way any code accessing the list will not get the wrong elements.

Please see the embedded comments in the following code.


On 8/22/05, Vincenzo Mallozzi <vinjunior@xxxxxxxx> wrote:

> 
> Then, the function that scans lists:
> 
> int mtpmc_protected_by_us(unsigned long addr, int rw)
> {
>     struct mtpmc_vm_wrprotected *wr_vma;
>     struct list_head *vma_list, *page_list;
>     struct mtpmc_wrprotected_pages *wr_page;
> /* LOCK */
>     spin_lock_irqsave(&write_protected_lock, flags_lock);
> 
>     list_for_each(vma_list, &vm_write_protected){
>         wr_vma = list_entry(vma_list, struct mtpmc_vm_wrprotected, list);
>         list_for_each_safe(page_list, &wr_vma->pages_list){
>             wr_page = list_entry(page_list, struct mtpmc_wrprotected_pages,
> list);
>             if (wr_page's address is one of the address we've write protected)

In this IF condition you can crash as the page list element was not
initialized when the vma structure is added to vma list

>             {
>                     spin_unlock_irqrestore(&write_protected_lock, flags_lock);
>                     return 1;
>             }
>         }
> /* UNLOCK */
>         spin_unlock_irqrestore(&write_protected_lock, flags_lock);
>         return 0;
> }
> 
> The function above is called from within the page fault handler function I
> create.
> 
> Now, the function that fills the lists:
> 

restructure the following function to first create the vma structure,
then prepare the page list, then attach attach the page list to vma
structure, set the start and end address of vma structure and finally
add the vma structure to vma list under the control of spinlocks

> void mtpmc_set_mm_not_writable(struct mm_struct *mm)
> {
>     struct mtpmc_vm_wrprotected *vma;
>     struct mtpmc_wrprotected_pages *page;
>     struct vm_area_struct *vm;
>     unsigned long addr;
>     pte_t *pte;
> 
>     down_write(&mm->mmap_sem);
> 
>     for(vm = mm->mmap; vm != NULL; vm = vm->vm_next)
>             /* this instruction create the needed structure for vma list */
>            vma = mtpmc_mk_vm_wrprotected(vm);

Initializes all the elements of vma in "mtpmc_mk_vm_wrprotected"
function (including the page_list element)

>             spin_lock_irqsave(&write_protected_lock, flags_lock);
>             list_add_tail(&vma->list, &vm_write_protected);
>             spin_unlock_irqrestore(&write_protected_lock, flags_lock);
>             INIT_LIST_HEAD(&vma->pages_list);

Here is the probable bug, due to which the code crashes. Do initialise
the page_list element before you add the vma structure to list

>             for (addr = vm->vm_start; addr<vm->vm_end; addr+=PAGE_SIZE){
>                  /*get the pte of the page with address "addr" */
>                 pte = mtpmc_get_pte_from_address(mm, addr);
>                 if (pte != NULL)
>                 /* if the page isn't already write protected */
>                     if (pte_write(*pte)){
>                        /*write protect it*/
>                         set_pte(pte, pte_wrprotect(*pte));
>                          /* this instruction create the needed structure for
>                              page list */
>                         page = mtpmc_mk_page_wrprotected(addr);
>   /* LOCK --> */   spin_lock_irqsave(&write_protected_lock, flags_lock);
>                         list_add_tail(&page->list, &vma->pages_list);
> /*UNLOCK --> */spin_unlock_irqrestore(&write_protected_lock, flags_lock);
>                     }
>             }
> 
>     up_write(&mm->mmap_sem);
>     return;
> }
> 
> I' hoe the code I've posted is not too big.
> I'll re-post the error type:
> 
> 
> Unable to handle kernel NULL pointer dereference at virtual address 00000000.
>               ...............
> <0>kernel panic: Aiee, killing interrupt handler
> In interrupt handler - not syncing
> 
> I hoe you've some suggests for me.
> I really ignore where is the problem and how I can resolve it.
> I go in panic any times the kernel goes in panic (Vincenzo panic).

Dont panic, things do go wrong sometimes and we need to find out why ;-)

regards,
-Gaurav

> Thanks.
> Vincenzo Mallozzi.
> 
> 
> 
> 
> 
> 
> 
> ___________________________________
> Yahoo! Mail: gratis 1GB per i messaggi e allegati da 10MB
> http://mail.yahoo.it
> 
>

--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive:       http://mail.nl.linux.org/kernelnewbies/
FAQ:           http://kernelnewbies.org/faq/



[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux