Estoy intentando navegar por las tablas de páginas para un proceso en Linux. En un módulo del kernel me di cuenta de la siguiente función:Tablas de páginas para caminar de un proceso en Linux
static struct page *walk_page_table(unsigned long addr)
{
pgd_t *pgd;
pte_t *ptep, pte;
pud_t *pud;
pmd_t *pmd;
struct page *page = NULL;
struct mm_struct *mm = current->mm;
pgd = pgd_offset(mm, addr);
if (pgd_none(*pgd) || pgd_bad(*pgd))
goto out;
printk(KERN_NOTICE "Valid pgd");
pud = pud_offset(pgd, addr);
if (pud_none(*pud) || pud_bad(*pud))
goto out;
printk(KERN_NOTICE "Valid pud");
pmd = pmd_offset(pud, addr);
if (pmd_none(*pmd) || pmd_bad(*pmd))
goto out;
printk(KERN_NOTICE "Valid pmd");
ptep = pte_offset_map(pmd, addr);
if (!ptep)
goto out;
pte = *ptep;
page = pte_page(pte);
if (page)
printk(KERN_INFO "page frame struct is @ %p", page);
out:
return page;
}
Esta función se llama desde el ioctl
y addr
es una dirección virtual en el espacio de direcciones del proceso:
static int my_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long addr)
{
struct page *page = walk_page_table(addr);
...
return 0;
}
Lo extraño es que llamar ioctl
en un proceso de espacio de usuario, esto segfaults ... pero parece que la forma en que estoy buscando la entrada de la tabla de la página es correcta porque con dmesg
obtengo por ejemplo para cada llamada ioctl
:
[ 1721.437104] Valid pgd
[ 1721.437108] Valid pud
[ 1721.437108] Valid pmd
[ 1721.437110] page frame struct is @ c17d9b80
¿Por qué el proceso no puede completar correctamente la llamada `ioctl '? ¿Tal vez tengo que bloquear algo antes de navegar por las tablas de páginas?
Estoy trabajando con kernel 2.6.35-22 y tablas de páginas de tres niveles.
¡Gracias a todos!
¿Es posible que ioctl syscall regrese con éxito y el código se segfaulting después de eso? –
No porque ioctl syscall es la última instrucción en 'main' antes' return'.Si digo 'ioctl', el proceso no segfault. – MirkoBanchi
¿Por qué escondiste la parte donde usas la dirección de la 'struct page'? ¿Estás seguro de que tus segfaults no provienen de aquí? ¿Has probado a depurar esto en qemu? –