> +/** > + * gmap_pmdp_idte_global - invalidate and clear a guest pmd entry > + * @mm: pointer to the process mm_struct > + * @vmaddr: virtual address in the process address space > + */ > +void gmap_pmdp_idte_global(struct mm_struct *mm, unsigned long vmaddr) > +{ > + unsigned long *entry, gaddr; > + struct gmap *gmap; > + pmd_t *pmdp; > + > + rcu_read_lock(); > + list_for_each_entry_rcu(gmap, &mm->context.gmap_list, list) { > + spin_lock(&gmap->guest_table_lock); > + entry = radix_tree_delete(&gmap->host_to_guest, > + vmaddr >> PMD_SHIFT); > + if (entry) { > + pmdp = (pmd_t *)entry; > + gaddr = __gmap_segment_gaddr(entry); > + WARN_ON(*entry & ~_SEGMENT_ENTRY_HARDWARE_BITS_LARGE); > + if (MACHINE_HAS_TLB_GUEST) > + __pmdp_idte(gaddr, pmdp, > + IDTE_GUEST_ASCE, > + gmap->asce, IDTE_GLOBAL); > + else if (MACHINE_HAS_IDTE) > + __pmdp_idte(gaddr, pmdp, 0, 0, > + IDTE_GLOBAL); > + else > + __pmdp_csp(pmdp); > + *entry = _SEGMENT_ENTRY_EMPTY; > + } > + spin_unlock(&gmap->guest_table_lock); > + } > + rcu_read_unlock(); > +} > +EXPORT_SYMBOL_GPL(gmap_pmdp_idte_global); AFAICS, gmap_pmdp_idte_local and gmap_pmdp_idte_global are 99% the same. Would it make sense to have a gmap_pmdp_idte() with an additional parameter (e.g. bool global or int idte_type) and let these two functions call it? (similar to gmap_pmdp_clear) Apart from that, looks good to me (not an expert of the different flushing mechanisms involved :) ) Acked-by: David Hildenbrand <david@xxxxxxxxxx> -- Thanks, David / dhildenb