Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/rth/tags/pull-i386-20160215' in…
Browse files Browse the repository at this point in the history
…to staging

Add XSAVE, MPX, FSGSBASE.

# gpg: Signature made Mon 15 Feb 2016 11:21:50 GMT using RSA key ID 4DD0279B
# gpg: Good signature from "Richard Henderson <rth7680@gmail.com>"
# gpg:                 aka "Richard Henderson <rth@redhat.com>"
# gpg:                 aka "Richard Henderson <rth@twiddle.net>"

* remotes/rth/tags/pull-i386-20160215:
  target-i386: Implement FSGSBASE
  target-i386: Enable CR4/XCR0 features for user-mode
  target-i386: Clear bndregs during legacy near jumps
  target-i386: Implement BNDLDX, BNDSTX
  target-i386: Update BNDSTATUS for exceptions raised by BOUND
  target-i386: Implement BNDCL, BNDCU, BNDCN
  target-i386: Implement BNDMOV
  target-i386: Implement BNDMK
  target-i386: Split up gen_lea_modrm
  target-i386: Perform set/reset_inhibit_irq inline
  target-i386: Enable control registers for MPX
  target-i386: Implement XSAVEOPT
  target-i386: Add XSAVE extension
  target-i386: Rearrange processing of 0F AE
  target-i386: Rearrange processing of 0F 01
  target-i386: Split fxsave/fxrstor implementation

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Feb 15, 2016
2 parents a5af128 + 07929f2 commit 80b5d6b
Show file tree
Hide file tree
Showing 14 changed files with 1,439 additions and 546 deletions.
2 changes: 1 addition & 1 deletion target-i386/Makefile.objs
@@ -1,6 +1,6 @@
obj-y += translate.o helper.o cpu.o bpt_helper.o
obj-y += excp_helper.o fpu_helper.o cc_helper.o int_helper.o svm_helper.o
obj-y += smm_helper.o misc_helper.o mem_helper.o seg_helper.o
obj-y += smm_helper.o misc_helper.o mem_helper.o seg_helper.o mpx_helper.o
obj-y += gdbstub.o
obj-$(CONFIG_SOFTMMU) += machine.o arch_memory_mapping.o arch_dump.o monitor.o
obj-$(CONFIG_KVM) += kvm.o hyperv.o
Expand Down
10 changes: 0 additions & 10 deletions target-i386/cc_helper.c
Expand Up @@ -383,13 +383,3 @@ void helper_sti_vm(CPUX86State *env)
}
}
#endif

void helper_set_inhibit_irq(CPUX86State *env)
{
env->hflags |= HF_INHIBIT_IRQ_MASK;
}

void helper_reset_inhibit_irq(CPUX86State *env)
{
env->hflags &= ~HF_INHIBIT_IRQ_MASK;
}
91 changes: 59 additions & 32 deletions target-i386/cpu.c
Expand Up @@ -331,14 +331,14 @@ static const char *cpuid_6_feature_name[] = {
#define TCG_EXT_FEATURES (CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | \
CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 | CPUID_EXT_CX16 | \
CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_POPCNT | \
CPUID_EXT_XSAVE | /* CPUID_EXT_OSXSAVE is dynamic */ \
CPUID_EXT_MOVBE | CPUID_EXT_AES | CPUID_EXT_HYPERVISOR)
/* missing:
CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_SMX,
CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_CID, CPUID_EXT_FMA,
CPUID_EXT_XTPR, CPUID_EXT_PDCM, CPUID_EXT_PCID, CPUID_EXT_DCA,
CPUID_EXT_X2APIC, CPUID_EXT_TSC_DEADLINE_TIMER, CPUID_EXT_XSAVE,
CPUID_EXT_OSXSAVE, CPUID_EXT_AVX, CPUID_EXT_F16C,
CPUID_EXT_RDRAND */
CPUID_EXT_X2APIC, CPUID_EXT_TSC_DEADLINE_TIMER, CPUID_EXT_AVX,
CPUID_EXT_F16C, CPUID_EXT_RDRAND */

