xref: /qemu/target/i386/helper.c (revision 4b77512b)
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"
2828a43cb4SPhilippe 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 
94*4b77512bSJohn Allen     if (IS_AMD_CPU(env)) {
95*4b77512bSJohn Allen         return 0;
96*4b77512bSJohn Allen     }
97*4b77512bSJohn Allen 
98fcf5ef2aSThomas Huth     cpu_x86_version(env, &family, &model);
99fcf5ef2aSThomas Huth     if ((family == 6 && model >= 14) || family > 6) {
100fcf5ef2aSThomas Huth         return 1;
101fcf5ef2aSThomas Huth     }
102fcf5ef2aSThomas Huth 
103fcf5ef2aSThomas Huth     return 0;
104fcf5ef2aSThomas Huth }
105fcf5ef2aSThomas Huth 
106fcf5ef2aSThomas Huth /***********************************************************/
107fcf5ef2aSThomas Huth /* x86 mmu */
108fcf5ef2aSThomas Huth /* XXX: add PGE support */
109fcf5ef2aSThomas Huth 
x86_cpu_set_a20(X86CPU * cpu,int a20_state)110fcf5ef2aSThomas Huth void x86_cpu_set_a20(X86CPU *cpu, int a20_state)
111fcf5ef2aSThomas Huth {
112fcf5ef2aSThomas Huth     CPUX86State *env = &cpu->env;
113fcf5ef2aSThomas Huth 
114fcf5ef2aSThomas Huth     a20_state = (a20_state != 0);
115fcf5ef2aSThomas Huth     if (a20_state != ((env->a20_mask >> 20) & 1)) {
116fcf5ef2aSThomas Huth         CPUState *cs = CPU(cpu);
117fcf5ef2aSThomas Huth 
118fcf5ef2aSThomas Huth         qemu_log_mask(CPU_LOG_MMU, "A20 update: a20=%d\n", a20_state);
119fcf5ef2aSThomas Huth         /* if the cpu is currently executing code, we must unlink it and
120fcf5ef2aSThomas Huth            all the potentially executing TB */
121fcf5ef2aSThomas Huth         cpu_interrupt(cs, CPU_INTERRUPT_EXITTB);
122fcf5ef2aSThomas Huth 
123fcf5ef2aSThomas Huth         /* when a20 is changed, all the MMU mappings are invalid, so
124fcf5ef2aSThomas Huth            we must flush everything */
125d10eb08fSAlex Bennée         tlb_flush(cs);
126fcf5ef2aSThomas Huth         env->a20_mask = ~(1 << 20) | (a20_state << 20);
127fcf5ef2aSThomas Huth     }
128fcf5ef2aSThomas Huth }
129fcf5ef2aSThomas Huth 
cpu_x86_update_cr0(CPUX86State * env,uint32_t new_cr0)130fcf5ef2aSThomas Huth void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
131fcf5ef2aSThomas Huth {
1326aa9e42fSRichard Henderson     X86CPU *cpu = env_archcpu(env);
133fcf5ef2aSThomas Huth     int pe_state;
134fcf5ef2aSThomas Huth 
135fcf5ef2aSThomas Huth     qemu_log_mask(CPU_LOG_MMU, "CR0 update: CR0=0x%08x\n", new_cr0);
136fcf5ef2aSThomas Huth     if ((new_cr0 & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK)) !=
137fcf5ef2aSThomas Huth         (env->cr[0] & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK))) {
138d10eb08fSAlex Bennée         tlb_flush(CPU(cpu));
139fcf5ef2aSThomas Huth     }
140fcf5ef2aSThomas Huth 
141fcf5ef2aSThomas Huth #ifdef TARGET_X86_64
142fcf5ef2aSThomas Huth     if (!(env->cr[0] & CR0_PG_MASK) && (new_cr0 & CR0_PG_MASK) &&
143fcf5ef2aSThomas Huth         (env->efer & MSR_EFER_LME)) {
144fcf5ef2aSThomas Huth         /* enter in long mode */
145fcf5ef2aSThomas Huth         /* XXX: generate an exception */
146fcf5ef2aSThomas Huth         if (!(env->cr[4] & CR4_PAE_MASK))
147fcf5ef2aSThomas Huth             return;
148fcf5ef2aSThomas Huth         env->efer |= MSR_EFER_LMA;
149fcf5ef2aSThomas Huth         env->hflags |= HF_LMA_MASK;
150fcf5ef2aSThomas Huth     } else if ((env->cr[0] & CR0_PG_MASK) && !(new_cr0 & CR0_PG_MASK) &&
151fcf5ef2aSThomas Huth                (env->efer & MSR_EFER_LMA)) {
152fcf5ef2aSThomas Huth         /* exit long mode */
153fcf5ef2aSThomas Huth         env->efer &= ~MSR_EFER_LMA;
154fcf5ef2aSThomas Huth         env->hflags &= ~(HF_LMA_MASK | HF_CS64_MASK);
155fcf5ef2aSThomas Huth         env->eip &= 0xffffffff;
156fcf5ef2aSThomas Huth     }
157fcf5ef2aSThomas Huth #endif
158fcf5ef2aSThomas Huth     env->cr[0] = new_cr0 | CR0_ET_MASK;
159fcf5ef2aSThomas Huth 
160fcf5ef2aSThomas Huth     /* update PE flag in hidden flags */
161fcf5ef2aSThomas Huth     pe_state = (env->cr[0] & CR0_PE_MASK);
162fcf5ef2aSThomas Huth     env->hflags = (env->hflags & ~HF_PE_MASK) | (pe_state << HF_PE_SHIFT);
163fcf5ef2aSThomas Huth     /* ensure that ADDSEG is always set in real mode */
164fcf5ef2aSThomas Huth     env->hflags |= ((pe_state ^ 1) << HF_ADDSEG_SHIFT);
165fcf5ef2aSThomas Huth     /* update FPU flags */
166fcf5ef2aSThomas Huth     env->hflags = (env->hflags & ~(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)) |
167fcf5ef2aSThomas Huth         ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
168fcf5ef2aSThomas Huth }
169fcf5ef2aSThomas Huth 
170fcf5ef2aSThomas Huth /* XXX: in legacy PAE mode, generate a GPF if reserved bits are set in
171fcf5ef2aSThomas Huth    the PDPT */
cpu_x86_update_cr3(CPUX86State * env,target_ulong new_cr3)172fcf5ef2aSThomas Huth void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3)
173fcf5ef2aSThomas Huth {
174fcf5ef2aSThomas Huth     env->cr[3] = new_cr3;
175fcf5ef2aSThomas Huth     if (env->cr[0] & CR0_PG_MASK) {
176fcf5ef2aSThomas Huth         qemu_log_mask(CPU_LOG_MMU,
177fcf5ef2aSThomas Huth                         "CR3 update: CR3=" TARGET_FMT_lx "\n", new_cr3);
1786aa9e42fSRichard Henderson         tlb_flush(env_cpu(env));
179fcf5ef2aSThomas Huth     }
180fcf5ef2aSThomas Huth }
181fcf5ef2aSThomas Huth 
cpu_x86_update_cr4(CPUX86State * env,uint32_t new_cr4)182fcf5ef2aSThomas Huth void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
183fcf5ef2aSThomas Huth {
184fcf5ef2aSThomas Huth     uint32_t hflags;
185fcf5ef2aSThomas Huth 
186fcf5ef2aSThomas Huth #if defined(DEBUG_MMU)
1876c7c3c21SKirill A. Shutemov     printf("CR4 update: %08x -> %08x\n", (uint32_t)env->cr[4], new_cr4);
188fcf5ef2aSThomas Huth #endif
189fcf5ef2aSThomas Huth     if ((new_cr4 ^ env->cr[4]) &
190fcf5ef2aSThomas Huth         (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK |
1916c7c3c21SKirill A. Shutemov          CR4_SMEP_MASK | CR4_SMAP_MASK | CR4_LA57_MASK)) {
1926aa9e42fSRichard Henderson         tlb_flush(env_cpu(env));
193fcf5ef2aSThomas Huth     }
194fcf5ef2aSThomas Huth 
195fcf5ef2aSThomas Huth     /* Clear bits we're going to recompute.  */
196637f1ee3SGareth Webb     hflags = env->hflags & ~(HF_OSFXSR_MASK | HF_SMAP_MASK | HF_UMIP_MASK);
197fcf5ef2aSThomas Huth 
198fcf5ef2aSThomas Huth     /* SSE handling */
199fcf5ef2aSThomas Huth     if (!(env->features[FEAT_1_EDX] & CPUID_SSE)) {
200fcf5ef2aSThomas Huth         new_cr4 &= ~CR4_OSFXSR_MASK;
201fcf5ef2aSThomas Huth     }
202fcf5ef2aSThomas Huth     if (new_cr4 & CR4_OSFXSR_MASK) {
203fcf5ef2aSThomas Huth         hflags |= HF_OSFXSR_MASK;
204fcf5ef2aSThomas Huth     }
205fcf5ef2aSThomas Huth 
206fcf5ef2aSThomas Huth     if (!(env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_SMAP)) {
207fcf5ef2aSThomas Huth         new_cr4 &= ~CR4_SMAP_MASK;
208fcf5ef2aSThomas Huth     }
209fcf5ef2aSThomas Huth     if (new_cr4 & CR4_SMAP_MASK) {
210fcf5ef2aSThomas Huth         hflags |= HF_SMAP_MASK;
211fcf5ef2aSThomas Huth     }
212637f1ee3SGareth Webb     if (!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_UMIP)) {
213637f1ee3SGareth Webb         new_cr4 &= ~CR4_UMIP_MASK;
214637f1ee3SGareth Webb     }
215637f1ee3SGareth Webb     if (new_cr4 & CR4_UMIP_MASK) {
216637f1ee3SGareth Webb         hflags |= HF_UMIP_MASK;
217637f1ee3SGareth Webb     }
218fcf5ef2aSThomas Huth 
219fcf5ef2aSThomas Huth     if (!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_PKU)) {
220fcf5ef2aSThomas Huth         new_cr4 &= ~CR4_PKE_MASK;
221fcf5ef2aSThomas Huth     }
222e7e7bdabSPaolo Bonzini     if (!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_PKS)) {
223e7e7bdabSPaolo Bonzini         new_cr4 &= ~CR4_PKS_MASK;
224e7e7bdabSPaolo Bonzini     }
225fcf5ef2aSThomas Huth 
22601170671SBinbin Wu     if (!(env->features[FEAT_7_1_EAX] & CPUID_7_1_EAX_LAM)) {
22701170671SBinbin Wu         new_cr4 &= ~CR4_LAM_SUP_MASK;
22801170671SBinbin Wu     }
22901170671SBinbin Wu 
230fcf5ef2aSThomas Huth     env->cr[4] = new_cr4;
231fcf5ef2aSThomas Huth     env->hflags = hflags;
232fcf5ef2aSThomas Huth 
233fcf5ef2aSThomas Huth     cpu_sync_bndcs_hflags(env);
234608db8dbSPaul Brook     cpu_sync_avx_hflag(env);
235fcf5ef2aSThomas Huth }
236fcf5ef2aSThomas Huth 
2376578eb25SPaolo Bonzini #if !defined(CONFIG_USER_ONLY)
x86_cpu_get_phys_page_attrs_debug(CPUState * cs,vaddr addr,MemTxAttrs * attrs)23856f99750SDmitry Poletaev hwaddr x86_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
23956f99750SDmitry Poletaev                                          MemTxAttrs *attrs)
240fcf5ef2aSThomas Huth {
241fcf5ef2aSThomas Huth     X86CPU *cpu = X86_CPU(cs);
242fcf5ef2aSThomas Huth     CPUX86State *env = &cpu->env;
243fcf5ef2aSThomas Huth     target_ulong pde_addr, pte_addr;
244fcf5ef2aSThomas Huth     uint64_t pte;
245c8bc83a4SPaolo Bonzini     int32_t a20_mask;
246fcf5ef2aSThomas Huth     uint32_t page_offset;
247fcf5ef2aSThomas Huth     int page_size;
248fcf5ef2aSThomas Huth 
24956f99750SDmitry Poletaev     *attrs = cpu_get_mem_attrs(env);
25056f99750SDmitry Poletaev 
251c8bc83a4SPaolo Bonzini     a20_mask = x86_get_a20_mask(env);
252fcf5ef2aSThomas Huth     if (!(env->cr[0] & CR0_PG_MASK)) {
253c8bc83a4SPaolo Bonzini         pte = addr & a20_mask;
254fcf5ef2aSThomas Huth         page_size = 4096;
255fcf5ef2aSThomas Huth     } else if (env->cr[4] & CR4_PAE_MASK) {
256fcf5ef2aSThomas Huth         target_ulong pdpe_addr;
257fcf5ef2aSThomas Huth         uint64_t pde, pdpe;
258fcf5ef2aSThomas Huth 
259fcf5ef2aSThomas Huth #ifdef TARGET_X86_64
260fcf5ef2aSThomas Huth         if (env->hflags & HF_LMA_MASK) {
2616c7c3c21SKirill A. Shutemov             bool la57 = env->cr[4] & CR4_LA57_MASK;
2626c7c3c21SKirill A. Shutemov             uint64_t pml5e_addr, pml5e;
263fcf5ef2aSThomas Huth             uint64_t pml4e_addr, pml4e;
264fcf5ef2aSThomas Huth             int32_t sext;
265fcf5ef2aSThomas Huth 
266fcf5ef2aSThomas Huth             /* test virtual address sign extension */
2676c7c3c21SKirill A. Shutemov             sext = la57 ? (int64_t)addr >> 56 : (int64_t)addr >> 47;
268fcf5ef2aSThomas Huth             if (sext != 0 && sext != -1) {
269fcf5ef2aSThomas Huth                 return -1;
270fcf5ef2aSThomas Huth             }
2716c7c3c21SKirill A. Shutemov 
2726c7c3c21SKirill A. Shutemov             if (la57) {
2736c7c3c21SKirill A. Shutemov                 pml5e_addr = ((env->cr[3] & ~0xfff) +
274c8bc83a4SPaolo Bonzini                         (((addr >> 48) & 0x1ff) << 3)) & a20_mask;
2756c7c3c21SKirill A. Shutemov                 pml5e = x86_ldq_phys(cs, pml5e_addr);
2766c7c3c21SKirill A. Shutemov                 if (!(pml5e & PG_PRESENT_MASK)) {
2776c7c3c21SKirill A. Shutemov                     return -1;
2786c7c3c21SKirill A. Shutemov                 }
2796c7c3c21SKirill A. Shutemov             } else {
2806c7c3c21SKirill A. Shutemov                 pml5e = env->cr[3];
2816c7c3c21SKirill A. Shutemov             }
2826c7c3c21SKirill A. Shutemov 
2836c7c3c21SKirill A. Shutemov             pml4e_addr = ((pml5e & PG_ADDRESS_MASK) +
284c8bc83a4SPaolo Bonzini                     (((addr >> 39) & 0x1ff) << 3)) & a20_mask;
285fcf5ef2aSThomas Huth             pml4e = x86_ldq_phys(cs, pml4e_addr);
286fcf5ef2aSThomas Huth             if (!(pml4e & PG_PRESENT_MASK)) {
287fcf5ef2aSThomas Huth                 return -1;
288fcf5ef2aSThomas Huth             }
289fcf5ef2aSThomas Huth             pdpe_addr = ((pml4e & PG_ADDRESS_MASK) +
290c8bc83a4SPaolo Bonzini                          (((addr >> 30) & 0x1ff) << 3)) & a20_mask;
291fcf5ef2aSThomas Huth             pdpe = x86_ldq_phys(cs, pdpe_addr);
292fcf5ef2aSThomas Huth             if (!(pdpe & PG_PRESENT_MASK)) {
293fcf5ef2aSThomas Huth                 return -1;
294fcf5ef2aSThomas Huth             }
295fcf5ef2aSThomas Huth             if (pdpe & PG_PSE_MASK) {
296fcf5ef2aSThomas Huth                 page_size = 1024 * 1024 * 1024;
297fcf5ef2aSThomas Huth                 pte = pdpe;
298fcf5ef2aSThomas Huth                 goto out;
299fcf5ef2aSThomas Huth             }
300fcf5ef2aSThomas Huth 
301fcf5ef2aSThomas Huth         } else
302fcf5ef2aSThomas Huth #endif
303fcf5ef2aSThomas Huth         {
304fcf5ef2aSThomas Huth             pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
305c8bc83a4SPaolo Bonzini                 a20_mask;
306fcf5ef2aSThomas Huth             pdpe = x86_ldq_phys(cs, pdpe_addr);
307fcf5ef2aSThomas Huth             if (!(pdpe & PG_PRESENT_MASK))
308fcf5ef2aSThomas Huth                 return -1;
309fcf5ef2aSThomas Huth         }
310fcf5ef2aSThomas Huth 
311fcf5ef2aSThomas Huth         pde_addr = ((pdpe & PG_ADDRESS_MASK) +
312c8bc83a4SPaolo Bonzini                     (((addr >> 21) & 0x1ff) << 3)) & a20_mask;
313fcf5ef2aSThomas Huth         pde = x86_ldq_phys(cs, pde_addr);
314fcf5ef2aSThomas Huth         if (!(pde & PG_PRESENT_MASK)) {
315fcf5ef2aSThomas Huth             return -1;
316fcf5ef2aSThomas Huth         }
317fcf5ef2aSThomas Huth         if (pde & PG_PSE_MASK) {
318fcf5ef2aSThomas Huth             /* 2 MB page */
319fcf5ef2aSThomas Huth             page_size = 2048 * 1024;
320fcf5ef2aSThomas Huth             pte = pde;
321fcf5ef2aSThomas Huth         } else {
322fcf5ef2aSThomas Huth             /* 4 KB page */
323fcf5ef2aSThomas Huth             pte_addr = ((pde & PG_ADDRESS_MASK) +
324c8bc83a4SPaolo Bonzini                         (((addr >> 12) & 0x1ff) << 3)) & a20_mask;
325fcf5ef2aSThomas Huth             page_size = 4096;
326fcf5ef2aSThomas Huth             pte = x86_ldq_phys(cs, pte_addr);
327fcf5ef2aSThomas Huth         }
328fcf5ef2aSThomas Huth         if (!(pte & PG_PRESENT_MASK)) {
329fcf5ef2aSThomas Huth             return -1;
330fcf5ef2aSThomas Huth         }
331fcf5ef2aSThomas Huth     } else {
332fcf5ef2aSThomas Huth         uint32_t pde;
333fcf5ef2aSThomas Huth 
334fcf5ef2aSThomas Huth         /* page directory entry */
335c8bc83a4SPaolo Bonzini         pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & a20_mask;
336fcf5ef2aSThomas Huth         pde = x86_ldl_phys(cs, pde_addr);
337fcf5ef2aSThomas Huth         if (!(pde & PG_PRESENT_MASK))
338fcf5ef2aSThomas Huth             return -1;
339fcf5ef2aSThomas Huth         if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
340fcf5ef2aSThomas Huth             pte = pde | ((pde & 0x1fe000LL) << (32 - 13));
341fcf5ef2aSThomas Huth             page_size = 4096 * 1024;
342fcf5ef2aSThomas Huth         } else {
343fcf5ef2aSThomas Huth             /* page directory entry */
344c8bc83a4SPaolo Bonzini             pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & a20_mask;
345fcf5ef2aSThomas Huth             pte = x86_ldl_phys(cs, pte_addr);
346fcf5ef2aSThomas Huth             if (!(pte & PG_PRESENT_MASK)) {
347fcf5ef2aSThomas Huth                 return -1;
348fcf5ef2aSThomas Huth             }
349fcf5ef2aSThomas Huth             page_size = 4096;
350fcf5ef2aSThomas Huth         }
351c8bc83a4SPaolo Bonzini         pte = pte & a20_mask;
352fcf5ef2aSThomas Huth     }
353fcf5ef2aSThomas Huth 
354fcf5ef2aSThomas Huth #ifdef TARGET_X86_64
355fcf5ef2aSThomas Huth out:
356fcf5ef2aSThomas Huth #endif
357fcf5ef2aSThomas Huth     pte &= PG_ADDRESS_MASK & ~(page_size - 1);
358fcf5ef2aSThomas Huth     page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
359fcf5ef2aSThomas Huth     return pte | page_offset;
360fcf5ef2aSThomas Huth }
361fcf5ef2aSThomas Huth 
362fcf5ef2aSThomas Huth typedef struct MCEInjectionParams {
363fcf5ef2aSThomas Huth     Monitor *mon;
364fcf5ef2aSThomas Huth     int bank;
365fcf5ef2aSThomas Huth     uint64_t status;
366fcf5ef2aSThomas Huth     uint64_t mcg_status;
367fcf5ef2aSThomas Huth     uint64_t addr;
368fcf5ef2aSThomas Huth     uint64_t misc;
369fcf5ef2aSThomas Huth     int flags;
370fcf5ef2aSThomas Huth } MCEInjectionParams;
371fcf5ef2aSThomas Huth 
emit_guest_memory_failure(MemoryFailureAction action,bool ar,bool recursive)3728efc4e51Szhenwei pi static void emit_guest_memory_failure(MemoryFailureAction action, bool ar,
3738efc4e51Szhenwei pi                                       bool recursive)
3748efc4e51Szhenwei pi {
3758efc4e51Szhenwei pi     MemoryFailureFlags mff = {.action_required = ar, .recursive = recursive};
3768efc4e51Szhenwei pi 
3778efc4e51Szhenwei pi     qapi_event_send_memory_failure(MEMORY_FAILURE_RECIPIENT_GUEST, action,
3788efc4e51Szhenwei pi                                    &mff);
3798efc4e51Szhenwei pi }
3808efc4e51Szhenwei pi 
do_inject_x86_mce(CPUState * cs,run_on_cpu_data data)381fcf5ef2aSThomas Huth static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data)
382fcf5ef2aSThomas Huth {
383fcf5ef2aSThomas Huth     MCEInjectionParams *params = data.host_ptr;
384fcf5ef2aSThomas Huth     X86CPU *cpu = X86_CPU(cs);
385fcf5ef2aSThomas Huth     CPUX86State *cenv = &cpu->env;
386fcf5ef2aSThomas Huth     uint64_t *banks = cenv->mce_banks + 4 * params->bank;
3879f89f303Szhenwei pi     g_autofree char *msg = NULL;
3889f89f303Szhenwei pi     bool need_reset = false;
3898efc4e51Szhenwei pi     bool recursive;
3908efc4e51Szhenwei pi     bool ar = !!(params->status & MCI_STATUS_AR);
391fcf5ef2aSThomas Huth 
392fcf5ef2aSThomas Huth     cpu_synchronize_state(cs);
3938efc4e51Szhenwei pi     recursive = !!(cenv->mcg_status & MCG_STATUS_MCIP);
394fcf5ef2aSThomas Huth 
395fcf5ef2aSThomas Huth     /*
396fcf5ef2aSThomas Huth      * If there is an MCE exception being processed, ignore this SRAO MCE
397fcf5ef2aSThomas Huth      * unless unconditional injection was requested.
398fcf5ef2aSThomas Huth      */
3998efc4e51Szhenwei pi     if (!(params->flags & MCE_INJECT_UNCOND_AO) && !ar && recursive) {
4008efc4e51Szhenwei pi         emit_guest_memory_failure(MEMORY_FAILURE_ACTION_IGNORE, ar, recursive);
401fcf5ef2aSThomas Huth         return;
402fcf5ef2aSThomas Huth     }
403fcf5ef2aSThomas Huth 
404fcf5ef2aSThomas Huth     if (params->status & MCI_STATUS_UC) {
405fcf5ef2aSThomas Huth         /*
406fcf5ef2aSThomas Huth          * if MSR_MCG_CTL is not all 1s, the uncorrected error
407fcf5ef2aSThomas Huth          * reporting is disabled
408fcf5ef2aSThomas Huth          */
409fcf5ef2aSThomas Huth         if ((cenv->mcg_cap & MCG_CTL_P) && cenv->mcg_ctl != ~(uint64_t)0) {
410fcf5ef2aSThomas Huth             monitor_printf(params->mon,
411fcf5ef2aSThomas Huth                            "CPU %d: Uncorrected error reporting disabled\n",
412fcf5ef2aSThomas Huth                            cs->cpu_index);
413fcf5ef2aSThomas Huth             return;
414fcf5ef2aSThomas Huth         }
415fcf5ef2aSThomas Huth 
416fcf5ef2aSThomas Huth         /*
417fcf5ef2aSThomas Huth          * if MSR_MCi_CTL is not all 1s, the uncorrected error
418fcf5ef2aSThomas Huth          * reporting is disabled for the bank
419fcf5ef2aSThomas Huth          */
420fcf5ef2aSThomas Huth         if (banks[0] != ~(uint64_t)0) {
421fcf5ef2aSThomas Huth             monitor_printf(params->mon,
422fcf5ef2aSThomas Huth                            "CPU %d: Uncorrected error reporting disabled for"
423fcf5ef2aSThomas Huth                            " bank %d\n",
424fcf5ef2aSThomas Huth                            cs->cpu_index, params->bank);
425fcf5ef2aSThomas Huth             return;
426fcf5ef2aSThomas Huth         }
427fcf5ef2aSThomas Huth 
4289f89f303Szhenwei pi         if (!(cenv->cr[4] & CR4_MCE_MASK)) {
4299f89f303Szhenwei pi             need_reset = true;
4309f89f303Szhenwei pi             msg = g_strdup_printf("CPU %d: MCE capability is not enabled, "
4319f89f303Szhenwei pi                                   "raising triple fault", cs->cpu_index);
43242ccce19SPaolo Bonzini         } else if (recursive) {
43342ccce19SPaolo Bonzini             need_reset = true;
43442ccce19SPaolo Bonzini             msg = g_strdup_printf("CPU %d: Previous MCE still in progress, "
43542ccce19SPaolo Bonzini                                   "raising triple fault", cs->cpu_index);
4369f89f303Szhenwei pi         }
4379f89f303Szhenwei pi 
4389f89f303Szhenwei pi         if (need_reset) {
4398efc4e51Szhenwei pi             emit_guest_memory_failure(MEMORY_FAILURE_ACTION_RESET, ar,
4408efc4e51Szhenwei pi                                       recursive);
4417fd226b0STao Su             monitor_printf(params->mon, "%s", msg);
4429f89f303Szhenwei pi             qemu_log_mask(CPU_LOG_RESET, "%s\n", msg);
443cf83f140SEric Blake             qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
444fcf5ef2aSThomas Huth             return;
445fcf5ef2aSThomas Huth         }
4469f89f303Szhenwei pi 
447fcf5ef2aSThomas Huth         if (banks[1] & MCI_STATUS_VAL) {
448fcf5ef2aSThomas Huth             params->status |= MCI_STATUS_OVER;
449fcf5ef2aSThomas Huth         }
450fcf5ef2aSThomas Huth         banks[2] = params->addr;
451fcf5ef2aSThomas Huth         banks[3] = params->misc;
452fcf5ef2aSThomas Huth         cenv->mcg_status = params->mcg_status;
453fcf5ef2aSThomas Huth         banks[1] = params->status;
454fcf5ef2aSThomas Huth         cpu_interrupt(cs, CPU_INTERRUPT_MCE);
455fcf5ef2aSThomas Huth     } else if (!(banks[1] & MCI_STATUS_VAL)
456fcf5ef2aSThomas Huth                || !(banks[1] & MCI_STATUS_UC)) {
457fcf5ef2aSThomas Huth         if (banks[1] & MCI_STATUS_VAL) {
458fcf5ef2aSThomas Huth             params->status |= MCI_STATUS_OVER;
459fcf5ef2aSThomas Huth         }
460fcf5ef2aSThomas Huth         banks[2] = params->addr;
461fcf5ef2aSThomas Huth         banks[3] = params->misc;
462fcf5ef2aSThomas Huth         banks[1] = params->status;
463fcf5ef2aSThomas Huth     } else {
464fcf5ef2aSThomas Huth         banks[1] |= MCI_STATUS_OVER;
465fcf5ef2aSThomas Huth     }
4668efc4e51Szhenwei pi 
4678efc4e51Szhenwei pi     emit_guest_memory_failure(MEMORY_FAILURE_ACTION_INJECT, ar, recursive);
468fcf5ef2aSThomas Huth }
469fcf5ef2aSThomas 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)470fcf5ef2aSThomas Huth void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
471fcf5ef2aSThomas Huth                         uint64_t status, uint64_t mcg_status, uint64_t addr,
472fcf5ef2aSThomas Huth                         uint64_t misc, int flags)
473fcf5ef2aSThomas Huth {
474fcf5ef2aSThomas Huth     CPUState *cs = CPU(cpu);
475fcf5ef2aSThomas Huth     CPUX86State *cenv = &cpu->env;
476fcf5ef2aSThomas Huth     MCEInjectionParams params = {
477fcf5ef2aSThomas Huth         .mon = mon,
478fcf5ef2aSThomas Huth         .bank = bank,
479fcf5ef2aSThomas Huth         .status = status,
480fcf5ef2aSThomas Huth         .mcg_status = mcg_status,
481fcf5ef2aSThomas Huth         .addr = addr,
482fcf5ef2aSThomas Huth         .misc = misc,
483fcf5ef2aSThomas Huth         .flags = flags,
484fcf5ef2aSThomas Huth     };
485fcf5ef2aSThomas Huth     unsigned bank_num = cenv->mcg_cap & 0xff;
486fcf5ef2aSThomas Huth 
487fcf5ef2aSThomas Huth     if (!cenv->mcg_cap) {
488fcf5ef2aSThomas Huth         monitor_printf(mon, "MCE injection not supported\n");
489fcf5ef2aSThomas Huth         return;
490fcf5ef2aSThomas Huth     }
491fcf5ef2aSThomas Huth     if (bank >= bank_num) {
492fcf5ef2aSThomas Huth         monitor_printf(mon, "Invalid MCE bank number\n");
493fcf5ef2aSThomas Huth         return;
494fcf5ef2aSThomas Huth     }
495fcf5ef2aSThomas Huth     if (!(status & MCI_STATUS_VAL)) {
496fcf5ef2aSThomas Huth         monitor_printf(mon, "Invalid MCE status code\n");
497fcf5ef2aSThomas Huth         return;
498fcf5ef2aSThomas Huth     }
499fcf5ef2aSThomas Huth     if ((flags & MCE_INJECT_BROADCAST)
500fcf5ef2aSThomas Huth         && !cpu_x86_support_mca_broadcast(cenv)) {
501fcf5ef2aSThomas Huth         monitor_printf(mon, "Guest CPU does not support MCA broadcast\n");
502fcf5ef2aSThomas Huth         return;
503fcf5ef2aSThomas Huth     }
504fcf5ef2aSThomas Huth 
505fcf5ef2aSThomas Huth     run_on_cpu(cs, do_inject_x86_mce, RUN_ON_CPU_HOST_PTR(&params));
506fcf5ef2aSThomas Huth     if (flags & MCE_INJECT_BROADCAST) {
507fcf5ef2aSThomas Huth         CPUState *other_cs;
508fcf5ef2aSThomas Huth 
509fcf5ef2aSThomas Huth         params.bank = 1;
510fcf5ef2aSThomas Huth         params.status = MCI_STATUS_VAL | MCI_STATUS_UC;
511fcf5ef2aSThomas Huth         params.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
512fcf5ef2aSThomas Huth         params.addr = 0;
513fcf5ef2aSThomas Huth         params.misc = 0;
514fcf5ef2aSThomas Huth         CPU_FOREACH(other_cs) {
515fcf5ef2aSThomas Huth             if (other_cs == cs) {
516fcf5ef2aSThomas Huth                 continue;
517fcf5ef2aSThomas Huth             }
518fcf5ef2aSThomas Huth             run_on_cpu(other_cs, do_inject_x86_mce, RUN_ON_CPU_HOST_PTR(&params));
519fcf5ef2aSThomas Huth         }
520fcf5ef2aSThomas Huth     }
521fcf5ef2aSThomas Huth }
522fcf5ef2aSThomas Huth 
get_memio_eip(CPUX86State * env)523f484f213SRichard Henderson static inline target_ulong get_memio_eip(CPUX86State *env)
524f484f213SRichard Henderson {
525f484f213SRichard Henderson #ifdef CONFIG_TCG
526f484f213SRichard Henderson     uint64_t data[TARGET_INSN_START_WORDS];
527f484f213SRichard Henderson     CPUState *cs = env_cpu(env);
528f484f213SRichard Henderson 
529f484f213SRichard Henderson     if (!cpu_unwind_state_data(cs, cs->mem_io_pc, data)) {
530f484f213SRichard Henderson         return env->eip;
531f484f213SRichard Henderson     }
532f484f213SRichard Henderson 
533f484f213SRichard Henderson     /* Per x86_restore_state_to_opc. */
534b254c342SPhilippe Mathieu-Daudé     if (tcg_cflags_has(cs, CF_PCREL)) {
535f484f213SRichard Henderson         return (env->eip & TARGET_PAGE_MASK) | data[0];
536f484f213SRichard Henderson     } else {
537f484f213SRichard Henderson         return data[0] - env->segs[R_CS].base;
538f484f213SRichard Henderson     }
539f484f213SRichard Henderson #else
540f484f213SRichard Henderson     qemu_build_not_reached();
541f484f213SRichard Henderson #endif
542f484f213SRichard Henderson }
543f484f213SRichard Henderson 
cpu_report_tpr_access(CPUX86State * env,TPRAccess access)544fcf5ef2aSThomas Huth void cpu_report_tpr_access(CPUX86State *env, TPRAccess access)
545fcf5ef2aSThomas Huth {
5466aa9e42fSRichard Henderson     X86CPU *cpu = env_archcpu(env);
5476aa9e42fSRichard Henderson     CPUState *cs = env_cpu(env);
548fcf5ef2aSThomas Huth 
549b9bc6169SReinoud Zandijk     if (kvm_enabled() || whpx_enabled() || nvmm_enabled()) {
550fcf5ef2aSThomas Huth         env->tpr_access_type = access;
551fcf5ef2aSThomas Huth 
552fcf5ef2aSThomas Huth         cpu_interrupt(cs, CPU_INTERRUPT_TPR);
55379c664f6SYang Zhong     } else if (tcg_enabled()) {
554f484f213SRichard Henderson         target_ulong eip = get_memio_eip(env);
555fcf5ef2aSThomas Huth 
556f484f213SRichard Henderson         apic_handle_tpr_access_report(cpu->apic_state, eip, access);
557fcf5ef2aSThomas Huth     }
558fcf5ef2aSThomas Huth }
559fcf5ef2aSThomas Huth #endif /* !CONFIG_USER_ONLY */
560fcf5ef2aSThomas Huth 
cpu_x86_get_descr_debug(CPUX86State * env,unsigned int selector,target_ulong * base,unsigned int * limit,unsigned int * flags)561fcf5ef2aSThomas Huth int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
562fcf5ef2aSThomas Huth                             target_ulong *base, unsigned int *limit,
563fcf5ef2aSThomas Huth                             unsigned int *flags)
564fcf5ef2aSThomas Huth {
5656aa9e42fSRichard Henderson     CPUState *cs = env_cpu(env);
566fcf5ef2aSThomas Huth     SegmentCache *dt;
567fcf5ef2aSThomas Huth     target_ulong ptr;
568fcf5ef2aSThomas Huth     uint32_t e1, e2;
569fcf5ef2aSThomas Huth     int index;
570fcf5ef2aSThomas Huth 
571fcf5ef2aSThomas Huth     if (selector & 0x4)
572fcf5ef2aSThomas Huth         dt = &env->ldt;
573fcf5ef2aSThomas Huth     else
574fcf5ef2aSThomas Huth         dt = &env->gdt;
575fcf5ef2aSThomas Huth     index = selector & ~7;
576fcf5ef2aSThomas Huth     ptr = dt->base + index;
577fcf5ef2aSThomas Huth     if ((index + 7) > dt->limit
578fcf5ef2aSThomas Huth         || cpu_memory_rw_debug(cs, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
579fcf5ef2aSThomas Huth         || cpu_memory_rw_debug(cs, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
580fcf5ef2aSThomas Huth         return 0;
581fcf5ef2aSThomas Huth 
582fcf5ef2aSThomas Huth     *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
583fcf5ef2aSThomas Huth     *limit = (e1 & 0xffff) | (e2 & 0x000f0000);
584fcf5ef2aSThomas Huth     if (e2 & DESC_G_MASK)
585fcf5ef2aSThomas Huth         *limit = (*limit << 12) | 0xfff;
586fcf5ef2aSThomas Huth     *flags = e2;
587fcf5ef2aSThomas Huth 
588fcf5ef2aSThomas Huth     return 1;
589fcf5ef2aSThomas Huth }
590fcf5ef2aSThomas Huth 
do_cpu_init(X86CPU * cpu)591fcf5ef2aSThomas Huth void do_cpu_init(X86CPU *cpu)
592fcf5ef2aSThomas Huth {
5936d70b36bSPhilippe Mathieu-Daudé #if !defined(CONFIG_USER_ONLY)
594fcf5ef2aSThomas Huth     CPUState *cs = CPU(cpu);
595fcf5ef2aSThomas Huth     CPUX86State *env = &cpu->env;
596fcf5ef2aSThomas Huth     CPUX86State *save = g_new(CPUX86State, 1);
597fcf5ef2aSThomas Huth     int sipi = cs->interrupt_request & CPU_INTERRUPT_SIPI;
598fcf5ef2aSThomas Huth 
599fcf5ef2aSThomas Huth     *save = *env;
600fcf5ef2aSThomas Huth 
601fcf5ef2aSThomas Huth     cpu_reset(cs);
602fcf5ef2aSThomas Huth     cs->interrupt_request = sipi;
603fcf5ef2aSThomas Huth     memcpy(&env->start_init_save, &save->start_init_save,
604fcf5ef2aSThomas Huth            offsetof(CPUX86State, end_init_save) -
605fcf5ef2aSThomas Huth            offsetof(CPUX86State, start_init_save));
606fcf5ef2aSThomas Huth     g_free(save);
607fcf5ef2aSThomas Huth 
608fcf5ef2aSThomas Huth     if (kvm_enabled()) {
609fcf5ef2aSThomas Huth         kvm_arch_do_init_vcpu(cpu);
610fcf5ef2aSThomas Huth     }
611fcf5ef2aSThomas Huth     apic_init_reset(cpu->apic_state);
6126d70b36bSPhilippe Mathieu-Daudé #endif /* CONFIG_USER_ONLY */
613fcf5ef2aSThomas Huth }
614fcf5ef2aSThomas Huth 
6156d70b36bSPhilippe Mathieu-Daudé #ifndef CONFIG_USER_ONLY
6166d70b36bSPhilippe Mathieu-Daudé 
do_cpu_sipi(X86CPU * cpu)617fcf5ef2aSThomas Huth void do_cpu_sipi(X86CPU *cpu)
618fcf5ef2aSThomas Huth {
619fcf5ef2aSThomas Huth     apic_sipi(cpu->apic_state);
620fcf5ef2aSThomas Huth }
62163087289SClaudio Fontana 
cpu_load_efer(CPUX86State * env,uint64_t val)62263087289SClaudio Fontana void cpu_load_efer(CPUX86State *env, uint64_t val)
62363087289SClaudio Fontana {
62463087289SClaudio Fontana     env->efer = val;
62563087289SClaudio Fontana     env->hflags &= ~(HF_LMA_MASK | HF_SVME_MASK);
62663087289SClaudio Fontana     if (env->efer & MSR_EFER_LMA) {
62763087289SClaudio Fontana         env->hflags |= HF_LMA_MASK;
62863087289SClaudio Fontana     }
62963087289SClaudio Fontana     if (env->efer & MSR_EFER_SVME) {
63063087289SClaudio Fontana         env->hflags |= HF_SVME_MASK;
63163087289SClaudio Fontana     }
63263087289SClaudio Fontana }
63363087289SClaudio Fontana 
x86_ldub_phys(CPUState * cs,hwaddr addr)634fcf5ef2aSThomas Huth uint8_t x86_ldub_phys(CPUState *cs, hwaddr addr)
635fcf5ef2aSThomas Huth {
636fcf5ef2aSThomas Huth     X86CPU *cpu = X86_CPU(cs);
637fcf5ef2aSThomas Huth     CPUX86State *env = &cpu->env;
638f8c45c65SPaolo Bonzini     MemTxAttrs attrs = cpu_get_mem_attrs(env);
639f8c45c65SPaolo Bonzini     AddressSpace *as = cpu_addressspace(cs, attrs);
640fcf5ef2aSThomas Huth 
641f8c45c65SPaolo Bonzini     return address_space_ldub(as, addr, attrs, NULL);
642fcf5ef2aSThomas Huth }
643fcf5ef2aSThomas Huth 
x86_lduw_phys(CPUState * cs,hwaddr addr)644fcf5ef2aSThomas Huth uint32_t x86_lduw_phys(CPUState *cs, hwaddr addr)
645fcf5ef2aSThomas Huth {
646fcf5ef2aSThomas Huth     X86CPU *cpu = X86_CPU(cs);
647fcf5ef2aSThomas Huth     CPUX86State *env = &cpu->env;
648f8c45c65SPaolo Bonzini     MemTxAttrs attrs = cpu_get_mem_attrs(env);
649f8c45c65SPaolo Bonzini     AddressSpace *as = cpu_addressspace(cs, attrs);
650fcf5ef2aSThomas Huth 
651f8c45c65SPaolo Bonzini     return address_space_lduw(as, addr, attrs, NULL);
652fcf5ef2aSThomas Huth }
653fcf5ef2aSThomas Huth 
x86_ldl_phys(CPUState * cs,hwaddr addr)654fcf5ef2aSThomas Huth uint32_t x86_ldl_phys(CPUState *cs, hwaddr addr)
655fcf5ef2aSThomas Huth {
656fcf5ef2aSThomas Huth     X86CPU *cpu = X86_CPU(cs);
657fcf5ef2aSThomas Huth     CPUX86State *env = &cpu->env;
658f8c45c65SPaolo Bonzini     MemTxAttrs attrs = cpu_get_mem_attrs(env);
659f8c45c65SPaolo Bonzini     AddressSpace *as = cpu_addressspace(cs, attrs);
660fcf5ef2aSThomas Huth 
661f8c45c65SPaolo Bonzini     return address_space_ldl(as, addr, attrs, NULL);
662fcf5ef2aSThomas Huth }
663fcf5ef2aSThomas Huth 
x86_ldq_phys(CPUState * cs,hwaddr addr)664fcf5ef2aSThomas Huth uint64_t x86_ldq_phys(CPUState *cs, hwaddr addr)
665fcf5ef2aSThomas Huth {
666fcf5ef2aSThomas Huth     X86CPU *cpu = X86_CPU(cs);
667fcf5ef2aSThomas Huth     CPUX86State *env = &cpu->env;
668f8c45c65SPaolo Bonzini     MemTxAttrs attrs = cpu_get_mem_attrs(env);
669f8c45c65SPaolo Bonzini     AddressSpace *as = cpu_addressspace(cs, attrs);
670fcf5ef2aSThomas Huth 
671f8c45c65SPaolo Bonzini     return address_space_ldq(as, addr, attrs, NULL);
672fcf5ef2aSThomas Huth }
673fcf5ef2aSThomas Huth 
x86_stb_phys(CPUState * cs,hwaddr addr,uint8_t val)674fcf5ef2aSThomas Huth void x86_stb_phys(CPUState *cs, hwaddr addr, uint8_t val)
675fcf5ef2aSThomas Huth {
676fcf5ef2aSThomas Huth     X86CPU *cpu = X86_CPU(cs);
677fcf5ef2aSThomas Huth     CPUX86State *env = &cpu->env;
678f8c45c65SPaolo Bonzini     MemTxAttrs attrs = cpu_get_mem_attrs(env);
679f8c45c65SPaolo Bonzini     AddressSpace *as = cpu_addressspace(cs, attrs);
680fcf5ef2aSThomas Huth 
681f8c45c65SPaolo Bonzini     address_space_stb(as, addr, val, attrs, NULL);
682fcf5ef2aSThomas Huth }
683fcf5ef2aSThomas Huth 
x86_stl_phys_notdirty(CPUState * cs,hwaddr addr,uint32_t val)684fcf5ef2aSThomas Huth void x86_stl_phys_notdirty(CPUState *cs, hwaddr addr, uint32_t val)
685fcf5ef2aSThomas Huth {
686fcf5ef2aSThomas Huth     X86CPU *cpu = X86_CPU(cs);
687fcf5ef2aSThomas Huth     CPUX86State *env = &cpu->env;
688f8c45c65SPaolo Bonzini     MemTxAttrs attrs = cpu_get_mem_attrs(env);
689f8c45c65SPaolo Bonzini     AddressSpace *as = cpu_addressspace(cs, attrs);
690fcf5ef2aSThomas Huth 
691f8c45c65SPaolo Bonzini     address_space_stl_notdirty(as, addr, val, attrs, NULL);
692fcf5ef2aSThomas Huth }
693fcf5ef2aSThomas Huth 
x86_stw_phys(CPUState * cs,hwaddr addr,uint32_t val)694fcf5ef2aSThomas Huth void x86_stw_phys(CPUState *cs, hwaddr addr, uint32_t val)
695fcf5ef2aSThomas Huth {
696fcf5ef2aSThomas Huth     X86CPU *cpu = X86_CPU(cs);
697fcf5ef2aSThomas Huth     CPUX86State *env = &cpu->env;
698f8c45c65SPaolo Bonzini     MemTxAttrs attrs = cpu_get_mem_attrs(env);
699f8c45c65SPaolo Bonzini     AddressSpace *as = cpu_addressspace(cs, attrs);
700fcf5ef2aSThomas Huth 
701f8c45c65SPaolo Bonzini     address_space_stw(as, addr, val, attrs, NULL);
702fcf5ef2aSThomas Huth }
703fcf5ef2aSThomas Huth 
x86_stl_phys(CPUState * cs,hwaddr addr,uint32_t val)704fcf5ef2aSThomas Huth void x86_stl_phys(CPUState *cs, hwaddr addr, uint32_t val)
705fcf5ef2aSThomas Huth {
706fcf5ef2aSThomas Huth     X86CPU *cpu = X86_CPU(cs);
707fcf5ef2aSThomas Huth     CPUX86State *env = &cpu->env;
708f8c45c65SPaolo Bonzini     MemTxAttrs attrs = cpu_get_mem_attrs(env);
709f8c45c65SPaolo Bonzini     AddressSpace *as = cpu_addressspace(cs, attrs);
710fcf5ef2aSThomas Huth 
711f8c45c65SPaolo Bonzini     address_space_stl(as, addr, val, attrs, NULL);
712fcf5ef2aSThomas Huth }
713fcf5ef2aSThomas Huth 
x86_stq_phys(CPUState * cs,hwaddr addr,uint64_t val)714fcf5ef2aSThomas Huth void x86_stq_phys(CPUState *cs, hwaddr addr, uint64_t val)
715fcf5ef2aSThomas Huth {
716fcf5ef2aSThomas Huth     X86CPU *cpu = X86_CPU(cs);
717fcf5ef2aSThomas Huth     CPUX86State *env = &cpu->env;
718f8c45c65SPaolo Bonzini     MemTxAttrs attrs = cpu_get_mem_attrs(env);
719f8c45c65SPaolo Bonzini     AddressSpace *as = cpu_addressspace(cs, attrs);
720fcf5ef2aSThomas Huth 
721f8c45c65SPaolo Bonzini     address_space_stq(as, addr, val, attrs, NULL);
722fcf5ef2aSThomas Huth }
723fcf5ef2aSThomas Huth #endif
724