VirtualBox

Changeset 46297 in vbox for trunk/src/VBox/VMM/VMMAll


Ignore:
Timestamp:
May 28, 2013 2:38:48 PM (12 years ago)
Author:
vboxsync
Message:

VMM: Started HMSVMR0 work. Unify the AMD-V erratum 170 verification code between R0 and R3. General HM tidying.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/HMAll.cpp

    r45701 r46297  
    3434#include <iprt/string.h>
    3535#include <iprt/x86.h>
     36#include <iprt/asm-amd64-x86.h>
    3637
    3738
     
    371372}
    372373
     374
     375/**
     376 * Checks if the current AMD CPU is subject to erratum 170 "In SVM mode,
     377 * incorrect code bytes may be fetched after a world-switch".
     378 *
     379 * @param   pu32Family      Where to store the CPU family (can be NULL).
     380 * @param   pu32Model       Where to store the CPU model (can be NULL).
     381 * @param   pu32Stepping    Where to store the CPU stepping (can be NULL).
     382 * @returns true if the erratum applies, false otherwise.
     383 */
     384VMM_INT_DECL(int) HMAmdIsSubjectToErratum170(uint32_t *pu32Family, uint32_t *pu32Model, uint32_t *pu32Stepping)
     385{
     386    /*
     387     * Erratum 170 which requires a forced TLB flush for each world switch:
     388     * See AMD spec. "Revision Guide for AMD NPT Family 0Fh Processors".
     389     *
     390     * All BH-G1/2 and DH-G1/2 models include a fix:
     391     * Athlon X2:   0x6b 1/2
     392     *              0x68 1/2
     393     * Athlon 64:   0x7f 1
     394     *              0x6f 2
     395     * Sempron:     0x7f 1/2
     396     *              0x6f 2
     397     *              0x6c 2
     398     *              0x7c 2
     399     * Turion 64:   0x68 2
     400     */
     401    uint32_t u32Dummy;
     402    uint32_t u32Version, u32Family, u32Model, u32Stepping, u32BaseFamily;
     403    ASMCpuId(1, &u32Version, &u32Dummy, &u32Dummy, &u32Dummy);
     404    u32BaseFamily = (u32Version >> 8) & 0xf;
     405    u32Family     = u32BaseFamily + (u32BaseFamily == 0xf ? ((u32Version >> 20) & 0x7f) : 0);
     406    u32Model      = ((u32Version >> 4) & 0xf);
     407    u32Model      = u32Model | ((u32BaseFamily == 0xf ? (u32Version >> 16) & 0x0f : 0) << 4);
     408    u32Stepping   = u32Version & 0xf;
     409
     410    bool fErratumApplies = false;
     411    if (   u32Family == 0xf
     412        && !((u32Model == 0x68 || u32Model == 0x6b || u32Model == 0x7f) && u32Stepping >= 1)
     413        && !((u32Model == 0x6f || u32Model == 0x6c || u32Model == 0x7c) && u32Stepping >= 2))
     414    {
     415        fErratumApplies = true;
     416    }
     417
     418    if (pu32Family)
     419        *pu32Family   = u32Family;
     420    if (pu32Model)
     421        *pu32Model    = u32Model;
     422    if (pu32Stepping)
     423        *pu32Stepping = u32Stepping;
     424
     425    return fErratumApplies;
     426}
     427
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette