Hi Tim,
You (Tim.Deegan) said:
>>> Are you worried about a race where the foreign domain is destroyed and
>>> another domain created, with the same struct domain pointer, and which
>>> owns the same frame, between the __acquire_grant_for_copy() and the
>>> get_page()?
>>
>> No, I'm worried that two domains use with same page frame.
>>
>> The released pages can be used by new domain, but old domain sturct
>> exists between domain_kill and domain_destroy.
>
> If the released frames are used by a new domain, get_page() will fail:
> the old domain still exists (we have a reference to it), so the new
> owner's domain pointer must be different from the one we pass to
> get_page.
In my investigation, get_page() assumes that the page frame is in
use. But, the page_info structure of released page frame should not
be treated as inuse. Thus the nd value might be invalid value in this
situation, I think.
[xen/include/asm-x86/mm.h]
static inline int get_page(struct page_info *page,
struct domain *domain)
{
u32 x, nx, y = page->count_info;
u32 d, nd = page->u.inuse._domain; /* <<=== THIS LINE */
u32 _domain = pickle_domptr(domain);
do {
x = y;
nx = x + 1;
d = nd;
if ( unlikely((x & PGC_count_mask) == 0) || /* Not allocated? */
unlikely((nx & PGC_count_mask) == 0) || /* Count overflow? */
unlikely(d != _domain) ) /* Wrong owner? */
{
if ( !_shadow_mode_refcounts(domain) )
DPRINTK("Error pfn %lx: rd=%p, od=%p, caf=%08x, taf=%"
PRtype_info "\n",
page_to_mfn(page), domain, unpickle_domptr(d),
x, page->u.inuse.type_info);
return 0;
}
__asm__ __volatile__(
LOCK_PREFIX "cmpxchg8b %3"
: "=d" (nd), "=a" (y), "=c" (d),
"=m" (*(volatile u64 *)(&page->count_info))
: "0" (d), "1" (x), "c" (d), "b" (nx) ); /* <<=== THIS LINE */
}
while ( unlikely(nd != d) || unlikely(y != x) );
return 1;
}
Thanks,
- Tsunehisa Doi
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|