direct-io.hg

changeset 7796:ed2ef64fdc33

get_page_type() must clean up writable pagetable state
before failing, otherwise functions like set_gdt() can
spuriously fail because a page appears to be writable
despite there being pending changes to mapping of that
page in ptwr state.

This should fix the reported cases of crashes in
vcpu_prepare in xenlinux.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Mon Nov 14 19:55:40 2005 +0100 (2005-11-14)
parents dd754654d427
children 312e3f18bd6c
files xen/arch/x86/mm.c
line diff
     1.1 --- a/xen/arch/x86/mm.c	Mon Nov 14 19:45:32 2005 +0100
     1.2 +++ b/xen/arch/x86/mm.c	Mon Nov 14 19:55:40 2005 +0100
     1.3 @@ -1461,6 +1461,22 @@ int get_page_type(struct pfn_info *page,
     1.4              {
     1.5                  if ( unlikely((x & PGT_type_mask) != (type & PGT_type_mask) ) )
     1.6                  {
     1.7 +                    if ( current->domain == page_get_owner(page) )
     1.8 +                    {
     1.9 +                        /*
    1.10 +                         * This ensures functions like set_gdt() see up-to-date
    1.11 +                         * type info without needing to clean up writable p.t.
    1.12 +                         * state on the fast path.
    1.13 +                         */
    1.14 +                        LOCK_BIGLOCK(current->domain);
    1.15 +                        cleanup_writable_pagetable(current->domain);
    1.16 +                        y = page->u.inuse.type_info;
    1.17 +                        UNLOCK_BIGLOCK(current->domain);
    1.18 +                        /* Can we make progress now? */
    1.19 +                        if ( ((y & PGT_type_mask) == (type & PGT_type_mask)) ||
    1.20 +                             ((y & PGT_count_mask) == 0) )
    1.21 +                            goto again;
    1.22 +                    }
    1.23                      if ( ((x & PGT_type_mask) != PGT_l2_page_table) ||
    1.24                           ((type & PGT_type_mask) != PGT_l1_page_table) )
    1.25                          MEM_LOG("Bad type (saw %" PRtype_info