if (slot) {
                rmap->next = radix_tree_deref_slot_protected(slot,
                                                        &sg->guest_table_lock);
-               radix_tree_replace_slot(slot, rmap);
+               radix_tree_replace_slot(&sg->host_to_rmap, slot, rmap);
        } else {
                rmap->next = NULL;
                radix_tree_insert(&sg->host_to_rmap, vmaddr >> PAGE_SHIFT,
 
 
                radix_tree_tag_clear(&d->tree, entry->enum_id,
                                     INTC_TAG_VIRQ_NEEDS_ALLOC);
-               radix_tree_replace_slot((void **)entries[i],
+               radix_tree_replace_slot(&d->tree, (void **)entries[i],
                                        &intc_irq_xlate[irq]);
        }
 
 
                radix_tree_deref_slot_protected(slot, &mapping->tree_lock);
 
        entry |= RADIX_DAX_ENTRY_LOCK;
-       radix_tree_replace_slot(slot, (void *)entry);
+       radix_tree_replace_slot(&mapping->page_tree, slot, (void *)entry);
        return (void *)entry;
 }
 
                radix_tree_deref_slot_protected(slot, &mapping->tree_lock);
 
        entry &= ~(unsigned long)RADIX_DAX_ENTRY_LOCK;
-       radix_tree_replace_slot(slot, (void *)entry);
+       radix_tree_replace_slot(&mapping->page_tree, slot, (void *)entry);
        return (void *)entry;
 }
 
 
        return unlikely((unsigned long)arg & RADIX_TREE_ENTRY_MASK);
 }
 
-/**
- * radix_tree_replace_slot     - replace item in a slot
- * @pslot:     pointer to slot, returned by radix_tree_lookup_slot
- * @item:      new item to store in the slot.
- *
- * For use with radix_tree_lookup_slot().  Caller must hold tree write locked
- * across slot lookup and replacement.
- */
-static inline void radix_tree_replace_slot(void **pslot, void *item)
-{
-       BUG_ON(radix_tree_is_internal_node(item));
-       rcu_assign_pointer(*pslot, item);
-}
-
 int __radix_tree_create(struct radix_tree_root *root, unsigned long index,
                        unsigned order, struct radix_tree_node **nodep,
                        void ***slotp);
 void __radix_tree_replace(struct radix_tree_root *root,
                          struct radix_tree_node *node,
                          void **slot, void *item);
+void radix_tree_replace_slot(struct radix_tree_root *root,
+                            void **slot, void *item);
 bool __radix_tree_delete_node(struct radix_tree_root *root,
                              struct radix_tree_node *node);
 void *radix_tree_delete_item(struct radix_tree_root *, unsigned long, void *);
 
 }
 EXPORT_SYMBOL(radix_tree_lookup);
 
-/**
- * __radix_tree_replace                - replace item in a slot
- * @root:      radix tree root
- * @node:      pointer to tree node
- * @slot:      pointer to slot in @node
- * @item:      new item to store in the slot.
- *
- * For use with __radix_tree_lookup().  Caller must hold tree write locked
- * across slot lookup and replacement.
- */
-void __radix_tree_replace(struct radix_tree_root *root,
-                         struct radix_tree_node *node,
-                         void **slot, void *item)
+static void replace_slot(struct radix_tree_root *root,
+                        struct radix_tree_node *node,
+                        void **slot, void *item,
+                        bool warn_typeswitch)
 {
        void *old = rcu_dereference_raw(*slot);
        int exceptional;
        exceptional = !!radix_tree_exceptional_entry(item) -
                      !!radix_tree_exceptional_entry(old);
 
-       WARN_ON_ONCE(exceptional && !node && slot != (void **)&root->rnode);
+       WARN_ON_ONCE(warn_typeswitch && exceptional);
 
        if (node)
                node->exceptional += exceptional;
        rcu_assign_pointer(*slot, item);
 }
 
