From nobody Mon May 6 03:34:03 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; dkim=fail spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1494502589000345.2665468017643; Thu, 11 May 2017 04:36:29 -0700 (PDT) Received: from localhost ([::1]:47498 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d8mOR-0001rG-CD for importer@patchew.org; Thu, 11 May 2017 07:36:27 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37694) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d8mNc-0001Z3-Pp for qemu-devel@nongnu.org; Thu, 11 May 2017 07:35:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1d8mNY-0000cP-Mz for qemu-devel@nongnu.org; Thu, 11 May 2017 07:35:36 -0400 Received: from mail-wr0-x241.google.com ([2a00:1450:400c:c0c::241]:34677) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1d8mNY-0000bt-D5 for qemu-devel@nongnu.org; Thu, 11 May 2017 07:35:32 -0400 Received: by mail-wr0-x241.google.com with SMTP id 6so3141454wrb.1 for ; Thu, 11 May 2017 04:35:32 -0700 (PDT) Received: from 640k.lan (94-39-157-43.adsl-ull.clienti.tiscali.it. [94.39.157.43]) by smtp.gmail.com with ESMTPSA id 128sm6412487wmh.21.2017.05.11.04.35.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 11 May 2017 04:35:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id; bh=7ru70/ESWIL0bKtfFIkY0PPgH9NfLi/vgomYrzX6plQ=; b=mv+qA2gA6g8xEdV1bLNVDO/9tWNXP+hB+rqtj1c9zoquTc6ofOnwxQqkSkXKbYrcU7 ZwzC6nz0uWbvqtfe6DF6pJ7SEA+UHIvyCH4HVypMtHn9OBxyDWR3AMuHPzE7InXHyiBs T9zK/eeRDt81v4pX3KPo2NOv+HjQbPkbPEUCap6hp0nJmr2Zma3M94nHJK3lk7+brh/Z RfOlIgOGPQJbbR/4+L/BVf/I2CBvBcahVw4pAH+cd5dGd195r+upjCsh0kmCfSH6hP0R 6MiJEYEoEzYvZToq90y6QY6tJGNVpaD0WlnHRGONYUn47DffXc5PW1NXCJtdN0jvFSur /+jw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id; bh=7ru70/ESWIL0bKtfFIkY0PPgH9NfLi/vgomYrzX6plQ=; b=IUITCEYkRhX4ULW/nJv9cKnh9KMaSiKKQKf0dtxMIQZ5iqtwpLhQq6QcPP7g7pNgX9 9WXOX1o3kly6GjGG1ozecchBugsQPdd4R7zju3ec6flxiCfuW8qE9DTVIMr8ThwxAfFk TXB8aRHLKP/BfoOPaiVPPM8GO1UGghKjXK/kVKE60+38nlwqr6wFKwG4lAxwUEL8GnNo 1RIZrWVGSQeaC+pNztExd6QdTRtV/s/z111GWeFGKRMdBJb6y6XK6WH+GWhZzJ0SPA0M XcLjyyb1g1e99SNCuBRoQfaLiKj/h/CkCaOj0wDr29wSMeKM6+pOfo0E5AV2TlC4PEzp hx4g== X-Gm-Message-State: AODbwcDAuEMAx4jJsAL/bJ2tri81p2gwoidrJSQ2/ZU6Zl/CxjcYh2VF aSLymKchTSemJg== X-Received: by 10.223.182.152 with SMTP id j24mr6802426wre.152.1494502531095; Thu, 11 May 2017 04:35:31 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Thu, 11 May 2017 13:35:28 +0200 Message-Id: <1494502528-12670-1-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.8.3.1 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::241 Subject: [Qemu-devel] [PATCH] target/i386: enable A20 automatically in system management mode X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kevin@koconnor.net, anthony.xu@intel.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Ignore env->a20_mask when running in system management mode. Reported-by: Anthony Xu Signed-off-by: Paolo Bonzini --- target/i386/arch_memory_mapping.c | 18 +++++++++-------- target/i386/cpu.h | 9 +++++++++ target/i386/helper.c | 42 +++++++++++++++++++++--------------= ---- 3 files changed, 42 insertions(+), 27 deletions(-) diff --git a/target/i386/arch_memory_mapping.c b/target/i386/arch_memory_ma= pping.c index 826aee5..647cff2 100644 --- a/target/i386/arch_memory_mapping.c +++ b/target/i386/arch_memory_mapping.c @@ -272,25 +272,27 @@ void x86_cpu_get_memory_mapping(CPUState *cs, MemoryM= appingList *list, { X86CPU *cpu =3D X86_CPU(cs); CPUX86State *env =3D &cpu->env; + int32_t a20_mask; =20 if (!cpu_paging_enabled(cs)) { /* paging is disabled */ return; } =20 + a20_mask =3D x86_get_a20_mask(env); if (env->cr[4] & CR4_PAE_MASK) { #ifdef TARGET_X86_64 if (env->hflags & HF_LMA_MASK) { if (env->cr[4] & CR4_LA57_MASK) { hwaddr pml5e_addr; =20 - pml5e_addr =3D (env->cr[3] & PLM4_ADDR_MASK) & env->a20_ma= sk; - walk_pml5e(list, cs->as, pml5e_addr, env->a20_mask); + pml5e_addr =3D (env->cr[3] & PLM4_ADDR_MASK) & a20_mask; + walk_pml5e(list, cs->as, pml5e_addr, a20_mask); } else { hwaddr pml4e_addr; =20 - pml4e_addr =3D (env->cr[3] & PLM4_ADDR_MASK) & env->a20_ma= sk; - walk_pml4e(list, cs->as, pml4e_addr, env->a20_mask, + pml4e_addr =3D (env->cr[3] & PLM4_ADDR_MASK) & a20_mask; + walk_pml4e(list, cs->as, pml4e_addr, a20_mask, 0xffffULL << 48); } } else @@ -298,16 +300,16 @@ void x86_cpu_get_memory_mapping(CPUState *cs, MemoryM= appingList *list, { hwaddr pdpe_addr; =20 - pdpe_addr =3D (env->cr[3] & ~0x1f) & env->a20_mask; - walk_pdpe2(list, cs->as, pdpe_addr, env->a20_mask); + pdpe_addr =3D (env->cr[3] & ~0x1f) & a20_mask; + walk_pdpe2(list, cs->as, pdpe_addr, a20_mask); } } else { hwaddr pde_addr; bool pse; =20 - pde_addr =3D (env->cr[3] & ~0xfff) & env->a20_mask; + pde_addr =3D (env->cr[3] & ~0xfff) & a20_mask; pse =3D !!(env->cr[4] & CR4_PSE_MASK); - walk_pde2(list, cs->as, pde_addr, env->a20_mask, pse); + walk_pde2(list, cs->as, pde_addr, a20_mask, pse); } } =20 diff --git a/target/i386/cpu.h b/target/i386/cpu.h index c4602ca..ff93974 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -1624,6 +1624,15 @@ static inline MemTxAttrs cpu_get_mem_attrs(CPUX86Sta= te *env) return ((MemTxAttrs) { .secure =3D (env->hflags & HF_SMM_MASK) !=3D 0 = }); } =20 +static int32_t x86_get_a20_mask(CPUX86State *env) +{ + if (env->hflags & HF_SMM_MASK) { + return -1; + } else { + return env->a20_mask; + } +} + /* fpu_helper.c */ void cpu_set_mxcsr(CPUX86State *env, uint32_t val); void cpu_set_fpuc(CPUX86State *env, uint16_t val); diff --git a/target/i386/helper.c b/target/i386/helper.c index f11cac6..6c16e7c 100644 --- a/target/i386/helper.c +++ b/target/i386/helper.c @@ -724,6 +724,7 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr, X86CPU *cpu =3D X86_CPU(cs); CPUX86State *env =3D &cpu->env; uint64_t ptep, pte; + int32_t a20_mask; target_ulong pde_addr, pte_addr; int error_code =3D 0; int is_dirty, prot, page_size, is_write, is_user; @@ -739,6 +740,7 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr, #endif is_write =3D is_write1 & 1; =20 + a20_mask =3D x86_get_a20_mask(env); if (!(env->cr[0] & CR0_PG_MASK)) { pte =3D addr; #ifdef TARGET_X86_64 @@ -777,7 +779,7 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr, =20 if (la57) { pml5e_addr =3D ((env->cr[3] & ~0xfff) + - (((addr >> 48) & 0x1ff) << 3)) & env->a20_mask; + (((addr >> 48) & 0x1ff) << 3)) & a20_mask; pml5e =3D x86_ldq_phys(cs, pml5e_addr); if (!(pml5e & PG_PRESENT_MASK)) { goto do_fault; @@ -796,7 +798,7 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr, } =20 pml4e_addr =3D ((pml5e & PG_ADDRESS_MASK) + - (((addr >> 39) & 0x1ff) << 3)) & env->a20_mask; + (((addr >> 39) & 0x1ff) << 3)) & a20_mask; pml4e =3D x86_ldq_phys(cs, pml4e_addr); if (!(pml4e & PG_PRESENT_MASK)) { goto do_fault; @@ -810,7 +812,7 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr, } ptep &=3D pml4e ^ PG_NX_MASK; pdpe_addr =3D ((pml4e & PG_ADDRESS_MASK) + (((addr >> 30) & 0x= 1ff) << 3)) & - env->a20_mask; + a20_mask; pdpe =3D x86_ldq_phys(cs, pdpe_addr); if (!(pdpe & PG_PRESENT_MASK)) { goto do_fault; @@ -835,7 +837,7 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr, { /* XXX: load them when cr3 is loaded ? */ pdpe_addr =3D ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) & - env->a20_mask; + a20_mask; pdpe =3D x86_ldq_phys(cs, pdpe_addr); if (!(pdpe & PG_PRESENT_MASK)) { goto do_fault; @@ -848,7 +850,7 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr, } =20 pde_addr =3D ((pdpe & PG_ADDRESS_MASK) + (((addr >> 21) & 0x1ff) <= < 3)) & - env->a20_mask; + a20_mask; pde =3D x86_ldq_phys(cs, pde_addr); if (!(pde & PG_PRESENT_MASK)) { goto do_fault; @@ -870,7 +872,7 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr, x86_stl_phys_notdirty(cs, pde_addr, pde); } pte_addr =3D ((pde & PG_ADDRESS_MASK) + (((addr >> 12) & 0x1ff) <<= 3)) & - env->a20_mask; + a20_mask; pte =3D x86_ldq_phys(cs, pte_addr); if (!(pte & PG_PRESENT_MASK)) { goto do_fault; @@ -886,7 +888,7 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr, =20 /* page directory entry */ pde_addr =3D ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & - env->a20_mask; + a20_mask; pde =3D x86_ldl_phys(cs, pde_addr); if (!(pde & PG_PRESENT_MASK)) { goto do_fault; @@ -913,7 +915,7 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr, =20 /* page directory entry */ pte_addr =3D ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & - env->a20_mask; + a20_mask; pte =3D x86_ldl_phys(cs, pte_addr); if (!(pte & PG_PRESENT_MASK)) { goto do_fault; @@ -992,7 +994,7 @@ do_check_protect_pse36: } =20 do_mapping: - pte =3D pte & env->a20_mask; + pte =3D pte & a20_mask; =20 /* align to page_size */ pte &=3D PG_ADDRESS_MASK & ~(page_size - 1); @@ -1039,11 +1041,13 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, va= ddr addr) CPUX86State *env =3D &cpu->env; target_ulong pde_addr, pte_addr; uint64_t pte; + int32_t a20_mask; uint32_t page_offset; int page_size; =20 + a20_mask =3D x86_get_a20_mask(env); if (!(env->cr[0] & CR0_PG_MASK)) { - pte =3D addr & env->a20_mask; + pte =3D addr & a20_mask; page_size =3D 4096; } else if (env->cr[4] & CR4_PAE_MASK) { target_ulong pdpe_addr; @@ -1064,7 +1068,7 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vadd= r addr) =20 if (la57) { pml5e_addr =3D ((env->cr[3] & ~0xfff) + - (((addr >> 48) & 0x1ff) << 3)) & env->a20_mask; + (((addr >> 48) & 0x1ff) << 3)) & a20_mask; pml5e =3D x86_ldq_phys(cs, pml5e_addr); if (!(pml5e & PG_PRESENT_MASK)) { return -1; @@ -1074,13 +1078,13 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, va= ddr addr) } =20 pml4e_addr =3D ((pml5e & PG_ADDRESS_MASK) + - (((addr >> 39) & 0x1ff) << 3)) & env->a20_mask; + (((addr >> 39) & 0x1ff) << 3)) & a20_mask; pml4e =3D x86_ldq_phys(cs, pml4e_addr); if (!(pml4e & PG_PRESENT_MASK)) { return -1; } pdpe_addr =3D ((pml4e & PG_ADDRESS_MASK) + - (((addr >> 30) & 0x1ff) << 3)) & env->a20_mask; + (((addr >> 30) & 0x1ff) << 3)) & a20_mask; pdpe =3D x86_ldq_phys(cs, pdpe_addr); if (!(pdpe & PG_PRESENT_MASK)) { return -1; @@ -1095,14 +1099,14 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, va= ddr addr) #endif { pdpe_addr =3D ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) & - env->a20_mask; + a20_mask; pdpe =3D x86_ldq_phys(cs, pdpe_addr); if (!(pdpe & PG_PRESENT_MASK)) return -1; } =20 pde_addr =3D ((pdpe & PG_ADDRESS_MASK) + - (((addr >> 21) & 0x1ff) << 3)) & env->a20_mask; + (((addr >> 21) & 0x1ff) << 3)) & a20_mask; pde =3D x86_ldq_phys(cs, pde_addr); if (!(pde & PG_PRESENT_MASK)) { return -1; @@ -1114,7 +1118,7 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vadd= r addr) } else { /* 4 KB page */ pte_addr =3D ((pde & PG_ADDRESS_MASK) + - (((addr >> 12) & 0x1ff) << 3)) & env->a20_mask; + (((addr >> 12) & 0x1ff) << 3)) & a20_mask; page_size =3D 4096; pte =3D x86_ldq_phys(cs, pte_addr); } @@ -1125,7 +1129,7 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vadd= r addr) uint32_t pde; =20 /* page directory entry */ - pde_addr =3D ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & en= v->a20_mask; + pde_addr =3D ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & a2= 0_mask; pde =3D x86_ldl_phys(cs, pde_addr); if (!(pde & PG_PRESENT_MASK)) return -1; @@ -1134,14 +1138,14 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, va= ddr addr) page_size =3D 4096 * 1024; } else { /* page directory entry */ - pte_addr =3D ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->= a20_mask; + pte_addr =3D ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & a20_m= ask; pte =3D x86_ldl_phys(cs, pte_addr); if (!(pte & PG_PRESENT_MASK)) { return -1; } page_size =3D 4096; } - pte =3D pte & env->a20_mask; + pte =3D pte & a20_mask; } =20 #ifdef TARGET_X86_64 --=20 1.8.3.1