xref: /qemu/target/i386/tcg/mpx_helper.c (revision d9ff33ada7f32ca59f99b270a2d0eb223b3c9c8f)
1f4f1110eSRichard Henderson /*
2f4f1110eSRichard Henderson  *  x86 MPX helpers
3f4f1110eSRichard Henderson  *
4f4f1110eSRichard Henderson  *  Copyright (c) 2015 Red Hat, Inc.
5f4f1110eSRichard Henderson  *
6f4f1110eSRichard Henderson  * This library is free software; you can redistribute it and/or
7f4f1110eSRichard Henderson  * modify it under the terms of the GNU Lesser General Public
8f4f1110eSRichard Henderson  * License as published by the Free Software Foundation; either
9d9ff33adSChetan Pant  * version 2.1 of the License, or (at your option) any later version.
10f4f1110eSRichard Henderson  *
11f4f1110eSRichard Henderson  * This library is distributed in the hope that it will be useful,
12f4f1110eSRichard Henderson  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13f4f1110eSRichard Henderson  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14f4f1110eSRichard Henderson  * Lesser General Public License for more details.
15f4f1110eSRichard Henderson  *
16f4f1110eSRichard Henderson  * You should have received a copy of the GNU Lesser General Public
17f4f1110eSRichard Henderson  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18f4f1110eSRichard Henderson  */
19f4f1110eSRichard Henderson 
2030456d5bSPeter Maydell #include "qemu/osdep.h"
21f4f1110eSRichard Henderson #include "cpu.h"
22f4f1110eSRichard Henderson #include "exec/helper-proto.h"
23f4f1110eSRichard Henderson #include "exec/cpu_ldst.h"
2463c91552SPaolo Bonzini #include "exec/exec-all.h"
25f4f1110eSRichard Henderson 
26f4f1110eSRichard Henderson 
27523e28d7SRichard Henderson void helper_bndck(CPUX86State *env, uint32_t fail)
28523e28d7SRichard Henderson {
29523e28d7SRichard Henderson     if (unlikely(fail)) {
30523e28d7SRichard Henderson         env->bndcs_regs.sts = 1;
31523e28d7SRichard Henderson         raise_exception_ra(env, EXCP05_BOUND, GETPC());
32523e28d7SRichard Henderson     }
33523e28d7SRichard Henderson }
34bdd87b3bSRichard Henderson 
35bdd87b3bSRichard Henderson static uint64_t lookup_bte64(CPUX86State *env, uint64_t base, uintptr_t ra)
36bdd87b3bSRichard Henderson {
37bdd87b3bSRichard Henderson     uint64_t bndcsr, bde, bt;
38bdd87b3bSRichard Henderson 
39bdd87b3bSRichard Henderson     if ((env->hflags & HF_CPL_MASK) == 3) {
40bdd87b3bSRichard Henderson         bndcsr = env->bndcs_regs.cfgu;
41bdd87b3bSRichard Henderson     } else {
42bdd87b3bSRichard Henderson         bndcsr = env->msr_bndcfgs;
43bdd87b3bSRichard Henderson     }
44bdd87b3bSRichard Henderson 
45bdd87b3bSRichard Henderson     bde = (extract64(base, 20, 28) << 3) + (extract64(bndcsr, 20, 44) << 12);
46bdd87b3bSRichard Henderson     bt = cpu_ldq_data_ra(env, bde, ra);
47bdd87b3bSRichard Henderson     if ((bt & 1) == 0) {
48bdd87b3bSRichard Henderson         env->bndcs_regs.sts = bde | 2;
49bdd87b3bSRichard Henderson         raise_exception_ra(env, EXCP05_BOUND, ra);
50bdd87b3bSRichard Henderson     }
51bdd87b3bSRichard Henderson 
52bdd87b3bSRichard Henderson     return (extract64(base, 3, 17) << 5) + (bt & ~7);
53bdd87b3bSRichard Henderson }
54bdd87b3bSRichard Henderson 
55bdd87b3bSRichard Henderson static uint32_t lookup_bte32(CPUX86State *env, uint32_t base, uintptr_t ra)
56bdd87b3bSRichard Henderson {
57bdd87b3bSRichard Henderson     uint32_t bndcsr, bde, bt;
58bdd87b3bSRichard Henderson 
59bdd87b3bSRichard Henderson     if ((env->hflags & HF_CPL_MASK) == 3) {
60bdd87b3bSRichard Henderson         bndcsr = env->bndcs_regs.cfgu;
61bdd87b3bSRichard Henderson     } else {
62bdd87b3bSRichard Henderson         bndcsr = env->msr_bndcfgs;
63bdd87b3bSRichard Henderson     }
64bdd87b3bSRichard Henderson 
65bdd87b3bSRichard Henderson     bde = (extract32(base, 12, 20) << 2) + (bndcsr & TARGET_PAGE_MASK);
66bdd87b3bSRichard Henderson     bt = cpu_ldl_data_ra(env, bde, ra);
67bdd87b3bSRichard Henderson     if ((bt & 1) == 0) {
68bdd87b3bSRichard Henderson         env->bndcs_regs.sts = bde | 2;
69bdd87b3bSRichard Henderson         raise_exception_ra(env, EXCP05_BOUND, ra);
70bdd87b3bSRichard Henderson     }
71bdd87b3bSRichard Henderson 
72bdd87b3bSRichard Henderson     return (extract32(base, 2, 10) << 4) + (bt & ~3);
73bdd87b3bSRichard Henderson }
74bdd87b3bSRichard Henderson 
75bdd87b3bSRichard Henderson uint64_t helper_bndldx64(CPUX86State *env, target_ulong base, target_ulong ptr)
76bdd87b3bSRichard Henderson {
77bdd87b3bSRichard Henderson     uintptr_t ra = GETPC();
78bdd87b3bSRichard Henderson     uint64_t bte, lb, ub, pt;
79bdd87b3bSRichard Henderson 
80bdd87b3bSRichard Henderson     bte = lookup_bte64(env, base, ra);
81bdd87b3bSRichard Henderson     lb = cpu_ldq_data_ra(env, bte, ra);
82bdd87b3bSRichard Henderson     ub = cpu_ldq_data_ra(env, bte + 8, ra);
83bdd87b3bSRichard Henderson     pt = cpu_ldq_data_ra(env, bte + 16, ra);
84bdd87b3bSRichard Henderson 
85bdd87b3bSRichard Henderson     if (pt != ptr) {
86bdd87b3bSRichard Henderson         lb = ub = 0;
87bdd87b3bSRichard Henderson     }
88bdd87b3bSRichard Henderson     env->mmx_t0.MMX_Q(0) = ub;
89bdd87b3bSRichard Henderson     return lb;
90bdd87b3bSRichard Henderson }
91bdd87b3bSRichard Henderson 
92bdd87b3bSRichard Henderson uint64_t helper_bndldx32(CPUX86State *env, target_ulong base, target_ulong ptr)
93bdd87b3bSRichard Henderson {
94bdd87b3bSRichard Henderson     uintptr_t ra = GETPC();
95bdd87b3bSRichard Henderson     uint32_t bte, lb, ub, pt;
96bdd87b3bSRichard Henderson 
97bdd87b3bSRichard Henderson     bte = lookup_bte32(env, base, ra);
98bdd87b3bSRichard Henderson     lb = cpu_ldl_data_ra(env, bte, ra);
99bdd87b3bSRichard Henderson     ub = cpu_ldl_data_ra(env, bte + 4, ra);
100bdd87b3bSRichard Henderson     pt = cpu_ldl_data_ra(env, bte + 8, ra);
101bdd87b3bSRichard Henderson 
102bdd87b3bSRichard Henderson     if (pt != ptr) {
103bdd87b3bSRichard Henderson         lb = ub = 0;
104bdd87b3bSRichard Henderson     }
105bdd87b3bSRichard Henderson     return ((uint64_t)ub << 32) | lb;
106bdd87b3bSRichard Henderson }
107bdd87b3bSRichard Henderson 
108bdd87b3bSRichard Henderson void helper_bndstx64(CPUX86State *env, target_ulong base, target_ulong ptr,
109bdd87b3bSRichard Henderson                      uint64_t lb, uint64_t ub)
110bdd87b3bSRichard Henderson {
111bdd87b3bSRichard Henderson     uintptr_t ra = GETPC();
112bdd87b3bSRichard Henderson     uint64_t bte;
113bdd87b3bSRichard Henderson 
114bdd87b3bSRichard Henderson     bte = lookup_bte64(env, base, ra);
115bdd87b3bSRichard Henderson     cpu_stq_data_ra(env, bte, lb, ra);
116bdd87b3bSRichard Henderson     cpu_stq_data_ra(env, bte + 8, ub, ra);
117bdd87b3bSRichard Henderson     cpu_stq_data_ra(env, bte + 16, ptr, ra);
118bdd87b3bSRichard Henderson }
119bdd87b3bSRichard Henderson 
120bdd87b3bSRichard Henderson void helper_bndstx32(CPUX86State *env, target_ulong base, target_ulong ptr,
121bdd87b3bSRichard Henderson                      uint64_t lb, uint64_t ub)
122bdd87b3bSRichard Henderson {
123bdd87b3bSRichard Henderson     uintptr_t ra = GETPC();
124bdd87b3bSRichard Henderson     uint32_t bte;
125bdd87b3bSRichard Henderson 
126bdd87b3bSRichard Henderson     bte = lookup_bte32(env, base, ra);
127bdd87b3bSRichard Henderson     cpu_stl_data_ra(env, bte, lb, ra);
128bdd87b3bSRichard Henderson     cpu_stl_data_ra(env, bte + 4, ub, ra);
129bdd87b3bSRichard Henderson     cpu_stl_data_ra(env, bte + 8, ptr, ra);
130bdd87b3bSRichard Henderson }
1317d117ce8SRichard Henderson 
1327d117ce8SRichard Henderson void helper_bnd_jmp(CPUX86State *env)
1337d117ce8SRichard Henderson {
1347d117ce8SRichard Henderson     if (!(env->hflags2 & HF2_MPX_PR_MASK)) {
1357d117ce8SRichard Henderson         memset(env->bnd_regs, 0, sizeof(env->bnd_regs));
1367d117ce8SRichard Henderson         env->hflags &= ~HF_MPX_IU_MASK;
1377d117ce8SRichard Henderson     }
1387d117ce8SRichard Henderson }
139