All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Subject: [PULL 26/33] target/i386: extend pg_mode to more CR0 and CR4 bits
Date: Tue, 11 May 2021 04:13:43 -0400	[thread overview]
Message-ID: <20210511081350.419428-27-pbonzini@redhat.com> (raw)
In-Reply-To: <20210511081350.419428-1-pbonzini@redhat.com>

In order to unify the two stages of page table lookup, we need
mmu_translate to use either the host CR0/EFER/CR4 or the guest's.
To do so, make mmu_translate use the same pg_mode constants that
were used for the NPT lookup.

This also prepares for adding 5-level NPT support, which however does
not work yet.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/cpu.h                    |  8 +++++
 target/i386/tcg/sysemu/excp_helper.c | 45 ++++++++++++++++++----------
 target/i386/tcg/sysemu/svm_helper.c  |  2 +-
 3 files changed, 39 insertions(+), 16 deletions(-)

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index dbebd67f98..324ef92beb 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -307,6 +307,14 @@ typedef enum X86Seg {
 #define PG_MODE_LMA      (1 << 1)
 #define PG_MODE_NXE      (1 << 2)
 #define PG_MODE_PSE      (1 << 3)
+#define PG_MODE_LA57     (1 << 4)
+#define PG_MODE_SVM_MASK MAKE_64BIT_MASK(0, 15)
+
+/* Bits of CR4 that do not affect the NPT page format.  */
+#define PG_MODE_WP       (1 << 16)
+#define PG_MODE_PKE      (1 << 17)
+#define PG_MODE_PKS      (1 << 18)
+#define PG_MODE_SMEP     (1 << 19)
 
 #define MCG_CTL_P       (1ULL<<8)   /* MCG_CAP register available */
 #define MCG_SER_P       (1ULL<<24) /* MCA recovery/new status bits */
diff --git a/target/i386/tcg/sysemu/excp_helper.c b/target/i386/tcg/sysemu/excp_helper.c
index 4cf04f4e96..2b7baa0193 100644
--- a/target/i386/tcg/sysemu/excp_helper.c
+++ b/target/i386/tcg/sysemu/excp_helper.c
@@ -24,12 +24,27 @@
 int get_pg_mode(CPUX86State *env)
 {
     int pg_mode = 0;
+    if (env->cr[0] & CR0_WP_MASK) {
+        pg_mode |= PG_MODE_WP;
+    }
     if (env->cr[4] & CR4_PAE_MASK) {
         pg_mode |= PG_MODE_PAE;
     }
     if (env->cr[4] & CR4_PSE_MASK) {
         pg_mode |= PG_MODE_PSE;
     }
+    if (env->cr[4] & CR4_PKE_MASK) {
+        pg_mode |= PG_MODE_PKE;
+    }
+    if (env->cr[4] & CR4_PKS_MASK) {
+        pg_mode |= PG_MODE_PKS;
+    }
+    if (env->cr[4] & CR4_SMEP_MASK) {
+        pg_mode |= PG_MODE_SMEP;
+    }
+    if (env->cr[4] & CR4_LA57_MASK) {
+        pg_mode |= PG_MODE_LA57;
+    }
     if (env->hflags & HF_LMA_MASK) {
         pg_mode |= PG_MODE_LMA;
     }
@@ -246,7 +261,7 @@ static hwaddr get_hphys(CPUState *cs, hwaddr gphys, MMUAccessType access_type,
 #define PG_ERROR_OK (-1)
 
 static int mmu_translate(CPUState *cs, vaddr addr,
-                         uint64_t cr3, int is_write1, int mmu_idx,
+                         uint64_t cr3, int is_write1, int mmu_idx, int pg_mode,
                          vaddr *xlat, int *page_size, int *prot)
 {
     X86CPU *cpu = X86_CPU(cs);
@@ -264,17 +279,17 @@ static int mmu_translate(CPUState *cs, vaddr addr,
     is_write = is_write1 & 1;
     a20_mask = x86_get_a20_mask(env);
 
-    if (!(env->efer & MSR_EFER_NXE)) {
+    if (!(pg_mode & PG_MODE_NXE)) {
         rsvd_mask |= PG_NX_MASK;
     }
 
-    if (env->cr[4] & CR4_PAE_MASK) {
+    if (pg_mode & PG_MODE_PAE) {
         uint64_t pde, pdpe;
         target_ulong pdpe_addr;
 
 #ifdef TARGET_X86_64
         if (env->hflags & HF_LMA_MASK) {
-            bool la57 = env->cr[4] & CR4_LA57_MASK;
+            bool la57 = pg_mode & PG_MODE_LA57;
             uint64_t pml5e_addr, pml5e;
             uint64_t pml4e_addr, pml4e;
             int32_t sext;
@@ -413,7 +428,7 @@ static int mmu_translate(CPUState *cs, vaddr addr,
         ptep = pde | PG_NX_MASK;
 
         /* if PSE bit is set, then we use a 4MB page */
-        if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
+        if ((pde & PG_PSE_MASK) && (pg_mode & PG_MODE_PSE)) {
             *page_size = 4096 * 1024;
             pte_addr = pde_addr;
 
@@ -460,22 +475,22 @@ do_check_protect_pse36:
     *prot = 0;
     if (mmu_idx != MMU_KSMAP_IDX || !(ptep & PG_USER_MASK)) {
         *prot |= PAGE_READ;
-        if ((ptep & PG_RW_MASK) || (!is_user && !(env->cr[0] & CR0_WP_MASK))) {
+        if ((ptep & PG_RW_MASK) || !(is_user || (pg_mode & PG_MODE_WP))) {
             *prot |= PAGE_WRITE;
         }
     }
     if (!(ptep & PG_NX_MASK) &&
         (mmu_idx == MMU_USER_IDX ||
-         !((env->cr[4] & CR4_SMEP_MASK) && (ptep & PG_USER_MASK)))) {
+         !((pg_mode & PG_MODE_SMEP) && (ptep & PG_USER_MASK)))) {
         *prot |= PAGE_EXEC;
     }
 
     if (!(env->hflags & HF_LMA_MASK)) {
         pkr = 0;
     } else if (ptep & PG_USER_MASK) {
-        pkr = env->cr[4] & CR4_PKE_MASK ? env->pkru : 0;
+        pkr = pg_mode & PG_MODE_PKE ? env->pkru : 0;
     } else {
-        pkr = env->cr[4] & CR4_PKS_MASK ? env->pkrs : 0;
+        pkr = pg_mode & PG_MODE_PKS ? env->pkrs : 0;
     }
     if (pkr) {
         uint32_t pk = (pte & PG_PKRU_MASK) >> PG_PKRU_BIT;
@@ -485,7 +500,7 @@ do_check_protect_pse36:
 
         if (pkr_ad) {
             pkr_prot &= ~(PAGE_READ | PAGE_WRITE);
-        } else if (pkr_wd && (is_user || env->cr[0] & CR0_WP_MASK)) {
+        } else if (pkr_wd && (is_user || (pg_mode & PG_MODE_WP))) {
             pkr_prot &= ~PAGE_WRITE;
         }
 
@@ -535,9 +550,8 @@ do_check_protect_pse36:
     if (is_user)
         error_code |= PG_ERROR_U_MASK;
     if (is_write1 == 2 &&
-        (((env->efer & MSR_EFER_NXE) &&
-	  (env->cr[4] & CR4_PAE_MASK)) ||
-         (env->cr[4] & CR4_SMEP_MASK)))
+        (((pg_mode & PG_MODE_NXE) && (pg_mode & PG_MODE_PAE)) ||
+         (pg_mode & PG_MODE_SMEP)))
         error_code |= PG_ERROR_I_D_MASK;
     return error_code;
 }
@@ -553,7 +567,7 @@ static int handle_mmu_fault(CPUState *cs, vaddr addr, int size,
     X86CPU *cpu = X86_CPU(cs);
     CPUX86State *env = &cpu->env;
     int error_code = PG_ERROR_OK;
-    int prot, page_size;
+    int pg_mode, prot, page_size;
     hwaddr paddr;
     target_ulong vaddr;
 
@@ -573,8 +587,9 @@ static int handle_mmu_fault(CPUState *cs, vaddr addr, int size,
         prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
         page_size = 4096;
     } else {
+        pg_mode = get_pg_mode(env);
         error_code = mmu_translate(cs, addr, env->cr[3], is_write1,
-                                   mmu_idx,
+                                   mmu_idx, pg_mode,
                                    &paddr, &page_size, &prot);
     }
 
diff --git a/target/i386/tcg/sysemu/svm_helper.c b/target/i386/tcg/sysemu/svm_helper.c
index 4d81d341b8..c4e8e717a9 100644
--- a/target/i386/tcg/sysemu/svm_helper.c
+++ b/target/i386/tcg/sysemu/svm_helper.c
@@ -163,7 +163,7 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
                                                         control.nested_cr3));
         env->hflags2 |= HF2_NPT_MASK;
 
-        env->nested_pg_mode = get_pg_mode(env);
+        env->nested_pg_mode = get_pg_mode(env) & PG_MODE_SVM_MASK;
     }
 
     /* enable intercepts */
-- 
2.26.2




  parent reply	other threads:[~2021-05-11  8:37 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-11  8:13 [PULL 00/33] Misc (mostly i386) patches for 2021-05-11 Paolo Bonzini
2021-05-11  8:13 ` [PULL 01/33] target/i386: Rename helper_fldt, helper_fstt Paolo Bonzini
2021-05-11  8:13 ` [PULL 02/33] target/i386: Split out do_fsave, do_frstor, do_fxsave, do_fxrstor Paolo Bonzini
2021-05-11  8:13 ` [PULL 03/33] i386: split cpu accelerators from cpu.c, using AccelCPUClass Paolo Bonzini
2021-08-20 16:55   ` Peter Maydell
2021-08-20 17:02     ` Philippe Mathieu-Daudé
2021-08-20 17:10       ` Peter Maydell
2021-05-11  8:13 ` [PULL 04/33] cpu: call AccelCPUClass::cpu_realizefn in cpu_exec_realizefn Paolo Bonzini
2021-05-11  8:13 ` [PULL 05/33] accel: introduce new accessor functions Paolo Bonzini
2021-05-11  8:13 ` [PULL 06/33] target/i386: fix host_cpu_adjust_phys_bits error handling Paolo Bonzini
2021-05-11  8:13 ` [PULL 07/33] accel-cpu: make cpu_realizefn return a bool Paolo Bonzini
2021-05-11  8:13 ` [PULL 08/33] i386: split off sysemu-only functionality in tcg-cpu Paolo Bonzini
2021-05-11  8:13 ` [PULL 09/33] i386: split smm helper (sysemu) Paolo Bonzini
2021-05-11  8:13 ` [PULL 10/33] i386: split tcg excp_helper into sysemu and user parts Paolo Bonzini
2021-05-11  8:13 ` [PULL 11/33] i386: move TCG bpt_helper into sysemu/ Paolo Bonzini
2021-05-11  8:13 ` [PULL 12/33] i386: split misc helper user stubs and sysemu part Paolo Bonzini
2021-05-11  8:13 ` [PULL 13/33] i386: separate fpu_helper sysemu-only parts Paolo Bonzini
2021-05-11  8:13 ` [PULL 14/33] i386: split svm_helper into sysemu and stub-only user Paolo Bonzini
2021-05-11  8:13 ` [PULL 15/33] i386: split seg_helper into user-only and sysemu parts Paolo Bonzini
2021-05-11  8:13 ` [PULL 16/33] i386: split off sysemu part of cpu.c Paolo Bonzini
2021-05-11  8:13 ` [PULL 17/33] target/i386: gdbstub: introduce aux functions to read/write CS64 regs Paolo Bonzini
2021-05-11  8:13 ` [PULL 18/33] target/i386: gdbstub: only write CR0/CR2/CR3/EFER for sysemu Paolo Bonzini
2021-05-11  8:13 ` [PULL 19/33] i386: make cpu_load_efer sysemu-only Paolo Bonzini
2021-05-11  8:13 ` [PULL 20/33] accel: move call to accel_init_interfaces Paolo Bonzini
2021-05-11  8:13 ` [PULL 21/33] accel: add init_accel_cpu for adapting accel behavior to CPU type Paolo Bonzini
2021-05-11  8:13 ` [PULL 22/33] target/i386: merge SVM_NPTEXIT_* with PF_ERROR_* constants Paolo Bonzini
2021-05-11  8:13 ` [PULL 23/33] target/i386: move paging mode constants from SVM to cpu.h Paolo Bonzini
2021-05-11  8:13 ` [PULL 24/33] target/i386: extract mmu_translate Paolo Bonzini
2021-05-11  8:13 ` [PULL 25/33] target/i386: pass cr3 to mmu_translate Paolo Bonzini
2021-05-11  8:13 ` Paolo Bonzini [this message]
2021-05-11  8:13 ` [PULL 27/33] target/i386: allow customizing the next phase of the translation Paolo Bonzini
2021-05-11  8:13 ` [PULL 28/33] target/i386: use mmu_translate for NPT walk Paolo Bonzini
2021-05-11  8:13 ` [PULL 29/33] main-loop: remove dead code Paolo Bonzini
2021-05-11  8:13 ` [PULL 30/33] migration: do not restart VM after successful snapshot-load Paolo Bonzini
2021-05-11  8:56   ` Dr. David Alan Gilbert
2021-05-12  8:05     ` Paolo Bonzini
2021-05-11  9:09   ` Daniel P. Berrangé
2021-05-11 17:06   ` Daniel P. Berrangé
2021-05-12  7:45     ` Kevin Wolf
2021-05-12 18:11       ` Paolo Bonzini
2021-05-11  8:13 ` [PULL 31/33] qemu-option: support accept-any QemuOptsList in qemu_opts_absorb_qdict Paolo Bonzini
2021-05-11  8:13 ` [PULL 32/33] configure: fix detection of gdbus-codegen Paolo Bonzini
2021-05-11  8:13 ` [PULL 33/33] coverity-scan: list components, move model to scripts/coverity-scan Paolo Bonzini
2021-05-11  8:48 ` [PULL 00/33] Misc (mostly i386) patches for 2021-05-11 no-reply
2021-05-12 16:29 ` Peter Maydell

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=20210511081350.419428-27-pbonzini@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.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.