+/*
+ * Set up the vmcs to automatically save and restore system
+ * msrs. Don't touch the 64-bit msrs if the guest is in legacy
+ * mode, as fiddling with msrs is very expensive.
+ */
+static void setup_msrs(struct kvm_vcpu *vcpu)
+{
+ int nr_skip, nr_good_msrs;
+
+ if (is_long_mode(vcpu))
+ nr_skip = NR_BAD_MSRS;
+ else
+ nr_skip = NR_64BIT_MSRS;
+ nr_good_msrs = vcpu->nmsrs - nr_skip;
+
+ /*
+ * MSR_K6_STAR is only needed on long mode guests, and only
+ * if efer.sce is enabled.
+ */
+ if (find_msr_entry(vcpu, MSR_K6_STAR)) {
+ --nr_good_msrs;
+#ifdef CONFIG_X86_64
+ if (is_long_mode(vcpu) && (vcpu->shadow_efer & EFER_SCE))
+ ++nr_good_msrs;
+#endif
+ }
+
+ vmcs_writel(VM_ENTRY_MSR_LOAD_ADDR,
+ virt_to_phys(vcpu->guest_msrs + nr_skip));
+ vmcs_writel(VM_EXIT_MSR_STORE_ADDR,
+ virt_to_phys(vcpu->guest_msrs + nr_skip));
+ vmcs_writel(VM_EXIT_MSR_LOAD_ADDR,
+ virt_to_phys(vcpu->host_msrs + nr_skip));
+ vmcs_write32(VM_EXIT_MSR_STORE_COUNT, nr_good_msrs); /* 22.2.2 */
+ vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, nr_good_msrs); /* 22.2.2 */
+ vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, nr_good_msrs); /* 22.2.2 */
+}
+