#include #include #include #include #include #include #include #include #include #include /*--------------------------------------------------------------------------------*\ * writep(un)protect virt_addr-area * ret: 0 ok \*--------------------------------------------------------------------------------*/ int __io_remap_setwriteprotect(unsigned char *virt_addr, unsigned int len, unsigned int wrprotect) { unsigned char *end_virt_addr = virt_addr + len; /*--- printk("%s(%p,%d,%d)\n", __func__, virt_addr, len, wrprotect); ---*/ flush_cache_all(); while(virt_addr < end_virt_addr) { spinlock_t *ptl; pte_t *pte; struct page *_page; _page = vmalloc_to_page(virt_addr); pte = page_check_address(_page, &init_mm, (unsigned long)virt_addr, &ptl, 1); if(pte == NULL) { printk(KERN_DEBUG"%s: info: no pte for addr %p\n", __func__, virt_addr); return 1; } if(wrprotect) { ptep_set_wrprotect(&init_mm, (unsigned int)virt_addr, pte); } else { pte_t old_pte = *pte; set_pte_at(&init_mm, (unsigned long)virt_addr, pte, pte_mkwrite(old_pte)); } pte_unmap_unlock(pte, ptl); virt_addr += PAGE_SIZE; } flush_tlb_all(); return 0; } EXPORT_SYMBOL(__io_remap_setwriteprotect);