changeset: 23978:fd3fa0a85020 user: Olaf Hering date: Thu Oct 20 11:25:55 2011 +0100 files: xen/arch/x86/mm/p2m.c description: xenpaging: check p2mt in p2m_mem_paging functions Add checks to forward the p2m_ram_paging* state properly during page-in. Resume can be called several times if several vcpus called populate for the gfn. Finish resume only once. Signed-off-by: Olaf Hering Acked-by: Tim Deegan Committed-by: Tim Deegan --- xen/arch/x86/mm/p2m.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) Index: xen-4.1.2-testing/xen/arch/x86/mm/p2m.c =================================================================== --- xen-4.1.2-testing.orig/xen/arch/x86/mm/p2m.c +++ xen-4.1.2-testing/xen/arch/x86/mm/p2m.c @@ -3020,16 +3020,22 @@ int p2m_mem_paging_prep(struct p2m_domai p2m_type_t p2mt; p2m_access_t a; mfn_t mfn; - int ret = -ENOMEM; + int ret; p2m_lock(p2m); mfn = p2m->get_entry(p2m, gfn, &p2mt, &a, p2m_query); + ret = -ENOENT; + /* Allow only missing pages */ + if ( p2mt != p2m_ram_paging_in_start ) + goto out; + /* Allocate a page if the gfn does not have one yet */ if ( !mfn_valid(mfn) ) { /* Get a free page */ + ret = -ENOMEM; page = alloc_domheap_page(p2m->domain, 0); if ( unlikely(page == NULL) ) goto out; @@ -3064,9 +3070,15 @@ void p2m_mem_paging_resume(struct p2m_do { p2m_lock(p2m); mfn = p2m->get_entry(p2m, rsp.gfn, &p2mt, &a, p2m_query); - set_p2m_entry(p2m, rsp.gfn, mfn, 0, p2m_ram_rw, a); - set_gpfn_from_mfn(mfn_x(mfn), rsp.gfn); - audit_p2m(p2m, 1); + /* Allow only pages which were prepared properly, or pages which + * were nominated but not evicted */ + if ( mfn_valid(mfn) && + (p2mt == p2m_ram_paging_in || p2mt == p2m_ram_paging_in_start) ) + { + set_p2m_entry(p2m, rsp.gfn, mfn, 0, p2m_ram_rw, a); + set_gpfn_from_mfn(mfn_x(mfn), rsp.gfn); + audit_p2m(p2m, 1); + } p2m_unlock(p2m); }