xen: introduce helper functions to do safe read and write accesses
authorJuergen Gross <jgross@suse.com>
Fri, 5 Dec 2014 12:28:04 +0000 (13:28 +0100)
committerDavid Vrabel <david.vrabel@citrix.com>
Mon, 8 Dec 2014 10:53:59 +0000 (10:53 +0000)
Introduce two helper functions to safely read and write unsigned long
values from or to memory when the access may fault because the mapping
is non-present or read-only.

These helpers can be used instead of open coded uses of __get_user()
and __put_user() avoiding the need to do casts to fix sparse warnings.

Use the helpers in page.h and p2m.c. This will fix the sparse
warnings when doing "make C=1".

Signed-off-by: Juergen Gross <jgross@suse.com>
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
arch/x86/include/asm/xen/page.h
arch/x86/xen/p2m.c

index b54a3d20d6b2f3abca2ef9391cd3b426ab798497..5eea09915a158cdbf7fc24570010e3c211e050ec 100644 (file)
@@ -59,6 +59,20 @@ extern int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
                                     struct page **pages, unsigned int count);
 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
@@ -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;
 
index 8b5db51be4dd5b0cecb164336412d356a75498be..edbc7a63fd737f0ca13edac752e1f06341f9dd97 100644 (file)
@@ -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);