summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/xen/page.h16
-rw-r--r--arch/x86/xen/p2m.c2
2 files changed, 16 insertions, 2 deletions
diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h
index b54a3d20d6b2..5eea09915a15 100644
--- a/arch/x86/include/asm/xen/page.h
+++ b/arch/x86/include/asm/xen/page.h
@@ -60,6 +60,20 @@ extern int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn);
/*
+ * Helper functions to write or read unsigned long values to/from
+ * memory, when the access may fault.
+ */
+static inline int xen_safe_write_ulong(unsigned long *addr, unsigned long val)
+{
+ return __put_user(val, (unsigned long __user *)addr);
+}
+
+static inline int xen_safe_read_ulong(unsigned long *addr, unsigned long *val)
+{
+ return __get_user(*val, (unsigned long __user *)addr);
+}
+
+/*
* When to use pfn_to_mfn(), __pfn_to_mfn() or get_phys_to_machine():
* - pfn_to_mfn() returns either INVALID_P2M_ENTRY or the mfn. No indicator
* bits (identity or foreign) are set.
@@ -125,7 +139,7 @@ static inline unsigned long mfn_to_pfn_no_overrides(unsigned long mfn)
* In such cases it doesn't matter what we return (we return garbage),
* but we must handle the fault without crashing!
*/
- ret = __get_user(pfn, &machine_to_phys_mapping[mfn]);
+ ret = xen_safe_read_ulong(&machine_to_phys_mapping[mfn], &pfn);
if (ret < 0)
return ~0;
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c
index 8b5db51be4dd..edbc7a63fd73 100644
--- a/arch/x86/xen/p2m.c
+++ b/arch/x86/xen/p2m.c
@@ -625,7 +625,7 @@ bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn)
return true;
}
- if (likely(!__put_user(mfn, xen_p2m_addr + pfn)))
+ if (likely(!xen_safe_write_ulong(xen_p2m_addr + pfn, mfn)))
return true;
ptep = lookup_address((unsigned long)(xen_p2m_addr + pfn), &level);