Skip to content

Commit 3eb4271

Browse files
eaugerchazy
authored andcommitted
KVM: arm/arm64: vgic-its: Implement KVM_DEV_ARM_ITS_CTRL_RESET
On reset we clear the valid bits of GITS_CBASER and GITS_BASER<n>. We also clear command queue registers and free the cache (device, collection, and lpi lists). As we need to take the same locks as save/restore functions, we create a vgic_its_ctrl() wrapper that handles KVM_DEV_ARM_VGIC_GRP_CTRL group functions. Reviewed-by: Christoffer Dall <[email protected]> Reviewed-by: Marc Zyngier <[email protected]> Signed-off-by: Eric Auger <[email protected]> Signed-off-by: Christoffer Dall <[email protected]>
1 parent ae204f8 commit 3eb4271

File tree

3 files changed

+58
-49
lines changed

3 files changed

+58
-49
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ struct kvm_arch_memory_slot {
221221
#define KVM_DEV_ARM_ITS_SAVE_TABLES 1
222222
#define KVM_DEV_ARM_ITS_RESTORE_TABLES 2
223223
#define KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES 3
224+
#define KVM_DEV_ARM_ITS_CTRL_RESET 4
224225

225226
/* KVM_IRQ_LINE irq field index values */
226227
#define KVM_ARM_IRQ_TYPE_SHIFT 24

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ struct kvm_arch_memory_slot {
233233
#define KVM_DEV_ARM_ITS_SAVE_TABLES 1
234234
#define KVM_DEV_ARM_ITS_RESTORE_TABLES 2
235235
#define KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES 3
236+
#define KVM_DEV_ARM_ITS_CTRL_RESET 4
236237

237238
/* Device Control API on vcpu fd */
238239
#define KVM_ARM_VCPU_PMU_V3_CTRL 0

virt/kvm/arm/vgic/vgic-its.c

Lines changed: 56 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2273,29 +2273,13 @@ static int vgic_its_restore_collection_table(struct vgic_its *its)
22732273
*/
22742274
static int vgic_its_save_tables_v0(struct vgic_its *its)
22752275
{
2276-
struct kvm *kvm = its->dev->kvm;
22772276
int ret;
22782277

2279-
mutex_lock(&kvm->lock);
2280-
mutex_lock(&its->its_lock);
2281-
2282-
if (!lock_all_vcpus(kvm)) {
2283-
mutex_unlock(&its->its_lock);
2284-
mutex_unlock(&kvm->lock);
2285-
return -EBUSY;
2286-
}
2287-
22882278
ret = vgic_its_save_device_tables(its);
22892279
if (ret)
2290-
goto out;
2291-
2292-
ret = vgic_its_save_collection_table(its);
2280+
return ret;
22932281

2294-
out:
2295-
unlock_all_vcpus(kvm);
2296-
mutex_unlock(&its->its_lock);
2297-
mutex_unlock(&kvm->lock);
2298-
return ret;
2282+
return vgic_its_save_collection_table(its);
22992283
}
23002284

23012285
/**
@@ -2305,29 +2289,13 @@ static int vgic_its_save_tables_v0(struct vgic_its *its)
23052289
*/
23062290
static int vgic_its_restore_tables_v0(struct vgic_its *its)
23072291
{
2308-
struct kvm *kvm = its->dev->kvm;
23092292
int ret;
23102293

2311-
mutex_lock(&kvm->lock);
2312-
mutex_lock(&its->its_lock);
2313-
2314-
if (!lock_all_vcpus(kvm)) {
2315-
mutex_unlock(&its->its_lock);
2316-
mutex_unlock(&kvm->lock);
2317-
return -EBUSY;
2318-
}
2319-
23202294
ret = vgic_its_restore_collection_table(its);
23212295
if (ret)
2322-
goto out;
2323-
2324-
ret = vgic_its_restore_device_tables(its);
2325-
out:
2326-
unlock_all_vcpus(kvm);
2327-
mutex_unlock(&its->its_lock);
2328-
mutex_unlock(&kvm->lock);
2296+
return ret;
23292297

2330-
return ret;
2298+
return vgic_its_restore_device_tables(its);
23312299
}
23322300

23332301
static int vgic_its_commit_v0(struct vgic_its *its)
@@ -2346,6 +2314,19 @@ static int vgic_its_commit_v0(struct vgic_its *its)
23462314
return 0;
23472315
}
23482316

2317+
static void vgic_its_reset(struct kvm *kvm, struct vgic_its *its)
2318+
{
2319+
/* We need to keep the ABI specific field values */
2320+
its->baser_coll_table &= ~GITS_BASER_VALID;
2321+
its->baser_device_table &= ~GITS_BASER_VALID;
2322+
its->cbaser = 0;
2323+
its->creadr = 0;
2324+
its->cwriter = 0;
2325+
its->enabled = 0;
2326+
vgic_its_free_device_list(kvm, its);
2327+
vgic_its_free_collection_list(kvm, its);
2328+
}
2329+
23492330
static int vgic_its_has_attr(struct kvm_device *dev,
23502331
struct kvm_device_attr *attr)
23512332
{
@@ -2360,6 +2341,8 @@ static int vgic_its_has_attr(struct kvm_device *dev,
23602341
switch (attr->attr) {
23612342
case KVM_DEV_ARM_VGIC_CTRL_INIT:
23622343
return 0;
2344+
case KVM_DEV_ARM_ITS_CTRL_RESET:
2345+
return 0;
23632346
case KVM_DEV_ARM_ITS_SAVE_TABLES:
23642347
return 0;
23652348
case KVM_DEV_ARM_ITS_RESTORE_TABLES:
@@ -2372,6 +2355,41 @@ static int vgic_its_has_attr(struct kvm_device *dev,
23722355
return -ENXIO;
23732356
}
23742357

2358+
static int vgic_its_ctrl(struct kvm *kvm, struct vgic_its *its, u64 attr)
2359+
{
2360+
const struct vgic_its_abi *abi = vgic_its_get_abi(its);
2361+
int ret = 0;
2362+
2363+
if (attr == KVM_DEV_ARM_VGIC_CTRL_INIT) /* Nothing to do */
2364+
return 0;
2365+
2366+
mutex_lock(&kvm->lock);
2367+
mutex_lock(&its->its_lock);
2368+
2369+
if (!lock_all_vcpus(kvm)) {
2370+
mutex_unlock(&its->its_lock);
2371+
mutex_unlock(&kvm->lock);
2372+
return -EBUSY;
2373+
}
2374+
2375+
switch (attr) {
2376+
case KVM_DEV_ARM_ITS_CTRL_RESET:
2377+
vgic_its_reset(kvm, its);
2378+
break;
2379+
case KVM_DEV_ARM_ITS_SAVE_TABLES:
2380+
ret = abi->save_tables(its);
2381+
break;
2382+
case KVM_DEV_ARM_ITS_RESTORE_TABLES:
2383+
ret = abi->restore_tables(its);
2384+
break;
2385+
}
2386+
2387+
unlock_all_vcpus(kvm);
2388+
mutex_unlock(&its->its_lock);
2389+
mutex_unlock(&kvm->lock);
2390+
return ret;
2391+
}
2392+
23752393
static int vgic_its_set_attr(struct kvm_device *dev,
23762394
struct kvm_device_attr *attr)
23772395
{
@@ -2397,19 +2415,8 @@ static int vgic_its_set_attr(struct kvm_device *dev,
23972415

23982416
return vgic_register_its_iodev(dev->kvm, its, addr);
23992417
}
2400-
case KVM_DEV_ARM_VGIC_GRP_CTRL: {
2401-
const struct vgic_its_abi *abi = vgic_its_get_abi(its);
2402-
2403-
switch (attr->attr) {
2404-
case KVM_DEV_ARM_VGIC_CTRL_INIT:
2405-
/* Nothing to do */
2406-
return 0;
2407-
case KVM_DEV_ARM_ITS_SAVE_TABLES:
2408-
return abi->save_tables(its);
2409-
case KVM_DEV_ARM_ITS_RESTORE_TABLES:
2410-
return abi->restore_tables(its);
2411-
}
2412-
}
2418+
case KVM_DEV_ARM_VGIC_GRP_CTRL:
2419+
return vgic_its_ctrl(dev->kvm, its, attr->attr);
24132420
case KVM_DEV_ARM_VGIC_GRP_ITS_REGS: {
24142421
u64 __user *uaddr = (u64 __user *)(long)attr->addr;
24152422
u64 reg;

0 commit comments

Comments
 (0)