Commit 6bc31bdc authored by Andre Przywara's avatar Andre Przywara Committed by Avi Kivity

KVM: SVM: implement NEXTRIPsave SVM feature

On SVM we set the instruction length of skipped instructions
to hard-coded, well known values, which could be wrong when (bogus,
but valid) prefixes (REX, segment override) are used.
Newer AMD processors (Fam10h 45nm and better, aka. PhenomII or
AthlonII) have an explicit NEXTRIP field in the VMCB containing the
desired information.
Since it is cheap to do so, we use this field to override the guessed
value on newer processors.
A fix for older CPUs would be rather expensive, as it would require
to fetch and partially decode the instruction. As the problem is not
a security issue and needs special, handcrafted code to trigger
(no compiler will ever generate such code), I omit a fix for older
CPUs.
If someone is interested, I have both a patch for these CPUs as well as
demo code triggering this issue: It segfaults under KVM, but runs
perfectly on native Linux.
Signed-off-by: default avatarAndre Przywara <andre.przywara@amd.com>
Signed-off-by: default avatarMarcelo Tosatti <mtosatti@redhat.com>
parent f7a71197
...@@ -81,7 +81,9 @@ struct __attribute__ ((__packed__)) vmcb_control_area { ...@@ -81,7 +81,9 @@ struct __attribute__ ((__packed__)) vmcb_control_area {
u32 event_inj_err; u32 event_inj_err;
u64 nested_cr3; u64 nested_cr3;
u64 lbr_ctl; u64 lbr_ctl;
u8 reserved_5[832]; u64 reserved_5;
u64 next_rip;
u8 reserved_6[816];
}; };
......
...@@ -320,6 +320,9 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu) ...@@ -320,6 +320,9 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu)
{ {
struct vcpu_svm *svm = to_svm(vcpu); struct vcpu_svm *svm = to_svm(vcpu);
if (svm->vmcb->control.next_rip != 0)
svm->next_rip = svm->vmcb->control.next_rip;
if (!svm->next_rip) { if (!svm->next_rip) {
if (emulate_instruction(vcpu, 0, 0, EMULTYPE_SKIP) != if (emulate_instruction(vcpu, 0, 0, EMULTYPE_SKIP) !=
EMULATE_DONE) EMULATE_DONE)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment