From: Andrew Cooper <andrew.cooper3@citrix.com>
To: Xen-devel <xen-devel@lists.xen.org>
Cc: George Dunlap <george.dunlap@eu.citrix.com>,
Andrew Cooper <andrew.cooper3@citrix.com>,
Tim Deegan <tim@xen.org>, Jan Beulich <JBeulich@suse.com>
Subject: [PATCH v2 5/9] x86/pagewalk: Helpers for reserved bit handling
Date: Thu, 16 Mar 2017 16:31:39 +0000 [thread overview]
Message-ID: <1489681903-28119-6-git-send-email-andrew.cooper3@citrix.com> (raw)
In-Reply-To: <1489681903-28119-1-git-send-email-andrew.cooper3@citrix.com>
Some bits are unconditionally reserved in pagetable entries, or reserved
because of alignment restrictions. Other bits are reserved because of control
register configuration.
Introduce helpers which take an individual vcpu and guest pagetable entry, and
calculates whether any reserved bits are set.
While here, add a couple of newlines to aid readability.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: George Dunlap <george.dunlap@eu.citrix.com>
CC: Tim Deegan <tim@xen.org>
v2:
* Cleanup split out to earlier patches.
* Switch guest_supports_pse36() to take a domain, and inherit hardwares pse36
setting.
---
xen/include/asm-x86/cpufeature.h | 1 +
xen/include/asm-x86/guest_pt.h | 96 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 97 insertions(+)
diff --git a/xen/include/asm-x86/cpufeature.h b/xen/include/asm-x86/cpufeature.h
index 5978783..84cc51d 100644
--- a/xen/include/asm-x86/cpufeature.h
+++ b/xen/include/asm-x86/cpufeature.h
@@ -38,6 +38,7 @@
#define cpu_has_mtrr 1
#define cpu_has_pge 1
#define cpu_has_pat 1
+#define cpu_has_pse36 boot_cpu_has(X86_FEATURE_PSE36)
#define cpu_has_clflush boot_cpu_has(X86_FEATURE_CLFLUSH)
#define cpu_has_mmx 1
#define cpu_has_htt boot_cpu_has(X86_FEATURE_HTT)
diff --git a/xen/include/asm-x86/guest_pt.h b/xen/include/asm-x86/guest_pt.h
index 43061b7..4e5018d 100644
--- a/xen/include/asm-x86/guest_pt.h
+++ b/xen/include/asm-x86/guest_pt.h
@@ -42,6 +42,18 @@ gfn_to_paddr(gfn_t gfn)
#undef get_gfn
#define get_gfn(d, g, t) get_gfn_type((d), gfn_x(g), (t), P2M_ALLOC)
+/* Mask covering the reserved bits from superpage alignment. */
+#define SUPERPAGE_RSVD(bit) \
+ (((1ULL << (bit)) - 1) & ~(_PAGE_PSE_PAT | (_PAGE_PSE_PAT - 1)))
+
+static inline uint32_t fold_pse36(uint64_t val)
+{
+ return (val & ~(0x1ffULL << 13)) | ((val & (0x1ffULL << 32)) >> (32 - 13));
+}
+static inline uint64_t unfold_pse36(uint32_t val)
+{
+ return (val & ~(0x1ffULL << 13)) | ((val & (0x1ffULL << 13)) << (32 - 13));
+}
/* Types of the guest's page tables and access functions for them */
@@ -49,9 +61,13 @@ gfn_to_paddr(gfn_t gfn)
#define GUEST_L1_PAGETABLE_ENTRIES 1024
#define GUEST_L2_PAGETABLE_ENTRIES 1024
+
#define GUEST_L1_PAGETABLE_SHIFT 12
#define GUEST_L2_PAGETABLE_SHIFT 22
+#define GUEST_L1_PAGETABLE_RSVD 0
+#define GUEST_L2_PAGETABLE_RSVD 0
+
typedef uint32_t guest_intpte_t;
typedef struct { guest_intpte_t l1; } guest_l1e_t;
typedef struct { guest_intpte_t l2; } guest_l2e_t;
@@ -86,21 +102,39 @@ static inline guest_l2e_t guest_l2e_from_gfn(gfn_t gfn, u32 flags)
#else /* GUEST_PAGING_LEVELS != 2 */
#if GUEST_PAGING_LEVELS == 3
+
#define GUEST_L1_PAGETABLE_ENTRIES 512
#define GUEST_L2_PAGETABLE_ENTRIES 512
#define GUEST_L3_PAGETABLE_ENTRIES 4
+
#define GUEST_L1_PAGETABLE_SHIFT 12
#define GUEST_L2_PAGETABLE_SHIFT 21
#define GUEST_L3_PAGETABLE_SHIFT 30
+
+#define GUEST_L1_PAGETABLE_RSVD 0x7ff0000000000000UL
+#define GUEST_L2_PAGETABLE_RSVD 0x7ff0000000000000UL
+#define GUEST_L3_PAGETABLE_RSVD \
+ (0xfff0000000000000UL | _PAGE_GLOBAL | _PAGE_PSE | _PAGE_DIRTY | \
+ _PAGE_ACCESSED | _PAGE_USER | _PAGE_RW)
+
#else /* GUEST_PAGING_LEVELS == 4 */
+
#define GUEST_L1_PAGETABLE_ENTRIES 512
#define GUEST_L2_PAGETABLE_ENTRIES 512
#define GUEST_L3_PAGETABLE_ENTRIES 512
#define GUEST_L4_PAGETABLE_ENTRIES 512
+
#define GUEST_L1_PAGETABLE_SHIFT 12
#define GUEST_L2_PAGETABLE_SHIFT 21
#define GUEST_L3_PAGETABLE_SHIFT 30
#define GUEST_L4_PAGETABLE_SHIFT 39
+
+#define GUEST_L1_PAGETABLE_RSVD 0
+#define GUEST_L2_PAGETABLE_RSVD 0
+#define GUEST_L3_PAGETABLE_RSVD 0
+/* NB L4e._PAGE_GLOBAL is reserved for AMD, but ignored for Intel. */
+#define GUEST_L4_PAGETABLE_RSVD _PAGE_PSE
+
#endif
typedef l1_pgentry_t guest_l1e_t;
@@ -182,6 +216,21 @@ static inline bool guest_supports_l2_superpages(const struct vcpu *v)
|| (v->arch.hvm_vcpu.guest_cr[4] & X86_CR4_PSE)));
}
+static inline bool guest_supports_pse36(const struct domain *d)
+{
+ /*
+ * Only called in the context of 2-level guests, after
+ * guest_supports_l2_superpages() has indicated true.
+ *
+ * Once L2 superpages are active, here are no control register settings
+ * for the hardware pagewalk on the subject of PSE36. If the guest
+ * constructs a PSE36 superpage on capable hardware, it will function
+ * irrespective of whether the feature is advertised. Xen's model of
+ * performing a pagewalk should match.
+ */
+ return paging_mode_hap(d) && cpu_has_pse36;
+}
+
static inline bool guest_supports_l3_superpages(const struct domain *d)
{
/*
@@ -218,6 +267,53 @@ static inline bool guest_supports_nx(const struct vcpu *v)
#define _PAGE_INVALID_BITS _PAGE_INVALID_BIT
#endif
+/* Helpers for identifying whether guest entries have reserved bits set. */
+
+/* Bits reserved because of maxphysaddr, and (lack of) EFER.NX */
+static inline uint64_t guest_rsvd_bits(const struct vcpu *v)
+{
+ return ((PADDR_MASK &
+ ~((1UL << v->domain->arch.cpuid->extd.maxphysaddr) - 1)) |
+ (guest_supports_nx(v) ? 0 : put_pte_flags(_PAGE_NX_BIT)));
+}
+
+static inline bool guest_l1e_rsvd_bits(const struct vcpu *v, guest_l1e_t l1e)
+{
+ return l1e.l1 & (guest_rsvd_bits(v) | GUEST_L1_PAGETABLE_RSVD);
+}
+
+static inline bool guest_l2e_rsvd_bits(const struct vcpu *v, guest_l2e_t l2e)
+{
+ uint64_t rsvd_bits = guest_rsvd_bits(v);
+
+ return ((l2e.l2 & (rsvd_bits | GUEST_L2_PAGETABLE_RSVD |
+ (guest_supports_l2_superpages(v) ? 0 : _PAGE_PSE))) ||
+ ((l2e.l2 & _PAGE_PSE) &&
+ (l2e.l2 & ((GUEST_PAGING_LEVELS == 2 &&
+ guest_supports_pse36(v->domain))
+ /* PSE36 tops out at 40 bits of address width. */
+ ? (fold_pse36(rsvd_bits | (1ULL << 40)))
+ : SUPERPAGE_RSVD(GUEST_L2_PAGETABLE_SHIFT)))));
+}
+
+#if GUEST_PAGING_LEVELS >= 3
+static inline bool guest_l3e_rsvd_bits(const struct vcpu *v, guest_l3e_t l3e)
+{
+ return ((l3e.l3 & (guest_rsvd_bits(v) | GUEST_L3_PAGETABLE_RSVD |
+ (guest_supports_l3_superpages(v->domain) ? 0 : _PAGE_PSE))) ||
+ ((l3e.l3 & _PAGE_PSE) &&
+ (l3e.l3 & SUPERPAGE_RSVD(GUEST_L3_PAGETABLE_SHIFT))));
+}
+
+#if GUEST_PAGING_LEVELS >= 4
+static inline bool guest_l4e_rsvd_bits(const struct vcpu *v, guest_l4e_t l4e)
+{
+ return l4e.l4 & (guest_rsvd_bits(v) | GUEST_L4_PAGETABLE_RSVD |
+ ((v->domain->arch.cpuid->x86_vendor == X86_VENDOR_AMD)
+ ? _PAGE_GLOBAL : 0));
+}
+#endif /* GUEST_PAGING_LEVELS >= 4 */
+#endif /* GUEST_PAGING_LEVELS >= 3 */
/* Type used for recording a walk through guest pagetables. It is
* filled in by the pagetable walk function, and also used as a cache
--
2.1.4
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
next prev parent reply other threads:[~2017-03-16 16:31 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-03-16 16:31 [PATCH v2 0/9] Fixes to pagetable handling Andrew Cooper
2017-03-16 16:31 ` [PATCH v2 1/9] x86/cpuid: Sort cpu_has_* predicates by feature number Andrew Cooper
2017-03-17 16:08 ` Jan Beulich
2017-03-16 16:31 ` [PATCH v2 2/9] x86/pagewalk: Use pointer syntax for pfec parameter Andrew Cooper
2017-03-17 16:09 ` Jan Beulich
2017-03-20 11:29 ` George Dunlap
2017-03-23 16:28 ` Tim Deegan
2017-03-16 16:31 ` [PATCH v2 3/9] x86/shadow: Drop VALID_GFN() Andrew Cooper
2017-03-23 16:30 ` Tim Deegan
2017-03-16 16:31 ` [PATCH v2 4/9] x86/pagewalk: Clean up guest_supports_* predicates Andrew Cooper
2017-03-20 8:45 ` Jan Beulich
2017-03-20 13:36 ` Andrew Cooper
2017-03-20 13:59 ` Jan Beulich
2017-03-23 17:32 ` Andrew Cooper
2017-03-24 7:19 ` Jan Beulich
2017-03-23 16:34 ` Tim Deegan
2017-03-16 16:31 ` Andrew Cooper [this message]
2017-03-20 8:48 ` [PATCH v2 5/9] x86/pagewalk: Helpers for reserved bit handling Jan Beulich
2017-03-23 16:55 ` Tim Deegan
2017-03-23 17:02 ` Andrew Cooper
2017-03-23 17:12 ` Tim Deegan
2017-03-23 17:35 ` Andrew Cooper
2017-03-24 5:45 ` Juergen Gross
2017-03-24 7:51 ` Jan Beulich
[not found] ` <58D4DDFF0200007800147138@suse.com>
2017-03-24 7:58 ` Juergen Gross
2017-03-24 8:25 ` Jan Beulich
2017-03-24 9:06 ` Andrew Cooper
2017-03-24 7:47 ` Jan Beulich
2017-03-24 8:36 ` Andrew Cooper
2017-03-16 16:31 ` [PATCH v2 6/9] x86/pagewalk: Re-implement the pagetable walker Andrew Cooper
2017-03-16 16:31 ` [PATCH v2 7/9] x86/shadow: Use the pagewalk reserved bits helpers Andrew Cooper
2017-03-16 17:25 ` Andrew Cooper
2017-03-20 8:53 ` Jan Beulich
2017-03-23 16:57 ` Tim Deegan
2017-03-16 16:31 ` [PATCH v2 8/9] x86/pagewalk: Improve the logic behind setting access and dirty bits Andrew Cooper
2017-03-20 9:03 ` Jan Beulich
2017-03-23 17:09 ` Tim Deegan
2017-03-23 17:40 ` Andrew Cooper
2017-03-16 16:31 ` [PATCH v2 9/9] x86/pagewalk: non-functional cleanup Andrew Cooper
2017-03-20 9:04 ` Jan Beulich
2017-03-23 17:10 ` Tim Deegan
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=1489681903-28119-6-git-send-email-andrew.cooper3@citrix.com \
--to=andrew.cooper3@citrix.com \
--cc=JBeulich@suse.com \
--cc=george.dunlap@eu.citrix.com \
--cc=tim@xen.org \
--cc=xen-devel@lists.xen.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).