Commit 706cc9d2 authored by Stefano Stabellini's avatar Stefano Stabellini Committed by Konrad Rzeszutek Wilk

xen/m2p: Check whether the MFN has IDENTITY_FRAME bit set..

If there is no proper PFN value in the M2P for the MFN
(so we get 0xFFFFF.. or 0x55555, or 0x0), we should
consult the M2P override to see if there is an entry for this.
[Note: we also consult the M2P override if the MFN
is past our machine_to_phys size].

We consult the P2M with the PFN. In case the returned
MFN is one of the special values: 0xFFF.., 0x5555
(which signify that the MFN can be either "missing" or it
belongs to DOMID_IO) or the p2m(m2p(mfn)) != mfn, we check
the M2P override. If we fail the M2P override check, we reset
the PFN value to INVALID_P2M_ENTRY.

Next we try to find the MFN in the P2M using the MFN
value (not the PFN value) and if found, we know
that this MFN is an identity value and return it as so.

Otherwise we have exhausted all the posibilities and we
return the PFN, which at this stage can either be a real
PFN value found in the machine_to_phys.. array, or
INVALID_P2M_ENTRY value.

[v1: Added Review-by tag]
Reviewed-by: default avatarIan Campbell <ian.campbell@citrix.com>
Signed-off-by: default avatarKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
parent 146c4e51
...@@ -81,6 +81,7 @@ static inline int phys_to_machine_mapping_valid(unsigned long pfn) ...@@ -81,6 +81,7 @@ static inline int phys_to_machine_mapping_valid(unsigned long pfn)
static inline unsigned long mfn_to_pfn(unsigned long mfn) static inline unsigned long mfn_to_pfn(unsigned long mfn)
{ {
unsigned long pfn; unsigned long pfn;
int ret = 0;
if (xen_feature(XENFEAT_auto_translated_physmap)) if (xen_feature(XENFEAT_auto_translated_physmap))
return mfn; return mfn;
...@@ -95,15 +96,29 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn) ...@@ -95,15 +96,29 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn)
* In such cases it doesn't matter what we return (we return garbage), * In such cases it doesn't matter what we return (we return garbage),
* but we must handle the fault without crashing! * but we must handle the fault without crashing!
*/ */
__get_user(pfn, &machine_to_phys_mapping[mfn]); ret = __get_user(pfn, &machine_to_phys_mapping[mfn]);
try_override: try_override:
/* ret might be < 0 if there are no entries in the m2p for mfn */
if (ret < 0)
pfn = ~0;
else if (get_phys_to_machine(pfn) != mfn)
/* /*
* If this appears to be a foreign mfn (because the pfn * If this appears to be a foreign mfn (because the pfn
* doesn't map back to the mfn), then check the local override * doesn't map back to the mfn), then check the local override
* table to see if there's a better pfn to use. * table to see if there's a better pfn to use.
*
* m2p_find_override_pfn returns ~0 if it doesn't find anything.
*/ */
if (get_phys_to_machine(pfn) != mfn) pfn = m2p_find_override_pfn(mfn, ~0);
pfn = m2p_find_override_pfn(mfn, pfn);
/*
* pfn is ~0 if there are no entries in the m2p for mfn or if the
* entry doesn't map back to the mfn and m2p_override doesn't have a
* valid entry for it.
*/
if (pfn == ~0 &&
get_phys_to_machine(mfn) == IDENTITY_FRAME(mfn))
pfn = mfn;
return pfn; return pfn;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment