Commit 57b77b75 authored by Qi Zheng's avatar Qi Zheng Committed by Andrew Morton
Browse files

s390: supplement for ptdesc conversion

After commit 6326c26c ("s390: convert various pgalloc functions to use
ptdescs"), there are still some positions that use page->{lru, index}
instead of ptdesc->{pt_list, pt_index}.  In order to make the use of
ptdesc->{pt_list, pt_index} clearer, it would be better to convert them as
well.

[zhengqi.arch@bytedance.com: fix build failure]
  Link: https://lkml.kernel.org/r/20240305072154.26168-1-zhengqi.arch@bytedance.com
Link: https://lkml.kernel.org/r/04beaf3255056ffe131a5ea595736066c1e84756.1709541697.git.zhengqi.arch@bytedance.com


Signed-off-by: default avatarQi Zheng <zhengqi.arch@bytedance.com>
Cc: Christian Borntraeger <borntraeger@linux.ibm.com>
Cc: Janosch Frank <frankja@linux.ibm.com>
Cc: Claudio Imbrenda <imbrenda@linux.ibm.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Mike Rapoport (IBM) <rppt@kernel.org>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Vishal Moola (Oracle) <vishal.moola@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent ea919671
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -23,9 +23,9 @@ unsigned long *crst_table_alloc(struct mm_struct *);
void crst_table_free(struct mm_struct *, unsigned long *);

unsigned long *page_table_alloc(struct mm_struct *);
struct page *page_table_alloc_pgste(struct mm_struct *mm);
struct ptdesc *page_table_alloc_pgste(struct mm_struct *mm);
void page_table_free(struct mm_struct *, unsigned long *);
void page_table_free_pgste(struct page *page);
void page_table_free_pgste(struct ptdesc *ptdesc);
extern int page_table_allocate_pgste;

static inline void crst_table_init(unsigned long *crst, unsigned long entry)
+20 −18
Original line number Diff line number Diff line
@@ -206,9 +206,11 @@ static void gmap_free(struct gmap *gmap)

	/* Free additional data for a shadow gmap */
	if (gmap_is_shadow(gmap)) {
		struct ptdesc *ptdesc, *n;

		/* Free all page tables. */
		list_for_each_entry_safe(page, next, &gmap->pt_list, lru)
			page_table_free_pgste(page);
		list_for_each_entry_safe(ptdesc, n, &gmap->pt_list, pt_list)
			page_table_free_pgste(ptdesc);
		gmap_rmap_radix_tree_free(&gmap->host_to_rmap);
		/* Release reference to the parent */
		gmap_put(gmap->parent);
@@ -1348,7 +1350,7 @@ static void gmap_unshadow_pgt(struct gmap *sg, unsigned long raddr)
{
	unsigned long *ste;
	phys_addr_t sto, pgt;
	struct page *page;
	struct ptdesc *ptdesc;

	BUG_ON(!gmap_is_shadow(sg));
	ste = gmap_table_walk(sg, raddr, 1); /* get segment pointer */
@@ -1361,9 +1363,9 @@ static void gmap_unshadow_pgt(struct gmap *sg, unsigned long raddr)
	*ste = _SEGMENT_ENTRY_EMPTY;
	__gmap_unshadow_pgt(sg, raddr, __va(pgt));
	/* Free page table */
	page = phys_to_page(pgt);
	list_del(&page->lru);
	page_table_free_pgste(page);
	ptdesc = page_ptdesc(phys_to_page(pgt));
	list_del(&ptdesc->pt_list);
	page_table_free_pgste(ptdesc);
}

/**
@@ -1377,7 +1379,7 @@ static void gmap_unshadow_pgt(struct gmap *sg, unsigned long raddr)
static void __gmap_unshadow_sgt(struct gmap *sg, unsigned long raddr,
				unsigned long *sgt)
{
	struct page *page;
	struct ptdesc *ptdesc;
	phys_addr_t pgt;
	int i;

@@ -1389,9 +1391,9 @@ static void __gmap_unshadow_sgt(struct gmap *sg, unsigned long raddr,
		sgt[i] = _SEGMENT_ENTRY_EMPTY;
		__gmap_unshadow_pgt(sg, raddr, __va(pgt));
		/* Free page table */
		page = phys_to_page(pgt);
		list_del(&page->lru);
		page_table_free_pgste(page);
		ptdesc = page_ptdesc(phys_to_page(pgt));
		list_del(&ptdesc->pt_list);
		page_table_free_pgste(ptdesc);
	}
}

