aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/virtual/kvm/api.txt38
-rw-r--r--arch/s390/kvm/kvm-s390.c50
-rw-r--r--include/linux/kvm.h10
3 files changed, 97 insertions, 1 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 579d40b26a5a..ee394b263261 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1496,6 +1496,44 @@ following algorithm:
1496Some guests configure the LINT1 NMI input to cause a panic, aiding in 1496Some guests configure the LINT1 NMI input to cause a panic, aiding in
1497debugging. 1497debugging.
1498 1498
14994.64 KVM_S390_UCAS_MAP
1500
1501Capability: KVM_CAP_S390_UCONTROL
1502Architectures: s390
1503Type: vcpu ioctl
1504Parameters: struct kvm_s390_ucas_mapping (in)
1505Returns: 0 in case of success
1506
1507The parameter is defined like this:
1508 struct kvm_s390_ucas_mapping {
1509 __u64 user_addr;
1510 __u64 vcpu_addr;
1511 __u64 length;
1512 };
1513
1514This ioctl maps the memory at "user_addr" with the length "length" to
1515the vcpu's address space starting at "vcpu_addr". All parameters need to
1516be alligned by 1 megabyte.
1517
15184.65 KVM_S390_UCAS_UNMAP
1519
1520Capability: KVM_CAP_S390_UCONTROL
1521Architectures: s390
1522Type: vcpu ioctl
1523Parameters: struct kvm_s390_ucas_mapping (in)
1524Returns: 0 in case of success
1525
1526The parameter is defined like this:
1527 struct kvm_s390_ucas_mapping {
1528 __u64 user_addr;
1529 __u64 vcpu_addr;
1530 __u64 length;
1531 };
1532
1533This ioctl unmaps the memory in the vcpu's address space starting at
1534"vcpu_addr" with the length "length". The field "user_addr" is ignored.
1535All parameters need to be alligned by 1 megabyte.
1536
14995. The kvm_run structure 15375. The kvm_run structure
1500 1538
1501Application code obtains a pointer to the kvm_run structure by 1539Application code obtains a pointer to the kvm_run structure by
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index f0937552175b..2d3248895def 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -233,6 +233,10 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
233 (__u64) vcpu->arch.sie_block) 233 (__u64) vcpu->arch.sie_block)
234 vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda = 0; 234 vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda = 0;
235 smp_mb(); 235 smp_mb();
236
237 if (kvm_is_ucontrol(vcpu->kvm))
238 gmap_free(vcpu->arch.gmap);
239
236 free_page((unsigned long)(vcpu->arch.sie_block)); 240 free_page((unsigned long)(vcpu->arch.sie_block));
237 kvm_vcpu_uninit(vcpu); 241 kvm_vcpu_uninit(vcpu);
238 kfree(vcpu); 242 kfree(vcpu);
@@ -263,12 +267,20 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
263 kvm_free_vcpus(kvm); 267 kvm_free_vcpus(kvm);
264 free_page((unsigned long)(kvm->arch.sca)); 268 free_page((unsigned long)(kvm->arch.sca));
265 debug_unregister(kvm->arch.dbf); 269 debug_unregister(kvm->arch.dbf);
266 gmap_free(kvm->arch.gmap); 270 if (!kvm_is_ucontrol(kvm))
271 gmap_free(kvm->arch.gmap);
267} 272}
268 273
269/* Section: vcpu related */ 274/* Section: vcpu related */
270int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) 275int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
271{ 276{
277 if (kvm_is_ucontrol(vcpu->kvm)) {
278 vcpu->arch.gmap = gmap_alloc(current->mm);
279 if (!vcpu->arch.gmap)
280 return -ENOMEM;
281 return 0;
282 }
283
272 vcpu->arch.gmap = vcpu->kvm->arch.gmap; 284 vcpu->arch.gmap = vcpu->kvm->arch.gmap;
273 return 0; 285 return 0;
274} 286}
@@ -687,6 +699,42 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
687 case KVM_S390_INITIAL_RESET: 699 case KVM_S390_INITIAL_RESET:
688 r = kvm_arch_vcpu_ioctl_initial_reset(vcpu); 700 r = kvm_arch_vcpu_ioctl_initial_reset(vcpu);
689 break; 701 break;
702#ifdef CONFIG_KVM_S390_UCONTROL
703 case KVM_S390_UCAS_MAP: {
704 struct kvm_s390_ucas_mapping ucasmap;
705
706 if (copy_from_user(&ucasmap, argp, sizeof(ucasmap))) {
707 r = -EFAULT;
708 break;
709 }
710
711 if (!kvm_is_ucontrol(vcpu->kvm)) {
712 r = -EINVAL;
713 break;
714 }
715
716 r = gmap_map_segment(vcpu->arch.gmap, ucasmap.user_addr,
717 ucasmap.vcpu_addr, ucasmap.length);
718 break;
719 }
720 case KVM_S390_UCAS_UNMAP: {
721 struct kvm_s390_ucas_mapping ucasmap;
722
723 if (copy_from_user(&ucasmap, argp, sizeof(ucasmap))) {
724 r = -EFAULT;
725 break;
726 }
727
728 if (!kvm_is_ucontrol(vcpu->kvm)) {
729 r = -EINVAL;
730 break;
731 }
732
733 r = gmap_unmap_segment(vcpu->arch.gmap, ucasmap.vcpu_addr,
734 ucasmap.length);
735 break;
736 }
737#endif
690 default: 738 default:
691 r = -EINVAL; 739 r = -EINVAL;
692 } 740 }
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index bba393a6760f..0a66c1072691 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -658,6 +658,16 @@ struct kvm_clock_data {
658 struct kvm_userspace_memory_region) 658 struct kvm_userspace_memory_region)
659#define KVM_SET_TSS_ADDR _IO(KVMIO, 0x47) 659#define KVM_SET_TSS_ADDR _IO(KVMIO, 0x47)
660#define KVM_SET_IDENTITY_MAP_ADDR _IOW(KVMIO, 0x48, __u64) 660#define KVM_SET_IDENTITY_MAP_ADDR _IOW(KVMIO, 0x48, __u64)
661
662/* enable ucontrol for s390 */
663struct kvm_s390_ucas_mapping {
664 __u64 user_addr;
665 __u64 vcpu_addr;
666 __u64 length;
667};
668#define KVM_S390_UCAS_MAP _IOW(KVMIO, 0x50, struct kvm_s390_ucas_mapping)
669#define KVM_S390_UCAS_UNMAP _IOW(KVMIO, 0x51, struct kvm_s390_ucas_mapping)
670
661/* Device model IOC */ 671/* Device model IOC */
662#define KVM_CREATE_IRQCHIP _IO(KVMIO, 0x60) 672#define KVM_CREATE_IRQCHIP _IO(KVMIO, 0x60)
663#define KVM_IRQ_LINE _IOW(KVMIO, 0x61, struct kvm_irq_level) 673#define KVM_IRQ_LINE _IOW(KVMIO, 0x61, struct kvm_irq_level)