cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

mpx_helper.c (3826B)


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