diff options
| author | Jan Kiszka <jan.kiszka@web.de> | 2009-12-06 12:24:15 -0500 |
|---|---|---|
| committer | Marcelo Tosatti <mtosatti@redhat.com> | 2009-12-27 10:36:33 -0500 |
| commit | dab4b911a5327859bb8f969249c6978c26cd4853 (patch) | |
| tree | a21d0ef04e3bf831b2f9e674b6266535267cc9ce | |
| parent | 6e24a6eff4571002cd48b99a2b92dc829ce39cb9 (diff) | |
KVM: x86: Extend KVM_SET_VCPU_EVENTS with selective updates
User space may not want to overwrite asynchronously changing VCPU event
states on write-back. So allow to skip nmi.pending and sipi_vector by
setting corresponding bits in the flags field of kvm_vcpu_events.
[avi: advertise the bits in KVM_GET_VCPU_EVENTS]
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
| -rw-r--r-- | Documentation/kvm/api.txt | 10 | ||||
| -rw-r--r-- | arch/x86/include/asm/kvm.h | 4 | ||||
| -rw-r--r-- | arch/x86/kvm/x86.c | 12 |
3 files changed, 21 insertions, 5 deletions
diff --git a/Documentation/kvm/api.txt b/Documentation/kvm/api.txt index e1a114161027..2811e452f756 100644 --- a/Documentation/kvm/api.txt +++ b/Documentation/kvm/api.txt | |||
| @@ -685,7 +685,7 @@ struct kvm_vcpu_events { | |||
| 685 | __u8 pad; | 685 | __u8 pad; |
| 686 | } nmi; | 686 | } nmi; |
| 687 | __u32 sipi_vector; | 687 | __u32 sipi_vector; |
| 688 | __u32 flags; /* must be zero */ | 688 | __u32 flags; |
| 689 | }; | 689 | }; |
| 690 | 690 | ||
| 691 | 4.30 KVM_SET_VCPU_EVENTS | 691 | 4.30 KVM_SET_VCPU_EVENTS |
| @@ -701,6 +701,14 @@ vcpu. | |||
| 701 | 701 | ||
| 702 | See KVM_GET_VCPU_EVENTS for the data structure. | 702 | See KVM_GET_VCPU_EVENTS for the data structure. |
| 703 | 703 | ||
| 704 | Fields that may be modified asynchronously by running VCPUs can be excluded | ||
| 705 | from the update. These fields are nmi.pending and sipi_vector. Keep the | ||
| 706 | corresponding bits in the flags field cleared to suppress overwriting the | ||
| 707 | current in-kernel state. The bits are: | ||
| 708 | |||
| 709 | KVM_VCPUEVENT_VALID_NMI_PENDING - transfer nmi.pending to the kernel | ||
| 710 | KVM_VCPUEVENT_VALID_SIPI_VECTOR - transfer sipi_vector | ||
| 711 | |||
| 704 | 712 | ||
| 705 | 5. The kvm_run structure | 713 | 5. The kvm_run structure |
| 706 | 714 | ||
diff --git a/arch/x86/include/asm/kvm.h b/arch/x86/include/asm/kvm.h index 950df434763f..f46b79f6c16c 100644 --- a/arch/x86/include/asm/kvm.h +++ b/arch/x86/include/asm/kvm.h | |||
| @@ -254,6 +254,10 @@ struct kvm_reinject_control { | |||
| 254 | __u8 reserved[31]; | 254 | __u8 reserved[31]; |
| 255 | }; | 255 | }; |
| 256 | 256 | ||
| 257 | /* When set in flags, include corresponding fields on KVM_SET_VCPU_EVENTS */ | ||
| 258 | #define KVM_VCPUEVENT_VALID_NMI_PENDING 0x00000001 | ||
| 259 | #define KVM_VCPUEVENT_VALID_SIPI_VECTOR 0x00000002 | ||
| 260 | |||
| 257 | /* for KVM_GET/SET_VCPU_EVENTS */ | 261 | /* for KVM_GET/SET_VCPU_EVENTS */ |
| 258 | struct kvm_vcpu_events { | 262 | struct kvm_vcpu_events { |
| 259 | struct { | 263 | struct { |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 9d068966fb2a..6651dbf58675 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
| @@ -1913,7 +1913,8 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu, | |||
| 1913 | 1913 | ||
| 1914 | events->sipi_vector = vcpu->arch.sipi_vector; | 1914 | events->sipi_vector = vcpu->arch.sipi_vector; |
| 1915 | 1915 | ||
| 1916 | events->flags = 0; | 1916 | events->flags = (KVM_VCPUEVENT_VALID_NMI_PENDING |
| 1917 | | KVM_VCPUEVENT_VALID_SIPI_VECTOR); | ||
| 1917 | 1918 | ||
| 1918 | vcpu_put(vcpu); | 1919 | vcpu_put(vcpu); |
| 1919 | } | 1920 | } |
| @@ -1921,7 +1922,8 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu, | |||
| 1921 | static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu, | 1922 | static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu, |
| 1922 | struct kvm_vcpu_events *events) | 1923 | struct kvm_vcpu_events *events) |
| 1923 | { | 1924 | { |
| 1924 | if (events->flags) | 1925 | if (events->flags & ~(KVM_VCPUEVENT_VALID_NMI_PENDING |
| 1926 | | KVM_VCPUEVENT_VALID_SIPI_VECTOR)) | ||
| 1925 | return -EINVAL; | 1927 | return -EINVAL; |
| 1926 | 1928 | ||
| 1927 | vcpu_load(vcpu); | 1929 | vcpu_load(vcpu); |
| @@ -1938,10 +1940,12 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu, | |||
| 1938 | kvm_pic_clear_isr_ack(vcpu->kvm); | 1940 | kvm_pic_clear_isr_ack(vcpu->kvm); |
| 1939 | 1941 | ||
| 1940 | vcpu->arch.nmi_injected = events->nmi.injected; | 1942 | vcpu->arch.nmi_injected = events->nmi.injected; |
| 1941 | vcpu->arch.nmi_pending = events->nmi.pending; | 1943 | if (events->flags & KVM_VCPUEVENT_VALID_NMI_PENDING) |
| 1944 | vcpu->arch.nmi_pending = events->nmi.pending; | ||
| 1942 | kvm_x86_ops->set_nmi_mask(vcpu, events->nmi.masked); | 1945 | kvm_x86_ops->set_nmi_mask(vcpu, events->nmi.masked); |
| 1943 | 1946 | ||
| 1944 | vcpu->arch.sipi_vector = events->sipi_vector; | 1947 | if (events->flags & KVM_VCPUEVENT_VALID_SIPI_VECTOR) |
| 1948 | vcpu->arch.sipi_vector = events->sipi_vector; | ||
| 1945 | 1949 | ||
| 1946 | vcpu_put(vcpu); | 1950 | vcpu_put(vcpu); |
| 1947 | 1951 | ||
