> Date: Fri, 11 Oct 2013 09:36:44 +0100
> From: JBeulich@xxxxxxxx
> To: zhangzhi2022@xxxxxxxxxxx
> CC: xen-devel@xxxxxxxxxxxxxxxxxxxx
> Subject: RE: [Xen-devel] pagetable RO
>
> >>> On 11.10.13 at 09:37, 张智<zhangzhi2022@xxxxxxxxxxx> wrote:
>
> >
> >> Date: Fri, 11 Oct 2013 08:15:43 +0100
> >> From: JBeulich@xxxxxxxx
> >> To: zhangzhi2022@xxxxxxxxxxx
> >> CC: xen-devel@xxxxxxxxxxxxxxxxxxxx
> >> Subject: Re: [Xen-devel] pagetable RO
> >>
> >> >>> On 11.10.13 at 08:30, 张智<zhangzhi2022@xxxxxxxxxxx> wrote:
> >> > Say, the sub-op: MMU_NORMAL_PT_UPDATE,
> >> > if the page that ptr of struct mmu_update points to is PGT_l2_page_table,
> >> > then
> >> > the address part of val of struct mmu_update points
> >> > to a page, which is PGT_l1_page_table.
> >> > However, I couldn't find the protections for this PGT_l1_page_table
> >> > page in the do_mmu_update, is it already set as read-only
> >> > before launching MMU_UPDATE hypercall?
> >>
> >
> >> Of course - a page can't be PGT_l1_page_table when there still is
> >> some writable mapping around.
> > Thanks, but when will the page be set as read-only before the MMU_UPDATE
> > hypercall ? is there any hint?
>
> Whenever the guest kernel wants to do that.
>
> >> So for an L2 entry update it is sufficient to verify that all contained L1
> > entries point to R/O
> >> pages (and transition them to PGT_l1_page_table if they aren't
> >> already).
> >
> > Besides, in the function do_mmu_update for an L2 entry update, the new
> > PGT_l1_page_table page, containing all L1 entries, does not have the process
> > of checking whether they are pointing to the pages of page table type.
>
> It surely does: mod_l2_entry() -> get_page_from_l2e() ->
> get_page_and_type_from_pagenr(mfn, PGT_l1_page_table, ...).
>
Not exactly, get_page_and_type_from_pagenr(mfn, PGT_l1_page_table, ...) -> ...->alloc_page_type(page, PGT_l1_page_table, 0) -> alloc_l1_table(page)
See, in the function: alloc_l1_table(page), only when the function: get_page_from_l1e(pl1e[i], ...) returns 1, will the function: l1e_remove_flags(pl1e[i], _PAGE_RW) does execute. This is what I've just said "R/W flag is removed from the L1 entry" . Further, the function: get_page_from_l1e(pl1e[i], ...) will return 1 only when this check: ( !mfn_valid(mfn) || (real_pg_owner = page_get_owner_and_reference(page)) == dom_io ) succeeds.
From above, it is concluded that do_mmu_update does not set the L1 entries in the new PGT_l1_page_table , which point to pages of page table type, as read-only.
In a nutshell, where does xen hypervisor set the new PGT_l1_page_table as read-only?
> > Instead, R/W flag is removed from the L1 entry only because the page that the
> > entry points to is non-sharable or is a I/O page. What's the reason?
>
> I don't think I understand what you're asking here.
>
> Jan