aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuergen Gross <jgross@suse.com>2014-12-05 07:28:04 -0500
committerDavid Vrabel <david.vrabel@citrix.com>2014-12-08 05:53:59 -0500
commit90fff3ea15a8fa6d2bd60cc0538d8ac33f14b692 (patch)
tree4626f1216f41e6074e2970aeb97086258f162981
parent2e917175e1ef147a527a9158b9f09773ec94c0bd (diff)
xen: introduce helper functions to do safe read and write accesses
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>
-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,
60extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn); 60extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn);
61 61
62/* 62/*
63 * Helper functions to write or read unsigned long values to/from
64 * memory, when the access may fault.
65 */
66static inline int xen_safe_write_ulong(unsigned long *addr, unsigned long val)
67{
68 return __put_user(val, (unsigned long __user *)addr);
69}
70
71static inline int xen_safe_read_ulong(unsigned long *addr, unsigned long *val)
72{
73 return __get_user(*val, (unsigned long __user *)addr);
74}
75
76/*
63 * When to use pfn_to_mfn(), __pfn_to_mfn() or get_phys_to_machine(): 77 * When to use pfn_to_mfn(), __pfn_to_mfn() or get_phys_to_machine():
64 * - pfn_to_mfn() returns either INVALID_P2M_ENTRY or the mfn. No indicator 78 * - pfn_to_mfn() returns either INVALID_P2M_ENTRY or the mfn. No indicator
65 * bits (identity or foreign) are set. 79 * bits (identity or foreign) are set.
@@ -125,7 +139,7 @@ static inline unsigned long mfn_to_pfn_no_overrides(unsigned long mfn)
125 * In such cases it doesn't matter what we return (we return garbage), 139 * In such cases it doesn't matter what we return (we return garbage),
126 * but we must handle the fault without crashing! 140 * but we must handle the fault without crashing!
127 */ 141 */
128 ret = __get_user(pfn, &machine_to_phys_mapping[mfn]); 142 ret = xen_safe_read_ulong(&machine_to_phys_mapping[mfn], &pfn);
129 if (ret < 0) 143 if (ret < 0)
130 return ~0; 144 return ~0;
131 145
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)
625 return true; 625 return true;
626 } 626 }
627 627
628 if (likely(!__put_user(mfn, xen_p2m_addr + pfn))) 628 if (likely(!xen_safe_write_ulong(xen_p2m_addr + pfn, mfn)))
629 return true; 629 return true;
630 630
631 ptep = lookup_address((unsigned long)(xen_p2m_addr + pfn), &level); 631 ptep = lookup_address((unsigned long)(xen_p2m_addr + pfn), &level);