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 | } |
