32-on-64: Fix domain address-size clamping, implement

copy-on-grant-transfer, and eliminate 166GB memory limit for x86/64
Xen.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
This commit is contained in:
Keir Fraser committed 2007-12-06 13:39:19 +00:00
1 parent 8fd28ec7bd
commit 5cc77f9098
7 files changed
+37 -32

No files matched your search

-2
View File
@@ -319,8 +319,6 @@ int switch_native(struct domain *d)
release_compat_l4(d->vcpu[vcpuid]);
}
d->arch.physaddr_bitsize = 64;
return 0;
}
+1 -1
View File
@@ -367,7 +367,7 @@ int __init construct_dom0(
#ifdef CONFIG_COMPAT
HYPERVISOR_COMPAT_VIRT_START(d) =
max_t(unsigned int, m2p_compat_vstart, value);
d->arch.physaddr_bitsize = !is_pv_32on64_domain(d) ? 64 :
d->arch.physaddr_bitsize =
fls((1UL << 32) - HYPERVISOR_COMPAT_VIRT_START(d)) - 1
+ (PAGE_SIZE - 2);
if ( value > (!is_pv_32on64_domain(d) ?
-7
View File
@@ -370,13 +370,6 @@ static void __init machine_specific_memory_setup(
"can be accessed by Xen in 32-bit mode.");
#endif
#ifdef __x86_64__
clip_to_limit((uint64_t)(MACH2PHYS_COMPAT_VIRT_END -
__HYPERVISOR_COMPAT_VIRT_START) << 10,
"Only the first %u GB of the physical memory map "
"can be accessed by 32-on-64 guests.");
#endif
reserve_dmi_region();
}
+1 -1
View File
@@ -442,7 +442,7 @@ int check_descriptor(const struct domain *dom, struct desc_struct *d)
unsigned int domain_clamp_alloc_bitsize(struct domain *d, unsigned int bits)
{
if ( d == NULL )
if ( (d == NULL) || !is_pv_32on64_domain(d) )
return bits;
return min(d->arch.physaddr_bitsize, bits);
}
+25
View File
@@ -1081,11 +1081,36 @@ gnttab_transfer(
if ( xsm_grant_transfer(d, e) )
{
unlock_and_copyback:
rcu_unlock_domain(e);
page->count_info &= ~(PGC_count_mask|PGC_allocated);
free_domheap_page(page);
gop.status = GNTST_permission_denied;
goto copyback;
}
if ( (1UL << domain_clamp_alloc_bitsize(e, BITS_PER_LONG-1)) <= mfn )
{
struct page_info *new_page;
void *sp, *dp;
new_page = alloc_domheap_pages(
NULL, 0,
MEMF_bits(domain_clamp_alloc_bitsize(e, BITS_PER_LONG-1)));
if ( new_page == NULL )
goto unlock_and_copyback;
sp = map_domain_page(mfn);
dp = map_domain_page(page_to_mfn(new_page));
memcpy(dp, sp, PAGE_SIZE);
unmap_domain_page(dp);
unmap_domain_page(sp);
page->count_info &= ~(PGC_count_mask|PGC_allocated);
free_domheap_page(page);
page = new_page;
}
spin_lock(&e->page_alloc_lock);
/*
+3 -12
View File
@@ -319,18 +319,6 @@ static long memory_exchange(XEN_GUEST_HANDLE(xen_memory_exchange_t) arg)
goto fail_early;
}
if ( (exch.out.address_bits != 0) &&
(exch.out.address_bits <
(get_order_from_pages(max_page) + PAGE_SHIFT)) )
{
if ( exch.out.address_bits <= PAGE_SHIFT )
{
rc = -ENOMEM;
goto fail_early;
}
memflags = MEMF_bits(exch.out.address_bits);
}
if ( exch.in.extent_order <= exch.out.extent_order )
{
in_chunk_order = exch.out.extent_order - exch.in.extent_order;
@@ -353,6 +341,9 @@ static long memory_exchange(XEN_GUEST_HANDLE(xen_memory_exchange_t) arg)
}
d = current->domain;
memflags |= MEMF_bits(domain_clamp_alloc_bitsize(
d, exch.out.address_bits ? : BITS_PER_LONG));
cpu = select_local_cpu(d);
for ( i = (exch.nr_exchanged >> in_chunk_order);
+7 -9
View File
@@ -786,15 +786,13 @@ struct page_info *__alloc_domheap_pages(
ASSERT(!in_irq());
if ( bits )
{
bits = domain_clamp_alloc_bitsize(d, bits);
if ( bits <= (PAGE_SHIFT + 1) )
return NULL;
bits -= PAGE_SHIFT + 1;
if ( bits < zone_hi )
zone_hi = bits;
}
bits = domain_clamp_alloc_bitsize(d, bits ? : BITS_PER_LONG);
if ( bits <= (PAGE_SHIFT + 1) )
return NULL;
bits -= PAGE_SHIFT + 1;
if ( bits < zone_hi )
zone_hi = bits;
if ( (zone_hi + PAGE_SHIFT) >= dma_bitsize )
{
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.