Skip to contentSkip to conversation

KVM: x86: Extend KVM_SET_VCPU_EVENTS with selective updates

PATCH Superseded Jan Kiszka 4 participants 19 messages Dec 6, 2009 – Dec 16, 2009

Subsystems (4)
lore
Share & tools
lore

Jan Kiszka

author
#0 lore raw

PATCH 1/1 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.

---

 Documentation/kvm/api.txt  |   10 +++++++++-
 arch/x86/include/asm/kvm.h |    4 ++++
 arch/x86/kvm/x86.c         |    9 ++++++---
 3 files changed, 19 insertions(+), 4 deletions(-)
Documentation/kvm/api.txt +9 -1
index e1a1141..ee07e3a 100644
@@ -685,7 +685,7 @@ struct kvm_vcpu_events {
 		__u8 pad;
 	} nmi;
 	__u32 sipi_vector;
-	__u32 flags;   /* must be zero */
+	__u32 flags;
 };
 
 4.30 KVM_SET_VCPU_EVENTS
@@ -701,6 +701,14 @@ vcpu.
 
 See KVM_GET_VCPU_EVENTS for the data structure.
 
+Fields that may be modified asynchronously by running VCPUs can be excluded
+from the update. These fields are nmi.pending and sipi_vector. Set the
+corresponding mask bits in the flags field to suppress overwriting their
+current state:
+
+KVM_VCPUEVENT_MASK_NMI_PENDING - do not update nmi.pending
+KVM_VCPUEVENT_MASK_SIPI_VECTOR - do not update sipi_vector
+
 
 5. The kvm_run structure
 
arch/x86/include/asm/kvm.h +4 -0
index 950df43..acf8585 100644
@@ -254,6 +254,10 @@ struct kvm_reinject_control {
 	__u8 reserved[31];
 };
 