+/**
+ * __radix_tree_replace                - replace item in a slot
+ * @root:      radix tree root
+ * @node:      pointer to tree node
+ * @slot:      pointer to slot in @node
+ * @item:      new item to store in the slot.
+ *
+ * For use with __radix_tree_lookup().  Caller must hold tree write locked
+ * across slot lookup and replacement.
+ */
+void __radix_tree_replace(struct radix_tree_root *root,
+                         struct radix_tree_node *node,
+                         void **slot, void *item)
+{
+       /*
+        * This function supports replacing exceptional entries, but
+        * that needs accounting against the node unless the slot is
+        * root->rnode.
+        */
+       replace_slot(root, node, slot, item,
+                    !node && slot != (void **)&root->rnode);
+}
+
+/**
+ * radix_tree_replace_slot     - replace item in a slot
+ * @root:      radix tree root
+ * @slot:      pointer to slot
+ * @item:      new item to store in the slot.
+ *
+ * For use with radix_tree_lookup_slot(), radix_tree_gang_lookup_slot(),
+ * radix_tree_gang_lookup_tag_slot().  Caller must hold tree write locked
+ * across slot lookup and replacement.
+ *
+ * NOTE: This cannot be used to switch between non-entries (empty slots),
+ * regular entries, and exceptional entries, as that requires accounting
+ * inside the radix tree node. When switching from one type of entry to
+ * another, use __radix_tree_lookup() and __radix_tree_replace().
+ */
+void radix_tree_replace_slot(struct radix_tree_root *root,
+                            void **slot, void *item)
+{
+       replace_slot(root, NULL, slot, item, true);
+}
+
 /**
  *     radix_tree_tag_set - set a tag on a radix tree node
  *     @root:          radix tree root
 
                                                      false);
                }
        }
-       radix_tree_replace_slot(slot, page);
+       radix_tree_replace_slot(&mapping->page_tree, slot, page);
        mapping->nrpages++;
        if (node) {
                workingset_node_pages_inc(node);
                        shadow = NULL;
                }
 
-               radix_tree_replace_slot(slot, shadow);
+               radix_tree_replace_slot(&mapping->page_tree, slot, shadow);
 
                if (!node)
                        break;
 
                list_add_tail(&page->lru, &pagelist);
 
                /* Finally, replace with the new page. */
-               radix_tree_replace_slot(slot,
+               radix_tree_replace_slot(&mapping->page_tree, slot,
                                new_page + (index % HPAGE_PMD_NR));
 
                slot = radix_tree_iter_next(&iter);
                        /* Unfreeze the page. */
                        list_del(&page->lru);
                        page_ref_unfreeze(page, 2);
-                       radix_tree_replace_slot(slot, page);
+                       radix_tree_replace_slot(&mapping->page_tree,
+                                               slot, page);
                        spin_unlock_irq(&mapping->tree_lock);
                        putback_lru_page(page);
                        unlock_page(page);
 
                SetPageDirty(newpage);
        }
 
-       radix_tree_replace_slot(pslot, newpage);
+       radix_tree_replace_slot(&mapping->page_tree, pslot, newpage);
 
        /*
         * Drop cache reference from old page by unfreezing
 
        get_page(newpage);
 
-       radix_tree_replace_slot(pslot, newpage);
+       radix_tree_replace_slot(&mapping->page_tree, pslot, newpage);
 
        page_ref_unfreeze(page, expected_count - 1);
 
 
                goto unlock;
        if (*slot != entry)
                goto unlock;
-       radix_tree_replace_slot(slot, NULL);
+       radix_tree_replace_slot(&mapping->page_tree, slot, NULL);
        mapping->nrexceptional--;
        if (!node)
                goto unlock;
 
 
        slot = radix_tree_lookup_slot(&tree, index);
        free(*slot);
-       radix_tree_replace_slot(slot, item2);
+       radix_tree_replace_slot(&tree, slot, item2);
        for (i = min; i < max; i++) {
                struct item *item = item_lookup(&tree, i);
                assert(item != 0);