aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Auger <eric.auger@redhat.com>2017-10-26 11:23:11 -0400
committerChristoffer Dall <christoffer.dall@linaro.org>2017-11-06 10:23:19 -0500
commit3eb4271b4ab6d38a3c113a19f358f606702e08ef (patch)
treefff5da9bc0f0fb5cb4403bda552648bda4b1a84b
parentae204f80ca4074b6db07bd28c75faf02718735a0 (diff)
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 <christoffer.dall@linaro.org> Reviewed-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
-rw-r--r--arch/arm/include/uapi/asm/kvm.h1
-rw-r--r--arch/arm64/include/uapi/asm/kvm.h1
-rw-r--r--virt/kvm/arm/vgic/vgic-its.c105
3 files changed, 58 insertions, 49 deletions
diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
index 665c454e50d0..b56895593c84 100644
--- a/arch/arm/include/uapi/asm/kvm.h
+++ b/arch/arm/include/uapi/asm/kvm.h
@@ -221,6 +221,7 @@ struct kvm_arch_memory_slot {
221#define KVM_DEV_ARM_ITS_SAVE_TABLES 1 221#define KVM_DEV_ARM_ITS_SAVE_TABLES 1
222#define KVM_DEV_ARM_ITS_RESTORE_TABLES 2 222#define KVM_DEV_ARM_ITS_RESTORE_TABLES 2
223#define KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES 3 223#define KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES 3
224#define KVM_DEV_ARM_ITS_CTRL_RESET 4
224 225
225/* KVM_IRQ_LINE irq field index values */ 226/* KVM_IRQ_LINE irq field index values */
226#define KVM_ARM_IRQ_TYPE_SHIFT 24 227#define KVM_ARM_IRQ_TYPE_SHIFT 24
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 0004feef7cc2..37ca7394549c 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -233,6 +233,7 @@ struct kvm_arch_memory_slot {
233#define KVM_DEV_ARM_ITS_SAVE_TABLES 1 233#define KVM_DEV_ARM_ITS_SAVE_TABLES 1
234#define KVM_DEV_ARM_ITS_RESTORE_TABLES 2 234#define KVM_DEV_ARM_ITS_RESTORE_TABLES 2
235#define KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES 3 235#define KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES 3
236#define KVM_DEV_ARM_ITS_CTRL_RESET 4
236 237
237/* Device Control API on vcpu fd */ 238/* Device Control API on vcpu fd */
238#define KVM_ARM_VCPU_PMU_V3_CTRL 0 239#define KVM_ARM_VCPU_PMU_V3_CTRL 0
diff --git a/virt/kvm/arm/vgic/vgic-its.c b/virt/kvm/arm/vgic/vgic-its.c
index 1732e08a4375..40791c121710 100644
--- a/virt/kvm/arm/vgic/vgic-its.c
+++ b/virt/kvm/arm/vgic/vgic-its.c
@@ -2273,29 +2273,13 @@ static int vgic_its_restore_collection_table(struct vgic_its *its)
2273 */ 2273 */
2274static int vgic_its_save_tables_v0(struct vgic_its *its) 2274static int vgic_its_save_tables_v0(struct vgic_its *its)
2275{ 2275{
2276 struct kvm *kvm = its->dev->kvm;
2277 int ret; 2276 int ret;
2278 2277
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
2288 ret = vgic_its_save_device_tables(its); 2278 ret = vgic_its_save_device_tables(its);
2289 if (ret) 2279 if (ret)
2290 goto out; 2280 return ret;
2291
2292 ret = vgic_its_save_collection_table(its);
2293 2281
2294out: 2282 return vgic_its_save_collection_table(its);
2295 unlock_all_vcpus(kvm);
2296 mutex_unlock(&its->its_lock);
2297 mutex_unlock(&kvm->lock);
2298 return ret;
2299} 2283}
2300 2284
2301/** 2285/**
@@ -2305,29 +2289,13 @@ out:
2305 */ 2289 */
2306static int vgic_its_restore_tables_v0(struct vgic_its *its) 2290static int vgic_its_restore_tables_v0(struct vgic_its *its)
2307{ 2291{
2308 struct kvm *kvm = its->dev->kvm;
2309 int ret; 2292 int ret;
2310 2293
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
2320 ret = vgic_its_restore_collection_table(its); 2294 ret = vgic_its_restore_collection_table(its);
2321 if (ret) 2295 if (ret)
2322 goto out; 2296 return ret;
2323
2324 ret = vgic_its_restore_device_tables(its);
2325out:
2326 unlock_all_vcpus(kvm);
2327 mutex_unlock(&its->its_lock);
2328 mutex_unlock(&kvm->lock);
2329 2297
2330 return ret; 2298 return vgic_its_restore_device_tables(its);
2331} 2299}
2332 2300
2333static int vgic_its_commit_v0(struct vgic_its *its) 2301static int vgic_its_commit_v0(struct vgic_its *its)
@@ -2346,6 +2314,19 @@ static int vgic_its_commit_v0(struct vgic_its *its)
2346 return 0; 2314 return 0;
2347} 2315}
2348 2316
2317static 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
2349static int vgic_its_has_attr(struct kvm_device *dev, 2330static int vgic_its_has_attr(struct kvm_device *dev,
2350 struct kvm_device_attr *attr) 2331 struct kvm_device_attr *attr)
2351{ 2332{
@@ -2360,6 +2341,8 @@ static int vgic_its_has_attr(struct kvm_device *dev,
2360 switch (attr->attr) { 2341 switch (attr->attr) {
2361 case KVM_DEV_ARM_VGIC_CTRL_INIT: 2342 case KVM_DEV_ARM_VGIC_CTRL_INIT:
2362 return 0; 2343 return 0;
2344 case KVM_DEV_ARM_ITS_CTRL_RESET:
2345 return 0;
2363 case KVM_DEV_ARM_ITS_SAVE_TABLES: 2346 case KVM_DEV_ARM_ITS_SAVE_TABLES:
2364 return 0; 2347 return 0;
2365 case KVM_DEV_ARM_ITS_RESTORE_TABLES: 2348 case KVM_DEV_ARM_ITS_RESTORE_TABLES:
@@ -2372,6 +2355,41 @@ static int vgic_its_has_attr(struct kvm_device *dev,
2372 return -ENXIO; 2355 return -ENXIO;
2373} 2356}
2374 2357
2358static 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
2375static int vgic_its_set_attr(struct kvm_device *dev, 2393static int vgic_its_set_attr(struct kvm_device *dev,
2376 struct kvm_device_attr *attr) 2394 struct kvm_device_attr *attr)
2377{ 2395{
@@ -2397,19 +2415,8 @@ static int vgic_its_set_attr(struct kvm_device *dev,
2397 2415
2398 return vgic_register_its_iodev(dev->kvm, its, addr); 2416 return vgic_register_its_iodev(dev->kvm, its, addr);
2399 } 2417 }
2400 case KVM_DEV_ARM_VGIC_GRP_CTRL: { 2418 case KVM_DEV_ARM_VGIC_GRP_CTRL:
2401 const struct vgic_its_abi *abi = vgic_its_get_abi(its); 2419 return vgic_its_ctrl(dev->kvm, its, attr->attr);
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 }
2413 case KVM_DEV_ARM_VGIC_GRP_ITS_REGS: { 2420 case KVM_DEV_ARM_VGIC_GRP_ITS_REGS: {
2414 u64 __user *uaddr = (u64 __user *)(long)attr->addr; 2421 u64 __user *uaddr = (u64 __user *)(long)attr->addr;
2415 u64 reg; 2422 u64 reg;