+/* When set in flags, skip corresponding fields on KVM_SET_VCPU_EVENTS */
+#define KVM_VCPUEVENT_MASK_NMI_PENDING	0x00000001
+#define KVM_VCPUEVENT_MASK_SIPI_VECTOR	0x00000002
+
 /* for KVM_GET/SET_VCPU_EVENTS */
 struct kvm_vcpu_events {
 	struct {
arch/x86/kvm/x86.c +6 -3
index dd15d7a..368843c 100644
@@ -1953,7 +1953,8 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu,
 static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
 					      struct kvm_vcpu_events *events)
 {
-	if (events->flags)
+	if (events->flags &
+	    ~(KVM_VCPUEVENT_MASK_NMI_PENDING | KVM_VCPUEVENT_MASK_SIPI_VECTOR))
 		return -EINVAL;
 
 	vcpu_load(vcpu);
@@ -1970,10 +1971,12 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
 		kvm_pic_clear_isr_ack(vcpu->kvm);
 
 	vcpu->arch.nmi_injected = events->nmi.injected;
-	vcpu->arch.nmi_pending = events->nmi.pending;
+	if (!(events->flags & KVM_VCPUEVENT_MASK_NMI_PENDING))
+		vcpu->arch.nmi_pending = events->nmi.pending;
 	kvm_x86_ops->set_nmi_mask(vcpu, events->nmi.masked);
 
-	vcpu->arch.sipi_vector = events->sipi_vector;
+	if (!(events->flags & KVM_VCPUEVENT_MASK_SIPI_VECTOR))
+		vcpu->arch.sipi_vector = events->sipi_vector;
 
 	vcpu_put(vcpu);
 
#1 lore raw
Quoted 4 lines · Jan Kiszka

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.

I think a positive flag (do update nmi and sipi_vector) will cause less confusion, no? If we do that, we'll need to set them on KVM_GET_VCPU_EVENTS.

Signature · 1 line
error compiling committee.c: too many arguments to function
author
#2 lore raw
Quoted 9 lines · Avi Kivity
Quoted 4 lines · Jan Kiszka

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.

I think a positive flag (do update nmi and sipi_vector) will cause less confusion, no? If we do that, we'll need to set them on KVM_GET_VCPU_EVENTS.

I'm fine with the former but I don't understand the latter.

Jan

author
#8 lore raw

PATCH v2 1/1 KVM: x86: Extend KVM_SET_VCPU_EVENTS with selective updates

In reply to Avi Kivity

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.

---

Changes in v2:
- invert selection logic

 Documentation/kvm/api.txt  |   10 +++++++++-
 arch/x86/include/asm/kvm.h |    4 ++++
 arch/x86/kvm/x86.c         |    9 ++++++---
 3 files changed, 19 insertions(+), 4 deletions(-)
Documentation/kvm/api.txt +9 -1
index e1a1141..b22592d 100644
@@ -685,7 +685,7 @@ struct kvm_vcpu_events {
 		__u8 pad;
 	} nmi;
 	__u32 sipi_vector;
-	__u32 flags;   /* must be zero */
+	__u32 flags;
 };
 
 4.30 KVM_SET_VCPU_EVENTS
@@ -701,6 +701,14 @@ vcpu.
 
 See KVM_GET_VCPU_EVENTS for the data structure.
 
+Fields that may be modified asynchronously by running VCPUs can be excluded
+from the update. These fields are nmi.pending and sipi_vector. Keep the
+corresponding bits in the flags field cleared to suppress overwriting the
+current in-kernel state. The bits are:
+
+KVM_VCPUEVENT_SET_NMI_PENDING - transfer nmi.pending to the kernel
+KVM_VCPUEVENT_SET_SIPI_VECTOR - transfer sipi_vector
+
 
 5. The kvm_run structure
 
arch/x86/include/asm/kvm.h +4 -0
index 950df43..d1a67ae 100644
@@ -254,6 +254,10 @@ struct kvm_reinject_control {
 	__u8 reserved[31];
 };
 
+/* When set in flags, include corresponding fields on KVM_SET_VCPU_EVENTS */
+#define KVM_VCPUEVENT_SET_NMI_PENDING	0x00000001
+#define KVM_VCPUEVENT_SET_SIPI_VECTOR	0x00000002
+
 /* for KVM_GET/SET_VCPU_EVENTS */
 struct kvm_vcpu_events {
 	struct {
arch/x86/kvm/x86.c +6 -3
index dd15d7a..e3c35ff 100644
@@ -1953,7 +1953,8 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu,
 static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
 					      struct kvm_vcpu_events *events)
 {
-	if (events->flags)
+	if (events->flags &
+	    ~(KVM_VCPUEVENT_SET_NMI_PENDING | KVM_VCPUEVENT_SET_SIPI_VECTOR))
 		return -EINVAL;
 
 	vcpu_load(vcpu);
@@ -1970,10 +1971,12 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
 		kvm_pic_clear_isr_ack(vcpu->kvm);
 
 	vcpu->arch.nmi_injected = events->nmi.injected;
-	vcpu->arch.nmi_pending = events->nmi.pending;
+	if (events->flags & KVM_VCPUEVENT_SET_NMI_PENDING)
+		vcpu->arch.nmi_pending = events->nmi.pending;
 	kvm_x86_ops->set_nmi_mask(vcpu, events->nmi.masked);
 
-	vcpu->arch.sipi_vector = events->sipi_vector;
+	if (events->flags & KVM_VCPUEVENT_SET_SIPI_VECTOR)
+		vcpu->arch.sipi_vector = events->sipi_vector;
 
 	vcpu_put(vcpu);
 
#9 lore raw
Quoted 5 lines · Jan Kiszka

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.

Can't you handle this in userspace entirely, only updating vcpu_events state when appropriate?

Shouldnt the vcpu be stopped in the first place, when its state is updated?

Quoted 83 lines

---

Changes in v2:
- invert selection logic

 Documentation/kvm/api.txt  |   10 +++++++++-
 arch/x86/include/asm/kvm.h |    4 ++++
 arch/x86/kvm/x86.c         |    9 ++++++---
 3 files changed, 19 insertions(+), 4 deletions(-)
Documentation/kvm/api.txt +9 -1
index e1a1141..b22592d 100644
@@ -685,7 +685,7 @@ struct kvm_vcpu_events {
 		__u8 pad;
 	} nmi;
 	__u32 sipi_vector;
-	__u32 flags;   /* must be zero */
+	__u32 flags;
 };
 
 4.30 KVM_SET_VCPU_EVENTS
@@ -701,6 +701,14 @@ vcpu.
 
 See KVM_GET_VCPU_EVENTS for the data structure.
 
+Fields that may be modified asynchronously by running VCPUs can be excluded
+from the update. These fields are nmi.pending and sipi_vector. Keep the
+corresponding bits in the flags field cleared to suppress overwriting the
+current in-kernel state. The bits are:
+
+KVM_VCPUEVENT_SET_NMI_PENDING - transfer nmi.pending to the kernel
+KVM_VCPUEVENT_SET_SIPI_VECTOR - transfer sipi_vector
+
 
 5. The kvm_run structure
 
arch/x86/include/asm/kvm.h +4 -0
index 950df43..d1a67ae 100644
@@ -254,6 +254,10 @@ struct kvm_reinject_control {
 	__u8 reserved[31];
 };
 
+/* When set in flags, include corresponding fields on KVM_SET_VCPU_EVENTS */
+#define KVM_VCPUEVENT_SET_NMI_PENDING	0x00000001
+#define KVM_VCPUEVENT_SET_SIPI_VECTOR	0x00000002
+
 /* for KVM_GET/SET_VCPU_EVENTS */
 struct kvm_vcpu_events {
 	struct {
arch/x86/kvm/x86.c +6 -3
index dd15d7a..e3c35ff 100644
@@ -1953,7 +1953,8 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu,
 static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
 					      struct kvm_vcpu_events *events)
 {
-	if (events->flags)
+	if (events->flags &
+	    ~(KVM_VCPUEVENT_SET_NMI_PENDING | KVM_VCPUEVENT_SET_SIPI_VECTOR))
 		return -EINVAL;
 
 	vcpu_load(vcpu);
@@ -1970,10 +1971,12 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
 		kvm_pic_clear_isr_ack(vcpu->kvm);
 
 	vcpu->arch.nmi_injected = events->nmi.injected;
-	vcpu->arch.nmi_pending = events->nmi.pending;
+	if (events->flags & KVM_VCPUEVENT_SET_NMI_PENDING)
+		vcpu->arch.nmi_pending = events->nmi.pending;
 	kvm_x86_ops->set_nmi_mask(vcpu, events->nmi.masked);
 
-	vcpu->arch.sipi_vector = events->sipi_vector;
+	if (events->flags & KVM_VCPUEVENT_SET_SIPI_VECTOR)
+		vcpu->arch.sipi_vector = events->sipi_vector;
 
 	vcpu_put(vcpu);
 
#10 lore raw
Quoted 11 lines · Marcelo Tosatti
Quoted 6 lines · Jan Kiszka

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.

Can't you handle this in userspace entirely, only updating vcpu_events state when appropriate?

For what we do now I think you're right, it can be handled in userspace.

But in general, there's currently no way to update vcpu_events without overwriting nmi and sipi_vector, which can also be written concurrently by other vcpus. So there's a hole in the interface.

Quoted 3 lines

Shouldnt the vcpu be stopped in the first place, when its state is updated?

It is stopped, but other vcpus are not.

Signature · 1 line
error compiling committee.c: too many arguments to function
#11 lore raw
Quoted 19 lines · Avi Kivity
Quoted 11 lines · Marcelo Tosatti
Quoted 6 lines · Jan Kiszka

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.

Can't you handle this in userspace entirely, only updating vcpu_events state when appropriate?

For what we do now I think you're right, it can be handled in userspace.

But in general, there's currently no way to update vcpu_events without overwriting nmi and sipi_vector, which can also be written concurrently by other vcpus. So there's a hole in the interface.

Quoted 5 lines
Quoted 3 lines

Shouldnt the vcpu be stopped in the first place, when its state is updated?

It is stopped, but other vcpus are not.

I don't see the need for setting any state in kvm_vcpu_events automatically, on kernel entry (apparently there was consensus that saving similar state explicitly in qemu was the way to go).

kvm_arch_put_registers in qemu saves mpstate now that way, and the same problem is present.

The sites to load vcpu_events would be machine reset and cpu_load only, right?

author
#12 lore raw
Quoted 19 lines · Marcelo Tosatti
Quoted 18 lines · Avi Kivity
Quoted 11 lines · Marcelo Tosatti
Quoted 6 lines · Jan Kiszka

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.

Can't you handle this in userspace entirely, only updating vcpu_events state when appropriate?

For what we do now I think you're right, it can be handled in userspace.

But in general, there's currently no way to update vcpu_events without overwriting nmi and sipi_vector, which can also be written concurrently by other vcpus. So there's a hole in the interface.

Quoted 8 lines
Quoted 4 lines
Quoted 3 lines

Shouldnt the vcpu be stopped in the first place, when its state is updated?

It is stopped, but other vcpus are not.

I don't see the need for setting any state in kvm_vcpu_events automatically, on kernel entry (apparently there was consensus that saving similar state explicitly in qemu was the way to go).

(I don't think so. IMHO the cleaner way is to avoid loading critical states unless we are resetting or vmloading.)

Quoted 6 lines

kvm_arch_put_registers in qemu saves mpstate now that way, and the same problem is present.

The sites to load vcpu_events would be machine reset and cpu_load only, right?

That is how qemu use it, currently. But this interface should be designed with more flexibility. For the (yet theoretical) case you want to update RIP of a single VCPU, you also have to reset all the context-related states but maybe not the asynchronously changing ones like nmi.pending. We have no such use case yet, but KVM should not prevent them by design (if the change is so trivial).

Jan

#17 lore raw
In reply to Jan Kiszka
Quoted 4 lines · Jan Kiszka

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.

What will happen to this patch now? Merge during 2.6.33 window or drop?

Jan

Quoted 81 lines

---

 Documentation/kvm/api.txt  |   10 +++++++++-
 arch/x86/include/asm/kvm.h |    4 ++++
 arch/x86/kvm/x86.c         |    9 ++++++---
 3 files changed, 19 insertions(+), 4 deletions(-)
Documentation/kvm/api.txt +9 -1
index e1a1141..ee07e3a 100644
@@ -685,7 +685,7 @@ struct kvm_vcpu_events {
 		__u8 pad;
 	} nmi;
 	__u32 sipi_vector;
-	__u32 flags;   /* must be zero */
+	__u32 flags;
 };
 
 4.30 KVM_SET_VCPU_EVENTS
@@ -701,6 +701,14 @@ vcpu.
 
 See KVM_GET_VCPU_EVENTS for the data structure.
 
+Fields that may be modified asynchronously by running VCPUs can be excluded
+from the update. These fields are nmi.pending and sipi_vector. Set the
+corresponding mask bits in the flags field to suppress overwriting their
+current state:
+
+KVM_VCPUEVENT_MASK_NMI_PENDING - do not update nmi.pending
+KVM_VCPUEVENT_MASK_SIPI_VECTOR - do not update sipi_vector
+
 
 5. The kvm_run structure
 
arch/x86/include/asm/kvm.h +4 -0
index 950df43..acf8585 100644
@@ -254,6 +254,10 @@ struct kvm_reinject_control {
 	__u8 reserved[31];
 };
 
+/* When set in flags, skip corresponding fields on KVM_SET_VCPU_EVENTS */
+#define KVM_VCPUEVENT_MASK_NMI_PENDING	0x00000001
+#define KVM_VCPUEVENT_MASK_SIPI_VECTOR	0x00000002
+
 /* for KVM_GET/SET_VCPU_EVENTS */
 struct kvm_vcpu_events {
 	struct {
arch/x86/kvm/x86.c +6 -3
index dd15d7a..368843c 100644
@@ -1953,7 +1953,8 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu,
 static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
 					      struct kvm_vcpu_events *events)
 {
-	if (events->flags)
+	if (events->flags &
+	    ~(KVM_VCPUEVENT_MASK_NMI_PENDING | KVM_VCPUEVENT_MASK_SIPI_VECTOR))
 		return -EINVAL;
 
 	vcpu_load(vcpu);
@@ -1970,10 +1971,12 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
 		kvm_pic_clear_isr_ack(vcpu->kvm);
 
 	vcpu->arch.nmi_injected = events->nmi.injected;
-	vcpu->arch.nmi_pending = events->nmi.pending;
+	if (!(events->flags & KVM_VCPUEVENT_MASK_NMI_PENDING))
+		vcpu->arch.nmi_pending = events->nmi.pending;
 	kvm_x86_ops->set_nmi_mask(vcpu, events->nmi.masked);
 
-	vcpu->arch.sipi_vector = events->sipi_vector;
+	if (!(events->flags & KVM_VCPUEVENT_MASK_SIPI_VECTOR))
+		vcpu->arch.sipi_vector = events->sipi_vector;
 
 	vcpu_put(vcpu);
 
Signature · 2 lines
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux
#18 lore raw
Quoted 9 lines · Jan Kiszka
Quoted 5 lines · Jan Kiszka

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.

What will happen to this patch now? Merge during 2.6.33 window or drop?

I'll merge it into 2.6.33.

Signature · 1 line
error compiling committee.c: too many arguments to function
#13 lore raw
In reply to Jan Kiszka
Quoted 9 lines · Jan Kiszka
Quoted 5 lines

I don't see the need for setting any state in kvm_vcpu_events automatically, on kernel entry (apparently there was consensus that saving similar state explicitly in qemu was the way to go).

(I don't think so. IMHO the cleaner way is to avoid loading critical states unless we are resetting or vmloading.)

I now agree. But instead of SCOPE_RESET and SCOPE_RUNTIME (or whatever that was), how about SCOPE_GPR, SCOPE_FPU, SCOPE_SREGS etc. That means the backing code in kvm.c doesn't have to know what qemu is interested in wrt SCOPE_RESET, and it's easier for readers to infer what is meant.

Quoted 6 lines
Quoted 6 lines

kvm_arch_put_registers in qemu saves mpstate now that way, and the same problem is present.

The sites to load vcpu_events would be machine reset and cpu_load only, right?

Quoted 8 lines

That is how qemu use it, currently. But this interface should be designed with more flexibility. For the (yet theoretical) case you want to update RIP of a single VCPU, you also have to reset all the context-related states but maybe not the asynchronously changing ones like nmi.pending. We have no such use case yet, but KVM should not prevent them by design (if the change is so trivial).

Yes.

Signature · 1 line
error compiling committee.c: too many arguments to function
#3 lore raw
In reply to Jan Kiszka
Quoted 9 lines · Jan Kiszka
Quoted 7 lines · Avi Kivity
Quoted 5 lines · Jan Kiszka

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.

Quoted 7 lines
Quoted 4 lines

I think a positive flag (do update nmi and sipi_vector) will cause less confusion, no? If we do that, we'll need to set them on KVM_GET_VCPU_EVENTS.

I'm fine with the former but I don't understand the latter.

What I meant was the on KVM_GET_VCPU_EVENTS, the two flags should be set. This way, the meaning of the flags is identical on both: the associated field contains valid data.

I made this change to your v2 and applied and queued for .33. Please review (in next) to make sure it makes sense.

Signature · 1 line
error compiling committee.c: too many arguments to function
author
#4 lore raw
Quoted 18 lines · Avi Kivity
Quoted 9 lines · Jan Kiszka
Quoted 7 lines · Avi Kivity
Quoted 5 lines · Jan Kiszka

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.

Quoted 7 lines
Quoted 4 lines

I think a positive flag (do update nmi and sipi_vector) will cause less confusion, no? If we do that, we'll need to set them on KVM_GET_VCPU_EVENTS.

I'm fine with the former but I don't understand the latter.

Quoted 7 lines

What I meant was the on KVM_GET_VCPU_EVENTS, the two flags should be set. This way, the meaning of the flags is identical on both: the associated field contains valid data.

I made this change to your v2 and applied and queued for .33. Please review (in next) to make sure it makes sense.

OK, but calling these bits "SET" makes no sense anymore. What about KVM_VCPUEVENT_VALID_*?

Jan

author
#14 lore raw
In reply to Avi Kivity
Quoted 11 lines · Avi Kivity
Quoted 9 lines · Jan Kiszka
Quoted 5 lines

I don't see the need for setting any state in kvm_vcpu_events automatically, on kernel entry (apparently there was consensus that saving similar state explicitly in qemu was the way to go).

(I don't think so. IMHO the cleaner way is to avoid loading critical states unless we are resetting or vmloading.)

Quoted 4 lines

I now agree. But instead of SCOPE_RESET and SCOPE_RUNTIME (or whatever that was), how about SCOPE_GPR, SCOPE_FPU, SCOPE_SREGS etc. That means the backing code in kvm.c doesn't have to know what qemu is interested in wrt SCOPE_RESET, and it's easier for readers to infer what is meant.

That's not my idea. I want to be able to state the scope in generic, arch-independent, KVM-unaware code. What the scope actually means /wrt writeback should only be defined in the arch-specific kvm service implementing it. Your suggestion would go in the wrong direction IMO.

Jan

#5 lore raw
In reply to Jan Kiszka
Quoted 4 lines · Jan Kiszka

OK, but calling these bits "SET" makes no sense anymore. What about KVM_VCPUEVENT_VALID_*?

Sure. Want to patch?

Signature · 1 line
error compiling committee.c: too many arguments to function
#15 lore raw
In reply to Jan Kiszka
Quoted 11 lines · Jan Kiszka
Quoted 6 lines

I now agree. But instead of SCOPE_RESET and SCOPE_RUNTIME (or whatever that was), how about SCOPE_GPR, SCOPE_FPU, SCOPE_SREGS etc. That means the backing code in kvm.c doesn't have to know what qemu is interested in wrt SCOPE_RESET, and it's easier for readers to infer what is meant.

That's not my idea. I want to be able to state the scope in generic, arch-independent, KVM-unaware code. What the scope actually means /wrt writeback should only be defined in the arch-specific kvm service implementing it. Your suggestion would go in the wrong direction IMO.

What I'm worried is how to tell which registers go in which scope? And contrariwise, when doing a cpu_synchronize_state(), how to select the scope? It's easy when there's just normal and reset, but what happens when we gain another one? The code may not know who calls it.

Signature · 1 line
error compiling committee.c: too many arguments to function
author
#16 lore raw
Quoted 13 lines · Avi Kivity
Quoted 11 lines · Jan Kiszka
Quoted 6 lines

I now agree. But instead of SCOPE_RESET and SCOPE_RUNTIME (or whatever that was), how about SCOPE_GPR, SCOPE_FPU, SCOPE_SREGS etc. That means the backing code in kvm.c doesn't have to know what qemu is interested in wrt SCOPE_RESET, and it's easier for readers to infer what is meant.

That's not my idea. I want to be able to state the scope in generic, arch-independent, KVM-unaware code. What the scope actually means /wrt writeback should only be defined in the arch-specific kvm service implementing it. Your suggestion would go in the wrong direction IMO.

Quoted 5 lines

What I'm worried is how to tell which registers go in which scope? And contrariwise, when doing a cpu_synchronize_state(), how to select the scope? It's easy when there's just normal and reset, but what happens when we gain another one? The code may not know who calls it.

In my original patch, scopes could only be widened: If we first sync'ed for potential register modifications and then added a sync for reset, the latter ruled on write-back. In my current idea, there would be three sync scopes (in increasing order):

CPU_SYNC_RUNTIME - only write states that cannot not change
asynchronously
CPU_SYNC_RESET - write everything that would change during a CPU
reset (excludes TSC MSR on x86)
CPU_SYNC_COMPLETE - write everything

I think these scopes are generic enough to match problems of other archs beyond x86 as well (though I don't if any exist).

Hope I'll find some time soon to code this down, but I'm currently stuffed with unrelated issues.

Jan

author
#6 lore raw

PATCH 1/1 KVM: x86: Adjust KVM_VCPUEVENT flag names

In reply to Avi Kivity
Quoted 8 lines · Avi Kivity
Quoted 4 lines · Jan Kiszka

OK, but calling these bits "SET" makes no sense anymore. What about KVM_VCPUEVENT_VALID_*?

Sure. Want to patch?

Here we go:

--------->

KVM: x86: Adjust KVM_VCPUEVENT flag names

They are also used on KVM_GET_VCPU_EVENTS, so 'VALID' is a better name element than 'SET'.

---

 Documentation/kvm/api.txt  |    4 ++--
 arch/x86/include/asm/kvm.h |    4 ++--
 arch/x86/kvm/x86.c         |   12 ++++++------
 3 files changed, 10 insertions(+), 10 deletions(-)
Documentation/kvm/api.txt +2 -2
index b22592d..2811e45 100644
@@ -706,8 +706,8 @@ from the update. These fields are nmi.pending and sipi_vector. Keep the
 corresponding bits in the flags field cleared to suppress overwriting the
 current in-kernel state. The bits are:
 
-KVM_VCPUEVENT_SET_NMI_PENDING - transfer nmi.pending to the kernel
-KVM_VCPUEVENT_SET_SIPI_VECTOR - transfer sipi_vector
+KVM_VCPUEVENT_VALID_NMI_PENDING - transfer nmi.pending to the kernel
+KVM_VCPUEVENT_VALID_SIPI_VECTOR - transfer sipi_vector
 
 
 5. The kvm_run structure
arch/x86/include/asm/kvm.h +2 -2
index d1a67ae..f46b79f 100644
@@ -255,8 +255,8 @@ struct kvm_reinject_control {
 };
 
 /* When set in flags, include corresponding fields on KVM_SET_VCPU_EVENTS */
-#define KVM_VCPUEVENT_SET_NMI_PENDING	0x00000001
-#define KVM_VCPUEVENT_SET_SIPI_VECTOR	0x00000002
+#define KVM_VCPUEVENT_VALID_NMI_PENDING	0x00000001
+#define KVM_VCPUEVENT_VALID_SIPI_VECTOR	0x00000002
 
 /* for KVM_GET/SET_VCPU_EVENTS */
 struct kvm_vcpu_events {
arch/x86/kvm/x86.c +6 -6
index e181c6f..0113752 100644
@@ -1945,8 +1945,8 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu,
 
 	events->sipi_vector = vcpu->arch.sipi_vector;
 
-	events->flags = (KVM_VCPUEVENT_SET_NMI_PENDING
-			 | KVM_VCPUEVENT_SET_SIPI_VECTOR);
+	events->flags = (KVM_VCPUEVENT_VALID_NMI_PENDING
+			 | KVM_VCPUEVENT_VALID_SIPI_VECTOR);
 
 	vcpu_put(vcpu);
 }
@@ -1954,8 +1954,8 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu,
 static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
 					      struct kvm_vcpu_events *events)
 {
-	if (events->flags &
-	    ~(KVM_VCPUEVENT_SET_NMI_PENDING | KVM_VCPUEVENT_SET_SIPI_VECTOR))
+	if (events->flags & ~(KVM_VCPUEVENT_VALID_NMI_PENDING
+			      | KVM_VCPUEVENT_VALID_SIPI_VECTOR))
 		return -EINVAL;
 
 	vcpu_load(vcpu);
@@ -1972,11 +1972,11 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
 		kvm_pic_clear_isr_ack(vcpu->kvm);
 
 	vcpu->arch.nmi_injected = events->nmi.injected;
-	if (events->flags & KVM_VCPUEVENT_SET_NMI_PENDING)
+	if (events->flags & KVM_VCPUEVENT_VALID_NMI_PENDING)
 		vcpu->arch.nmi_pending = events->nmi.pending;
 	kvm_x86_ops->set_nmi_mask(vcpu, events->nmi.masked);
 
-	if (events->flags & KVM_VCPUEVENT_SET_SIPI_VECTOR)
+	if (events->flags & KVM_VCPUEVENT_VALID_SIPI_VECTOR)
 		vcpu->arch.sipi_vector = events->sipi_vector;
 
 	vcpu_put(vcpu);
#7 lore raw

Re: [PATCH] KVM: x86: Adjust KVM_VCPUEVENT flag names

Quoted 4 lines · Jan Kiszka

They are also used on KVM_GET_VCPU_EVENTS, so 'VALID' is a better name element than 'SET'.

Thanks - applied and queued.

Signature · 1 line
error compiling committee.c: too many arguments to function