summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2014-05-11 19:08:32 -0400
committerAlexander Graf <agraf@suse.de>2014-05-30 08:26:24 -0400
commitf3383cf80e417e86fcc84a2eb4c96bc52842d8d9 (patch)
tree69cde42c1f516992ef2e6db665d1098ee0eac951
parent1f365bb0de12da4a9ef8e56ffba2218d9a026011 (diff)
KVM: PPC: Disable NX for old magic page using guests
Old guests try to use the magic page, but map their trampoline code inside of an NX region. Since we can't fix those old kernels, try to detect whether the guest is sane or not. If not, just disable NX functionality in KVM so that old guests at least work at all. For newer guests, add a bit that we can set to keep NX functionality available. Signed-off-by: Alexander Graf <agraf@suse.de>
-rw-r--r--Documentation/virtual/kvm/ppc-pv.txt14
-rw-r--r--arch/powerpc/include/asm/kvm_host.h1
-rw-r--r--arch/powerpc/include/uapi/asm/kvm_para.h6
-rw-r--r--arch/powerpc/kvm/book3s_64_mmu.c3
-rw-r--r--arch/powerpc/kvm/powerpc.c14
5 files changed, 36 insertions, 2 deletions
diff --git a/Documentation/virtual/kvm/ppc-pv.txt b/Documentation/virtual/kvm/ppc-pv.txt
index 4643cde517c4..319560646f32 100644
--- a/Documentation/virtual/kvm/ppc-pv.txt
+++ b/Documentation/virtual/kvm/ppc-pv.txt
@@ -94,10 +94,24 @@ a bitmap of available features inside the magic page.
94The following enhancements to the magic page are currently available: 94The following enhancements to the magic page are currently available:
95 95
96 KVM_MAGIC_FEAT_SR Maps SR registers r/w in the magic page 96 KVM_MAGIC_FEAT_SR Maps SR registers r/w in the magic page
97 KVM_MAGIC_FEAT_MAS0_TO_SPRG7 Maps MASn, ESR, PIR and high SPRGs
97 98
98For enhanced features in the magic page, please check for the existence of the 99For enhanced features in the magic page, please check for the existence of the
99feature before using them! 100feature before using them!
100 101
102Magic page flags
103================
104
105In addition to features that indicate whether a host is capable of a particular
106feature we also have a channel for a guest to tell the guest whether it's capable
107of something. This is what we call "flags".
108
109Flags are passed to the host in the low 12 bits of the Effective Address.
110
111The following flags are currently available for a guest to expose:
112
113 MAGIC_PAGE_FLAG_NOT_MAPPED_NX Guest handles NX bits correclty wrt magic page
114
101MSR bits 115MSR bits
102======== 116========
103 117
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 29fbb554af5c..bb66d8b8efdf 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -631,6 +631,7 @@ struct kvm_vcpu_arch {
631#endif 631#endif
632 unsigned long magic_page_pa; /* phys addr to map the magic page to */ 632 unsigned long magic_page_pa; /* phys addr to map the magic page to */
633 unsigned long magic_page_ea; /* effect. addr to map the magic page to */ 633 unsigned long magic_page_ea; /* effect. addr to map the magic page to */
634 bool disable_kernel_nx;
634 635
635 int irq_type; /* one of KVM_IRQ_* */ 636 int irq_type; /* one of KVM_IRQ_* */
636 int irq_cpu_id; 637 int irq_cpu_id;
diff --git a/arch/powerpc/include/uapi/asm/kvm_para.h b/arch/powerpc/include/uapi/asm/kvm_para.h
index e3af3286a068..91e42f09b323 100644
--- a/arch/powerpc/include/uapi/asm/kvm_para.h
+++ b/arch/powerpc/include/uapi/asm/kvm_para.h
@@ -82,10 +82,16 @@ struct kvm_vcpu_arch_shared {
82 82
83#define KVM_FEATURE_MAGIC_PAGE 1 83#define KVM_FEATURE_MAGIC_PAGE 1
84 84
85/* Magic page flags from host to guest */
86
85#define KVM_MAGIC_FEAT_SR (1 << 0) 87#define KVM_MAGIC_FEAT_SR (1 << 0)
86 88
87/* MASn, ESR, PIR, and high SPRGs */ 89/* MASn, ESR, PIR, and high SPRGs */
88#define KVM_MAGIC_FEAT_MAS0_TO_SPRG7 (1 << 1) 90#define KVM_MAGIC_FEAT_MAS0_TO_SPRG7 (1 << 1)
89 91
92/* Magic page flags from guest to host */
93
94#define MAGIC_PAGE_FLAG_NOT_MAPPED_NX (1 << 0)
95
90 96
91#endif /* _UAPI__POWERPC_KVM_PARA_H__ */ 97#endif /* _UAPI__POWERPC_KVM_PARA_H__ */
diff --git a/arch/powerpc/kvm/book3s_64_mmu.c b/arch/powerpc/kvm/book3s_64_mmu.c
index 278729f4df80..774a253ca4e1 100644
--- a/arch/powerpc/kvm/book3s_64_mmu.c
+++ b/arch/powerpc/kvm/book3s_64_mmu.c
@@ -313,6 +313,9 @@ do_second:
313 gpte->raddr = (r & HPTE_R_RPN & ~eaddr_mask) | (eaddr & eaddr_mask); 313 gpte->raddr = (r & HPTE_R_RPN & ~eaddr_mask) | (eaddr & eaddr_mask);
314 gpte->page_size = pgsize; 314 gpte->page_size = pgsize;
315 gpte->may_execute = ((r & HPTE_R_N) ? false : true); 315 gpte->may_execute = ((r & HPTE_R_N) ? false : true);
316 if (unlikely(vcpu->arch.disable_kernel_nx) &&
317 !(kvmppc_get_msr(vcpu) & MSR_PR))
318 gpte->may_execute = true;
316 gpte->may_read = false; 319 gpte->may_read = false;
317 gpte->may_write = false; 320 gpte->may_write = false;
318 321
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index b4e15bf3ff88..154f352c39ae 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -177,8 +177,18 @@ int kvmppc_kvm_pv(struct kvm_vcpu *vcpu)
177 vcpu->arch.shared_big_endian = shared_big_endian; 177 vcpu->arch.shared_big_endian = shared_big_endian;
178#endif 178#endif
179 179
180 vcpu->arch.magic_page_pa = param1; 180 if (!(param2 & MAGIC_PAGE_FLAG_NOT_MAPPED_NX)) {
181 vcpu->arch.magic_page_ea = param2; 181 /*
182 * Older versions of the Linux magic page code had
183 * a bug where they would map their trampoline code
184 * NX. If that's the case, remove !PR NX capability.
185 */
186 vcpu->arch.disable_kernel_nx = true;
187 kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu);
188 }
189
190 vcpu->arch.magic_page_pa = param1 & ~0xfffULL;
191 vcpu->arch.magic_page_ea = param2 & ~0xfffULL;
182 192
183 r2 = KVM_MAGIC_FEAT_SR | KVM_MAGIC_FEAT_MAS0_TO_SPRG7; 193 r2 = KVM_MAGIC_FEAT_SR | KVM_MAGIC_FEAT_MAS0_TO_SPRG7;
184 194