Skip to content

Commit b0960b9

Browse files
James MorseMarc Zyngier
authored andcommitted
KVM: arm: Add 32bit get/set events support
arm64's new use of KVMs get_events/set_events API calls isn't just or RAS, it allows an SError that has been made pending by KVM as part of its device emulation to be migrated. Wire this up for 32bit too. We only need to read/write the HCR_VA bit, and check that no esr has been provided, as we don't yet support VDFSR. Signed-off-by: James Morse <[email protected]> Reviewed-by: Dongjiu Geng <[email protected]> Signed-off-by: Marc Zyngier <[email protected]>
1 parent 539aee0 commit b0960b9

File tree

5 files changed

+45
-8
lines changed

5 files changed

+45
-8
lines changed

Documentation/virtual/kvm/api.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -835,7 +835,7 @@ struct kvm_clock_data {
835835

836836
Capability: KVM_CAP_VCPU_EVENTS
837837
Extended by: KVM_CAP_INTR_SHADOW
838-
Architectures: x86, arm64
838+
Architectures: x86, arm, arm64
839839
Type: vcpu ioctl
840840
Parameters: struct kvm_vcpu_event (out)
841841
Returns: 0 on success, -1 on error
@@ -883,7 +883,7 @@ Only two fields are defined in the flags field:
883883
- KVM_VCPUEVENT_VALID_SMM may be set in the flags field to signal that
884884
smi contains a valid state.
885885

886-
ARM64:
886+
ARM/ARM64:
887887

888888
If the guest accesses a device that is being emulated by the host kernel in
889889
such a way that a real device would generate a physical SError, KVM may make
@@ -934,7 +934,7 @@ struct kvm_vcpu_events {
934934

935935
Capability: KVM_CAP_VCPU_EVENTS
936936
Extended by: KVM_CAP_INTR_SHADOW
937-
Architectures: x86, arm64
937+
Architectures: x86, arm, arm64
938938
Type: vcpu ioctl
939939
Parameters: struct kvm_vcpu_event (in)
940940
Returns: 0 on success, -1 on error
@@ -961,7 +961,7 @@ shall be written into the VCPU.
961961

962962
KVM_VCPUEVENT_VALID_SMM can only be set if KVM_CAP_X86_SMM is available.
963963

964-
ARM64:
964+
ARM/ARM64:
965965

966966
Set the pending SError exception state for this VCPU. It is not possible to
967967
'cancel' an Serror that has been made pending.

arch/arm/include/asm/kvm_host.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,11 @@ int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
216216
int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
217217
unsigned long kvm_call_hyp(void *hypfn, ...);
218218
void force_vm_exit(const cpumask_t *mask);
219+
int __kvm_arm_vcpu_get_events(struct kvm_vcpu *vcpu,
220+
struct kvm_vcpu_events *events);
221+
222+
int __kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu,
223+
struct kvm_vcpu_events *events);
219224

220225
#define KVM_ARCH_WANT_MMU_NOTIFIER
221226
int kvm_unmap_hva(struct kvm *kvm, unsigned long hva);

arch/arm/include/uapi/asm/kvm.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#define __KVM_HAVE_GUEST_DEBUG
2828
#define __KVM_HAVE_IRQ_LINE
2929
#define __KVM_HAVE_READONLY_MEM
30+
#define __KVM_HAVE_VCPU_EVENTS
3031

3132
#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
3233

@@ -125,6 +126,18 @@ struct kvm_sync_regs {
125126
struct kvm_arch_memory_slot {
126127
};
127128

129+
/* for KVM_GET/SET_VCPU_EVENTS */
130+
struct kvm_vcpu_events {
131+
struct {
132+
__u8 serror_pending;
133+
__u8 serror_has_esr;
134+
/* Align it to 8 bytes */
135+
__u8 pad[6];
136+
__u64 serror_esr;
137+
} exception;
138+
__u32 reserved[12];
139+
};
140+
128141
/* If you need to interpret the index values, here is the key: */
129142
#define KVM_REG_ARM_COPROC_MASK 0x000000000FFF0000
130143
#define KVM_REG_ARM_COPROC_SHIFT 16

arch/arm/kvm/guest.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,29 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
261261
return -EINVAL;
262262
}
263263

264+
265+
int __kvm_arm_vcpu_get_events(struct kvm_vcpu *vcpu,
266+
struct kvm_vcpu_events *events)
267+
{
268+
events->exception.serror_pending = !!(*vcpu_hcr(vcpu) & HCR_VA);
269+
270+
return 0;
271+
}
272+
273+
int __kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu,
274+
struct kvm_vcpu_events *events)
275+
{
276+
bool serror_pending = events->exception.serror_pending;
277+
bool has_esr = events->exception.serror_has_esr;
278+
279+
if (serror_pending && has_esr)
280+
return -EINVAL;
281+
else if (serror_pending)
282+
kvm_inject_vabt(vcpu);
283+
284+
return 0;
285+
}
286+
264287
int __attribute_const__ kvm_target_cpu(void)
265288
{
266289
switch (read_cpuid_part()) {

virt/kvm/arm/arm.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,7 +1050,6 @@ static int kvm_arm_vcpu_has_attr(struct kvm_vcpu *vcpu,
10501050
return ret;
10511051
}
10521052

1053-
#ifdef __KVM_HAVE_VCPU_EVENTS /* temporary: until 32bit is wired up */
10541053
static int kvm_arm_vcpu_get_events(struct kvm_vcpu *vcpu,
10551054
struct kvm_vcpu_events *events)
10561055
{
@@ -1076,7 +1075,6 @@ static int kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu,
10761075

10771076
return __kvm_arm_vcpu_set_events(vcpu, events);
10781077
}
1079-
#endif /* __KVM_HAVE_VCPU_EVENTS */
10801078

10811079
long kvm_arch_vcpu_ioctl(struct file *filp,
10821080
unsigned int ioctl, unsigned long arg)
@@ -1158,7 +1156,6 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
11581156
r = kvm_arm_vcpu_has_attr(vcpu, &attr);
11591157
break;
11601158
}
1161-
#ifdef __KVM_HAVE_VCPU_EVENTS
11621159
case KVM_GET_VCPU_EVENTS: {
11631160
struct kvm_vcpu_events events;
11641161

@@ -1178,7 +1175,6 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
11781175

11791176
return kvm_arm_vcpu_set_events(vcpu, &events);
11801177
}
1181-
#endif
11821178
default:
11831179
r = -EINVAL;
11841180
}

0 commit comments

Comments
 (0)