KVM: s390: add capability indicating COW support
authorChristian Borntraeger <borntraeger@de.ibm.com>
Tue, 15 May 2012 12:15:25 +0000 (14:15 +0200)
committerMarcelo Tosatti <mtosatti@redhat.com>
Fri, 18 May 2012 00:06:01 +0000 (21:06 -0300)
Currently qemu/kvm on s390 uses a guest mapping that does not
allow the guest backing page table to be write-protected to
support older systems. On those older systems a host write
protection fault will be delivered to the guest.

Newer systems allow to write-protect the guest backing memory
and let the fault be delivered to the host, thus allowing COW.

Use a capability bit to tell qemu if that is possible.

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Acked-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
arch/s390/include/asm/sclp.h
arch/s390/kvm/kvm-s390.c
drivers/s390/char/sclp_cmd.c
include/linux/kvm.h

index fed7bee..bf238c5 100644 (file)
@@ -48,6 +48,7 @@ int sclp_cpu_deconfigure(u8 cpu);
 void sclp_facilities_detect(void);
 unsigned long long sclp_get_rnmax(void);
 unsigned long long sclp_get_rzm(void);
+u8 sclp_get_fac85(void);
 int sclp_sdias_blk_count(void);
 int sclp_sdias_copy(void *dest, int blk_num, int nr_blks);
 int sclp_chp_configure(struct chp_id chpid);
index e5e3800..5c761bf 100644 (file)
@@ -28,6 +28,7 @@
 #include <asm/pgtable.h>
 #include <asm/nmi.h>
 #include <asm/switch_to.h>
+#include <asm/sclp.h>
 #include "kvm-s390.h"
 #include "gaccess.h"
 
@@ -140,6 +141,9 @@ int kvm_dev_ioctl_check_extension(long ext)
        case KVM_CAP_MAX_VCPUS:
                r = KVM_MAX_VCPUS;
                break;
+       case KVM_CAP_S390_COW:
+               r = sclp_get_fac85() & 0x2;
+               break;
        default:
                r = 0;
        }
index 231a1d8..032171e 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/mm.h>
 #include <linux/mmzone.h>
 #include <linux/memory.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <asm/chpid.h>
 #include <asm/sclp.h>
@@ -38,7 +39,8 @@ struct read_info_sccb {
        u64     facilities;             /* 48-55 */
        u8      _reserved2[84 - 56];    /* 56-83 */
        u8      fac84;                  /* 84 */
-       u8      _reserved3[91 - 85];    /* 85-90 */
+       u8      fac85;                  /* 85 */
+       u8      _reserved3[91 - 86];    /* 86-90 */
        u8      flags;                  /* 91 */
        u8      _reserved4[100 - 92];   /* 92-99 */
        u32     rnsize2;                /* 100-103 */
@@ -51,6 +53,7 @@ static int __initdata early_read_info_sccb_valid;
 
 u64 sclp_facilities;
 static u8 sclp_fac84;
+static u8 sclp_fac85;
 static unsigned long long rzm;
 static unsigned long long rnmax;
 
@@ -112,6 +115,7 @@ void __init sclp_facilities_detect(void)
        sccb = &early_read_info_sccb;
        sclp_facilities = sccb->facilities;
        sclp_fac84 = sccb->fac84;
+       sclp_fac85 = sccb->fac85;
        rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2;
        rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2;
        rzm <<= 20;
@@ -127,6 +131,12 @@ unsigned long long sclp_get_rzm(void)
        return rzm;
 }
 
+u8 sclp_get_fac85(void)
+{
+       return sclp_fac85;
+}
+EXPORT_SYMBOL_GPL(sclp_get_fac85);
+
 /*
  * This function will be called after sclp_facilities_detect(), which gets
  * called from early.c code. Therefore the sccb should have valid contents.
index 8d696cf..09f2b3a 100644 (file)
@@ -616,6 +616,7 @@ struct kvm_ppc_smmu_info {
 #define KVM_CAP_KVMCLOCK_CTRL 76
 #define KVM_CAP_SIGNAL_MSI 77
 #define KVM_CAP_PPC_GET_SMMU_INFO 78
+#define KVM_CAP_S390_COW 79
 
 #ifdef KVM_CAP_IRQ_ROUTING