aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarsten Otte <cotte@de.ibm.com>2012-01-04 04:25:21 -0500
committerAvi Kivity <avi@redhat.com>2012-03-05 07:52:18 -0500
commit27e0393f15fc8bc855c6a888387ff5ffd2181089 (patch)
tree7dd5f6f49f6e11ee5cfbbc4d00fb39f649caa61b
parente08b96371625aaa84cb03f51acc4c8e0be27403a (diff)
KVM: s390: ucontrol: per vcpu address spaces
This patch introduces two ioctls for virtual cpus, that are only valid for kernel virtual machines that are controlled by userspace. Each virtual cpu has its individual address space in this mode of operation, and each address space is backed by the gmap implementation just like the address space for regular KVM guests. KVM_S390_UCAS_MAP allows to map a part of the user's virtual address space to the vcpu. Starting offset and length in both the user and the vcpu address space need to be aligned to 1M. KVM_S390_UCAS_UNMAP can be used to unmap a range of memory from a virtual cpu in a similar way. Signed-off-by: Carsten Otte <cotte@de.ibm.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
-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)