Hi all,
I've modified it, so submit the patch.
Doi.Tsunehisa@xxxxxxxxxxxxxx wrote:
> You (yamahata) said:
>>>> Probably it should looks like the following.
>>>> if (page->count_info != 1) { /* no one but us is using this page */
>>>> put_page(page);
>>>> goto out;
>>>> }
>>>> __set_bit(&page->count_info, _PGC_allocated);
>>> Does `page->count_info' have to be operated with atomic ?
>> Atomic operation is safe bet.
>> XENMAPSPACE hypercall isn't performance critical.
>> If you want to be paranoia, use "if (test_and_set_bit())" to check whether
>> some else set the bit.
>
> I'll modify it with this policy.
>
> Thanks,
> - Tsunehisa Doi
Signed-off-by: Tsunehisa Doi <Doi.Tsunehisa@xxxxxxxxxxxxxx>
diff -r 61eb6589e720 xen/arch/ia64/xen/mm.c
--- a/xen/arch/ia64/xen/mm.c Tue Mar 06 21:11:37 2007 +0900
+++ b/xen/arch/ia64/xen/mm.c Thu Mar 08 20:42:26 2007 +0900
@@ -2087,18 +2087,33 @@ arch_memory_op(int op, XEN_GUEST_HANDLE(
break;
case XENMAPSPACE_grant_table:
spin_lock(&d->grant_table->lock);
+
+ if ((xatp.idx >= nr_grant_frames(d->grant_table)) &&
+ (xatp.idx < max_nr_grant_frames))
+ gnttab_grow_table(d, xatp.idx + 1);
+
if (xatp.idx < nr_grant_frames(d->grant_table))
- mfn = virt_to_mfn(d->grant_table->shared) + xatp.idx;
+ mfn = virt_to_mfn(d->grant_table->shared[xatp.idx]);
+
spin_unlock(&d->grant_table->lock);
break;
default:
break;
}
+ if (mfn == 0) {
+ put_domain(d);
+ return -EINVAL;
+ }
+
LOCK_BIGLOCK(d);
+ /* Check remapping necessity */
+ prev_mfn = gmfn_to_mfn(d, xatp.gpfn);
+ if (mfn == prev_mfn)
+ goto out;
+
/* Remove previously mapped page if it was present. */
- prev_mfn = gmfn_to_mfn(d, xatp.gpfn);
if (prev_mfn && mfn_valid(prev_mfn)) {
if (IS_XEN_HEAP_FRAME(mfn_to_page(prev_mfn)))
/* Xen heap frames are simply unhooked from this phys slot. */
@@ -2110,12 +2125,31 @@ arch_memory_op(int op, XEN_GUEST_HANDLE(
/* Unmap from old location, if any. */
gpfn = get_gpfn_from_mfn(mfn);
- if (gpfn != INVALID_M2P_ENTRY)
+ if (gpfn != INVALID_M2P_ENTRY) {
+ /*
+ * guest_physmap_remove_page() (for IPF) descrements page
+ * counter and unset PGC_allocated flag,
+ * so pre-increment page counter and post-set flag inserted
+ */
+ /* pre-increment page counter */
+ if (!get_page(mfn_to_page(mfn), d))
+ goto out;
+
guest_physmap_remove_page(d, gpfn, mfn);
+
+ /* post-set PGC_allocated flag */
+ if ((mfn_to_page(mfn)->count_info & PGC_count_mask) != 1) {
+ /* no one but us is using this page */
+ put_page(mfn_to_page(mfn));
+ goto out;
+ }
+ set_bit(_PGC_allocated, &mfn_to_page(mfn)->count_info);
+ }
/* Map at new location. */
guest_physmap_add_page(d, xatp.gpfn, mfn);
+ out:
UNLOCK_BIGLOCK(d);
put_domain(d);
_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ia64-devel
|