aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Borntraeger <borntraeger@de.ibm.com>2012-05-15 08:15:25 -0400
committerMarcelo Tosatti <mtosatti@redhat.com>2012-05-17 20:06:01 -0400
commit1526bf9ccf310f1d35c1275b8b477a249d25aaf2 (patch)
tree61c7b138818c52df2dfcdc8a58ee891b198f424e
parentd8368af8b46b904def42a0f341d2f4f29001fa77 (diff)
KVM: s390: add capability indicating COW support
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>
-rw-r--r--arch/s390/include/asm/sclp.h1
-rw-r--r--arch/s390/kvm/kvm-s390.c4
-rw-r--r--drivers/s390/char/sclp_cmd.c12
-rw-r--r--include/linux/kvm.h1
4 files changed, 17 insertions, 1 deletions
diff --git a/arch/s390/include/asm/sclp.h b/arch/s390/include/asm/sclp.h
index fed7bee650a0..bf238c55740b 100644
--- a/arch/s390/include/asm/sclp.h
+++ b/arch/s390/include/asm/sclp.h
@@ -48,6 +48,7 @@ int sclp_cpu_deconfigure(u8 cpu);
48void sclp_facilities_detect(void); 48void sclp_facilities_detect(void);
49unsigned long long sclp_get_rnmax(void); 49unsigned long long sclp_get_rnmax(void);
50unsigned long long sclp_get_rzm(void); 50unsigned long long sclp_get_rzm(void);
51u8 sclp_get_fac85(void);
51int sclp_sdias_blk_count(void); 52int sclp_sdias_blk_count(void);
52int sclp_sdias_copy(void *dest, int blk_num, int nr_blks); 53int sclp_sdias_copy(void *dest, int blk_num, int nr_blks);
53int sclp_chp_configure(struct chp_id chpid); 54int sclp_chp_configure(struct chp_id chpid);
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index e5e3800b0125..5c761bffa02d 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -28,6 +28,7 @@
28#include <asm/pgtable.h> 28#include <asm/pgtable.h>
29#include <asm/nmi.h> 29#include <asm/nmi.h>
30#include <asm/switch_to.h> 30#include <asm/switch_to.h>
31#include <asm/sclp.h>
31#include "kvm-s390.h" 32#include "kvm-s390.h"
32#include "gaccess.h" 33#include "gaccess.h"
33 34
@@ -140,6 +141,9 @@ int kvm_dev_ioctl_check_extension(long ext)
140 case KVM_CAP_MAX_VCPUS: 141 case KVM_CAP_MAX_VCPUS:
141 r = KVM_MAX_VCPUS; 142 r = KVM_MAX_VCPUS;
142 break; 143 break;
144 case KVM_CAP_S390_COW:
145 r = sclp_get_fac85() & 0x2;
146 break;
143 default: 147 default:
144 r = 0; 148 r = 0;
145 } 149 }
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c
index 231a1d85127b..032171e335e9 100644
--- a/drivers/s390/char/sclp_cmd.c
+++ b/drivers/s390/char/sclp_cmd.c
@@ -17,6 +17,7 @@
17#include <linux/mm.h> 17#include <linux/mm.h>
18#include <linux/mmzone.h> 18#include <linux/mmzone.h>
19#include <linux/memory.h> 19#include <linux/memory.h>
20#include <linux/module.h>
20#include <linux/platform_device.h> 21#include <linux/platform_device.h>
21#include <asm/chpid.h> 22#include <asm/chpid.h>
22#include <asm/sclp.h> 23#include <asm/sclp.h>
@@ -38,7 +39,8 @@ struct read_info_sccb {
38 u64 facilities; /* 48-55 */ 39 u64 facilities; /* 48-55 */
39 u8 _reserved2[84 - 56]; /* 56-83 */ 40 u8 _reserved2[84 - 56]; /* 56-83 */
40 u8 fac84; /* 84 */ 41 u8 fac84; /* 84 */
41 u8 _reserved3[91 - 85]; /* 85-90 */ 42 u8 fac85; /* 85 */
43 u8 _reserved3[91 - 86]; /* 86-90 */
42 u8 flags; /* 91 */ 44 u8 flags; /* 91 */
43 u8 _reserved4[100 - 92]; /* 92-99 */ 45 u8 _reserved4[100 - 92]; /* 92-99 */
44 u32 rnsize2; /* 100-103 */ 46 u32 rnsize2; /* 100-103 */
@@ -51,6 +53,7 @@ static int __initdata early_read_info_sccb_valid;
51 53
52u64 sclp_facilities; 54u64 sclp_facilities;
53static u8 sclp_fac84; 55static u8 sclp_fac84;
56static u8 sclp_fac85;
54static unsigned long long rzm; 57static unsigned long long rzm;
55static unsigned long long rnmax; 58static unsigned long long rnmax;
56 59
@@ -112,6 +115,7 @@ void __init sclp_facilities_detect(void)
112 sccb = &early_read_info_sccb; 115 sccb = &early_read_info_sccb;
113 sclp_facilities = sccb->facilities; 116 sclp_facilities = sccb->facilities;
114 sclp_fac84 = sccb->fac84; 117 sclp_fac84 = sccb->fac84;
118 sclp_fac85 = sccb->fac85;
115 rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2; 119 rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2;
116 rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2; 120 rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2;
117 rzm <<= 20; 121 rzm <<= 20;
@@ -127,6 +131,12 @@ unsigned long long sclp_get_rzm(void)
127 return rzm; 131 return rzm;
128} 132}
129 133
134u8 sclp_get_fac85(void)
135{
136 return sclp_fac85;
137}
138EXPORT_SYMBOL_GPL(sclp_get_fac85);
139
130/* 140/*
131 * This function will be called after sclp_facilities_detect(), which gets 141 * This function will be called after sclp_facilities_detect(), which gets
132 * called from early.c code. Therefore the sccb should have valid contents. 142 * called from early.c code. Therefore the sccb should have valid contents.
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 8d696cf6edcc..09f2b3aa2da7 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -616,6 +616,7 @@ struct kvm_ppc_smmu_info {
616#define KVM_CAP_KVMCLOCK_CTRL 76 616#define KVM_CAP_KVMCLOCK_CTRL 76
617#define KVM_CAP_SIGNAL_MSI 77 617#define KVM_CAP_SIGNAL_MSI 77
618#define KVM_CAP_PPC_GET_SMMU_INFO 78 618#define KVM_CAP_PPC_GET_SMMU_INFO 78
619#define KVM_CAP_S390_COW 79
619 620
620#ifdef KVM_CAP_IRQ_ROUTING 621#ifdef KVM_CAP_IRQ_ROUTING
621 622