aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoerg Roedel <joerg.roedel@amd.com>2010-11-30 12:03:58 -0500
committerAvi Kivity <avi@redhat.com>2011-01-12 04:30:11 -0500
commit3aed041a4c1b78cac87db76cf264b081df64dd37 (patch)
treedfaa91c967b0ccf261bae663069fc5dabc5bdccb
parent4ee546b434504a618eac40421e595c68e494da9f (diff)
KVM: SVM: Add manipulation functions for DRx intercepts
This patch wraps changes to the DRx intercepts of SVM into seperate functions to abstract nested-svm better and prepare the implementation of the vmcb-clean-bits feature. Signed-off-by: Joerg Roedel <joerg.roedel@amd.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
-rw-r--r--arch/x86/include/asm/svm.h27
-rw-r--r--arch/x86/kvm/svm.c80
2 files changed, 61 insertions, 46 deletions
diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h
index 39f9ddf07136..11dbca7a582a 100644
--- a/arch/x86/include/asm/svm.h
+++ b/arch/x86/include/asm/svm.h
@@ -52,8 +52,7 @@ enum {
52 52
53struct __attribute__ ((__packed__)) vmcb_control_area { 53struct __attribute__ ((__packed__)) vmcb_control_area {
54 u32 intercept_cr; 54 u32 intercept_cr;
55 u16 intercept_dr_read; 55 u32 intercept_dr;
56 u16 intercept_dr_write;
57 u32 intercept_exceptions; 56 u32 intercept_exceptions;
58 u64 intercept; 57 u64 intercept;
59 u8 reserved_1[42]; 58 u8 reserved_1[42];
@@ -212,14 +211,22 @@ struct __attribute__ ((__packed__)) vmcb {
212#define INTERCEPT_CR4_WRITE (16 + 4) 211#define INTERCEPT_CR4_WRITE (16 + 4)
213#define INTERCEPT_CR8_WRITE (16 + 8) 212#define INTERCEPT_CR8_WRITE (16 + 8)
214 213
215#define INTERCEPT_DR0_MASK 1 214#define INTERCEPT_DR0_READ 0
216#define INTERCEPT_DR1_MASK (1 << 1) 215#define INTERCEPT_DR1_READ 1
217#define INTERCEPT_DR2_MASK (1 << 2) 216#define INTERCEPT_DR2_READ 2
218#define INTERCEPT_DR3_MASK (1 << 3) 217#define INTERCEPT_DR3_READ 3
219#define INTERCEPT_DR4_MASK (1 << 4) 218#define INTERCEPT_DR4_READ 4
220#define INTERCEPT_DR5_MASK (1 << 5) 219#define INTERCEPT_DR5_READ 5
221#define INTERCEPT_DR6_MASK (1 << 6) 220#define INTERCEPT_DR6_READ 6
222#define INTERCEPT_DR7_MASK (1 << 7) 221#define INTERCEPT_DR7_READ 7
222#define INTERCEPT_DR0_WRITE (16 + 0)
223#define INTERCEPT_DR1_WRITE (16 + 1)
224#define INTERCEPT_DR2_WRITE (16 + 2)
225#define INTERCEPT_DR3_WRITE (16 + 3)
226#define INTERCEPT_DR4_WRITE (16 + 4)
227#define INTERCEPT_DR5_WRITE (16 + 5)
228#define INTERCEPT_DR6_WRITE (16 + 6)
229#define INTERCEPT_DR7_WRITE (16 + 7)
223 230
224#define SVM_EVTINJ_VEC_MASK 0xff 231#define SVM_EVTINJ_VEC_MASK 0xff
225 232
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 1e7bb9c77084..a7c38eb9d2e3 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -99,8 +99,7 @@ struct nested_state {
99 99
100 /* cache for intercepts of the guest */ 100 /* cache for intercepts of the guest */
101 u32 intercept_cr; 101 u32 intercept_cr;
102 u16 intercept_dr_read; 102 u32 intercept_dr;
103 u16 intercept_dr_write;
104 u32 intercept_exceptions; 103 u32 intercept_exceptions;
105 u64 intercept; 104 u64 intercept;
106 105
@@ -204,8 +203,7 @@ static void recalc_intercepts(struct vcpu_svm *svm)
204 g = &svm->nested; 203 g = &svm->nested;
205 204
206 c->intercept_cr = h->intercept_cr | g->intercept_cr; 205 c->intercept_cr = h->intercept_cr | g->intercept_cr;
207 c->intercept_dr_read = h->intercept_dr_read | g->intercept_dr_read; 206 c->intercept_dr = h->intercept_dr | g->intercept_dr;
208 c->intercept_dr_write = h->intercept_dr_write | g->intercept_dr_write;
209 c->intercept_exceptions = h->intercept_exceptions | g->intercept_exceptions; 207 c->intercept_exceptions = h->intercept_exceptions | g->intercept_exceptions;
210 c->intercept = h->intercept | g->intercept; 208 c->intercept = h->intercept | g->intercept;
211} 209}
@@ -243,6 +241,24 @@ static inline bool is_cr_intercept(struct vcpu_svm *svm, int bit)
243 return vmcb->control.intercept_cr & (1U << bit); 241 return vmcb->control.intercept_cr & (1U << bit);
244} 242}
245 243
244static inline void set_dr_intercept(struct vcpu_svm *svm, int bit)
245{
246 struct vmcb *vmcb = get_host_vmcb(svm);
247
248 vmcb->control.intercept_dr |= (1U << bit);
249
250 recalc_intercepts(svm);
251}
252
253static inline void clr_dr_intercept(struct vcpu_svm *svm, int bit)
254{
255 struct vmcb *vmcb = get_host_vmcb(svm);
256
257 vmcb->control.intercept_dr &= ~(1U << bit);
258
259 recalc_intercepts(svm);
260}
261
246static inline void enable_gif(struct vcpu_svm *svm) 262static inline void enable_gif(struct vcpu_svm *svm)
247{ 263{
248 svm->vcpu.arch.hflags |= HF_GIF_MASK; 264 svm->vcpu.arch.hflags |= HF_GIF_MASK;
@@ -807,23 +823,23 @@ static void init_vmcb(struct vcpu_svm *svm)
807 set_cr_intercept(svm, INTERCEPT_CR4_WRITE); 823 set_cr_intercept(svm, INTERCEPT_CR4_WRITE);
808 set_cr_intercept(svm, INTERCEPT_CR8_WRITE); 824 set_cr_intercept(svm, INTERCEPT_CR8_WRITE);
809 825
810 control->intercept_dr_read = INTERCEPT_DR0_MASK | 826 set_dr_intercept(svm, INTERCEPT_DR0_READ);
811 INTERCEPT_DR1_MASK | 827 set_dr_intercept(svm, INTERCEPT_DR1_READ);
812 INTERCEPT_DR2_MASK | 828 set_dr_intercept(svm, INTERCEPT_DR2_READ);
813 INTERCEPT_DR3_MASK | 829 set_dr_intercept(svm, INTERCEPT_DR3_READ);
814 INTERCEPT_DR4_MASK | 830 set_dr_intercept(svm, INTERCEPT_DR4_READ);
815 INTERCEPT_DR5_MASK | 831 set_dr_intercept(svm, INTERCEPT_DR5_READ);
816 INTERCEPT_DR6_MASK | 832 set_dr_intercept(svm, INTERCEPT_DR6_READ);
817 INTERCEPT_DR7_MASK; 833 set_dr_intercept(svm, INTERCEPT_DR7_READ);
818 834
819 control->intercept_dr_write = INTERCEPT_DR0_MASK | 835 set_dr_intercept(svm, INTERCEPT_DR0_WRITE);
820 INTERCEPT_DR1_MASK | 836 set_dr_intercept(svm, INTERCEPT_DR1_WRITE);
821 INTERCEPT_DR2_MASK | 837 set_dr_intercept(svm, INTERCEPT_DR2_WRITE);
822 INTERCEPT_DR3_MASK | 838 set_dr_intercept(svm, INTERCEPT_DR3_WRITE);
823 INTERCEPT_DR4_MASK | 839 set_dr_intercept(svm, INTERCEPT_DR4_WRITE);
824 INTERCEPT_DR5_MASK | 840 set_dr_intercept(svm, INTERCEPT_DR5_WRITE);
825 INTERCEPT_DR6_MASK | 841 set_dr_intercept(svm, INTERCEPT_DR6_WRITE);
826 INTERCEPT_DR7_MASK; 842 set_dr_intercept(svm, INTERCEPT_DR7_WRITE);
827 843
828 control->intercept_exceptions = (1 << PF_VECTOR) | 844 control->intercept_exceptions = (1 << PF_VECTOR) |
829 (1 << UD_VECTOR) | 845 (1 << UD_VECTOR) |
@@ -1923,15 +1939,9 @@ static int nested_svm_intercept(struct vcpu_svm *svm)
1923 vmexit = NESTED_EXIT_DONE; 1939 vmexit = NESTED_EXIT_DONE;
1924 break; 1940 break;
1925 } 1941 }
1926 case SVM_EXIT_READ_DR0 ... SVM_EXIT_READ_DR7: { 1942 case SVM_EXIT_READ_DR0 ... SVM_EXIT_WRITE_DR7: {
1927 u32 dr_bits = 1 << (exit_code - SVM_EXIT_READ_DR0); 1943 u32 bit = 1U << (exit_code - SVM_EXIT_READ_DR0);
1928 if (svm->nested.intercept_dr_read & dr_bits) 1944 if (svm->nested.intercept_dr & bit)
1929 vmexit = NESTED_EXIT_DONE;
1930 break;
1931 }
1932 case SVM_EXIT_WRITE_DR0 ... SVM_EXIT_WRITE_DR7: {
1933 u32 dr_bits = 1 << (exit_code - SVM_EXIT_WRITE_DR0);
1934 if (svm->nested.intercept_dr_write & dr_bits)
1935 vmexit = NESTED_EXIT_DONE; 1945 vmexit = NESTED_EXIT_DONE;
1936 break; 1946 break;
1937 } 1947 }
@@ -1977,8 +1987,7 @@ static inline void copy_vmcb_control_area(struct vmcb *dst_vmcb, struct vmcb *fr
1977 struct vmcb_control_area *from = &from_vmcb->control; 1987 struct vmcb_control_area *from = &from_vmcb->control;
1978 1988
1979 dst->intercept_cr = from->intercept_cr; 1989 dst->intercept_cr = from->intercept_cr;
1980 dst->intercept_dr_read = from->intercept_dr_read; 1990 dst->intercept_dr = from->intercept_dr;
1981 dst->intercept_dr_write = from->intercept_dr_write;
1982 dst->intercept_exceptions = from->intercept_exceptions; 1991 dst->intercept_exceptions = from->intercept_exceptions;
1983 dst->intercept = from->intercept; 1992 dst->intercept = from->intercept;
1984 dst->iopm_base_pa = from->iopm_base_pa; 1993 dst->iopm_base_pa = from->iopm_base_pa;
@@ -2280,8 +2289,7 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm)
2280 2289
2281 /* cache intercepts */ 2290 /* cache intercepts */
2282 svm->nested.intercept_cr = nested_vmcb->control.intercept_cr; 2291 svm->nested.intercept_cr = nested_vmcb->control.intercept_cr;
2283 svm->nested.intercept_dr_read = nested_vmcb->control.intercept_dr_read; 2292 svm->nested.intercept_dr = nested_vmcb->control.intercept_dr;
2284 svm->nested.intercept_dr_write = nested_vmcb->control.intercept_dr_write;
2285 svm->nested.intercept_exceptions = nested_vmcb->control.intercept_exceptions; 2293 svm->nested.intercept_exceptions = nested_vmcb->control.intercept_exceptions;
2286 svm->nested.intercept = nested_vmcb->control.intercept; 2294 svm->nested.intercept = nested_vmcb->control.intercept;
2287 2295
@@ -2906,8 +2914,8 @@ void dump_vmcb(struct kvm_vcpu *vcpu)
2906 pr_err("VMCB Control Area:\n"); 2914 pr_err("VMCB Control Area:\n");
2907 pr_err("cr_read: %04x\n", control->intercept_cr & 0xffff); 2915 pr_err("cr_read: %04x\n", control->intercept_cr & 0xffff);
2908 pr_err("cr_write: %04x\n", control->intercept_cr >> 16); 2916 pr_err("cr_write: %04x\n", control->intercept_cr >> 16);
2909 pr_err("dr_read: %04x\n", control->intercept_dr_read); 2917 pr_err("dr_read: %04x\n", control->intercept_dr & 0xffff);
2910 pr_err("dr_write: %04x\n", control->intercept_dr_write); 2918 pr_err("dr_write: %04x\n", control->intercept_dr >> 16);
2911 pr_err("exceptions: %08x\n", control->intercept_exceptions); 2919 pr_err("exceptions: %08x\n", control->intercept_exceptions);
2912 pr_err("intercepts: %016llx\n", control->intercept); 2920 pr_err("intercepts: %016llx\n", control->intercept);
2913 pr_err("pause filter count: %d\n", control->pause_filter_count); 2921 pr_err("pause filter count: %d\n", control->pause_filter_count);