All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexandre Chartre <alexandre.chartre@oracle.com>
To: tglx@linutronix.de, mingo@redhat.com, bp@alien8.de,
	hpa@zytor.com, dave.hansen@linux.intel.com, luto@kernel.org,
	peterz@infradead.org, x86@kernel.org, linux-mm@kvack.org,
	linux-kernel@vger.kernel.org
Cc: pbonzini@redhat.com, konrad.wilk@oracle.com,
	jan.setjeeilers@oracle.com, liran.alon@oracle.com,
	junaids@google.com, graf@amazon.de, rppt@linux.vnet.ibm.com,
	kuzuno@gmail.com, mgross@linux.intel.com,
	alexandre.chartre@oracle.com
Subject: [RFC v4][PATCH part-2 08/13] mm/dpt: Keep track of VA ranges mapped in a decorated page-table
Date: Mon,  4 May 2020 16:58:05 +0200	[thread overview]
Message-ID: <20200504145810.11882-9-alexandre.chartre@oracle.com> (raw)
In-Reply-To: <20200504145810.11882-1-alexandre.chartre@oracle.com>

Add functions to keep track of VA ranges mapped in a decorated page-table.
This will be used when unmapping to ensure the same range is unmapped,
at the same page-table level. This will also be used to handle mapping
and unmapping of overlapping VA ranges.

Signed-off-by: Alexandre Chartre <alexandre.chartre@oracle.com>
---
 arch/x86/include/asm/dpt.h | 12 ++++++++
 arch/x86/mm/dpt.c          | 60 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 72 insertions(+)

diff --git a/arch/x86/include/asm/dpt.h b/arch/x86/include/asm/dpt.h
index 5a38d97a70a8..0d74afb10141 100644
--- a/arch/x86/include/asm/dpt.h
+++ b/arch/x86/include/asm/dpt.h
@@ -16,6 +16,17 @@ enum page_table_level {
 	PGT_LEVEL_PGD
 };
 
+/*
+ * Structure to keep track of address ranges mapped into a decorated
+ * page-table.
+ */
+struct dpt_range_mapping {
+	struct list_head list;
+	void *ptr;			/* range start address */
+	size_t size;			/* range size */
+	enum page_table_level level;	/* mapping level */
+};
+
 /*
  * A decorated page-table (dpt) encapsulates a native page-table (e.g.
  * a PGD) and maintain additional attributes related to this page-table.
@@ -24,6 +35,7 @@ struct dpt {
 	spinlock_t		lock;		/* protect all attributes */
 	pgd_t			*pagetable;	/* the actual page-table */
 	unsigned int		alignment;	/* page-table alignment */
+	struct list_head	mapping_list;	/* list of VA range mapping */
 
 	/*
 	 * A page-table can have direct references to another page-table,
diff --git a/arch/x86/mm/dpt.c b/arch/x86/mm/dpt.c
index 0e725344b921..12eb0d794d84 100644
--- a/arch/x86/mm/dpt.c
+++ b/arch/x86/mm/dpt.c
@@ -59,6 +59,24 @@ static int dpt_add_backend_page(struct dpt *dpt, void *addr,
 	return 0;
 }
 
+/*
+ * Return the range mapping starting at the specified address, or NULL if
+ * no such range is found.
+ */
+static struct dpt_range_mapping *dpt_get_range_mapping(struct dpt *dpt,
+						       void *ptr)
+{
+	struct dpt_range_mapping *range;
+
+	lockdep_assert_held(&dpt->lock);
+	list_for_each_entry(range, &dpt->mapping_list, list) {
+		if (range->ptr == ptr)
+			return range;
+	}
+
+	return NULL;
+}
+
 /*
  * Check if an offset in the page-table is valid, i.e. check that the
  * offset is on a page effectively belonging to the page-table.
@@ -563,6 +581,7 @@ static int dpt_copy_pgd_range(struct dpt *dpt,
 int dpt_map_range(struct dpt *dpt, void *ptr, size_t size,
 		  enum page_table_level level)
 {
+	struct dpt_range_mapping *range_mapping;
 	unsigned long addr = (unsigned long)ptr;
 	unsigned long end = addr + ((unsigned long)size);
 	unsigned long flags;
@@ -571,8 +590,36 @@ int dpt_map_range(struct dpt *dpt, void *ptr, size_t size,
 	pr_debug("DPT %p: MAP %px/%lx/%d\n", dpt, ptr, size, level);
 
 	spin_lock_irqsave(&dpt->lock, flags);
+
+	/* check if the range is already mapped */
+	range_mapping = dpt_get_range_mapping(dpt, ptr);
+	if (range_mapping) {
+		pr_debug("DPT %p: MAP %px/%lx/%d already mapped\n",
+			 dpt, ptr, size, level);
+		err = -EBUSY;
+		goto done;
+	}
+
+	/* map new range */
+	range_mapping = kmalloc(sizeof(*range_mapping), GFP_KERNEL);
+	if (!range_mapping) {
+		err = -ENOMEM;
+		goto done;
+	}
+
 	err = dpt_copy_pgd_range(dpt, dpt->pagetable, current->mm->pgd,
 				 addr, end, level);
