xref: /openbmc/qemu/target/i386/helper.c (revision 28a43cb4)
1fcf5ef2aSThomas Huth /*
2fcf5ef2aSThomas Huth  *  i386 helpers (without register variable usage)
3fcf5ef2aSThomas Huth  *
4fcf5ef2aSThomas Huth  *  Copyright (c) 2003 Fabrice Bellard
5fcf5ef2aSThomas Huth  *
6fcf5ef2aSThomas Huth  * This library is free software; you can redistribute it and/or
7fcf5ef2aSThomas Huth  * modify it under the terms of the GNU Lesser General Public
8fcf5ef2aSThomas Huth  * License as published by the Free Software Foundation; either
9d9ff33adSChetan Pant  * version 2.1 of the License, or (at your option) any later version.
10fcf5ef2aSThomas Huth  *
11fcf5ef2aSThomas Huth  * This library is distributed in the hope that it will be useful,
12fcf5ef2aSThomas Huth  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13fcf5ef2aSThomas Huth  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14fcf5ef2aSThomas Huth  * Lesser General Public License for more details.
15fcf5ef2aSThomas Huth  *
16fcf5ef2aSThomas Huth  * You should have received a copy of the GNU Lesser General Public
17fcf5ef2aSThomas Huth  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18fcf5ef2aSThomas Huth  */
19fcf5ef2aSThomas Huth 
20fcf5ef2aSThomas Huth #include "qemu/osdep.h"
218efc4e51Szhenwei pi #include "qapi/qapi-events-run-state.h"
22fcf5ef2aSThomas Huth #include "cpu.h"
23fcf5ef2aSThomas Huth #include "exec/exec-all.h"
2454d31236SMarkus Armbruster #include "sysemu/runstate.h"
25fcf5ef2aSThomas Huth #ifndef CONFIG_USER_ONLY
26b3946626SVincent Palatin #include "sysemu/hw_accel.h"
27fcf5ef2aSThomas Huth #include "monitor/monitor.h"
28*28a43cb4SPhilippe Mathieu-Daudé #include "kvm/kvm_i386.h"
29fcf5ef2aSThomas Huth #endif
30cd617484SPhilippe Mathieu-Daudé #include "qemu/log.h"
31e5b49063SRichard Henderson #ifdef CONFIG_TCG
32747bd69dSRichard Henderson #include "tcg/insn-start-words.h"
33e5b49063SRichard Henderson #endif
34fcf5ef2aSThomas Huth 
cpu_sync_avx_hflag(CPUX86State * env)35608db8dbSPaul Brook void cpu_sync_avx_hflag(CPUX86State *env)
36608db8dbSPaul Brook {
37608db8dbSPaul Brook     if ((env->cr[4] & CR4_OSXSAVE_MASK)
38608db8dbSPaul Brook         && (env->xcr0 & (XSTATE_SSE_MASK | XSTATE_YMM_MASK))
39608db8dbSPaul Brook             == (XSTATE_SSE_MASK | XSTATE_YMM_MASK)) {
40608db8dbSPaul Brook         env->hflags |= HF_AVX_EN_MASK;
41608db8dbSPaul Brook     } else{
42608db8dbSPaul Brook         env->hflags &= ~HF_AVX_EN_MASK;
43608db8dbSPaul Brook     }
44608db8dbSPaul Brook }
45608db8dbSPaul Brook 
cpu_sync_bndcs_hflags(CPUX86State * env)46ab0a19d4SYang Zhong void cpu_sync_bndcs_hflags(CPUX86State *env)
47ab0a19d4SYang Zhong {
48ab0a19d4SYang Zhong     uint32_t hflags = env->hflags;
49ab0a19d4SYang Zhong     uint32_t hflags2 = env->hflags2;
50ab0a19d4SYang Zhong     uint32_t bndcsr;
51ab0a19d4SYang Zhong 
52ab0a19d4SYang Zhong     if ((hflags & HF_CPL_MASK) == 3) {
53ab0a19d4SYang Zhong         bndcsr = env->bndcs_regs.cfgu;
54ab0a19d4SYang Zhong     } else {
55ab0a19d4SYang Zhong         bndcsr = env->msr_bndcfgs;
56ab0a19d4SYang Zhong     }
57ab0a19d4SYang Zhong 
58ab0a19d4SYang Zhong     if ((env->cr[4] & CR4_OSXSAVE_MASK)
59ab0a19d4SYang Zhong         && (env->xcr0 & XSTATE_BNDCSR_MASK)
60ab0a19d4SYang Zhong         && (bndcsr & BNDCFG_ENABLE)) {
61ab0a19d4SYang Zhong         hflags |= HF_MPX_EN_MASK;
62ab0a19d4SYang Zhong     } else {
63ab0a19d4SYang Zhong         hflags &= ~HF_MPX_EN_MASK;
64ab0a19d4SYang Zhong     }
65ab0a19d4SYang Zhong 
66ab0a19d4SYang Zhong     if (bndcsr & BNDCFG_BNDPRESERVE) {
67ab0a19d4SYang Zhong         hflags2 |= HF2_MPX_PR_MASK;
68ab0a19d4SYang Zhong     } else {
69ab0a19d4SYang Zhong         hflags2 &= ~HF2_MPX_PR_MASK;
70ab0a19d4SYang Zhong     }
71ab0a19d4SYang Zhong 
72ab0a19d4SYang Zhong     env->hflags = hflags;
73ab0a19d4SYang Zhong     env->hflags2 = hflags2;
74ab0a19d4SYang Zhong }
75ab0a19d4SYang Zhong 
cpu_x86_version(CPUX86State * env,int * family,int * model)76fcf5ef2aSThomas Huth static void cpu_x86_version(CPUX86State *env, int *family, int *model)
77fcf5ef2aSThomas Huth {
78fcf5ef2aSThomas Huth     int cpuver = env->cpuid_version;
79fcf5ef2aSThomas Huth 
80fcf5ef2aSThomas Huth     if (family == NULL || model == NULL) {
81fcf5ef2aSThomas Huth         return;
82fcf5ef2aSThomas Huth     }
83fcf5ef2aSThomas Huth 
84fcf5ef2aSThomas Huth     *family = (cpuver >> 8) & 0x0f;
85fcf5ef2aSThomas Huth     *model = ((cpuver >> 12) & 0xf0) + ((cpuver >> 4) & 0x0f);
86fcf5ef2aSThomas Huth }
87fcf5ef2aSThomas Huth 
88fcf5ef2aSThomas Huth /* Broadcast MCA signal for processor version 06H_EH and above */
cpu_x86_support_mca_broadcast(CPUX86State * env)89fcf5ef2aSThomas Huth int cpu_x86_support_mca_broadcast(CPUX86State *env)
90fcf5ef2aSThomas Huth {
91fcf5ef2aSThomas Huth     int family = 0;
92fcf5ef2aSThomas Huth     int model = 0;
93fcf5ef2aSThomas Huth 
94fcf5ef2aSThomas Huth     cpu_x86_version(env, &family, &model);
95fcf5ef2aSThomas Huth     if ((family == 6 && model >= 14) || family > 6) {
96fcf5ef2aSThomas Huth         return 1;
97fcf5ef2aSThomas Huth     }
98fcf5ef2aSThomas Huth 
99fcf5ef2aSThomas Huth     return 0;
100fcf5ef2aSThomas Huth }
101fcf5ef2aSThomas Huth 
102fcf5ef2aSThomas Huth /***********************************************************/
103fcf5ef2aSThomas Huth /* x86 mmu */
104fcf5ef2aSThomas Huth /* XXX: add PGE support */
105fcf5ef2aSThomas Huth 
x86_cpu_set_a20(X86CPU * cpu,int a20_state)106fcf5ef2aSThomas Huth void x86_cpu_set_a20(X86CPU *cpu, int a20_state)
107fcf5ef2aSThomas Huth {
108fcf5ef2aSThomas Huth     CPUX86State *env = &cpu->env;
109fcf5ef2aSThomas Huth 
110fcf5ef2aSThomas Huth     a20_state = (a20_state != 0);
111fcf5ef2aSThomas Huth     if (a20_state != ((env->a20_mask >> 20) & 1)) {
112fcf5ef2aSThomas Huth         CPUState *cs = CPU(cpu);
113fcf5ef2aSThomas Huth 
114fcf5ef2aSThomas Huth         qemu_log_mask(CPU_LOG_MMU, "A20 update: a20=%d\n", a20_state);
115fcf5ef2aSThomas Huth         /* if the cpu is currently executing code, we must unlink it and
116fcf5ef2aSThomas Huth            all the potentially executing TB */
117fcf5ef2aSThomas Huth         cpu_interrupt(cs, CPU_INTERRUPT_EXITTB);
118fcf5ef2aSThomas Huth 
119fcf5ef2aSThomas Huth         /* when a20 is changed, all the MMU mappings are invalid, so
120fcf5ef2aSThomas Huth            we must flush everything */
121d10eb08fSAlex Bennée         tlb_flush(cs);
122fcf5ef2aSThomas Huth         env->a20_mask = ~(1 << 20) | (a20_state << 20);
123fcf5ef2aSThomas Huth     }
124fcf5ef2aSThomas Huth }
125fcf5ef2aSThomas Huth 
cpu_x86_update_cr0(CPUX86State * env,uint32_t new_cr0)126fcf5ef2aSThomas Huth void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
127fcf5ef2aSThomas Huth {
1286aa9e42fSRichard Henderson     X86CPU *cpu = env_archcpu(env);
129fcf5ef2aSThomas Huth     int pe_state;
130fcf5ef2aSThomas Huth 
131fcf5ef2aSThomas Huth     qemu_log_mask(CPU_LOG_MMU, "CR0 update: CR0=0x%08x\n", new_cr0);
132fcf5ef2aSThomas Huth     if ((new_cr0 & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK)) !=
133fcf5ef2aSThomas Huth         (env->cr[0] & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK))) {
134d10eb08fSAlex Bennée         tlb_flush(CPU(cpu));
135fcf5ef2aSThomas Huth     }
136fcf5ef2aSThomas Huth 
137fcf5ef2aSThomas Huth #ifdef TARGET_X86_64
138fcf5ef2aSThomas Huth     if (!(env->cr[0] & CR0_PG_MASK) && (new_cr0 & CR0_PG_MASK) &&
139fcf5ef2aSThomas Huth         (env->efer & MSR_EFER_LME)) {
140fcf5ef2aSThomas Huth         /* enter in long mode */
141fcf5ef2aSThomas Huth         /* XXX: generate an exception */
142fcf5ef2aSThomas Huth         if (!(env->cr[4] & CR4_PAE_MASK))
143fcf5ef2aSThomas Huth             return;
144fcf5ef2aSThomas Huth         env->efer |= MSR_EFER_LMA;
145fcf5ef2aSThomas Huth         env->hflags |= HF_LMA_MASK;
146fcf5ef2aSThomas Huth     } else if ((env->cr[0] & CR0_PG_MASK) && !(new_cr0 & CR0_PG_MASK) &&
147fcf5ef2aSThomas Huth                (env->efer & MSR_EFER_LMA)) {
148fcf5ef2aSThomas Huth         /* exit long mode */
149fcf5ef2aSThomas Huth         env->efer &= ~MSR_EFER_LMA;
150fcf5ef2aSThomas Huth         env->hflags &= ~(HF_LMA_MASK | HF_CS64_MASK);
151fcf5ef2aSThomas Huth         env->eip &= 0xffffffff;
152fcf5ef2aSThomas Huth     }
153fcf5ef2aSThomas Huth #endif
154fcf5ef2aSThomas Huth     env->cr[0] = new_cr0 | CR0_ET_MASK;
155fcf5ef2aSThomas Huth 
156fcf5ef2aSThomas Huth     /* update PE flag in hidden flags */
157fcf5ef2aSThomas Huth     pe_state = (env->cr[0] & CR0_PE_MASK);
158fcf5ef2aSThomas Huth     env->hflags = (env->hflags & ~HF_PE_MASK) | (pe_state << HF_PE_SHIFT);
159fcf5ef2aSThomas Huth     /* ensure that ADDSEG is always set in real mode */
160fcf5ef2aSThomas Huth     env->hflags |= ((pe_state ^ 1) << HF_ADDSEG_SHIFT);
161fcf5ef2aSThomas Huth     /* update FPU flags */
162fcf5ef2aSThomas Huth     env->hflags = (env->hflags & ~(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)) |
163fcf5ef2aSThomas Huth         ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
164fcf5ef2aSThomas Huth }
165fcf5ef2aSThomas Huth 
166fcf5ef2aSThomas Huth /* XXX: in legacy PAE mode, generate a GPF if reserved bits are set in
167fcf5ef2aSThomas Huth    the PDPT */
cpu_x86_update_cr3(CPUX86State * env,target_ulong new_cr3)168fcf5ef2aSThomas Huth void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3)
169fcf5ef2aSThomas Huth {
170fcf5ef2aSThomas Huth     env->cr[3] = new_cr3;
171fcf5ef2aSThomas Huth     if (env->cr[0] & CR0_PG_MASK) {
172fcf5ef2aSThomas Huth         qemu_log_mask(CPU_LOG_MMU,
173fcf5ef2aSThomas Huth                         "CR3 update: CR3=" TARGET_FMT_lx "\n", new_cr3);
1746aa9e42fSRichard Henderson         tlb_flush(env_cpu(env));
175fcf5ef2aSThomas Huth     }
176fcf5ef2aSThomas Huth }
177fcf5ef2aSThomas Huth 
cpu_x86_update_cr4(CPUX86State * env,uint32_t new_cr4)178fcf5ef2aSThomas Huth void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
179fcf5ef2aSThomas Huth {
180fcf5ef2aSThomas Huth     uint32_t hflags;
181fcf5ef2aSThomas Huth 
182fcf5ef2aSThomas Huth #if defined(DEBUG_MMU)
1836c7c3c21SKirill A. Shutemov     printf("CR4 update: %08x -> %08x\n", (uint32_t)env->cr[4], new_cr4);
184fcf5ef2aSThomas Huth #endif
185fcf5ef2aSThomas Huth     if ((new_cr4 ^ env->cr[4]) &
186fcf5ef2aSThomas Huth         (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK |
1876c7c3c21SKirill A. Shutemov          CR4_SMEP_MASK | CR4_SMAP_MASK | CR4_LA57_MASK)) {
1886aa9e42fSRichard Henderson         tlb_flush(env_cpu(env));
189fcf5ef2aSThomas Huth     }
190fcf5ef2aSThomas Huth 
191fcf5ef2aSThomas Huth     /* Clear bits we're going to recompute.  */
192637f1ee3SGareth Webb     hflags = env->hflags & ~(HF_OSFXSR_MASK | HF_SMAP_MASK | HF_UMIP_MASK);
193fcf5ef2aSThomas Huth 
194fcf5ef2aSThomas Huth     /* SSE handling */
195fcf5ef2aSThomas Huth     if (!(env->features[FEAT_1_EDX] & CPUID_SSE)) {
196fcf5ef2aSThomas Huth         new_cr4 &= ~CR4_OSFXSR_MASK;
197fcf5ef2aSThomas Huth     }
198fcf5ef2aSThomas Huth     if (new_cr4 & CR4_OSFXSR_MASK) {
199fcf5ef2aSThomas Huth         hflags |= HF_OSFXSR_MASK;
200fcf5ef2aSThomas Huth     }
201fcf5ef2aSThomas Huth 
202fcf5ef2aSThomas Huth     if (!(env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_SMAP)) {
203fcf5ef2aSThomas Huth         new_cr4 &= ~CR4_SMAP_MASK;
204fcf5ef2aSThomas Huth     }
205fcf5ef2aSThomas Huth     if (new_cr4 & CR4_SMAP_MASK) {
206fcf5ef2aSThomas Huth         hflags |= HF_SMAP_MASK;
207fcf5ef2aSThomas Huth     }
208637f1ee3SGareth Webb     if (!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_UMIP)) {
209637f1ee3SGareth Webb         new_cr4 &= ~CR4_UMIP_MASK;
210637f1ee3SGareth Webb     }
211637f1ee3SGareth Webb     if (new_cr4 & CR4_UMIP_MASK) {
212637f1ee3SGareth Webb         hflags |= HF_UMIP_MASK;
213637f1ee3SGareth Webb     }
214fcf5ef2aSThomas Huth 
215fcf5ef2aSThomas Huth     if (!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_PKU)) {
216fcf5ef2aSThomas Huth         new_cr4 &= ~CR4_PKE_MASK;
217fcf5ef2aSThomas Huth     }
218e7e7bdabSPaolo Bonzini     if (!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_PKS)) {
219e7e7bdabSPaolo Bonzini         new_cr4 &= ~CR4_PKS_MASK;
220e7e7bdabSPaolo Bonzini     }
221fcf5ef2aSThomas Huth 
222fcf5ef2aSThomas Huth     env->cr[4] = new_cr4;
223fcf5ef2aSThomas Huth     env->hflags = hflags;
224fcf5ef2aSThomas Huth 
225fcf5ef2aSThomas Huth     cpu_sync_bndcs_hflags(env);
226608db8dbSPaul Brook     cpu_sync_avx_hflag(env);
227fcf5ef2aSThomas Huth }
228fcf5ef2aSThomas Huth 
2296578eb25SPaolo Bonzini #if !defined(CONFIG_USER_ONLY)
x86_cpu_get_phys_page_attrs_debug(CPUState * cs,vaddr addr,MemTxAttrs * attrs)23056f99750SDmitry Poletaev hwaddr x86_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
23156f99750SDmitry Poletaev                                          MemTxAttrs *attrs)
232fcf5ef2aSThomas Huth {
233fcf5ef2aSThomas Huth     X86CPU *cpu = X86_CPU(cs);
234fcf5ef2aSThomas Huth     CPUX86State *env = &cpu->env;
235fcf5ef2aSThomas Huth     target_ulong pde_addr, pte_addr;
236fcf5ef2aSThomas Huth     uint64_t pte;
237c8bc83a4SPaolo Bonzini     int32_t a20_mask;
238fcf5ef2aSThomas Huth     uint32_t page_offset;
239fcf5ef2aSThomas Huth     int page_size;
240fcf5ef2aSThomas Huth 
24156f99750SDmitry Poletaev     *attrs = cpu_get_mem_attrs(env);
24256f99750SDmitry Poletaev 
243c8bc83a4SPaolo Bonzini     a20_mask = x86_get_a20_mask(env);
244fcf5ef2aSThomas Huth     if (!(env->cr[0] & CR0_PG_MASK)) {
245c8bc83a4SPaolo Bonzini         pte = addr & a20_mask;
246fcf5ef2aSThomas Huth         page_size = 4096;
247fcf5ef2aSThomas Huth     } else if (env->cr[4] & CR4_PAE_MASK) {
248fcf5ef2aSThomas Huth         target_ulong pdpe_addr;
249fcf5ef2aSThomas Huth         uint64_t pde, pdpe;
250fcf5ef2aSThomas Huth 
251fcf5ef2aSThomas Huth #ifdef TARGET_X86_64
252fcf5ef2aSThomas Huth         if (env->hflags & HF_LMA_MASK) {
2536c7c3c21SKirill A. Shutemov             bool la57 = env->cr[4] & CR4_LA57_MASK;
2546c7c3c21SKirill A. Shutemov             uint64_t pml5e_addr, pml5e;
255fcf5ef2aSThomas Huth             uint64_t pml4e_addr, pml4e;
256fcf5ef2aSThomas Huth             int32_t sext;
257fcf5ef2aSThomas Huth 
258fcf5ef2aSThomas Huth             /* test virtual address sign extension */
2596c7c3c21SKirill A. Shutemov             sext = la57 ? (int64_t)addr >> 56 : (int64_t)addr >> 47;
260fcf5ef2aSThomas Huth             if (sext != 0 && sext != -1) {
261fcf5ef2aSThomas Huth                 return -1;
262fcf5ef2aSThomas Huth             }
2636c7c3c21SKirill A. Shutemov 
2646c7c3c21SKirill A. Shutemov             if (la57) {
2656c7c3c21SKirill A. Shutemov                 pml5e_addr = ((env->cr[3] & ~0xfff) +
266c8bc83a4SPaolo Bonzini                         (((addr >> 48) & 0x1ff) << 3)) & a20_mask;
2676c7c3c21SKirill A. Shutemov                 pml5e = x86_ldq_phys(cs, pml5e_addr);
2686c7c3c21SKirill A. Shutemov                 if (!(pml5e & PG_PRESENT_MASK)) {
2696c7c3c21SKirill A. Shutemov                     return -1;
2706c7c3c21SKirill A. Shutemov                 }
2716c7c3c21SKirill A. Shutemov             } else {
2726c7c3c21SKirill A. Shutemov                 pml5e = env->cr[3];
2736c7c3c21SKirill A. Shutemov             }
2746c7c3c21SKirill A. Shutemov 
2756c7c3c21SKirill A. Shutemov             pml4e_addr = ((pml5e & PG_ADDRESS_MASK) +
276c8bc83a4SPaolo Bonzini                     (((addr >> 39) & 0x1ff) << 3)) & a20_mask;
277fcf5ef2aSThomas Huth             pml4e = x86_ldq_phys(cs, pml4e_addr);
278fcf5ef2aSThomas Huth             if (!(pml4e & PG_PRESENT_MASK)) {
279fcf5ef2aSThomas Huth                 return -1;
280fcf5ef2aSThomas Huth             }
281fcf5ef2aSThomas Huth             pdpe_addr = ((pml4e & PG_ADDRESS_MASK) +
282c8bc83a4SPaolo Bonzini                          (((addr >> 30) & 0x1ff) << 3)) & a20_mask;
283fcf5ef2aSThomas Huth             pdpe = x86_ldq_phys(cs, pdpe_addr);
284fcf5ef2aSThomas Huth             if (!(pdpe & PG_PRESENT_MASK)) {
285fcf5ef2aSThomas Huth                 return -1;
286fcf5ef2aSThomas Huth             }
287fcf5ef2aSThomas Huth             if (pdpe & PG_PSE_MASK) {
288fcf5ef2aSThomas Huth                 page_size = 1024 * 1024 * 1024;
289fcf5ef2aSThomas Huth                 pte = pdpe;
290fcf5ef2aSThomas Huth                 goto out;
291fcf5ef2aSThomas Huth             }
292fcf5ef2aSThomas Huth 
293fcf5ef2aSThomas Huth         } else
294fcf5ef2aSThomas Huth #endif
295fcf5ef2aSThomas Huth         {
296fcf5ef2aSThomas Huth             pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
297c8bc83a4SPaolo Bonzini                 a20_mask;
298fcf5ef2aSThomas Huth             pdpe = x86_ldq_phys(cs, pdpe_addr);
299fcf5ef2aSThomas Huth             if (!(pdpe & PG_PRESENT_MASK))
300fcf5ef2aSThomas Huth                 return -1;
301fcf5ef2aSThomas Huth         }
302fcf5ef2aSThomas Huth 
303fcf5ef2aSThomas Huth         pde_addr = ((pdpe & PG_ADDRESS_MASK) +
304c8bc83a4SPaolo Bonzini                     (((addr >> 21) & 0x1ff) << 3)) & a20_mask;
305fcf5ef2aSThomas Huth         pde = x86_ldq_phys(cs, pde_addr);
306fcf5ef2aSThomas Huth         if (!(pde & PG_PRESENT_MASK)) {
307fcf5ef2aSThomas Huth             return -1;
308fcf5ef2aSThomas Huth         }
309fcf5ef2aSThomas Huth         if (pde & PG_PSE_MASK) {
310fcf5ef2aSThomas Huth             /* 2 MB page */
311fcf5ef2aSThomas Huth             page_size = 2048 * 1024;
312fcf5ef2aSThomas Huth             pte = pde;
313fcf5ef2aSThomas Huth         } else {
314fcf5ef2aSThomas Huth             /* 4 KB page */
315fcf5ef2aSThomas Huth             pte_addr = ((pde & PG_ADDRESS_MASK) +
316c8bc83a4SPaolo Bonzini                         (((addr >> 12) & 0x1ff) << 3)) & a20_mask;
317fcf5ef2aSThomas Huth             page_size = 4096;
318fcf5ef2aSThomas Huth             pte = x86_ldq_phys(cs, pte_addr);
319fcf5ef2aSThomas Huth         }
320fcf5ef2aSThomas Huth         if (!(pte & PG_PRESENT_MASK)) {
321fcf5ef2aSThomas Huth             return -1;
322fcf5ef2aSThomas Huth         }
323fcf5ef2aSThomas Huth     } else {
324fcf5ef2aSThomas Huth         uint32_t pde;
325fcf5ef2aSThomas Huth 
326fcf5ef2aSThomas Huth         /* page directory entry */
327c8bc83a4SPaolo Bonzini         pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & a20_mask;
328fcf5ef2aSThomas Huth         pde = x86_ldl_phys(cs, pde_addr);
329fcf5ef2aSThomas Huth         if (!(pde & PG_PRESENT_MASK))
330fcf5ef2aSThomas Huth             return -1;
331fcf5ef2aSThomas Huth         if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
332fcf5ef2aSThomas Huth             pte = pde | ((pde & 0x1fe000LL) << (32 - 13));
333fcf5ef2aSThomas Huth             page_size = 4096 * 1024;
334fcf5ef2aSThomas Huth         } else {
335fcf5ef2aSThomas Huth             /* page directory entry */
336c8bc83a4SPaolo Bonzini             pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & a20_mask;
337fcf5ef2aSThomas Huth             pte = x86_ldl_phys(cs, pte_addr);
338fcf5ef2aSThomas Huth             if (!(pte & PG_PRESENT_MASK)) {
339fcf5ef2aSThomas Huth                 return -1;
340fcf5ef2aSThomas Huth             }
341fcf5ef2aSThomas Huth             page_size = 4096;
342fcf5ef2aSThomas Huth         }
343c8bc83a4SPaolo Bonzini         pte = pte & a20_mask;
344fcf5ef2aSThomas Huth     }
345fcf5ef2aSThomas Huth 
346fcf5ef2aSThomas Huth #ifdef TARGET_X86_64
347fcf5ef2aSThomas Huth out:
348fcf5ef2aSThomas Huth #endif
349fcf5ef2aSThomas Huth     pte &= PG_ADDRESS_MASK & ~(page_size - 1);
350fcf5ef2aSThomas Huth     page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
351fcf5ef2aSThomas Huth     return pte | page_offset;
352fcf5ef2aSThomas Huth }
353fcf5ef2aSThomas Huth 
354fcf5ef2aSThomas Huth typedef struct MCEInjectionParams {
355fcf5ef2aSThomas Huth     Monitor *mon;
356fcf5ef2aSThomas Huth     int bank;
357fcf5ef2aSThomas Huth     uint64_t status;
358fcf5ef2aSThomas Huth     uint64_t mcg_status;
359fcf5ef2aSThomas Huth     uint64_t addr;
360fcf5ef2aSThomas Huth     uint64_t misc;
361fcf5ef2aSThomas Huth     int flags;
362fcf5ef2aSThomas Huth } MCEInjectionParams;
363fcf5ef2aSThomas Huth 
emit_guest_memory_failure(MemoryFailureAction action,bool ar,bool recursive)3648efc4e51Szhenwei pi static void emit_guest_memory_failure(MemoryFailureAction action, bool ar,
3658efc4e51Szhenwei pi                                       bool recursive)
3668efc4e51Szhenwei pi {
3678efc4e51Szhenwei pi     MemoryFailureFlags mff = {.action_required = ar, .recursive = recursive};
3688efc4e51Szhenwei pi 
3698efc4e51Szhenwei pi     qapi_event_send_memory_failure(MEMORY_FAILURE_RECIPIENT_GUEST, action,
3708efc4e51Szhenwei pi                                    &mff);
3718efc4e51Szhenwei pi }
3728efc4e51Szhenwei pi 
do_inject_x86_mce(CPUState * cs,run_on_cpu_data data)373fcf5ef2aSThomas Huth static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data)
374fcf5ef2aSThomas Huth {
375fcf5ef2aSThomas Huth     MCEInjectionParams *params = data.host_ptr;
376fcf5ef2aSThomas Huth     X86CPU *cpu = X86_CPU(cs);
377fcf5ef2aSThomas Huth     CPUX86State *cenv = &cpu->env;
378fcf5ef2aSThomas Huth     uint64_t *banks = cenv->mce_banks + 4 * params->bank;
3799f89f303Szhenwei pi     g_autofree char *msg = NULL;
3809f89f303Szhenwei pi     bool need_reset = false;
3818efc4e51Szhenwei pi     bool recursive;
3828efc4e51Szhenwei pi     bool ar = !!(params->status & MCI_STATUS_AR);
383fcf5ef2aSThomas Huth 
384fcf5ef2aSThomas Huth     cpu_synchronize_state(cs);
3858efc4e51Szhenwei pi     recursive = !!(cenv->mcg_status & MCG_STATUS_MCIP);
386fcf5ef2aSThomas Huth 
387fcf5ef2aSThomas Huth     /*
388fcf5ef2aSThomas Huth      * If there is an MCE exception being processed, ignore this SRAO MCE
389fcf5ef2aSThomas Huth      * unless unconditional injection was requested.
390fcf5ef2aSThomas Huth      */
3918efc4e51Szhenwei pi     if (!(params->flags & MCE_INJECT_UNCOND_AO) && !ar && recursive) {
3928efc4e51Szhenwei pi         emit_guest_memory_failure(MEMORY_FAILURE_ACTION_IGNORE, ar, recursive);
393fcf5ef2aSThomas Huth         return;
394fcf5ef2aSThomas Huth     }
395fcf5ef2aSThomas Huth 
396fcf5ef2aSThomas Huth     if (params->status & MCI_STATUS_UC) {
397fcf5ef2aSThomas Huth         /*
398fcf5ef2aSThomas Huth          * if MSR_MCG_CTL is not all 1s, the uncorrected error
399fcf5ef2aSThomas Huth          * reporting is disabled
400fcf5ef2aSThomas Huth          */
401fcf5ef2aSThomas Huth         if ((cenv->mcg_cap & MCG_CTL_P) && cenv->mcg_ctl != ~(uint64_t)0) {
402fcf5ef2aSThomas Huth             monitor_printf(params->mon,
403fcf5ef2aSThomas Huth                            "CPU %d: Uncorrected error reporting disabled\n",
404fcf5ef2aSThomas Huth                            cs->cpu_index);
405fcf5ef2aSThomas Huth             return;
406fcf5ef2aSThomas Huth         }
407fcf5ef2aSThomas Huth 
408fcf5ef2aSThomas Huth         /*
409fcf5ef2aSThomas Huth          * if MSR_MCi_CTL is not all 1s, the uncorrected error
410fcf5ef2aSThomas Huth          * reporting is disabled for the bank
411fcf5ef2aSThomas Huth          */
412fcf5ef2aSThomas Huth         if (banks[0] != ~(uint64_t)0) {
413fcf5ef2aSThomas Huth             monitor_printf(params->mon,
414fcf5ef2aSThomas Huth                            "CPU %d: Uncorrected error reporting disabled for"
415fcf5ef2aSThomas Huth                            " bank %d\n",
416fcf5ef2aSThomas Huth                            cs->cpu_index, params->bank);
417fcf5ef2aSThomas Huth             return;
418fcf5ef2aSThomas Huth         }
419fcf5ef2aSThomas Huth 
4209f89f303Szhenwei pi         if (!(cenv->cr[4] & CR4_MCE_MASK)) {
4219f89f303Szhenwei pi             need_reset = true;
4229f89f303Szhenwei pi             msg = g_strdup_printf("CPU %d: MCE capability is not enabled, "
4239f89f303Szhenwei pi                                   "raising triple fault", cs->cpu_index);
42442ccce19SPaolo Bonzini         } else if (recursive) {
42542ccce19SPaolo Bonzini             need_reset = true;
42642ccce19SPaolo Bonzini             msg = g_strdup_printf("CPU %d: Previous MCE still in progress, "
42742ccce19SPaolo Bonzini                                   "raising triple fault", cs->cpu_index);
4289f89f303Szhenwei pi         }
4299f89f303Szhenwei pi 
4309f89f303Szhenwei pi         if (need_reset) {
4318efc4e51Szhenwei pi             emit_guest_memory_failure(MEMORY_FAILURE_ACTION_RESET, ar,
4328efc4e51Szhenwei pi                                       recursive);
433bf0c50d4SAlex Bennée             monitor_puts(params->mon, msg);
4349f89f303Szhenwei pi             qemu_log_mask(CPU_LOG_RESET, "%s\n", msg);
435cf83f140SEric Blake             qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
436fcf5ef2aSThomas Huth             return;
437fcf5ef2aSThomas Huth         }
4389f89f303Szhenwei pi 
439fcf5ef2aSThomas Huth         if (banks[1] & MCI_STATUS_VAL) {
440fcf5ef2aSThomas Huth             params->status |= MCI_STATUS_OVER;
441fcf5ef2aSThomas Huth         }
442fcf5ef2aSThomas Huth         banks[2] = params->addr;
443fcf5ef2aSThomas Huth         banks[3] = params->misc;
444fcf5ef2aSThomas Huth         cenv->mcg_status = params->mcg_status;
445fcf5ef2aSThomas Huth         banks[1] = params->status;
446fcf5ef2aSThomas Huth         cpu_interrupt(cs, CPU_INTERRUPT_MCE);
447fcf5ef2aSThomas Huth     } else if (!(banks[1] & MCI_STATUS_VAL)
448fcf5ef2aSThomas Huth                || !(banks[1] & MCI_STATUS_UC)) {
449fcf5ef2aSThomas Huth         if (banks[1] & MCI_STATUS_VAL) {
450fcf5ef2aSThomas Huth             params->status |= MCI_STATUS_OVER;
451fcf5ef2aSThomas Huth         }
452fcf5ef2aSThomas Huth         banks[2] = params->addr;
453fcf5ef2aSThomas Huth         banks[3] = params->misc;
454fcf5ef2aSThomas Huth         banks[1] = params->status;
455fcf5ef2aSThomas Huth     } else {
456fcf5ef2aSThomas Huth         banks[1] |= MCI_STATUS_OVER;
457fcf5ef2aSThomas Huth     }
4588efc4e51Szhenwei pi 
4598efc4e51Szhenwei pi     emit_guest_memory_failure(MEMORY_FAILURE_ACTION_INJECT, ar, recursive);
460fcf5ef2aSThomas Huth }
461fcf5ef2aSThomas Huth 
cpu_x86_inject_mce(Monitor * mon,X86CPU * cpu,int bank,uint64_t status,uint64_t mcg_status,uint64_t addr,uint64_t misc,int flags)462fcf5ef2aSThomas Huth void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
463fcf5ef2aSThomas Huth                         uint64_t status, uint64_t mcg_status, uint64_t addr,
464fcf5ef2aSThomas Huth                         uint64_t misc, int flags)
465fcf5ef2aSThomas Huth {
466fcf5ef2aSThomas Huth     CPUState *cs = CPU(cpu);
467fcf5ef2aSThomas Huth     CPUX86State *cenv = &cpu->env;
468fcf5ef2aSThomas Huth     MCEInjectionParams params = {
469fcf5ef2aSThomas Huth         .mon = mon,
470fcf5ef2aSThomas Huth         .bank = bank,
471fcf5ef2aSThomas Huth         .status = status,
472fcf5ef2aSThomas Huth         .mcg_status = mcg_status,
473fcf5ef2aSThomas Huth         .addr = addr,
474fcf5ef2aSThomas Huth         .misc = misc,
475fcf5ef2aSThomas Huth         .flags = flags,
476fcf5ef2aSThomas Huth     };
477fcf5ef2aSThomas Huth     unsigned bank_num = cenv->mcg_cap & 0xff;
478fcf5ef2aSThomas Huth 
479fcf5ef2aSThomas Huth     if (!cenv->mcg_cap) {
480fcf5ef2aSThomas Huth         monitor_printf(mon, "MCE injection not supported\n");
481fcf5ef2aSThomas Huth         return;
482fcf5ef2aSThomas Huth     }
483fcf5ef2aSThomas Huth     if (bank >= bank_num) {
484fcf5ef2aSThomas Huth         monitor_printf(mon, "Invalid MCE bank number\n");
485fcf5ef2aSThomas Huth         return;
486fcf5ef2aSThomas Huth     }
487fcf5ef2aSThomas Huth     if (!(status & MCI_STATUS_VAL)) {
488fcf5ef2aSThomas Huth         monitor_printf(mon, "Invalid MCE status code\n");
489fcf5ef2aSThomas Huth         return;
490fcf5ef2aSThomas Huth     }
491fcf5ef2aSThomas Huth     if ((flags & MCE_INJECT_BROADCAST)
492fcf5ef2aSThomas Huth         && !cpu_x86_support_mca_broadcast(cenv)) {
493fcf5ef2aSThomas Huth         monitor_printf(mon, "Guest CPU does not support MCA broadcast\n");
494fcf5ef2aSThomas Huth         return;
495fcf5ef2aSThomas Huth     }
496fcf5ef2aSThomas Huth 
497fcf5ef2aSThomas Huth     run_on_cpu(cs, do_inject_x86_mce, RUN_ON_CPU_HOST_PTR(&params));
498fcf5ef2aSThomas Huth     if (flags & MCE_INJECT_BROADCAST) {
499fcf5ef2aSThomas Huth         CPUState *other_cs;
500fcf5ef2aSThomas Huth 
501fcf5ef2aSThomas Huth         params.bank = 1;
502fcf5ef2aSThomas Huth         params.status = MCI_STATUS_VAL | MCI_STATUS_UC;
503fcf5ef2aSThomas Huth         params.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
504fcf5ef2aSThomas Huth         params.addr = 0;
505fcf5ef2aSThomas Huth         params.misc = 0;
506fcf5ef2aSThomas Huth         CPU_FOREACH(other_cs) {
507fcf5ef2aSThomas Huth             if (other_cs == cs) {
508fcf5ef2aSThomas Huth                 continue;
509fcf5ef2aSThomas Huth             }
510fcf5ef2aSThomas Huth             run_on_cpu(other_cs, do_inject_x86_mce, RUN_ON_CPU_HOST_PTR(&params));
511fcf5ef2aSThomas Huth         }
512fcf5ef2aSThomas Huth     }
513fcf5ef2aSThomas Huth }
514fcf5ef2aSThomas Huth 
get_memio_eip(CPUX86State * env)515f484f213SRichard Henderson static inline target_ulong get_memio_eip(CPUX86State *env)
516f484f213SRichard Henderson {
517f484f213SRichard Henderson #ifdef CONFIG_TCG
518f484f213SRichard Henderson     uint64_t data[TARGET_INSN_START_WORDS];
519f484f213SRichard Henderson     CPUState *cs = env_cpu(env);
520f484f213SRichard Henderson 
521f484f213SRichard Henderson     if (!cpu_unwind_state_data(cs, cs->mem_io_pc, data)) {
522f484f213SRichard Henderson         return env->eip;
523f484f213SRichard Henderson     }
524f484f213SRichard Henderson 
525f484f213SRichard Henderson     /* Per x86_restore_state_to_opc. */
5262e3afe8eSAnton Johansson     if (cs->tcg_cflags & CF_PCREL) {
527f484f213SRichard Henderson         return (env->eip & TARGET_PAGE_MASK) | data[0];
528f484f213SRichard Henderson     } else {
529f484f213SRichard Henderson         return data[0] - env->segs[R_CS].base;
530f484f213SRichard Henderson     }
531f484f213SRichard Henderson #else
532f484f213SRichard Henderson     qemu_build_not_reached();
533f484f213SRichard Henderson #endif
534f484f213SRichard Henderson }
535f484f213SRichard Henderson 
cpu_report_tpr_access(CPUX86State * env,TPRAccess access)536fcf5ef2aSThomas Huth void cpu_report_tpr_access(CPUX86State *env, TPRAccess access)
537fcf5ef2aSThomas Huth {
5386aa9e42fSRichard Henderson     X86CPU *cpu = env_archcpu(env);
5396aa9e42fSRichard Henderson     CPUState *cs = env_cpu(env);
540fcf5ef2aSThomas Huth 
541b9bc6169SReinoud Zandijk     if (kvm_enabled() || whpx_enabled() || nvmm_enabled()) {
542fcf5ef2aSThomas Huth         env->tpr_access_type = access;
543fcf5ef2aSThomas Huth 
544fcf5ef2aSThomas Huth         cpu_interrupt(cs, CPU_INTERRUPT_TPR);
54579c664f6SYang Zhong     } else if (tcg_enabled()) {
546f484f213SRichard Henderson         target_ulong eip = get_memio_eip(env);
547fcf5ef2aSThomas Huth 
548f484f213SRichard Henderson         apic_handle_tpr_access_report(cpu->apic_state, eip, access);
549fcf5ef2aSThomas Huth     }
550fcf5ef2aSThomas Huth }
551fcf5ef2aSThomas Huth #endif /* !CONFIG_USER_ONLY */
552fcf5ef2aSThomas Huth 
cpu_x86_get_descr_debug(CPUX86State * env,unsigned int selector,target_ulong * base,unsigned int * limit,unsigned int * flags)553fcf5ef2aSThomas Huth int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
554fcf5ef2aSThomas Huth                             target_ulong *base, unsigned int *limit,
555fcf5ef2aSThomas Huth                             unsigned int *flags)
556fcf5ef2aSThomas Huth {
5576aa9e42fSRichard Henderson     CPUState *cs = env_cpu(env);
558fcf5ef2aSThomas Huth     SegmentCache *dt;
559fcf5ef2aSThomas Huth     target_ulong ptr;
560fcf5ef2aSThomas Huth     uint32_t e1, e2;
561fcf5ef2aSThomas Huth     int index;
562fcf5ef2aSThomas Huth 
563fcf5ef2aSThomas Huth     if (selector & 0x4)
564fcf5ef2aSThomas Huth         dt = &env->ldt;
565fcf5ef2aSThomas Huth     else
566fcf5ef2aSThomas Huth         dt = &env->gdt;
567fcf5ef2aSThomas Huth     index = selector & ~7;
568fcf5ef2aSThomas Huth     ptr = dt->base + index;
569fcf5ef2aSThomas Huth     if ((index + 7) > dt->limit
570fcf5ef2aSThomas Huth         || cpu_memory_rw_debug(cs, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
571fcf5ef2aSThomas Huth         || cpu_memory_rw_debug(cs, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
572fcf5ef2aSThomas Huth         return 0;
573fcf5ef2aSThomas Huth 
574fcf5ef2aSThomas Huth     *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
575fcf5ef2aSThomas Huth     *limit = (e1 & 0xffff) | (e2 & 0x000f0000);
576fcf5ef2aSThomas Huth     if (e2 & DESC_G_MASK)
577fcf5ef2aSThomas Huth         *limit = (*limit << 12) | 0xfff;
578fcf5ef2aSThomas Huth     *flags = e2;
579fcf5ef2aSThomas Huth 
580fcf5ef2aSThomas Huth     return 1;
581fcf5ef2aSThomas Huth }
582fcf5ef2aSThomas Huth 
do_cpu_init(X86CPU * cpu)583fcf5ef2aSThomas Huth void do_cpu_init(X86CPU *cpu)
584fcf5ef2aSThomas Huth {
5856d70b36bSPhilippe Mathieu-Daudé #if !defined(CONFIG_USER_ONLY)
586fcf5ef2aSThomas Huth     CPUState *cs = CPU(cpu);
587fcf5ef2aSThomas Huth     CPUX86State *env = &cpu->env;
588fcf5ef2aSThomas Huth     CPUX86State *save = g_new(CPUX86State, 1);
589fcf5ef2aSThomas Huth     int sipi = cs->interrupt_request & CPU_INTERRUPT_SIPI;
590fcf5ef2aSThomas Huth 
591fcf5ef2aSThomas Huth     *save = *env;
592fcf5ef2aSThomas Huth 
593fcf5ef2aSThomas Huth     cpu_reset(cs);
594fcf5ef2aSThomas Huth     cs->interrupt_request = sipi;
595fcf5ef2aSThomas Huth     memcpy(&env->start_init_save, &save->start_init_save,
596fcf5ef2aSThomas Huth            offsetof(CPUX86State, end_init_save) -
597fcf5ef2aSThomas Huth            offsetof(CPUX86State, start_init_save));
598fcf5ef2aSThomas Huth     g_free(save);
599fcf5ef2aSThomas Huth 
600fcf5ef2aSThomas Huth     if (kvm_enabled()) {
601fcf5ef2aSThomas Huth         kvm_arch_do_init_vcpu(cpu);
602fcf5ef2aSThomas Huth     }
603fcf5ef2aSThomas Huth     apic_init_reset(cpu->apic_state);
6046d70b36bSPhilippe Mathieu-Daudé #endif /* CONFIG_USER_ONLY */
605fcf5ef2aSThomas Huth }
606fcf5ef2aSThomas Huth 
6076d70b36bSPhilippe Mathieu-Daudé #ifndef CONFIG_USER_ONLY
6086d70b36bSPhilippe Mathieu-Daudé 
do_cpu_sipi(X86CPU * cpu)609fcf5ef2aSThomas Huth void do_cpu_sipi(X86CPU *cpu)
610fcf5ef2aSThomas Huth {
611fcf5ef2aSThomas Huth     apic_sipi(cpu->apic_state);
612fcf5ef2aSThomas Huth }
61363087289SClaudio Fontana 
cpu_load_efer(CPUX86State * env,uint64_t val)61463087289SClaudio Fontana void cpu_load_efer(CPUX86State *env, uint64_t val)
61563087289SClaudio Fontana {
61663087289SClaudio Fontana     env->efer = val;
61763087289SClaudio Fontana     env->hflags &= ~(HF_LMA_MASK | HF_SVME_MASK);
61863087289SClaudio Fontana     if (env->efer & MSR_EFER_LMA) {
61963087289SClaudio Fontana         env->hflags |= HF_LMA_MASK;
62063087289SClaudio Fontana     }
62163087289SClaudio Fontana     if (env->efer & MSR_EFER_SVME) {
62263087289SClaudio Fontana         env->hflags |= HF_SVME_MASK;
62363087289SClaudio Fontana     }
62463087289SClaudio Fontana }
62563087289SClaudio Fontana 
x86_ldub_phys(CPUState * cs,hwaddr addr)626fcf5ef2aSThomas Huth uint8_t x86_ldub_phys(CPUState *cs, hwaddr addr)
627fcf5ef2aSThomas Huth {
628fcf5ef2aSThomas Huth     X86CPU *cpu = X86_CPU(cs);
629fcf5ef2aSThomas Huth     CPUX86State *env = &cpu->env;
630f8c45c65SPaolo Bonzini     MemTxAttrs attrs = cpu_get_mem_attrs(env);
631f8c45c65SPaolo Bonzini     AddressSpace *as = cpu_addressspace(cs, attrs);
632fcf5ef2aSThomas Huth 
633f8c45c65SPaolo Bonzini     return address_space_ldub(as, addr, attrs, NULL);
634fcf5ef2aSThomas Huth }
635fcf5ef2aSThomas Huth 
x86_lduw_phys(CPUState * cs,hwaddr addr)636fcf5ef2aSThomas Huth uint32_t x86_lduw_phys(CPUState *cs, hwaddr addr)
637fcf5ef2aSThomas Huth {
638fcf5ef2aSThomas Huth     X86CPU *cpu = X86_CPU(cs);
639fcf5ef2aSThomas Huth     CPUX86State *env = &cpu->env;
640f8c45c65SPaolo Bonzini     MemTxAttrs attrs = cpu_get_mem_attrs(env);
641f8c45c65SPaolo Bonzini     AddressSpace *as = cpu_addressspace(cs, attrs);
642fcf5ef2aSThomas Huth 
643f8c45c65SPaolo Bonzini     return address_space_lduw(as, addr, attrs, NULL);
644fcf5ef2aSThomas Huth }
645fcf5ef2aSThomas Huth 
x86_ldl_phys(CPUState * cs,hwaddr addr)646fcf5ef2aSThomas Huth uint32_t x86_ldl_phys(CPUState *cs, hwaddr addr)
647fcf5ef2aSThomas Huth {
648fcf5ef2aSThomas Huth     X86CPU *cpu = X86_CPU(cs);
649fcf5ef2aSThomas Huth     CPUX86State *env = &cpu->env;
650f8c45c65SPaolo Bonzini     MemTxAttrs attrs = cpu_get_mem_attrs(env);
651f8c45c65SPaolo Bonzini     AddressSpace *as = cpu_addressspace(cs, attrs);
652fcf5ef2aSThomas Huth 
653f8c45c65SPaolo Bonzini     return address_space_ldl(as, addr, attrs, NULL);
654fcf5ef2aSThomas Huth }
655fcf5ef2aSThomas Huth 
x86_ldq_phys(CPUState * cs,hwaddr addr)656fcf5ef2aSThomas Huth uint64_t x86_ldq_phys(CPUState *cs, hwaddr addr)
657fcf5ef2aSThomas Huth {
658fcf5ef2aSThomas Huth     X86CPU *cpu = X86_CPU(cs);
659fcf5ef2aSThomas Huth     CPUX86State *env = &cpu->env;
660f8c45c65SPaolo Bonzini     MemTxAttrs attrs = cpu_get_mem_attrs(env);
661f8c45c65SPaolo Bonzini     AddressSpace *as = cpu_addressspace(cs, attrs);
662fcf5ef2aSThomas Huth 
663f8c45c65SPaolo Bonzini     return address_space_ldq(as, addr, attrs, NULL);
664fcf5ef2aSThomas Huth }
665fcf5ef2aSThomas Huth 
x86_stb_phys(CPUState * cs,hwaddr addr,uint8_t val)666fcf5ef2aSThomas Huth void x86_stb_phys(CPUState *cs, hwaddr addr, uint8_t val)
667fcf5ef2aSThomas Huth {
668fcf5ef2aSThomas Huth     X86CPU *cpu = X86_CPU(cs);
669fcf5ef2aSThomas Huth     CPUX86State *env = &cpu->env;
670f8c45c65SPaolo Bonzini     MemTxAttrs attrs = cpu_get_mem_attrs(env);
671f8c45c65SPaolo Bonzini     AddressSpace *as = cpu_addressspace(cs, attrs);
672fcf5ef2aSThomas Huth 
673f8c45c65SPaolo Bonzini     address_space_stb(as, addr, val, attrs, NULL);
674fcf5ef2aSThomas Huth }
675fcf5ef2aSThomas Huth 
x86_stl_phys_notdirty(CPUState * cs,hwaddr addr,uint32_t val)676fcf5ef2aSThomas Huth void x86_stl_phys_notdirty(CPUState *cs, hwaddr addr, uint32_t val)
677fcf5ef2aSThomas Huth {
678fcf5ef2aSThomas Huth     X86CPU *cpu = X86_CPU(cs);
679fcf5ef2aSThomas Huth     CPUX86State *env = &cpu->env;
680f8c45c65SPaolo Bonzini     MemTxAttrs attrs = cpu_get_mem_attrs(env);
681f8c45c65SPaolo Bonzini     AddressSpace *as = cpu_addressspace(cs, attrs);
682fcf5ef2aSThomas Huth 
683f8c45c65SPaolo Bonzini     address_space_stl_notdirty(as, addr, val, attrs, NULL);
684fcf5ef2aSThomas Huth }
685fcf5ef2aSThomas Huth 
x86_stw_phys(CPUState * cs,hwaddr addr,uint32_t val)686fcf5ef2aSThomas Huth void x86_stw_phys(CPUState *cs, hwaddr addr, uint32_t val)
687fcf5ef2aSThomas Huth {
688fcf5ef2aSThomas Huth     X86CPU *cpu = X86_CPU(cs);
689fcf5ef2aSThomas Huth     CPUX86State *env = &cpu->env;
690f8c45c65SPaolo Bonzini     MemTxAttrs attrs = cpu_get_mem_attrs(env);
691f8c45c65SPaolo Bonzini     AddressSpace *as = cpu_addressspace(cs, attrs);
692fcf5ef2aSThomas Huth 
693f8c45c65SPaolo Bonzini     address_space_stw(as, addr, val, attrs, NULL);
694fcf5ef2aSThomas Huth }
695fcf5ef2aSThomas Huth 
x86_stl_phys(CPUState * cs,hwaddr addr,uint32_t val)696fcf5ef2aSThomas Huth void x86_stl_phys(CPUState *cs, hwaddr addr, uint32_t val)
697fcf5ef2aSThomas Huth {
698fcf5ef2aSThomas Huth     X86CPU *cpu = X86_CPU(cs);
699fcf5ef2aSThomas Huth     CPUX86State *env = &cpu->env;
700f8c45c65SPaolo Bonzini     MemTxAttrs attrs = cpu_get_mem_attrs(env);
701f8c45c65SPaolo Bonzini     AddressSpace *as = cpu_addressspace(cs, attrs);
702fcf5ef2aSThomas Huth 
703f8c45c65SPaolo Bonzini     address_space_stl(as, addr, val, attrs, NULL);
704fcf5ef2aSThomas Huth }
705fcf5ef2aSThomas Huth 
x86_stq_phys(CPUState * cs,hwaddr addr,uint64_t val)706fcf5ef2aSThomas Huth void x86_stq_phys(CPUState *cs, hwaddr addr, uint64_t val)
707fcf5ef2aSThomas Huth {
708fcf5ef2aSThomas Huth     X86CPU *cpu = X86_CPU(cs);
709fcf5ef2aSThomas Huth     CPUX86State *env = &cpu->env;
710f8c45c65SPaolo Bonzini     MemTxAttrs attrs = cpu_get_mem_attrs(env);
711f8c45c65SPaolo Bonzini     AddressSpace *as = cpu_addressspace(cs, attrs);
712fcf5ef2aSThomas Huth 
713f8c45c65SPaolo Bonzini     address_space_stq(as, addr, val, attrs, NULL);
714fcf5ef2aSThomas Huth }
715fcf5ef2aSThomas Huth #endif
716