On 18.07.2018 07:32, Martin Schwidefsky wrote: > On Tue, 17 Jul 2018 21:43:03 +0200 > David Hildenbrand <david@xxxxxxxxxx> wrote: > >>> +/** >>> + * 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); >>> + pmdp_notify_gmap(gmap, pmdp, gaddr); >>> + WARN_ON(*entry & ~(_SEGMENT_ENTRY_HARDWARE_BITS_LARGE | >>> + _SEGMENT_ENTRY_GMAP_UC)); >>> + 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); >> >> So you didn't like my suggestion of factoring out the common code of >> gmap_pmdp_idte_local and gmap_pmdp_idte_global? They are almost >> identical except of the IDTE flag. > > The local flag is passed to the inline assembly with [m4] "i" (local). > The compiler has to pass in a *constant*, otherwise the compile will > fail. If you factor out the code the flag is not a constant anymore, no? > If we pass IDTE_GLOBAL/IDTE_LOCAL to that new function and make it always inline, that should work, no? Produced code will be the same but only one code instance to maintain. -- Thanks, David / dhildenb