diff options
author | Stefano Stabellini <stefano.stabellini@eu.citrix.com> | 2014-09-10 18:49:48 -0400 |
---|---|---|
committer | Stefano Stabellini <stefano.stabellini@eu.citrix.com> | 2014-09-11 14:11:53 -0400 |
commit | d50582e06fd5a58281151e097ff68b02ca65cf2d (patch) | |
tree | 5f6de6110c13598515adf5d5d6d8a0ae86d858c9 | |
parent | 340720be32d458ee11d1117719a8e4b6b82981b2 (diff) |
xen/arm: remove mach_to_phys rbtree
Remove the rbtree used to keep track of machine to physical mappings:
the frontend can grant the same page multiple times, leading to errors
inserting or removing entries from the mach_to_phys tree.
Linux only needed to know the physical address corresponding to a given
machine address in swiotlb-xen. Now that swiotlb-xen can call the
xen_dma_* functions passing the machine address directly, we can remove
it.
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Tested-by: Denis Schneider <v1ne2go@gmail.com>
-rw-r--r-- | arch/arm/include/asm/xen/page.h | 9 | ||||
-rw-r--r-- | arch/arm/xen/p2m.c | 66 |
2 files changed, 1 insertions, 74 deletions
diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h index ded062f9b358..135c24a5ba26 100644 --- a/arch/arm/include/asm/xen/page.h +++ b/arch/arm/include/asm/xen/page.h | |||
@@ -33,7 +33,6 @@ typedef struct xpaddr { | |||
33 | #define INVALID_P2M_ENTRY (~0UL) | 33 | #define INVALID_P2M_ENTRY (~0UL) |
34 | 34 | ||
35 | unsigned long __pfn_to_mfn(unsigned long pfn); | 35 | unsigned long __pfn_to_mfn(unsigned long pfn); |
36 | unsigned long __mfn_to_pfn(unsigned long mfn); | ||
37 | extern struct rb_root phys_to_mach; | 36 | extern struct rb_root phys_to_mach; |
38 | 37 | ||
39 | static inline unsigned long pfn_to_mfn(unsigned long pfn) | 38 | static inline unsigned long pfn_to_mfn(unsigned long pfn) |
@@ -51,14 +50,6 @@ static inline unsigned long pfn_to_mfn(unsigned long pfn) | |||
51 | 50 | ||
52 | static inline unsigned long mfn_to_pfn(unsigned long mfn) | 51 | static inline unsigned long mfn_to_pfn(unsigned long mfn) |
53 | { | 52 | { |
54 | unsigned long pfn; | ||
55 | |||
56 | if (phys_to_mach.rb_node != NULL) { | ||
57 | pfn = __mfn_to_pfn(mfn); | ||
58 | if (pfn != INVALID_P2M_ENTRY) | ||
59 | return pfn; | ||
60 | } | ||
61 | |||
62 | return mfn; | 53 | return mfn; |
63 | } | 54 | } |
64 | 55 | ||
diff --git a/arch/arm/xen/p2m.c b/arch/arm/xen/p2m.c index 97baf4427817..054857776254 100644 --- a/arch/arm/xen/p2m.c +++ b/arch/arm/xen/p2m.c | |||
@@ -21,14 +21,12 @@ struct xen_p2m_entry { | |||
21 | unsigned long pfn; | 21 | unsigned long pfn; |
22 | unsigned long mfn; | 22 | unsigned long mfn; |
23 | unsigned long nr_pages; | 23 | unsigned long nr_pages; |
24 | struct rb_node rbnode_mach; | ||
25 | struct rb_node rbnode_phys; | 24 | struct rb_node rbnode_phys; |
26 | }; | 25 | }; |
27 | 26 | ||
28 | static rwlock_t p2m_lock; | 27 | static rwlock_t p2m_lock; |
29 | struct rb_root phys_to_mach = RB_ROOT; | 28 | struct rb_root phys_to_mach = RB_ROOT; |
30 | EXPORT_SYMBOL_GPL(phys_to_mach); | 29 | EXPORT_SYMBOL_GPL(phys_to_mach); |
31 | static struct rb_root mach_to_phys = RB_ROOT; | ||
32 | 30 | ||
33 | static int xen_add_phys_to_mach_entry(struct xen_p2m_entry *new) | 31 | static int xen_add_phys_to_mach_entry(struct xen_p2m_entry *new) |
34 | { | 32 | { |
@@ -41,8 +39,6 @@ static int xen_add_phys_to_mach_entry(struct xen_p2m_entry *new) | |||
41 | parent = *link; | 39 | parent = *link; |
42 | entry = rb_entry(parent, struct xen_p2m_entry, rbnode_phys); | 40 | entry = rb_entry(parent, struct xen_p2m_entry, rbnode_phys); |
43 | 41 | ||
44 | if (new->mfn == entry->mfn) | ||
45 | goto err_out; | ||
46 | if (new->pfn == entry->pfn) | 42 | if (new->pfn == entry->pfn) |
47 | goto err_out; | 43 | goto err_out; |
48 | 44 | ||
@@ -88,64 +84,6 @@ unsigned long __pfn_to_mfn(unsigned long pfn) | |||
88 | } | 84 | } |
89 | EXPORT_SYMBOL_GPL(__pfn_to_mfn); | 85 | EXPORT_SYMBOL_GPL(__pfn_to_mfn); |
90 | 86 | ||
91 | static int xen_add_mach_to_phys_entry(struct xen_p2m_entry *new) | ||
92 | { | ||
93 | struct rb_node **link = &mach_to_phys.rb_node; | ||
94 | struct rb_node *parent = NULL; | ||
95 | struct xen_p2m_entry *entry; | ||
96 | int rc = 0; | ||
97 | |||
98 | while (*link) { | ||
99 | parent = *link; | ||
100 | entry = rb_entry(parent, struct xen_p2m_entry, rbnode_mach); | ||
101 | |||
102 | if (new->mfn == entry->mfn) | ||
103 | goto err_out; | ||
104 | if (new->pfn == entry->pfn) | ||
105 | goto err_out; | ||
106 | |||
107 | if (new->mfn < entry->mfn) | ||
108 | link = &(*link)->rb_left; | ||
109 | else | ||
110 | link = &(*link)->rb_right; | ||
111 | } | ||
112 | rb_link_node(&new->rbnode_mach, parent, link); | ||
113 | rb_insert_color(&new->rbnode_mach, &mach_to_phys); | ||
114 | goto out; | ||
115 | |||
116 | err_out: | ||
117 | rc = -EINVAL; | ||
118 | pr_warn("%s: cannot add pfn=%pa -> mfn=%pa: pfn=%pa -> mfn=%pa already exists\n", | ||
119 | __func__, &new->pfn, &new->mfn, &entry->pfn, &entry->mfn); | ||
120 | out: | ||
121 | return rc; | ||
122 | } | ||
123 | |||
124 | unsigned long __mfn_to_pfn(unsigned long mfn) | ||
125 | { | ||
126 | struct rb_node *n = mach_to_phys.rb_node; | ||
127 | struct xen_p2m_entry *entry; | ||
128 | unsigned long irqflags; | ||
129 | |||
130 | read_lock_irqsave(&p2m_lock, irqflags); | ||
131 | while (n) { | ||
132 | entry = rb_entry(n, struct xen_p2m_entry, rbnode_mach); | ||
133 | if (entry->mfn <= mfn && | ||
134 | entry->mfn + entry->nr_pages > mfn) { | ||
135 | read_unlock_irqrestore(&p2m_lock, irqflags); | ||
136 | return entry->pfn + (mfn - entry->mfn); | ||
137 | } | ||
138 | if (mfn < entry->mfn) | ||
139 | n = n->rb_left; | ||
140 | else | ||
141 | n = n->rb_right; | ||
142 | } | ||
143 | read_unlock_irqrestore(&p2m_lock, irqflags); | ||
144 | |||
145 | return INVALID_P2M_ENTRY; | ||
146 | } | ||
147 | EXPORT_SYMBOL_GPL(__mfn_to_pfn); | ||
148 | |||
149 | int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops, | 87 | int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops, |
150 | struct gnttab_map_grant_ref *kmap_ops, | 88 | struct gnttab_map_grant_ref *kmap_ops, |
151 | struct page **pages, unsigned int count) | 89 | struct page **pages, unsigned int count) |
@@ -192,7 +130,6 @@ bool __set_phys_to_machine_multi(unsigned long pfn, | |||
192 | p2m_entry = rb_entry(n, struct xen_p2m_entry, rbnode_phys); | 130 | p2m_entry = rb_entry(n, struct xen_p2m_entry, rbnode_phys); |
193 | if (p2m_entry->pfn <= pfn && | 131 | if (p2m_entry->pfn <= pfn && |
194 | p2m_entry->pfn + p2m_entry->nr_pages > pfn) { | 132 | p2m_entry->pfn + p2m_entry->nr_pages > pfn) { |
195 | rb_erase(&p2m_entry->rbnode_mach, &mach_to_phys); | ||
196 | rb_erase(&p2m_entry->rbnode_phys, &phys_to_mach); | 133 | rb_erase(&p2m_entry->rbnode_phys, &phys_to_mach); |
197 | write_unlock_irqrestore(&p2m_lock, irqflags); | 134 | write_unlock_irqrestore(&p2m_lock, irqflags); |
198 | kfree(p2m_entry); | 135 | kfree(p2m_entry); |
@@ -217,8 +154,7 @@ bool __set_phys_to_machine_multi(unsigned long pfn, | |||
217 | p2m_entry->mfn = mfn; | 154 | p2m_entry->mfn = mfn; |
218 | 155 | ||
219 | write_lock_irqsave(&p2m_lock, irqflags); | 156 | write_lock_irqsave(&p2m_lock, irqflags); |
220 | if ((rc = xen_add_phys_to_mach_entry(p2m_entry) < 0) || | 157 | if ((rc = xen_add_phys_to_mach_entry(p2m_entry)) < 0) { |
221 | (rc = xen_add_mach_to_phys_entry(p2m_entry) < 0)) { | ||
222 | write_unlock_irqrestore(&p2m_lock, irqflags); | 158 | write_unlock_irqrestore(&p2m_lock, irqflags); |
223 | return false; | 159 | return false; |
224 | } | 160 | } |