Background: qemu-4.2.0 qemu-system-i386, host os is linux-kernel 4.19.193 ubuntu desktop
start
qemu-system-i386 with its seabios, during the bios process, there are two store operations: store 0x6ffc, store 0xd4ad0 by store_helper.
0x6ffc and 0xd4ad0 are GVA, their HVA maybe are 7f65efe06ffc, 7f65efed4ad0.
Then I wrote a kernel module to try to get their HPA.
static inline void QEMU_ALWAYS_INLINE
store_helper(CPUArchState *env, target_ulong addr, uint64_t val,
TCGMemOpIdx oi, uintptr_t retaddr, MemOp op)
{
......
haddr = (void *)((uintptr_t)addr + entry->addend);
store_memop(haddr, val, op);
++ print_entry_hpa(haddr);
......
}
void
print_entry_hpa() // in kernel module
{
hpa_pgd = pgd_offset(mm, hpa);
printk("pgd: %llx\n", pgd_val(*hpa_pgd));
hpa_pud = pud_offset(&__p4d(pgd_val(*hpa_pgd)), hpa);
printk("pud: %llx\n", pud_val(*hpa_pud));
hpa_pmd = pmd_offset(hpa_pud, hpa);
printk("pmd: %llx\n", pmd_val(*hpa_pmd));
hpa_pte = pte_offset_kernel(hpa_pmd, hpa);
printk("pte: %llx\n", pte_val(*hpa_pte));
}
However, I found that their PTE are both 0.
[19772.167927] pgd: 800000021c310067
[19772.167928] pud: 20fe22067
[19772.167929] pmd: 80000002142008e7
[19772.167929] pte: 0
Then I wrote a line of printk in kernel:/arch/x86/mm/fault.c, which is the interrupt entry function of page fault.
static noinline void
__do_page_fault(struct pt_regs *regs, unsigned long error_code,
unsigned long address)
{
struct vm_area_struct *vma;
struct task_struct *tsk;
struct mm_struct *mm;
vm_fault_t fault, major = 0;
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
u32 pkey;
++
if((address & 0xFFFFF) == 0xd4ad0)
++
printk("__do_page_fault addr: %lx\n", address);
tsk = current;
mm = tsk->mm;
......
}
But in dmesg I caught nothing that means the zero pte didn't trigger a page fault.
It's so strange, the value of store 0x6ffc and store 0xd4ad0 is not zero and the qemu runs normally.
SO what's the problem?
Thanks a lot!
--