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(¶ms));
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(¶ms));
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