{
struct domain *d = v->domain;
unsigned long cr3_gfn;
- unsigned long cr3_pfn = INVALID_MFN;
+ struct page_info *cr3_page;
unsigned long flags, cr4;
unsigned int i;
int rc = 0, compat;
if ( !compat )
{
cr3_gfn = xen_cr3_to_pfn(c.nat->ctrlreg[3]);
- cr3_pfn = get_gfn_untyped(d, cr3_gfn);
+ cr3_page = get_page_from_gfn(d, cr3_gfn, NULL, P2M_ALLOC);
- if ( !mfn_valid(cr3_pfn) ||
- (paging_mode_refcounts(d)
- ? !get_page(mfn_to_page(cr3_pfn), d)
- : !get_page_and_type(mfn_to_page(cr3_pfn), d,
- PGT_base_page_table)) )
+ if ( !cr3_page )
{
- put_gfn(d, cr3_gfn);
+ destroy_gdt(v);
+ return -EINVAL;
+ }
+ if ( !paging_mode_refcounts(d)
+ && !get_page_type(cr3_page, PGT_base_page_table) )
+ {
+ put_page(cr3_page);
destroy_gdt(v);
return -EINVAL;
}
- v->arch.guest_table = pagetable_from_pfn(cr3_pfn);
- put_gfn(d, cr3_gfn);
+ v->arch.guest_table = pagetable_from_page(cr3_page);
#ifdef __x86_64__
if ( c.nat->ctrlreg[1] )
{
cr3_gfn = xen_cr3_to_pfn(c.nat->ctrlreg[1]);
- cr3_pfn = get_gfn_untyped(d, cr3_gfn);
+ cr3_page = get_page_from_gfn(d, cr3_gfn, NULL, P2M_ALLOC);
- if ( !mfn_valid(cr3_pfn) ||
- (paging_mode_refcounts(d)
- ? !get_page(mfn_to_page(cr3_pfn), d)
- : !get_page_and_type(mfn_to_page(cr3_pfn), d,
- PGT_base_page_table)) )
+ if ( !cr3_page ||
+ (!paging_mode_refcounts(d)
+ && !get_page_type(cr3_page, PGT_base_page_table)) )
{
- cr3_pfn = pagetable_get_pfn(v->arch.guest_table);
+ if (cr3_page)
+ put_page(cr3_page);
+ cr3_page = pagetable_get_page(v->arch.guest_table);
v->arch.guest_table = pagetable_null();
if ( paging_mode_refcounts(d) )
- put_page(mfn_to_page(cr3_pfn));
+ put_page(cr3_page);
else
- put_page_and_type(mfn_to_page(cr3_pfn));
- put_gfn(d, cr3_gfn);
+ put_page_and_type(cr3_page);
destroy_gdt(v);
return -EINVAL;
}
- v->arch.guest_table_user = pagetable_from_pfn(cr3_pfn);
- put_gfn(d, cr3_gfn);
+ v->arch.guest_table_user = pagetable_from_page(cr3_page);
}
else if ( !(flags & VGCF_in_kernel) )
{
l4_pgentry_t *l4tab;
cr3_gfn = compat_cr3_to_pfn(c.cmp->ctrlreg[3]);
- cr3_pfn = get_gfn_untyped(d, cr3_gfn);
+ cr3_page = get_page_from_gfn(d, cr3_gfn, NULL, P2M_ALLOC);
+
+ if ( !cr3_page)
+ {
+ destroy_gdt(v);
+ return -EINVAL;
+ }
- if ( !mfn_valid(cr3_pfn) ||
- (paging_mode_refcounts(d)
- ? !get_page(mfn_to_page(cr3_pfn), d)
- : !get_page_and_type(mfn_to_page(cr3_pfn), d,
- PGT_l3_page_table)) )
+ if (!paging_mode_refcounts(d)
+ && !get_page_type(cr3_page, PGT_l3_page_table) )
{
- put_gfn(d, cr3_gfn);
+ put_page(cr3_page);
destroy_gdt(v);
return -EINVAL;
}
l4tab = __va(pagetable_get_paddr(v->arch.guest_table));
- *l4tab = l4e_from_pfn(
- cr3_pfn, _PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED);
- put_gfn(d, cr3_gfn);
+ *l4tab = l4e_from_pfn(page_to_mfn(cr3_page),
+ _PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED);
#endif
}
struct domain *d = v->domain;
void *mapping;
vcpu_info_t *new_info;
- unsigned long mfn;
+ struct page_info *page;
int i;
if ( offset > (PAGE_SIZE - sizeof(vcpu_info_t)) )
if ( (v != current) && !test_bit(_VPF_down, &v->pause_flags) )
return -EINVAL;
- mfn = get_gfn_untyped(d, gfn);
- if ( !mfn_valid(mfn) ||
- !get_page_and_type(mfn_to_page(mfn), d, PGT_writable_page) )
+ page = get_page_from_gfn(d, gfn, NULL, P2M_ALLOC);
+ if ( !page )
+ return -EINVAL;
+
+ if ( !get_page_type(page, PGT_writable_page) )
{
- put_gfn(d, gfn);
+ put_page(page);
return -EINVAL;
}
- mapping = map_domain_page_global(mfn);
+ mapping = __map_domain_page_global(page);
if ( mapping == NULL )
{
- put_page_and_type(mfn_to_page(mfn));
- put_gfn(d, gfn);
+ put_page_and_type(page);
return -ENOMEM;
}
}
v->vcpu_info = new_info;
- v->arch.pv_vcpu.vcpu_info_mfn = mfn;
+ v->arch.pv_vcpu.vcpu_info_mfn = page_to_mfn(page);
/* Set new vcpu_info pointer /before/ setting pending flags. */
wmb();
for ( i = 0; i < BITS_PER_EVTCHN_WORD(d); i++ )
set_bit(i, &vcpu_info(v, evtchn_pending_sel));
- put_gfn(d, gfn);
return 0;
}
for ( j = 0; j < k; j++ )
{
- unsigned long type = 0, mfn = get_gfn_untyped(d, arr[j]);
+ unsigned long type = 0;
- page = mfn_to_page(mfn);
+ page = get_page_from_gfn(d, arr[j], NULL, P2M_ALLOC);
- if ( unlikely(!mfn_valid(mfn)) ||
- unlikely(is_xen_heap_mfn(mfn)) )
+ if ( unlikely(!page) ||
+ unlikely(is_xen_heap_page(page)) )
type = XEN_DOMCTL_PFINFO_XTAB;
else if ( xsm_getpageframeinfo(page) != 0 )
;
- else if ( likely(get_page(page, d)) )
+ else
{
switch( page->u.inuse.type_info & PGT_type_mask )
{
if ( page->u.inuse.type_info & PGT_pinned )
type |= XEN_DOMCTL_PFINFO_LPINTAB;
-
- put_page(page);
}
- else
- type = XEN_DOMCTL_PFINFO_XTAB;
- put_gfn(d, arr[j]);
+ if ( page )
+ put_page(page);
arr[j] = type;
}
{
struct page_info *page;
unsigned long gfn = arr32[j];
- unsigned long mfn = get_gfn_untyped(d, gfn);
- page = mfn_to_page(mfn);
+ page = get_page_from_gfn(d, gfn, NULL, P2M_ALLOC);
if ( domctl->cmd == XEN_DOMCTL_getpageframeinfo3)
arr32[j] = 0;
- if ( unlikely(!mfn_valid(mfn)) ||
- unlikely(is_xen_heap_mfn(mfn)) )
+ if ( unlikely(!page) ||
+ unlikely(is_xen_heap_page(page)) )
arr32[j] |= XEN_DOMCTL_PFINFO_XTAB;
else if ( xsm_getpageframeinfo(page) != 0 )
{
- put_gfn(d, gfn);
+ put_page(page);
continue;
- } else if ( likely(get_page(page, d)) )
+ }
+ else
{
unsigned long type = 0;
if ( page->u.inuse.type_info & PGT_pinned )
type |= XEN_DOMCTL_PFINFO_LPINTAB;
arr32[j] |= type;
- put_page(page);
}
- else
- arr32[j] |= XEN_DOMCTL_PFINFO_XTAB;
- put_gfn(d, gfn);
+ if ( page )
+ put_page(page);
}
if ( copy_to_guest_offset(domctl->u.getpageframeinfo2.array,
{
struct domain *d = rcu_lock_domain_by_id(domctl->domain);
unsigned long gmfn = domctl->u.hypercall_init.gmfn;
- unsigned long mfn;
+ struct page_info *page;
void *hypercall_page;
ret = -ESRCH;
break;
}
- mfn = get_gfn_untyped(d, gmfn);
+ page = get_page_from_gfn(d, gmfn, NULL, P2M_ALLOC);
ret = -EACCES;
- if ( !mfn_valid(mfn) ||
- !get_page_and_type(mfn_to_page(mfn), d, PGT_writable_page) )
+ if ( !page || !get_page_type(page, PGT_writable_page) )
{
- put_gfn(d, gmfn);
+ if ( page )
+ put_page(page);
rcu_unlock_domain(d);
break;
}
ret = 0;
- hypercall_page = map_domain_page(mfn);
+ hypercall_page = __map_domain_page(page);
hypercall_page_initialise(d, hypercall_page);
unmap_domain_page(hypercall_page);
- put_page_and_type(mfn_to_page(mfn));
+ put_page_and_type(page);
- put_gfn(d, gmfn);
rcu_unlock_domain(d);
}
break;
case PHYSDEVOP_pirq_eoi_gmfn_v1: {
struct physdev_pirq_eoi_gmfn info;
unsigned long mfn;
+ struct page_info *page;
ret = -EFAULT;
if ( copy_from_guest(&info, arg, 1) != 0 )
break;
ret = -EINVAL;
- mfn = get_gfn_untyped(current->domain, info.gmfn);
- if ( !mfn_valid(mfn) ||
- !get_page_and_type(mfn_to_page(mfn), v->domain,
- PGT_writable_page) )
+ page = get_page_from_gfn(current->domain, info.gmfn, NULL, P2M_ALLOC);
+ if ( !page )
+ break;
+ if ( !get_page_type(page, PGT_writable_page) )
{
- put_gfn(current->domain, info.gmfn);
+ put_page(page);
break;
}
+ mfn = page_to_mfn(page);
if ( cmpxchg(&v->domain->arch.pv_domain.pirq_eoi_map_mfn,
0, mfn) != 0 )
{
put_page_and_type(mfn_to_page(mfn));
- put_gfn(current->domain, info.gmfn);
ret = -EBUSY;
break;
}
{
v->domain->arch.pv_domain.pirq_eoi_map_mfn = 0;
put_page_and_type(mfn_to_page(mfn));
- put_gfn(current->domain, info.gmfn);
ret = -ENOSPC;
break;
}
if ( cmd == PHYSDEVOP_pirq_eoi_gmfn_v1 )
v->domain->arch.pv_domain.auto_unmask = 1;
- put_gfn(current->domain, info.gmfn);
ret = 0;
break;
}
case 0:
{
void *hypercall_page;
- unsigned long mfn;
unsigned long gmfn = val >> 12;
unsigned int idx = val & 0xfff;
+ struct page_info *page;
if ( idx > 0 )
{
return 0;
}
- mfn = get_gfn_untyped(d, gmfn);
+ page = get_page_from_gfn(d, gmfn, NULL, P2M_ALLOC);
- if ( !mfn_valid(mfn) ||
- !get_page_and_type(mfn_to_page(mfn), d, PGT_writable_page) )
+ if ( !page || !get_page_type(page, PGT_writable_page) )
{
- put_gfn(d, gmfn);
+ if ( page )
+ put_page(page);
gdprintk(XENLOG_WARNING,
"Bad GMFN %lx (MFN %lx) to MSR %08x\n",
- gmfn, mfn, base + idx);
+ gmfn, page_to_mfn(page), base + idx);
return 0;
}
- hypercall_page = map_domain_page(mfn);
+ hypercall_page = __map_domain_page(page);
hypercall_page_initialise(d, hypercall_page);
unmap_domain_page(hypercall_page);
- put_page_and_type(mfn_to_page(mfn));
- put_gfn(d, gmfn);
+ put_page_and_type(page);
break;
}
break;
case 3: {/* Write CR3 */
- unsigned long mfn, gfn;
+ unsigned long gfn;
+ struct page_info *page;
domain_lock(v->domain);
if ( !is_pv_32on64_vcpu(v) )
{
gfn = compat_cr3_to_pfn(*reg);
#endif
}
- mfn = get_gfn_untyped(v->domain, gfn);
- rc = new_guest_cr3(mfn);
- put_gfn(v->domain, gfn);
+ page = get_page_from_gfn(v->domain, gfn, NULL, P2M_ALLOC);
+ rc = page ? new_guest_cr3(page_to_mfn(page)) : 0;
+ if ( page )
+ put_page(page);
domain_unlock(v->domain);
if ( rc == 0 ) /* not okay */
goto fail;