#ifdef TARGET_X86_64
#define TCG_EXT2_X86_64_FEATURES (CPUID_EXT2_SYSCALL | CPUID_EXT2_LM)
Expand All @@ -358,15 +358,17 @@ static const char *cpuid_6_feature_name[] = {
#define TCG_7_0_EBX_FEATURES (CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_SMAP | \
CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ADX | \
CPUID_7_0_EBX_PCOMMIT | CPUID_7_0_EBX_CLFLUSHOPT | \
CPUID_7_0_EBX_CLWB)
CPUID_7_0_EBX_CLWB | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_FSGSBASE)
/* missing:
CPUID_7_0_EBX_FSGSBASE, CPUID_7_0_EBX_HLE, CPUID_7_0_EBX_AVX2,
CPUID_7_0_EBX_HLE, CPUID_7_0_EBX_AVX2,
CPUID_7_0_EBX_ERMS, CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM,
CPUID_7_0_EBX_RDSEED */
#define TCG_7_0_ECX_FEATURES 0
#define TCG_APM_FEATURES 0
#define TCG_6_EAX_FEATURES CPUID_6_EAX_ARAT

#define TCG_XSAVE_FEATURES (CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XGETBV1)
/* missing:
CPUID_XSAVE_XSAVEC, CPUID_XSAVE_XSAVES */

