diff options
author | Gleb Natapov <gleb@redhat.com> | 2010-01-25 05:01:04 -0500 |
---|---|---|
committer | Marcelo Tosatti <mtosatti@redhat.com> | 2010-03-01 10:36:06 -0500 |
commit | e01c2426149d70dc6dd46ad0453195656b6eeaa4 (patch) | |
tree | 84c9e16ac21c7a78c3aa1f6308adfa26c6c742a4 /arch/x86/kvm/x86.c | |
parent | 81231c698a71af6e1815df72c06685d295e1cc1d (diff) |
KVM: mark segments accessed on HW task switch
On HW task switch newly loaded segments should me marked as accessed.
Reported-by: Lorenzo Martignoni <martignlo@gmail.com>
Signed-off-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r-- | arch/x86/kvm/x86.c | 22 |
1 files changed, 9 insertions, 13 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 3b90298fb980..d47ceda7a928 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -4697,18 +4697,6 @@ static u16 get_segment_selector(struct kvm_vcpu *vcpu, int seg) | |||
4697 | return kvm_seg.selector; | 4697 | return kvm_seg.selector; |
4698 | } | 4698 | } |
4699 | 4699 | ||
4700 | static int load_segment_descriptor_to_kvm_desct(struct kvm_vcpu *vcpu, | ||
4701 | u16 selector, | ||
4702 | struct kvm_segment *kvm_seg) | ||
4703 | { | ||
4704 | struct desc_struct seg_desc; | ||
4705 | |||
4706 | if (load_guest_segment_descriptor(vcpu, selector, &seg_desc)) | ||
4707 | return 1; | ||
4708 | seg_desct_to_kvm_desct(&seg_desc, selector, kvm_seg); | ||
4709 | return 0; | ||
4710 | } | ||
4711 | |||
4712 | static int kvm_load_realmode_segment(struct kvm_vcpu *vcpu, u16 selector, int seg) | 4700 | static int kvm_load_realmode_segment(struct kvm_vcpu *vcpu, u16 selector, int seg) |
4713 | { | 4701 | { |
4714 | struct kvm_segment segvar = { | 4702 | struct kvm_segment segvar = { |
@@ -4749,11 +4737,14 @@ int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, | |||
4749 | int type_bits, int seg) | 4737 | int type_bits, int seg) |
4750 | { | 4738 | { |
4751 | struct kvm_segment kvm_seg; | 4739 | struct kvm_segment kvm_seg; |
4740 | struct desc_struct seg_desc; | ||
4752 | 4741 | ||
4753 | if (is_vm86_segment(vcpu, seg) || !is_protmode(vcpu)) | 4742 | if (is_vm86_segment(vcpu, seg) || !is_protmode(vcpu)) |
4754 | return kvm_load_realmode_segment(vcpu, selector, seg); | 4743 | return kvm_load_realmode_segment(vcpu, selector, seg); |
4755 | if (load_segment_descriptor_to_kvm_desct(vcpu, selector, &kvm_seg)) | 4744 | |
4745 | if (load_guest_segment_descriptor(vcpu, selector, &seg_desc)) | ||
4756 | return 1; | 4746 | return 1; |
4747 | seg_desct_to_kvm_desct(&seg_desc, selector, &kvm_seg); | ||
4757 | 4748 | ||
4758 | kvm_check_segment_descriptor(vcpu, seg, selector); | 4749 | kvm_check_segment_descriptor(vcpu, seg, selector); |
4759 | kvm_seg.type |= type_bits; | 4750 | kvm_seg.type |= type_bits; |
@@ -4764,6 +4755,11 @@ int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, | |||
4764 | kvm_seg.unusable = 1; | 4755 | kvm_seg.unusable = 1; |
4765 | 4756 | ||
4766 | kvm_set_segment(vcpu, &kvm_seg, seg); | 4757 | kvm_set_segment(vcpu, &kvm_seg, seg); |
4758 | if (selector && !kvm_seg.unusable && kvm_seg.s) { | ||
4759 | /* mark segment as accessed */ | ||
4760 | seg_desc.type |= 1; | ||
4761 | save_guest_segment_descriptor(vcpu, selector, &seg_desc); | ||
4762 | } | ||
4767 | return 0; | 4763 | return 0; |
4768 | } | 4764 | } |
4769 | 4765 | ||