On Tue, Jan 03, 2012 at 11:38:13PM -0500, Boris Ostrovsky wrote:
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index e32243e..b19769d 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -110,6 +110,13 @@ struct nested_state {
#define MSRPM_OFFSETS 16
static u32 msrpm_offsets[MSRPM_OFFSETS] __read_mostly;
+/*
+ * Set osvw_len to higher value when updated Revision Guides
+ * are published and we know what the new status bits are
+ */
+static uint64_t osvw_len = 4, osvw_status;
+static DEFINE_SPINLOCK(svm_lock);
No need for this lock, operation already serialized by kvm_lock.
struct vcpu_svm {
struct kvm_vcpu vcpu;
struct vmcb *vmcb;
@@ -556,6 +563,20 @@ static void svm_init_erratum_383(void)
erratum_383_found = true;
}
+static void svm_init_osvw(struct kvm_vcpu *vcpu)
+{
+ /*
+ * Guests should see errata 400 and 415 as fixed (assuming that
+ * HLT and IO instructions are intercepted).
+ */
+ vcpu->arch.osvw.length = (osvw_len>= 3) ? (osvw_len) : 3;
+ vcpu->arch.osvw.status = osvw_status& ~(6ULL);
Do you really want to expose the hosts osvw_status and osvw_len? If
only exposure of 400 and 415 as fixed is necessary, then dealing with
migration is simpler (that is, you control what workarounds are applied
in the guest instead of making it dependent on particular hosts).
+ /* Mark erratum 298 as present */
+ if (osvw_len == 0&& boot_cpu_data.x86 == 0x10)
+ vcpu->arch.osvw.status |= 1;
+}
Why is it necessary to explicitly do this? Please add documentation.
+ case MSR_AMD64_OSVW_ID_LENGTH:
+ if (!guest_cpuid_has_osvw(vcpu))
+ return 1;
+ vcpu->arch.osvw.length = data;
+ break;
+ case MSR_AMD64_OSVW_STATUS:
+ if (!guest_cpuid_has_osvw(vcpu))
+ return 1;
+ vcpu->arch.osvw.status = data;
+ break;
If writes are allowed, it is necessary to migrate this.