typedef struct FeatureWordInfo {
const char **feat_names;
Expand Down Expand Up @@ -440,7 +442,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
.cpuid_eax = 0xd,
.cpuid_needs_ecx = true, .cpuid_ecx = 1,
.cpuid_reg = R_EAX,
.tcg_features = 0,
.tcg_features = TCG_XSAVE_FEATURES,
},
[FEAT_6_EAX] = {
.feat_names = cpuid_6_feature_name,
Expand Down Expand Up @@ -470,12 +472,7 @@ static const X86RegisterInfo32 x86_reg_info_32[CPU_NB_REGS32] = {
};
#undef REGISTER

typedef struct ExtSaveArea {
uint32_t feature, bits;
uint32_t offset, size;
} ExtSaveArea;

static const ExtSaveArea ext_save_areas[] = {
const ExtSaveArea x86_ext_save_areas[] = {
[2] = { .feature = FEAT_1_ECX, .bits = CPUID_EXT_AVX,
.offset = 0x240, .size = 0x100 },
[3] = { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX,
Expand Down Expand Up @@ -2323,10 +2320,13 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
*ebx = (cpu->apic_id << 24) |
8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
*ecx = env->features[FEAT_1_ECX];
if ((*ecx & CPUID_EXT_XSAVE) && (env->cr[4] & CR4_OSXSAVE_MASK)) {
*ecx |= CPUID_EXT_OSXSAVE;
}
*edx = env->features[FEAT_1_EDX];
if (cs->nr_cores * cs->nr_threads > 1) {
*ebx |= (cs->nr_cores * cs->nr_threads) << 16;
*edx |= 1 << 28; /* HTT bit */
*edx |= CPUID_HT;
}
break;
case 2:
Expand Down Expand Up @@ -2450,43 +2450,47 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
break;
case 0xD: {
KVMState *s = cs->kvm_state;
uint64_t kvm_mask;
uint64_t ena_mask;
int i;

/* Processor Extended State */
*eax = 0;
*ebx = 0;
*ecx = 0;
*edx = 0;
if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE) || !kvm_enabled()) {
if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) {
break;
}
kvm_mask =
kvm_arch_get_supported_cpuid(s, 0xd, 0, R_EAX) |
((uint64_t)kvm_arch_get_supported_cpuid(s, 0xd, 0, R_EDX) << 32);
if (kvm_enabled()) {
ena_mask = kvm_arch_get_supported_cpuid(s, 0xd, 0, R_EDX);
ena_mask <<= 32;
ena_mask |= kvm_arch_get_supported_cpuid(s, 0xd, 0, R_EAX);
} else {
ena_mask = -1;
}

if (count == 0) {
*ecx = 0x240;
for (i = 2; i < ARRAY_SIZE(ext_save_areas); i++) {
const ExtSaveArea *esa = &ext_save_areas[i];
if ((env->features[esa->feature] & esa->bits) == esa->bits &&
(kvm_mask & (1 << i)) != 0) {
for (i = 2; i < ARRAY_SIZE(x86_ext_save_areas); i++) {
const ExtSaveArea *esa = &x86_ext_save_areas[i];
if ((env->features[esa->feature] & esa->bits) == esa->bits
&& ((ena_mask >> i) & 1) != 0) {
if (i < 32) {
*eax |= 1 << i;
*eax |= 1u << i;
} else {
*edx |= 1 << (i - 32);
*edx |= 1u << (i - 32);
}
*ecx = MAX(*ecx, esa->offset + esa->size);
}
}
*eax |= kvm_mask & (XSTATE_FP | XSTATE_SSE);
*eax |= ena_mask & (XSTATE_FP | XSTATE_SSE);
*ebx = *ecx;
} else if (count == 1) {
*eax = env->features[FEAT_XSAVE];
} else if (count < ARRAY_SIZE(ext_save_areas)) {
const ExtSaveArea *esa = &ext_save_areas[count];
if ((env->features[esa->feature] & esa->bits) == esa->bits &&
(kvm_mask & (1 << count)) != 0) {
} else if (count < ARRAY_SIZE(x86_ext_save_areas)) {
const ExtSaveArea *esa = &x86_ext_save_areas[count];
if ((env->features[esa->feature] & esa->bits) == esa->bits
&& ((ena_mask >> count) & 1) != 0) {
*eax = esa->size;
*ebx = esa->offset;
}
Expand Down Expand Up @@ -2639,6 +2643,8 @@ static void x86_cpu_reset(CPUState *s)
X86CPU *cpu = X86_CPU(s);
X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu);
CPUX86State *env = &cpu->env;
target_ulong cr4;
uint64_t xcr0;
int i;

xcc->parent_reset(s);
Expand Down Expand Up @@ -2698,7 +2704,8 @@ static void x86_cpu_reset(CPUState *s)
cpu_set_fpuc(env, 0x37f);

env->mxcsr = 0x1f80;
env->xstate_bv = XSTATE_FP | XSTATE_SSE;
/* All units are in INIT state. */
env->xstate_bv = 0;

env->pat = 0x0007040600070406ULL;
env->msr_ia32_misc_enable = MSR_IA32_MISC_ENABLE_DEFAULT;
Expand All @@ -2709,7 +2716,27 @@ static void x86_cpu_reset(CPUState *s)
cpu_breakpoint_remove_all(s, BP_CPU);
cpu_watchpoint_remove_all(s, BP_CPU);

env->xcr0 = 1;
cr4 = 0;
xcr0 = XSTATE_FP;

#ifdef CONFIG_USER_ONLY
/* Enable all the features for user-mode. */
if (env->features[FEAT_1_EDX] & CPUID_SSE) {
xcr0 |= XSTATE_SSE;
}
if (env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_MPX) {
xcr0 |= XSTATE_BNDREGS | XSTATE_BNDCSR;
}
if (env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE) {
cr4 |= CR4_OSFXSR_MASK | CR4_OSXSAVE_MASK;
}
if (env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_FSGSBASE) {
cr4 |= CR4_FSGSBASE_MASK;
}
#endif

env->xcr0 = xcr0;
cpu_x86_update_cr4(env, cr4);

/*
* SDM 11.11.5 requires:
Expand Down
21 changes: 20 additions & 1 deletion target-i386/cpu.h
Expand Up @@ -156,6 +156,8 @@
#define HF_OSFXSR_SHIFT 22 /* CR4.OSFXSR */
#define HF_SMAP_SHIFT 23 /* CR4.SMAP */
#define HF_IOBPT_SHIFT 24 /* an io breakpoint enabled */
#define HF_MPX_EN_SHIFT 25 /* MPX Enabled (CR4+XCR0+BNDCFGx) */
#define HF_MPX_IU_SHIFT 26 /* BND registers in-use */

#define HF_CPL_MASK (3 << HF_CPL_SHIFT)
#define HF_SOFTMMU_MASK (1 << HF_SOFTMMU_SHIFT)
Expand All @@ -180,6 +182,8 @@
#define HF_OSFXSR_MASK (1 << HF_OSFXSR_SHIFT)
#define HF_SMAP_MASK (1 << HF_SMAP_SHIFT)
#define HF_IOBPT_MASK (1 << HF_IOBPT_SHIFT)
#define HF_MPX_EN_MASK (1 << HF_MPX_EN_SHIFT)
#define HF_MPX_IU_MASK (1 << HF_MPX_IU_SHIFT)

/* hflags2 */

Expand All @@ -188,12 +192,14 @@
#define HF2_NMI_SHIFT 2 /* CPU serving NMI */
#define HF2_VINTR_SHIFT 3 /* value of V_INTR_MASKING bit */
#define HF2_SMM_INSIDE_NMI_SHIFT 4 /* CPU serving SMI nested inside NMI */
#define HF2_MPX_PR_SHIFT 5 /* BNDCFGx.BNDPRESERVE */

#define HF2_GIF_MASK (1 << HF2_GIF_SHIFT)
#define HF2_HIF_MASK (1 << HF2_HIF_SHIFT)
#define HF2_NMI_MASK (1 << HF2_NMI_SHIFT)
#define HF2_VINTR_MASK (1 << HF2_VINTR_SHIFT)
#define HF2_SMM_INSIDE_NMI_MASK (1 << HF2_SMM_INSIDE_NMI_SHIFT)
#define HF2_MPX_PR_MASK (1 << HF2_MPX_PR_SHIFT)

#define CR0_PE_SHIFT 0
#define CR0_MP_SHIFT 1
Expand Down Expand Up @@ -753,6 +759,10 @@ typedef struct BNDCSReg {
uint64_t sts;
} BNDCSReg;

#define BNDCFG_ENABLE 1ULL
#define BNDCFG_BNDPRESERVE 2ULL
#define BNDCFG_BDIR_MASK TARGET_PAGE_MASK

#ifdef HOST_WORDS_BIGENDIAN
#define ZMM_B(n) _b_ZMMReg[63 - (n)]
#define ZMM_W(n) _w_ZMMReg[31 - (n)]
Expand Down Expand Up @@ -1121,7 +1131,14 @@ void cpu_x86_frstor(CPUX86State *s, target_ulong ptr, int data32);
int cpu_x86_signal_handler(int host_signum, void *pinfo,
void *puc);

/* cpuid.c */
/* cpu.c */
typedef struct ExtSaveArea {
uint32_t feature, bits;
uint32_t offset, size;
} ExtSaveArea;

extern const ExtSaveArea x86_ext_save_areas[];

void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
uint32_t *eax, uint32_t *ebx,
uint32_t *ecx, uint32_t *edx);
Expand Down Expand Up @@ -1342,6 +1359,8 @@ void cpu_report_tpr_access(CPUX86State *env, TPRAccess access);
*/
void x86_cpu_change_kvm_default(const char *prop, const char *value);

/* mpx_helper.c */
void cpu_sync_bndcs_hflags(CPUX86State *env);

/* Return name of 32-bit register, from a R_* constant */
const char *get_register_name_32(unsigned int reg);
Expand Down

0 comments on commit 80b5d6b

Please sign in to comment.