> Date: Fri, 11 Oct 2013 10:04:15 +0100
> From: JBeulich@xxxxxxxx
> To: zhangzhi2022@xxxxxxxxxxx
> CC: xen-devel@xxxxxxxxxxxxx
> Subject: RE: [Xen-devel] pagetable RO
>
> >>> On 11.10.13 at 10:59, 张智<zhangzhi2022@xxxxxxxxxxx> wrote:
> >> Date: Fri, 11 Oct 2013 09:36:44 +0100
> >> From: JBeulich@xxxxxxxx
> >> >>> On 11.10.13 at 09:37, 张智<zhangzhi2022@xxxxxxxxxxx> wrote:
> >> >> Date: Fri, 11 Oct 2013 08:15:43 +0100
> >> >> From: JBeulich@xxxxxxxx
> >> >> >>> 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.
>
> Did you read this at all? Because it answers ...
>
> >> >> 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?
>
> ... this question: The hypervisor does not do this at all. It only
> verifies that the guest kernel did.
I've read the source code of do_mmu_update and could only find that macro: define_get_linear_pagetable(l2) checks whether its entry is read-only. However, this function does execute only when get_page_and_type_from_pagenr(mfn, PGT_l1_page_table, ...) returns an invalid value. Is this the point or somewhere else about checking whether the new PGT_l1_page_table as read-only ? I did not find the check points in the function: get_page_and_type_from_pagenr(mfn, PGT_l1_page_table, ...) as well as its sub-branch functions.
henry
>
> Jan