aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kvm/lapic.c21
-rw-r--r--arch/x86/kvm/x86.c25
-rw-r--r--include/asm-x86/kvm_host.h1
-rw-r--r--include/linux/kvm.h17
-rw-r--r--include/linux/kvm_host.h2
5 files changed, 65 insertions, 1 deletions
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 4076331b01ee..50c3f3a8dd3d 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -551,6 +551,23 @@ static u32 apic_get_tmcct(struct kvm_lapic *apic)
551 return tmcct; 551 return tmcct;
552} 552}
553 553
554static void __report_tpr_access(struct kvm_lapic *apic, bool write)
555{
556 struct kvm_vcpu *vcpu = apic->vcpu;
557 struct kvm_run *run = vcpu->run;
558
559 set_bit(KVM_REQ_REPORT_TPR_ACCESS, &vcpu->requests);
560 kvm_x86_ops->cache_regs(vcpu);
561 run->tpr_access.rip = vcpu->arch.rip;
562 run->tpr_access.is_write = write;
563}
564
565static inline void report_tpr_access(struct kvm_lapic *apic, bool write)
566{
567 if (apic->vcpu->arch.tpr_access_reporting)
568 __report_tpr_access(apic, write);
569}
570
554static u32 __apic_read(struct kvm_lapic *apic, unsigned int offset) 571static u32 __apic_read(struct kvm_lapic *apic, unsigned int offset)
555{ 572{
556 u32 val = 0; 573 u32 val = 0;
@@ -568,6 +585,9 @@ static u32 __apic_read(struct kvm_lapic *apic, unsigned int offset)
568 val = apic_get_tmcct(apic); 585 val = apic_get_tmcct(apic);
569 break; 586 break;
570 587
588 case APIC_TASKPRI:
589 report_tpr_access(apic, false);
590 /* fall thru */
571 default: 591 default:
572 apic_update_ppr(apic); 592 apic_update_ppr(apic);
573 val = apic_get_reg(apic, offset); 593 val = apic_get_reg(apic, offset);
@@ -677,6 +697,7 @@ static void apic_mmio_write(struct kvm_io_device *this,
677 break; 697 break;
678 698
679 case APIC_TASKPRI: 699 case APIC_TASKPRI:
700 report_tpr_access(apic, true);
680 apic_set_tpr(apic, val & 0xff); 701 apic_set_tpr(apic, val & 0xff);
681 break; 702 break;
682 703
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 513258c797ca..c2b80884447e 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -684,6 +684,7 @@ int kvm_dev_ioctl_check_extension(long ext)
684 case KVM_CAP_USER_MEMORY: 684 case KVM_CAP_USER_MEMORY:
685 case KVM_CAP_SET_TSS_ADDR: 685 case KVM_CAP_SET_TSS_ADDR:
686 case KVM_CAP_EXT_CPUID: 686 case KVM_CAP_EXT_CPUID:
687 case KVM_CAP_VAPIC:
687 r = 1; 688 r = 1;
688 break; 689 break;
689 default: 690 default:
@@ -1055,6 +1056,15 @@ static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
1055 return 0; 1056 return 0;
1056} 1057}
1057 1058
1059static int vcpu_ioctl_tpr_access_reporting(struct kvm_vcpu *vcpu,
1060 struct kvm_tpr_access_ctl *tac)
1061{
1062 if (tac->flags)
1063 return -EINVAL;
1064 vcpu->arch.tpr_access_reporting = !!tac->enabled;
1065 return 0;
1066}
1067
1058long kvm_arch_vcpu_ioctl(struct file *filp, 1068long kvm_arch_vcpu_ioctl(struct file *filp,
1059 unsigned int ioctl, unsigned long arg) 1069 unsigned int ioctl, unsigned long arg)
1060{ 1070{
@@ -1148,6 +1158,21 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
1148 case KVM_SET_MSRS: 1158 case KVM_SET_MSRS:
1149 r = msr_io(vcpu, argp, do_set_msr, 0); 1159 r = msr_io(vcpu, argp, do_set_msr, 0);
1150 break; 1160 break;
1161 case KVM_TPR_ACCESS_REPORTING: {
1162 struct kvm_tpr_access_ctl tac;
1163
1164 r = -EFAULT;
1165 if (copy_from_user(&tac, argp, sizeof tac))
1166 goto out;
1167 r = vcpu_ioctl_tpr_access_reporting(vcpu, &tac);
1168 if (r)
1169 goto out;
1170 r = -EFAULT;
1171 if (copy_to_user(argp, &tac, sizeof tac))
1172 goto out;
1173 r = 0;
1174 break;
1175 };
1151 default: 1176 default:
1152 r = -EINVAL; 1177 r = -EINVAL;
1153 } 1178 }
diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h
index ced1bebabbc8..6e649af08d19 100644
--- a/include/asm-x86/kvm_host.h
+++ b/include/asm-x86/kvm_host.h
@@ -211,6 +211,7 @@ struct kvm_vcpu_arch {
211 int mp_state; 211 int mp_state;
212 int sipi_vector; 212 int sipi_vector;
213 u64 ia32_misc_enable_msr; 213 u64 ia32_misc_enable_msr;
214 bool tpr_access_reporting;
214 215
215 struct kvm_mmu mmu; 216 struct kvm_mmu mmu;
216 217
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index de9f28d96ced..850f5ef76636 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -72,6 +72,7 @@ struct kvm_irqchip {
72#define KVM_EXIT_FAIL_ENTRY 9 72#define KVM_EXIT_FAIL_ENTRY 9
73#define KVM_EXIT_INTR 10 73#define KVM_EXIT_INTR 10
74#define KVM_EXIT_SET_TPR 11 74#define KVM_EXIT_SET_TPR 11
75#define KVM_EXIT_TPR_ACCESS 12
75 76
76/* for KVM_RUN, returned by mmap(vcpu_fd, offset=0) */ 77/* for KVM_RUN, returned by mmap(vcpu_fd, offset=0) */
77struct kvm_run { 78struct kvm_run {
@@ -130,6 +131,12 @@ struct kvm_run {
130 __u32 longmode; 131 __u32 longmode;
131 __u32 pad; 132 __u32 pad;
132 } hypercall; 133 } hypercall;
134 /* KVM_EXIT_TPR_ACCESS */
135 struct {
136 __u64 rip;
137 __u32 is_write;
138 __u32 pad;
139 } tpr_access;
133 /* Fix the size of the union. */ 140 /* Fix the size of the union. */
134 char padding[256]; 141 char padding[256];
135 }; 142 };
@@ -202,6 +209,13 @@ struct kvm_signal_mask {
202 __u8 sigset[0]; 209 __u8 sigset[0];
203}; 210};
204 211
212/* for KVM_TPR_ACCESS_REPORTING */
213struct kvm_tpr_access_ctl {
214 __u32 enabled;
215 __u32 flags;
216 __u32 reserved[8];
217};
218
205#define KVMIO 0xAE 219#define KVMIO 0xAE
206 220
207/* 221/*
@@ -229,6 +243,7 @@ struct kvm_signal_mask {
229#define KVM_CAP_USER_MEMORY 3 243#define KVM_CAP_USER_MEMORY 3
230#define KVM_CAP_SET_TSS_ADDR 4 244#define KVM_CAP_SET_TSS_ADDR 4
231#define KVM_CAP_EXT_CPUID 5 245#define KVM_CAP_EXT_CPUID 5
246#define KVM_CAP_VAPIC 6
232 247
233/* 248/*
234 * ioctls for VM fds 249 * ioctls for VM fds
@@ -274,5 +289,7 @@ struct kvm_signal_mask {
274#define KVM_SET_LAPIC _IOW(KVMIO, 0x8f, struct kvm_lapic_state) 289#define KVM_SET_LAPIC _IOW(KVMIO, 0x8f, struct kvm_lapic_state)
275#define KVM_SET_CPUID2 _IOW(KVMIO, 0x90, struct kvm_cpuid2) 290#define KVM_SET_CPUID2 _IOW(KVMIO, 0x90, struct kvm_cpuid2)
276#define KVM_GET_CPUID2 _IOWR(KVMIO, 0x91, struct kvm_cpuid2) 291#define KVM_GET_CPUID2 _IOWR(KVMIO, 0x91, struct kvm_cpuid2)
292/* Available with KVM_CAP_VAPIC */
293#define KVM_TPR_ACCESS_REPORTING _IOWR(KVMIO, 0x92, struct kvm_tpr_access_ctl)
277 294
278#endif 295#endif
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 953b50aa0e61..9ff5904c5072 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -35,7 +35,7 @@
35 * vcpu->requests bit members 35 * vcpu->requests bit members
36 */ 36 */
37#define KVM_REQ_TLB_FLUSH 0 37#define KVM_REQ_TLB_FLUSH 0
38 38#define KVM_REQ_REPORT_TPR_ACCESS 2
39 39
40struct kvm_vcpu; 40struct kvm_vcpu;
41extern struct kmem_cache *kvm_vcpu_cache; 41extern struct kmem_cache *kvm_vcpu_cache;