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.
Unified · Split
| @@ -33,7 +33,6 @@ typedef struct xpaddr { · 32 unmodified lines | ||
| 33 | 33 | #define INVALID_P2M_ENTRY (~0UL) |
| 34 | 34 | |
| 35 | 35 | unsigned long __pfn_to_mfn(unsigned long pfn); |
| 36 | −unsigned long __mfn_to_pfn(unsigned long mfn); | |
| 37 | 36 | extern struct rb_root phys_to_mach; |
| 38 | 37 | |
| 39 | 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) · 11 unmodified lines | ||
| 51 | 50 | |
| 52 | 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 | 53 | return mfn; |
| 63 | 54 | } |
| 64 | 55 | |
| @@ -21,14 +21,12 @@ struct xen_p2m_entry { · 20 unmodified lines | ||
| 21 | 21 | unsigned long pfn; |
| 22 | 22 | unsigned long mfn; |
| 23 | 23 | unsigned long nr_pages; |
| 24 | − struct rb_node rbnode_mach; | |
| 25 | 24 | struct rb_node rbnode_phys; |
| 26 | 25 | }; |
| 27 | 26 | |
| 28 | 27 | static rwlock_t p2m_lock; |
| 29 | 28 | struct rb_root phys_to_mach = RB_ROOT; |
| 30 | 29 | EXPORT_SYMBOL_GPL(phys_to_mach); |
| 31 | −static struct rb_root mach_to_phys = RB_ROOT; | |
| 32 | 30 | |
| 33 | 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) · 6 unmodified lines | ||
| 41 | 39 | parent = *link; |
| 42 | 40 | entry = rb_entry(parent, struct xen_p2m_entry, rbnode_phys); |
| 43 | 41 | |
| 44 | − if (new->mfn == entry->mfn) | |
| 45 | − goto err_out; | |
| 46 | 42 | if (new->pfn == entry->pfn) |
| 47 | 43 | goto err_out; |
| 48 | 44 | |
| @@ -88,64 +84,6 @@ unsigned long __pfn_to_mfn(unsigned long pfn) · 39 unmodified lines | ||
| 88 | 84 | } |
| 89 | 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 | 87 | int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops, |
| 150 | 88 | struct gnttab_map_grant_ref *kmap_ops, |
| 151 | 89 | struct page **pages, unsigned int count) |
| @@ -192,7 +130,6 @@ bool __set_phys_to_machine_multi(unsigned long pfn, · 40 unmodified lines | ||
| 192 | 130 | p2m_entry = rb_entry(n, struct xen_p2m_entry, rbnode_phys); |
| 193 | 131 | if (p2m_entry->pfn <= pfn && |
| 194 | 132 | p2m_entry->pfn + p2m_entry->nr_pages > pfn) { |
| 195 | − rb_erase(&p2m_entry->rbnode_mach, &mach_to_phys); | |
| 196 | 133 | rb_erase(&p2m_entry->rbnode_phys, &phys_to_mach); |
| 197 | 134 | write_unlock_irqrestore(&p2m_lock, irqflags); |
| 198 | 135 | kfree(p2m_entry); |
| @@ -217,8 +154,7 @@ bool __set_phys_to_machine_multi(unsigned long pfn, · 18 unmodified lines | ||
| 217 | 154 | p2m_entry->mfn = mfn; |
| 218 | 155 | |
| 219 | 156 | write_lock_irqsave(&p2m_lock, irqflags); |
| 220 | − if ((rc = xen_add_phys_to_mach_entry(p2m_entry) < 0) || | |
| 221 | − (rc = xen_add_mach_to_phys_entry(p2m_entry) < 0)) { | |
| 157 | + if ((rc = xen_add_phys_to_mach_entry(p2m_entry)) < 0) { | |
| 222 | 158 | write_unlock_irqrestore(&p2m_lock, irqflags); |
| 223 | 159 | return false; |
| 224 | 160 | } |