@@ -2058,19 +2060,19 @@ int gmap_shadow_pgt(struct gmap *sg, unsigned long saddr, unsigned long pgt,
{
	unsigned long raddr, origin;
	unsigned long *table;
	struct page *page;
	struct ptdesc *ptdesc;
	phys_addr_t s_pgt;
	int rc;

	BUG_ON(!gmap_is_shadow(sg) || (pgt & _SEGMENT_ENTRY_LARGE));
	/* Allocate a shadow page table */
	page = page_table_alloc_pgste(sg->mm);
	if (!page)
	ptdesc = page_table_alloc_pgste(sg->mm);
	if (!ptdesc)
		return -ENOMEM;
	page->index = pgt & _SEGMENT_ENTRY_ORIGIN;
	ptdesc->pt_index = pgt & _SEGMENT_ENTRY_ORIGIN;
	if (fake)
		page->index |= GMAP_SHADOW_FAKE_TABLE;
	s_pgt = page_to_phys(page);
		ptdesc->pt_index |= GMAP_SHADOW_FAKE_TABLE;
	s_pgt = page_to_phys(ptdesc_page(ptdesc));
	/* Install shadow page table */
	spin_lock(&sg->guest_table_lock);
	table = gmap_table_walk(sg, saddr, 1); /* get segment pointer */
@@ -2088,7 +2090,7 @@ int gmap_shadow_pgt(struct gmap *sg, unsigned long saddr, unsigned long pgt,
	/* mark as invalid as long as the parent table is not protected */
	*table = (unsigned long) s_pgt | _SEGMENT_ENTRY |
		 (pgt & _SEGMENT_ENTRY_PROTECT) | _SEGMENT_ENTRY_INVALID;
	list_add(&page->lru, &sg->pt_list);
	list_add(&ptdesc->pt_list, &sg->pt_list);
	if (fake) {
		/* nothing to protect for fake tables */
		*table &= ~_SEGMENT_ENTRY_INVALID;
@@ -2114,7 +2116,7 @@ int gmap_shadow_pgt(struct gmap *sg, unsigned long saddr, unsigned long pgt,
	return rc;
out_free:
	spin_unlock(&sg->guest_table_lock);
	page_table_free_pgste(page);
	page_table_free_pgste(ptdesc);
	return rc;

}
+4 −4
Original line number Diff line number Diff line
@@ -135,7 +135,7 @@ int crst_table_upgrade(struct mm_struct *mm, unsigned long end)

#ifdef CONFIG_PGSTE

struct page *page_table_alloc_pgste(struct mm_struct *mm)
struct ptdesc *page_table_alloc_pgste(struct mm_struct *mm)
{
	struct ptdesc *ptdesc;
	u64 *table;
@@ -147,12 +147,12 @@ struct page *page_table_alloc_pgste(struct mm_struct *mm)
		memset64(table, _PAGE_INVALID, PTRS_PER_PTE);
		memset64(table + PTRS_PER_PTE, 0, PTRS_PER_PTE);
	}
	return ptdesc_page(ptdesc);
	return ptdesc;
}

void page_table_free_pgste(struct page *page)
void page_table_free_pgste(struct ptdesc *ptdesc)
{
	pagetable_free(page_ptdesc(page));
	pagetable_free(ptdesc);
}

#endif /* CONFIG_PGSTE */