Merge remote-tracking branch 'qemu-kvm/uq/master' into staging
* qemu-kvm/uq/master: kvm: always update the MPX model specific register KVM: fix addr type for KVM_IOEVENTFD KVM: Retry KVM_CREATE_VM on EINTR mempath prefault: fix off-by-one error kvm: x86: Separately write feature control MSR on reset roms: Flush icache when writing roms to guest memory target-i386: clear guest TSC on reset target-i386: do not special case TSC writeback target-i386: Intel MPX Conflicts: exec.c aliguori: fix trivial merge conflict in exec.c Signed-off-by: Anthony Liguori <aliguori@amazon.com>
This commit is contained in:
		
						commit
						0169c51155
					
				
							
								
								
									
										2
									
								
								exec.c
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								exec.c
									
									
									
									
									
								
							| @ -1070,7 +1070,7 @@ static void *file_ram_alloc(RAMBlock *block, | ||||
|         } | ||||
| 
 | ||||
|         /* MAP_POPULATE silently ignores failures */ | ||||
|         for (i = 0; i < (memory/hpagesize)-1; i++) { | ||||
|         for (i = 0; i < (memory/hpagesize); i++) { | ||||
|             memset(area + (hpagesize*i), 0, 1); | ||||
|         } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										14
									
								
								kvm-all.c
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								kvm-all.c
									
									
									
									
									
								
							| @ -499,7 +499,7 @@ int kvm_check_extension(KVMState *s, unsigned int extension) | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| static int kvm_set_ioeventfd_mmio(int fd, uint32_t addr, uint32_t val, | ||||
| static int kvm_set_ioeventfd_mmio(int fd, hwaddr addr, uint32_t val, | ||||
|                                   bool assign, uint32_t size, bool datamatch) | ||||
| { | ||||
|     int ret; | ||||
| @ -1422,16 +1422,22 @@ int kvm_init(void) | ||||
|         nc++; | ||||
|     } | ||||
| 
 | ||||
|     s->vmfd = kvm_ioctl(s, KVM_CREATE_VM, 0); | ||||
|     if (s->vmfd < 0) { | ||||
|     do { | ||||
|         ret = kvm_ioctl(s, KVM_CREATE_VM, 0); | ||||
|     } while (ret == -EINTR); | ||||
| 
 | ||||
|     if (ret < 0) { | ||||
|         fprintf(stderr, "ioctl(KVM_CREATE_VM) failed: %d %s\n", -s->vmfd, | ||||
|                 strerror(-ret)); | ||||
| 
 | ||||
| #ifdef TARGET_S390X | ||||
|         fprintf(stderr, "Please add the 'switch_amode' kernel parameter to " | ||||
|                         "your host kernel command line\n"); | ||||
| #endif | ||||
|         ret = s->vmfd; | ||||
|         goto err; | ||||
|     } | ||||
| 
 | ||||
|     s->vmfd = ret; | ||||
|     missing_cap = kvm_check_extension_list(s, kvm_required_capabilites); | ||||
|     if (!missing_cap) { | ||||
|         missing_cap = | ||||
|  | ||||
| @ -336,6 +336,10 @@ typedef struct ExtSaveArea { | ||||
| static const ExtSaveArea 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, | ||||
|             .offset = 0x3c0, .size = 0x40  }, | ||||
|     [4] = { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX, | ||||
|             .offset = 0x400, .size = 0x10  }, | ||||
| }; | ||||
| 
 | ||||
| const char *get_register_name_32(unsigned int reg) | ||||
| @ -2461,6 +2465,9 @@ static void x86_cpu_reset(CPUState *s) | ||||
|     cpu_breakpoint_remove_all(env, BP_CPU); | ||||
|     cpu_watchpoint_remove_all(env, BP_CPU); | ||||
| 
 | ||||
|     env->tsc_adjust = 0; | ||||
|     env->tsc = 0; | ||||
| 
 | ||||
| #if !defined(CONFIG_USER_ONLY) | ||||
|     /* We hard-wire the BSP to the first CPU. */ | ||||
|     if (s->cpu_index == 0) { | ||||
|  | ||||
| @ -380,9 +380,14 @@ | ||||
| 
 | ||||
| #define MSR_VM_HSAVE_PA                 0xc0010117 | ||||
| 
 | ||||
| #define XSTATE_FP                       1 | ||||
| #define XSTATE_SSE                      2 | ||||
| #define XSTATE_YMM                      4 | ||||
| #define MSR_IA32_BNDCFGS                0x00000d90 | ||||
| 
 | ||||
| #define XSTATE_FP                       (1ULL << 0) | ||||
| #define XSTATE_SSE                      (1ULL << 1) | ||||
| #define XSTATE_YMM                      (1ULL << 2) | ||||
| #define XSTATE_BNDREGS                  (1ULL << 3) | ||||
| #define XSTATE_BNDCSR                   (1ULL << 4) | ||||
| 
 | ||||
| 
 | ||||
| /* CPUID feature words */ | ||||
| typedef enum FeatureWord { | ||||
| @ -545,6 +550,7 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS]; | ||||
| #define CPUID_7_0_EBX_ERMS     (1 << 9) | ||||
| #define CPUID_7_0_EBX_INVPCID  (1 << 10) | ||||
| #define CPUID_7_0_EBX_RTM      (1 << 11) | ||||
| #define CPUID_7_0_EBX_MPX      (1 << 14) | ||||
| #define CPUID_7_0_EBX_RDSEED   (1 << 18) | ||||
| #define CPUID_7_0_EBX_ADX      (1 << 19) | ||||
| #define CPUID_7_0_EBX_SMAP     (1 << 20) | ||||
| @ -695,6 +701,16 @@ typedef union { | ||||
|     uint64_t q; | ||||
| } MMXReg; | ||||
| 
 | ||||
| typedef struct BNDReg { | ||||
|     uint64_t lb; | ||||
|     uint64_t ub; | ||||
| } BNDReg; | ||||
| 
 | ||||
| typedef struct BNDCSReg { | ||||
|     uint64_t cfgu; | ||||
|     uint64_t sts; | ||||
| } BNDCSReg; | ||||
| 
 | ||||
| #ifdef HOST_WORDS_BIGENDIAN | ||||
| #define XMM_B(n) _b[15 - (n)] | ||||
| #define XMM_W(n) _w[7 - (n)] | ||||
| @ -908,6 +924,9 @@ typedef struct CPUX86State { | ||||
| 
 | ||||
|     uint64_t xstate_bv; | ||||
|     XMMReg ymmh_regs[CPU_NB_REGS]; | ||||
|     BNDReg bnd_regs[4]; | ||||
|     BNDCSReg bndcs_regs; | ||||
|     uint64_t msr_bndcfgs; | ||||
| 
 | ||||
|     uint64_t xcr0; | ||||
| 
 | ||||
|  | ||||
| @ -69,6 +69,7 @@ static bool has_msr_feature_control; | ||||
| static bool has_msr_async_pf_en; | ||||
| static bool has_msr_pv_eoi_en; | ||||
| static bool has_msr_misc_enable; | ||||
| static bool has_msr_bndcfgs; | ||||
| static bool has_msr_kvm_steal_time; | ||||
| static int lm_capable_kernel; | ||||
| 
 | ||||
| @ -772,6 +773,10 @@ static int kvm_get_supported_msrs(KVMState *s) | ||||
|                     has_msr_misc_enable = true; | ||||
|                     continue; | ||||
|                 } | ||||
|                 if (kvm_msr_list->indices[i] == MSR_IA32_BNDCFGS) { | ||||
|                     has_msr_bndcfgs = true; | ||||
|                     continue; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| @ -975,6 +980,8 @@ static int kvm_put_fpu(X86CPU *cpu) | ||||
| #define XSAVE_XMM_SPACE   40 | ||||
| #define XSAVE_XSTATE_BV   128 | ||||
| #define XSAVE_YMMH_SPACE  144 | ||||
| #define XSAVE_BNDREGS     240 | ||||
| #define XSAVE_BNDCSR      256 | ||||
| 
 | ||||
| static int kvm_put_xsave(X86CPU *cpu) | ||||
| { | ||||
| @ -1007,6 +1014,10 @@ static int kvm_put_xsave(X86CPU *cpu) | ||||
|     *(uint64_t *)&xsave->region[XSAVE_XSTATE_BV] = env->xstate_bv; | ||||
|     memcpy(&xsave->region[XSAVE_YMMH_SPACE], env->ymmh_regs, | ||||
|             sizeof env->ymmh_regs); | ||||
|     memcpy(&xsave->region[XSAVE_BNDREGS], env->bnd_regs, | ||||
|             sizeof env->bnd_regs); | ||||
|     memcpy(&xsave->region[XSAVE_BNDCSR], &env->bndcs_regs, | ||||
|             sizeof(env->bndcs_regs)); | ||||
|     r = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_XSAVE, xsave); | ||||
|     return r; | ||||
| } | ||||
| @ -1104,6 +1115,25 @@ static int kvm_put_tscdeadline_msr(X86CPU *cpu) | ||||
|     return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MSRS, &msr_data); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Provide a separate write service for the feature control MSR in order to | ||||
|  * kick the VCPU out of VMXON or even guest mode on reset. This has to be done | ||||
|  * before writing any other state because forcibly leaving nested mode | ||||
|  * invalidates the VCPU state. | ||||
|  */ | ||||
| static int kvm_put_msr_feature_control(X86CPU *cpu) | ||||
| { | ||||
|     struct { | ||||
|         struct kvm_msrs info; | ||||
|         struct kvm_msr_entry entry; | ||||
|     } msr_data; | ||||
| 
 | ||||
|     kvm_msr_entry_set(&msr_data.entry, MSR_IA32_FEATURE_CONTROL, | ||||
|                       cpu->env.msr_ia32_feature_control); | ||||
|     msr_data.info.nmsrs = 1; | ||||
|     return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MSRS, &msr_data); | ||||
| } | ||||
| 
 | ||||
| static int kvm_put_msrs(X86CPU *cpu, int level) | ||||
| { | ||||
|     CPUX86State *env = &cpu->env; | ||||
| @ -1131,6 +1161,9 @@ static int kvm_put_msrs(X86CPU *cpu, int level) | ||||
|         kvm_msr_entry_set(&msrs[n++], MSR_IA32_MISC_ENABLE, | ||||
|                           env->msr_ia32_misc_enable); | ||||
|     } | ||||
|     if (has_msr_bndcfgs) { | ||||
|         kvm_msr_entry_set(&msrs[n++], MSR_IA32_BNDCFGS, env->msr_bndcfgs); | ||||
|     } | ||||
| #ifdef TARGET_X86_64 | ||||
|     if (lm_capable_kernel) { | ||||
|         kvm_msr_entry_set(&msrs[n++], MSR_CSTAR, env->cstar); | ||||
| @ -1139,22 +1172,12 @@ static int kvm_put_msrs(X86CPU *cpu, int level) | ||||
|         kvm_msr_entry_set(&msrs[n++], MSR_LSTAR, env->lstar); | ||||
|     } | ||||
| #endif | ||||
|     if (level == KVM_PUT_FULL_STATE) { | ||||
|         /*
 | ||||
|          * KVM is yet unable to synchronize TSC values of multiple VCPUs on | ||||
|          * writeback. Until this is fixed, we only write the offset to SMP | ||||
|          * guests after migration, desynchronizing the VCPUs, but avoiding | ||||
|          * huge jump-backs that would occur without any writeback at all. | ||||
|          */ | ||||
|         if (smp_cpus == 1 || env->tsc != 0) { | ||||
|             kvm_msr_entry_set(&msrs[n++], MSR_IA32_TSC, env->tsc); | ||||
|         } | ||||
|     } | ||||
|     /*
 | ||||
|      * The following MSRs have side effects on the guest or are too heavy | ||||
|      * for normal writeback. Limit them to reset or full state updates. | ||||
|      */ | ||||
|     if (level >= KVM_PUT_RESET_STATE) { | ||||
|         kvm_msr_entry_set(&msrs[n++], MSR_IA32_TSC, env->tsc); | ||||
|         kvm_msr_entry_set(&msrs[n++], MSR_KVM_SYSTEM_TIME, | ||||
|                           env->system_time_msr); | ||||
|         kvm_msr_entry_set(&msrs[n++], MSR_KVM_WALL_CLOCK, env->wall_clock_msr); | ||||
| @ -1204,10 +1227,9 @@ static int kvm_put_msrs(X86CPU *cpu, int level) | ||||
|         if (cpu->hyperv_vapic) { | ||||
|             kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_APIC_ASSIST_PAGE, 0); | ||||
|         } | ||||
|         if (has_msr_feature_control) { | ||||
|             kvm_msr_entry_set(&msrs[n++], MSR_IA32_FEATURE_CONTROL, | ||||
|                               env->msr_ia32_feature_control); | ||||
|         } | ||||
| 
 | ||||
|         /* Note: MSR_IA32_FEATURE_CONTROL is written separately, see
 | ||||
|          *       kvm_put_msr_feature_control. */ | ||||
|     } | ||||
|     if (env->mcg_cap) { | ||||
|         int i; | ||||
| @ -1289,6 +1311,10 @@ static int kvm_get_xsave(X86CPU *cpu) | ||||
|     env->xstate_bv = *(uint64_t *)&xsave->region[XSAVE_XSTATE_BV]; | ||||
|     memcpy(env->ymmh_regs, &xsave->region[XSAVE_YMMH_SPACE], | ||||
|             sizeof env->ymmh_regs); | ||||
|     memcpy(env->bnd_regs, &xsave->region[XSAVE_BNDREGS], | ||||
|             sizeof env->bnd_regs); | ||||
|     memcpy(&env->bndcs_regs, &xsave->region[XSAVE_BNDCSR], | ||||
|             sizeof(env->bndcs_regs)); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| @ -1435,6 +1461,9 @@ static int kvm_get_msrs(X86CPU *cpu) | ||||
|     if (has_msr_feature_control) { | ||||
|         msrs[n++].index = MSR_IA32_FEATURE_CONTROL; | ||||
|     } | ||||
|     if (has_msr_bndcfgs) { | ||||
|         msrs[n++].index = MSR_IA32_BNDCFGS; | ||||
|     } | ||||
| 
 | ||||
|     if (!env->tsc_valid) { | ||||
|         msrs[n++].index = MSR_IA32_TSC; | ||||
| @ -1550,6 +1579,9 @@ static int kvm_get_msrs(X86CPU *cpu) | ||||
|         case MSR_IA32_FEATURE_CONTROL: | ||||
|             env->msr_ia32_feature_control = msrs[i].data; | ||||
|             break; | ||||
|         case MSR_IA32_BNDCFGS: | ||||
|             env->msr_bndcfgs = msrs[i].data; | ||||
|             break; | ||||
|         default: | ||||
|             if (msrs[i].index >= MSR_MC0_CTL && | ||||
|                 msrs[i].index < MSR_MC0_CTL + (env->mcg_cap & 0xff) * 4) { | ||||
| @ -1799,6 +1831,13 @@ int kvm_arch_put_registers(CPUState *cpu, int level) | ||||
| 
 | ||||
|     assert(cpu_is_stopped(cpu) || qemu_cpu_is_self(cpu)); | ||||
| 
 | ||||
|     if (level >= KVM_PUT_RESET_STATE && has_msr_feature_control) { | ||||
|         ret = kvm_put_msr_feature_control(x86_cpu); | ||||
|         if (ret < 0) { | ||||
|             return ret; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     ret = kvm_getput_regs(x86_cpu, 1); | ||||
|     if (ret < 0) { | ||||
|         return ret; | ||||
|  | ||||
| @ -63,6 +63,21 @@ static const VMStateDescription vmstate_ymmh_reg = { | ||||
| #define VMSTATE_YMMH_REGS_VARS(_field, _state, _n, _v)                         \ | ||||
|     VMSTATE_STRUCT_ARRAY(_field, _state, _n, _v, vmstate_ymmh_reg, XMMReg) | ||||
| 
 | ||||
| static const VMStateDescription vmstate_bnd_regs = { | ||||
|     .name = "bnd_regs", | ||||
|     .version_id = 1, | ||||
|     .minimum_version_id = 1, | ||||
|     .minimum_version_id_old = 1, | ||||
|     .fields      = (VMStateField[]) { | ||||
|         VMSTATE_UINT64(lb, BNDReg), | ||||
|         VMSTATE_UINT64(ub, BNDReg), | ||||
|         VMSTATE_END_OF_LIST() | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| #define VMSTATE_BND_REGS(_field, _state, _n)          \ | ||||
|     VMSTATE_STRUCT_ARRAY(_field, _state, _n, 0, vmstate_bnd_regs, BNDReg) | ||||
| 
 | ||||
| static const VMStateDescription vmstate_mtrr_var = { | ||||
|     .name = "mtrr_var", | ||||
|     .version_id = 1, | ||||
| @ -506,6 +521,39 @@ static const VMStateDescription vmstate_msr_architectural_pmu = { | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| static bool mpx_needed(void *opaque) | ||||
| { | ||||
|     X86CPU *cpu = opaque; | ||||
|     CPUX86State *env = &cpu->env; | ||||
|     unsigned int i; | ||||
| 
 | ||||
|     for (i = 0; i < 4; i++) { | ||||
|         if (env->bnd_regs[i].lb || env->bnd_regs[i].ub) { | ||||
|             return true; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (env->bndcs_regs.cfgu || env->bndcs_regs.sts) { | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     return !!env->msr_bndcfgs; | ||||
| } | ||||
| 
 | ||||
| static const VMStateDescription vmstate_mpx = { | ||||
|     .name = "cpu/mpx", | ||||
|     .version_id = 1, | ||||
|     .minimum_version_id = 1, | ||||
|     .minimum_version_id_old = 1, | ||||
|     .fields      = (VMStateField[]) { | ||||
|         VMSTATE_BND_REGS(env.bnd_regs, X86CPU, 4), | ||||
|         VMSTATE_UINT64(env.bndcs_regs.cfgu, X86CPU), | ||||
|         VMSTATE_UINT64(env.bndcs_regs.sts, X86CPU), | ||||
|         VMSTATE_UINT64(env.msr_bndcfgs, X86CPU), | ||||
|         VMSTATE_END_OF_LIST() | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| const VMStateDescription vmstate_x86_cpu = { | ||||
|     .name = "cpu", | ||||
|     .version_id = 12, | ||||
| @ -637,6 +685,9 @@ const VMStateDescription vmstate_x86_cpu = { | ||||
|         }, { | ||||
|             .vmsd = &vmstate_msr_architectural_pmu, | ||||
|             .needed = pmu_enable_needed, | ||||
|         } , { | ||||
|             .vmsd = &vmstate_mpx, | ||||
|             .needed = mpx_needed, | ||||
|         } , { | ||||
|             /* empty */ | ||||
|         } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Anthony Liguori
						Anthony Liguori