Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 295729 Details for
Bug 425411
[RHEL5.2]: i386 PV guests on x86_64 HV fail "xm save"
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
PATCH 3 to fix 32-on-64 save/restore issue
compat.patch (text/plain), 9.99 KB, created by
Chris Lalancette
on 2008-02-24 03:41:49 UTC
(
hide
)
Description:
PATCH 3 to fix 32-on-64 save/restore issue
Filename:
MIME Type:
Creator:
Chris Lalancette
Created:
2008-02-24 03:41:49 UTC
Size:
9.99 KB
patch
obsolete
>diff -r 2a3111016f88 tools/libxc/xc_domain_restore.c >--- a/tools/libxc/xc_domain_restore.c Mon Feb 11 15:59:49 2008 +0000 >+++ b/tools/libxc/xc_domain_restore.c Tue Feb 12 17:16:48 2008 +0000 >@@ -251,7 +251,7 @@ static xen_pfn_t *load_p2m_frame_list( > > /* Now that we know the guest's word-size, can safely allocate > * the p2m frame list */ >- if ( (p2m_frame_list = malloc(P2M_FL_SIZE)) == NULL ) >+ if ( (p2m_frame_list = malloc(P2M_TOOLS_FL_SIZE)) == NULL ) > { > ERROR("Couldn't allocate p2m_frame_list array"); > return NULL; >@@ -1040,7 +1040,7 @@ int xc_domain_restore(int xc_handle, int > SET_FIELD(&ctxt, gdt_frames[j], p2m[pfn]); > } > /* Uncanonicalise the page table base pointer. */ >- pfn = xen_cr3_to_pfn(GET_FIELD(&ctxt, ctrlreg[3])); >+ pfn = UNFOLD_CR3(GET_FIELD(&ctxt, ctrlreg[3])); > > if ( pfn >= p2m_size ) > { >@@ -1057,12 +1057,12 @@ int xc_domain_restore(int xc_handle, int > (unsigned long)pt_levels<<XEN_DOMCTL_PFINFO_LTAB_SHIFT); > goto out; > } >- SET_FIELD(&ctxt, ctrlreg[3], xen_pfn_to_cr3(p2m[pfn])); >+ SET_FIELD(&ctxt, ctrlreg[3], FOLD_CR3(p2m[pfn])); > > /* Guest pagetable (x86/64) stored in otherwise-unused CR1. */ > if ( (pt_levels == 4) && (ctxt.x64.ctrlreg[1] & 1) ) > { >- pfn = xen_cr3_to_pfn(ctxt.x64.ctrlreg[1] & ~1); >+ pfn = UNFOLD_CR3(ctxt.x64.ctrlreg[1] & ~1); > if ( pfn >= p2m_size ) > { > ERROR("User PT base is bad: pfn=%lu p2m_size=%lu", >@@ -1077,7 +1077,7 @@ int xc_domain_restore(int xc_handle, int > (unsigned long)pt_levels<<XEN_DOMCTL_PFINFO_LTAB_SHIFT); > goto out; > } >- ctxt.x64.ctrlreg[1] = xen_pfn_to_cr3(p2m[pfn]); >+ ctxt.x64.ctrlreg[1] = FOLD_CR3(p2m[pfn]); > } > domctl.cmd = XEN_DOMCTL_setvcpucontext; > domctl.domain = (domid_t)dom; >@@ -1158,7 +1158,7 @@ int xc_domain_restore(int xc_handle, int > if ( guest_width > sizeof (xen_pfn_t) ) > for ( i = p2m_size - 1; i >= 0; i-- ) > ((uint64_t *)p2m)[i] = p2m[i]; >- else if ( guest_width > sizeof (xen_pfn_t) ) >+ else if ( guest_width < sizeof (xen_pfn_t) ) > for ( i = 0; i < p2m_size; i++ ) > ((uint32_t *)p2m)[i] = p2m[i]; > >diff -r 2a3111016f88 tools/libxc/xc_domain_save.c >--- a/tools/libxc/xc_domain_save.c Mon Feb 11 15:59:49 2008 +0000 >+++ b/tools/libxc/xc_domain_save.c Tue Feb 12 17:19:17 2008 +0000 >@@ -61,10 +61,11 @@ unsigned int guest_width; > > #define mfn_to_pfn(_mfn) (live_m2p[(_mfn)]) > >-#define pfn_to_mfn(_pfn) \ >- ((xen_pfn_t) ((guest_width==8) \ >- ? (((uint64_t *)live_p2m)[(_pfn)]) \ >- : (((uint32_t *)live_p2m)[(_pfn)]))) >+#define pfn_to_mfn(_pfn) \ >+ ((xen_pfn_t) ((guest_width==8) \ >+ ? (((uint64_t *)live_p2m)[(_pfn)]) \ >+ : ((((uint32_t *)live_p2m)[(_pfn)]) == 0xffffffffU \ >+ ? (-1UL) : (((uint32_t *)live_p2m)[(_pfn)])))) > > /* > * Returns TRUE if the given machine frame number has a unique mapping >@@ -496,10 +497,9 @@ static int canonicalize_pagetable(unsign > xen_start = L3_PAGETABLE_ENTRIES_PAE; > > /* >- ** in PAE only the L2 mapping the top 1GB contains Xen mappings. >- ** We can spot this by looking for the guest linear mapping which >- ** Xen always ensures is present in that L2. Guests must ensure >- ** that this check will fail for other L2s. >+ ** In PAE only the L2 mapping the top 1GB contains Xen mappings. >+ ** We can spot this by looking for the guest's mappingof the m2p. >+ ** Guests must ensure that this check will fail for other L2s. > */ > if ( (pt_levels == 3) && (type == XEN_DOMCTL_PFINFO_L2TAB) ) > { >@@ -555,7 +555,13 @@ static int canonicalize_pagetable(unsign > /* This will happen if the type info is stale which > is quite feasible under live migration */ > pfn = 0; /* zap it - we'll retransmit this page later */ >- race = 1; /* inform the caller of race; fatal if !live */ >+ /* XXX: We can't spot Xen mappings in compat-mode L2es >+ * from 64-bit tools, but the only thing in them is the >+ * compat m2p, so we quietly zap them. This doesn't >+ * count as a race, so don't report it. */ >+ if ( !(type == XEN_DOMCTL_PFINFO_L2TAB >+ && sizeof (unsigned long) > guest_width) ) >+ race = 1; /* inform the caller; fatal if !live */ > } > else > pfn = mfn_to_pfn(mfn); >@@ -690,7 +696,7 @@ static xen_pfn_t *map_and_save_p2m_table > else > p2m_frame_list_list[i] = 0; > else if ( guest_width < sizeof(unsigned long) ) >- for ( i = PAGE_SIZE/sizeof(unsigned long) - 1; i >= 0; i++ ) >+ for ( i = PAGE_SIZE/sizeof(unsigned long) - 1; i >= 0; i-- ) > p2m_frame_list_list[i] = ((uint32_t *)p2m_frame_list_list)[i]; > > live_p2m_frame_list = >@@ -704,19 +710,20 @@ static xen_pfn_t *map_and_save_p2m_table > } > > /* Get a local copy of the live_P2M_frame_list */ >- if ( !(p2m_frame_list = malloc(P2M_FL_SIZE)) ) >+ if ( !(p2m_frame_list = malloc(P2M_TOOLS_FL_SIZE)) ) > { > ERROR("Couldn't allocate p2m_frame_list array"); > goto out; > } >- memcpy(p2m_frame_list, live_p2m_frame_list, P2M_FL_SIZE); >+ memset(p2m_frame_list, 0, P2M_TOOLS_FL_SIZE); >+ memcpy(p2m_frame_list, live_p2m_frame_list, P2M_GUEST_FL_SIZE); > > /* Canonicalize guest's unsigned long vs ours */ > if ( guest_width > sizeof(unsigned long) ) > for ( i = 0; i < P2M_FL_ENTRIES; i++ ) > p2m_frame_list[i] = ((uint64_t *)p2m_frame_list)[i]; > else if ( guest_width < sizeof(unsigned long) ) >- for ( i = P2M_FL_ENTRIES - 1; i >= 0; i++ ) >+ for ( i = P2M_FL_ENTRIES - 1; i >= 0; i-- ) > p2m_frame_list[i] = ((uint32_t *)p2m_frame_list)[i]; > > >@@ -1559,31 +1566,26 @@ int xc_domain_save(int xc_handle, int io > } > > /* Canonicalise the page table base pointer. */ >- if ( !MFN_IS_IN_PSEUDOPHYS_MAP(xen_cr3_to_pfn( >- GET_FIELD(&ctxt, ctrlreg[3]))) ) >+ if ( !MFN_IS_IN_PSEUDOPHYS_MAP(UNFOLD_CR3( >+ GET_FIELD(&ctxt, ctrlreg[3]))) ) > { > ERROR("PT base is not in range of pseudophys map"); > goto out; > } > SET_FIELD(&ctxt, ctrlreg[3], >- xen_pfn_to_cr3( >- mfn_to_pfn( >- xen_cr3_to_pfn( >- GET_FIELD(&ctxt, ctrlreg[3]))))); >+ FOLD_CR3(mfn_to_pfn(UNFOLD_CR3(GET_FIELD(&ctxt, ctrlreg[3]))))); > > /* Guest pagetable (x86/64) stored in otherwise-unused CR1. */ > if ( (pt_levels == 4) && ctxt.x64.ctrlreg[1] ) > { >- if ( !MFN_IS_IN_PSEUDOPHYS_MAP( >- xen_cr3_to_pfn(ctxt.x64.ctrlreg[1])) ) >+ if ( !MFN_IS_IN_PSEUDOPHYS_MAP(UNFOLD_CR3(ctxt.x64.ctrlreg[1])) ) > { > ERROR("PT base is not in range of pseudophys map"); > goto out; > } > /* Least-significant bit means 'valid PFN'. */ > ctxt.x64.ctrlreg[1] = 1 | >- xen_pfn_to_cr3( >- mfn_to_pfn(xen_cr3_to_pfn(ctxt.x64.ctrlreg[1]))); >+ FOLD_CR3(mfn_to_pfn(UNFOLD_CR3(ctxt.x64.ctrlreg[1]))); > } > > if ( write_exact(io_fd, &ctxt, ((guest_width==8) >diff -r 2a3111016f88 tools/libxc/xg_private.h >--- a/tools/libxc/xg_private.h Mon Feb 11 15:59:49 2008 +0000 >+++ b/tools/libxc/xg_private.h Wed Feb 13 09:36:13 2008 +0000 >@@ -155,7 +155,9 @@ typedef l4_pgentry_64_t l4_pgentry_t; > #define P2M_FL_ENTRIES (((p2m_size)+FPP-1)/FPP) > > /* Size in bytes of the pfn_to_mfn_frame_list */ >-#define P2M_FL_SIZE ((P2M_FL_ENTRIES)*(guest_width)) >+#define P2M_GUEST_FL_SIZE ((P2M_FL_ENTRIES) * (guest_width)) >+#define P2M_TOOLS_FL_SIZE ((P2M_FL_ENTRIES) * \ >+ MAX((sizeof (xen_pfn_t)), guest_width)) > > /* Masks for PTE<->PFN conversions */ > #define MADDR_BITS_X86 ((guest_width == 8) ? 52 : 44) >diff -r 2a3111016f88 tools/libxc/xg_save_restore.h >--- a/tools/libxc/xg_save_restore.h Mon Feb 11 15:59:49 2008 +0000 >+++ b/tools/libxc/xg_save_restore.h Tue Feb 12 14:30:59 2008 +0000 >@@ -68,6 +68,13 @@ static inline int get_platform_info(int > > *guest_width = domctl.u.address_size.size / 8; > >+ /* 64-bit tools will see the 64-bit hvirt_start, but 32-bit guests >+ * will be using the compat one. */ >+ if ( *guest_width < sizeof (unsigned long) ) >+ /* XXX need to fix up a way of extracting this value from Xen if >+ * XXX it becomes variable for domU */ >+ *hvirt_start = 0xf5800000; >+ > if (strstr(xen_caps, "xen-3.0-x86_64")) > /* Depends on whether it's a compat 32-on-64 guest */ > *pt_levels = ( (*guest_width == 8) ? 4 : 3 ); >@@ -136,6 +143,16 @@ typedef union > (_p)->x32._f = (_v); \ > } while (0) > >+#define UNFOLD_CR3(_c) \ >+ ((uint64_t)((guest_width == 8) \ >+ ? ((_c) >> 12) \ >+ : (((uint32_t)(_c) >> 12) | ((uint32_t)(_c) << 20)))) >+ >+#define FOLD_CR3(_c) \ >+ ((uint64_t)((guest_width == 8) \ >+ ? ((uint64_t)(_c)) << 12 \ >+ : (((uint32_t)(_c) << 12) | ((uint32_t)(_c) >> 20)))) >+ > #define MEMCPY_FIELD(_d, _s, _f) do { \ > if (guest_width == 8) \ > memcpy(&(_d)->x64._f, &(_s)->x64._f,sizeof((_d)->x64._f)); \
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 425411
:
289421
|
295727
|
295728
|
295729
|
329322