+	if (err) {
+		kfree(range_mapping);
+		goto done;
+	}
+
+	INIT_LIST_HEAD(&range_mapping->list);
+	range_mapping->ptr = ptr;
+	range_mapping->size = size;
+	range_mapping->level = level;
+	list_add(&range_mapping->list, &dpt->mapping_list);
+done:
 	spin_unlock_irqrestore(&dpt->lock, flags);
 
 	return err;
@@ -611,6 +658,8 @@ struct dpt *dpt_create(unsigned int pgt_alignment)
 	if (!dpt)
 		return NULL;
 
+	INIT_LIST_HEAD(&dpt->mapping_list);
+
 	pagetable = (unsigned long)__get_free_pages(GFP_KERNEL_ACCOUNT |
 						    __GFP_ZERO,
 						    alloc_order);
@@ -632,6 +681,7 @@ void dpt_destroy(struct dpt *dpt)
 {
 	unsigned int pgt_alignment;
 	unsigned int alloc_order;
+	struct dpt_range_mapping *range, *range_next;
 	unsigned long index;
 	void *entry;
 
@@ -643,6 +693,16 @@ void dpt_destroy(struct dpt *dpt)
 			free_page((unsigned long)DPT_BACKEND_PAGE_ADDR(entry));
 	}
 
+	list_for_each_entry_safe(range, range_next, &dpt->mapping_list, list) {
+		list_del(&range->list);
+		kfree(range);
+	}
+
+	if (dpt->backend_pages_count) {
+		xa_for_each(&dpt->backend_pages, index, entry)
+			free_page((unsigned long)DPT_BACKEND_PAGE_ADDR(entry));
+	}
+
 	if (dpt->pagetable) {
 		pgt_alignment = dpt->alignment;
 		alloc_order = round_up(PAGE_SIZE + pgt_alignment,
-- 
2.18.2


  parent reply	other threads:[~2020-05-04 15:00 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-04 14:57 [RFC v4][PATCH part-2 00/13] ASI - Part II (Decorated Page-Table) Alexandre Chartre
2020-05-04 14:57 ` [RFC v4][PATCH part-2 01/13] mm/x86: Introduce decorated page-table (dpt) Alexandre Chartre
2020-05-04 14:57 ` [RFC v4][PATCH part-2 02/13] mm/dpt: Track buffers allocated for a decorated page-table Alexandre Chartre
2020-05-04 14:58 ` [RFC v4][PATCH part-2 03/13] mm/dpt: Add decorated page-table entry offset functions Alexandre Chartre
2020-05-04 14:58 ` [RFC v4][PATCH part-2 04/13] mm/dpt: Add decorated page-table entry allocation functions Alexandre Chartre
2020-05-04 14:58 ` [RFC v4][PATCH part-2 05/13] mm/dpt: Add decorated page-table entry set functions Alexandre Chartre
2020-05-04 14:58 ` [RFC v4][PATCH part-2 06/13] mm/dpt: Functions to populate a decorated page-table from a VA range Alexandre Chartre
2020-05-04 14:58 ` [RFC v4][PATCH part-2 07/13] mm/dpt: Helper functions to map module into a decorated page-table Alexandre Chartre
2020-05-04 14:58 ` Alexandre Chartre [this message]
2020-05-04 14:58 ` [RFC v4][PATCH part-2 09/13] mm/dpt: Functions to clear decorated page-table entries for a VA range Alexandre Chartre
2020-05-04 14:58 ` [RFC v4][PATCH part-2 10/13] mm/dpt: Function to copy page-table entries for percpu buffer Alexandre Chartre
2020-05-04 14:58 ` [RFC v4][PATCH part-2 11/13] mm/dpt: Add decorated page-table remap function Alexandre Chartre
2020-05-04 14:58 ` [RFC v4][PATCH part-2 12/13] mm/dpt: Handle decorated page-table mapped range leaks and overlaps Alexandre Chartre
2020-05-04 14:58 ` [RFC v4][PATCH part-2 13/13] mm/asi: Function to init decorated page-table with ASI core mappings Alexandre Chartre
2020-05-14  9:29 ` [RFC v4][PATCH part-2 00/13] ASI - Part II (Decorated Page-Table) Mike Rapoport
2020-05-14 11:42   ` Alexandre Chartre

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200504145810.11882-9-alexandre.chartre@oracle.com \
    --to=alexandre.chartre@oracle.com \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=graf@amazon.de \
    --cc=hpa@zytor.com \
    --cc=jan.setjeeilers@oracle.com \
    --cc=junaids@google.com \
    --cc=konrad.wilk@oracle.com \
    --cc=kuzuno@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=liran.alon@oracle.com \
    --cc=luto@kernel.org \
    --cc=mgross@linux.intel.com \
    --cc=mingo@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peterz@infradead.org \
    --cc=rppt@linux.vnet.ibm.com \
    --cc=tglx@linutronix.de \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.