aboutsummaryrefslogtreecommitdiffstats
path: root/virt
diff options
context:
space:
mode:
Diffstat (limited to 'virt')
-rw-r--r--virt/kvm/arm/vgic.c78
1 files changed, 54 insertions, 24 deletions
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 7589e2c82db2..06073fac03a9 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -2440,7 +2440,8 @@ out:
2440 return ret; 2440 return ret;
2441} 2441}
2442 2442
2443static int vgic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr) 2443static int vgic_set_common_attr(struct kvm_device *dev,
2444 struct kvm_device_attr *attr)
2444{ 2445{
2445 int r; 2446 int r;
2446 2447
@@ -2456,17 +2457,6 @@ static int vgic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr)
2456 r = kvm_vgic_addr(dev->kvm, type, &addr, true); 2457 r = kvm_vgic_addr(dev->kvm, type, &addr, true);
2457 return (r == -ENODEV) ? -ENXIO : r; 2458 return (r == -ENODEV) ? -ENXIO : r;
2458 } 2459 }
2459
2460 case KVM_DEV_ARM_VGIC_GRP_DIST_REGS:
2461 case KVM_DEV_ARM_VGIC_GRP_CPU_REGS: {
2462 u32 __user *uaddr = (u32 __user *)(long)attr->addr;
2463 u32 reg;
2464
2465 if (get_user(reg, uaddr))
2466 return -EFAULT;
2467
2468 return vgic_attr_regs_access(dev, attr, &reg, true);
2469 }
2470 case KVM_DEV_ARM_VGIC_GRP_NR_IRQS: { 2460 case KVM_DEV_ARM_VGIC_GRP_NR_IRQS: {
2471 u32 __user *uaddr = (u32 __user *)(long)attr->addr; 2461 u32 __user *uaddr = (u32 __user *)(long)attr->addr;
2472 u32 val; 2462 u32 val;
@@ -2510,7 +2500,33 @@ static int vgic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr)
2510 return -ENXIO; 2500 return -ENXIO;
2511} 2501}
2512 2502
2513static int vgic_get_attr(struct kvm_device *dev, struct kvm_device_attr *attr) 2503static int vgic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr)
2504{
2505 int ret;
2506
2507 ret = vgic_set_common_attr(dev, attr);
2508 if (ret != -ENXIO)
2509 return ret;
2510
2511 switch (attr->group) {
2512 case KVM_DEV_ARM_VGIC_GRP_DIST_REGS:
2513 case KVM_DEV_ARM_VGIC_GRP_CPU_REGS: {
2514 u32 __user *uaddr = (u32 __user *)(long)attr->addr;
2515 u32 reg;
2516
2517 if (get_user(reg, uaddr))
2518 return -EFAULT;
2519
2520 return vgic_attr_regs_access(dev, attr, &reg, true);
2521 }
2522
2523 }
2524
2525 return -ENXIO;
2526}
2527
2528static int vgic_get_common_attr(struct kvm_device *dev,
2529 struct kvm_device_attr *attr)
2514{ 2530{
2515 int r = -ENXIO; 2531 int r = -ENXIO;
2516 2532
@@ -2528,27 +2544,41 @@ static int vgic_get_attr(struct kvm_device *dev, struct kvm_device_attr *attr)
2528 return -EFAULT; 2544 return -EFAULT;
2529 break; 2545 break;
2530 } 2546 }
2547 case KVM_DEV_ARM_VGIC_GRP_NR_IRQS: {
2548 u32 __user *uaddr = (u32 __user *)(long)attr->addr;
2549
2550 r = put_user(dev->kvm->arch.vgic.nr_irqs, uaddr);
2551 break;
2552 }
2553
2554 }
2555
2556 return r;
2557}
2558
2559static int vgic_get_attr(struct kvm_device *dev, struct kvm_device_attr *attr)
2560{
2561 int ret;
2562
2563 ret = vgic_get_common_attr(dev, attr);
2564 if (ret != -ENXIO)
2565 return ret;
2531 2566
2567 switch (attr->group) {
2532 case KVM_DEV_ARM_VGIC_GRP_DIST_REGS: 2568 case KVM_DEV_ARM_VGIC_GRP_DIST_REGS:
2533 case KVM_DEV_ARM_VGIC_GRP_CPU_REGS: { 2569 case KVM_DEV_ARM_VGIC_GRP_CPU_REGS: {
2534 u32 __user *uaddr = (u32 __user *)(long)attr->addr; 2570 u32 __user *uaddr = (u32 __user *)(long)attr->addr;
2535 u32 reg = 0; 2571 u32 reg = 0;
2536 2572
2537 r = vgic_attr_regs_access(dev, attr, &reg, false); 2573 ret = vgic_attr_regs_access(dev, attr, &reg, false);
2538 if (r) 2574 if (ret)
2539 return r; 2575 return ret;
2540 r = put_user(reg, uaddr); 2576 return put_user(reg, uaddr);
2541 break;
2542 }
2543 case KVM_DEV_ARM_VGIC_GRP_NR_IRQS: {
2544 u32 __user *uaddr = (u32 __user *)(long)attr->addr;
2545 r = put_user(dev->kvm->arch.vgic.nr_irqs, uaddr);
2546 break;
2547 } 2577 }
2548 2578
2549 } 2579 }
2550 2580
2551 return r; 2581 return -ENXIO;
2552} 2582}
2553 2583
2554static int vgic_has_attr_regs(const struct mmio_range *ranges, 2584static int vgic_has_attr_regs(const struct mmio_range *ranges,