diff options
| -rw-r--r-- | Documentation/virtual/kvm/ppc-pv.txt | 14 | ||||
| -rw-r--r-- | arch/powerpc/include/asm/kvm_host.h | 1 | ||||
| -rw-r--r-- | arch/powerpc/include/uapi/asm/kvm_para.h | 6 | ||||
| -rw-r--r-- | arch/powerpc/kvm/book3s_64_mmu.c | 3 | ||||
| -rw-r--r-- | arch/powerpc/kvm/powerpc.c | 14 |
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. | |||
| 94 | The following enhancements to the magic page are currently available: | 94 | The 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 | ||
| 98 | For enhanced features in the magic page, please check for the existence of the | 99 | For enhanced features in the magic page, please check for the existence of the |
| 99 | feature before using them! | 100 | feature before using them! |
| 100 | 101 | ||
| 102 | Magic page flags | ||
| 103 | ================ | ||
| 104 | |||
| 105 | In addition to features that indicate whether a host is capable of a particular | ||
| 106 | feature we also have a channel for a guest to tell the guest whether it's capable | ||
| 107 | of something. This is what we call "flags". | ||
| 108 | |||
| 109 | Flags are passed to the host in the low 12 bits of the Effective Address. | ||
| 110 | |||
| 111 | The 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 | |||
| 101 | MSR bits | 115 | MSR 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 | ||
