diff options
author | Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> | 2014-05-04 23:09:44 -0400 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2014-05-30 08:26:18 -0400 |
commit | e5ee5422f8867d8b8108f8e1f0f47dc59b043f5b (patch) | |
tree | e9d4ee8a35e32b1fd83a555515f5854e51f0468a /arch | |
parent | 8f20a3ab27342171462781cef4637c18d3dbc5f8 (diff) |
KVM: PPC: BOOK3S: PR: Enable Little Endian PR guest
This patch make sure we inherit the LE bit correctly in different case
so that we can run Little Endian distro in PR mode
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/include/asm/kvm_host.h | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/asm-offsets.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_64_mmu.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_pr.c | 23 |
4 files changed, 25 insertions, 4 deletions
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 1eaea2dea174..d342f8efc843 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h | |||
@@ -562,6 +562,7 @@ struct kvm_vcpu_arch { | |||
562 | #ifdef CONFIG_PPC_BOOK3S | 562 | #ifdef CONFIG_PPC_BOOK3S |
563 | ulong fault_dar; | 563 | ulong fault_dar; |
564 | u32 fault_dsisr; | 564 | u32 fault_dsisr; |
565 | unsigned long intr_msr; | ||
565 | #endif | 566 | #endif |
566 | 567 | ||
567 | #ifdef CONFIG_BOOKE | 568 | #ifdef CONFIG_BOOKE |
@@ -654,7 +655,6 @@ struct kvm_vcpu_arch { | |||
654 | spinlock_t tbacct_lock; | 655 | spinlock_t tbacct_lock; |
655 | u64 busy_stolen; | 656 | u64 busy_stolen; |
656 | u64 busy_preempt; | 657 | u64 busy_preempt; |
657 | unsigned long intr_msr; | ||
658 | #endif | 658 | #endif |
659 | }; | 659 | }; |
660 | 660 | ||
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index dba8140ebc20..6a4b77d197f3 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -493,7 +493,6 @@ int main(void) | |||
493 | DEFINE(VCPU_DAR, offsetof(struct kvm_vcpu, arch.shregs.dar)); | 493 | DEFINE(VCPU_DAR, offsetof(struct kvm_vcpu, arch.shregs.dar)); |
494 | DEFINE(VCPU_VPA, offsetof(struct kvm_vcpu, arch.vpa.pinned_addr)); | 494 | DEFINE(VCPU_VPA, offsetof(struct kvm_vcpu, arch.vpa.pinned_addr)); |
495 | DEFINE(VCPU_VPA_DIRTY, offsetof(struct kvm_vcpu, arch.vpa.dirty)); | 495 | DEFINE(VCPU_VPA_DIRTY, offsetof(struct kvm_vcpu, arch.vpa.dirty)); |
496 | DEFINE(VCPU_INTR_MSR, offsetof(struct kvm_vcpu, arch.intr_msr)); | ||
497 | #endif | 496 | #endif |
498 | #ifdef CONFIG_PPC_BOOK3S | 497 | #ifdef CONFIG_PPC_BOOK3S |
499 | DEFINE(VCPU_VCPUID, offsetof(struct kvm_vcpu, vcpu_id)); | 498 | DEFINE(VCPU_VCPUID, offsetof(struct kvm_vcpu, vcpu_id)); |
@@ -528,6 +527,7 @@ int main(void) | |||
528 | DEFINE(VCPU_SLB_NR, offsetof(struct kvm_vcpu, arch.slb_nr)); | 527 | DEFINE(VCPU_SLB_NR, offsetof(struct kvm_vcpu, arch.slb_nr)); |
529 | DEFINE(VCPU_FAULT_DSISR, offsetof(struct kvm_vcpu, arch.fault_dsisr)); | 528 | DEFINE(VCPU_FAULT_DSISR, offsetof(struct kvm_vcpu, arch.fault_dsisr)); |
530 | DEFINE(VCPU_FAULT_DAR, offsetof(struct kvm_vcpu, arch.fault_dar)); | 529 | DEFINE(VCPU_FAULT_DAR, offsetof(struct kvm_vcpu, arch.fault_dar)); |
530 | DEFINE(VCPU_INTR_MSR, offsetof(struct kvm_vcpu, arch.intr_msr)); | ||
531 | DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst)); | 531 | DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst)); |
532 | DEFINE(VCPU_TRAP, offsetof(struct kvm_vcpu, arch.trap)); | 532 | DEFINE(VCPU_TRAP, offsetof(struct kvm_vcpu, arch.trap)); |
533 | DEFINE(VCPU_CFAR, offsetof(struct kvm_vcpu, arch.cfar)); | 533 | DEFINE(VCPU_CFAR, offsetof(struct kvm_vcpu, arch.cfar)); |
diff --git a/arch/powerpc/kvm/book3s_64_mmu.c b/arch/powerpc/kvm/book3s_64_mmu.c index 83da1f868fd5..8231b83c493b 100644 --- a/arch/powerpc/kvm/book3s_64_mmu.c +++ b/arch/powerpc/kvm/book3s_64_mmu.c | |||
@@ -38,7 +38,7 @@ | |||
38 | 38 | ||
39 | static void kvmppc_mmu_book3s_64_reset_msr(struct kvm_vcpu *vcpu) | 39 | static void kvmppc_mmu_book3s_64_reset_msr(struct kvm_vcpu *vcpu) |
40 | { | 40 | { |
41 | kvmppc_set_msr(vcpu, MSR_SF); | 41 | kvmppc_set_msr(vcpu, vcpu->arch.intr_msr); |
42 | } | 42 | } |
43 | 43 | ||
44 | static struct kvmppc_slb *kvmppc_mmu_book3s_64_find_slbe( | 44 | static struct kvmppc_slb *kvmppc_mmu_book3s_64_find_slbe( |
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index c5c052a9729c..8c05cb5877a9 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c | |||
@@ -249,7 +249,7 @@ static void kvmppc_recalc_shadow_msr(struct kvm_vcpu *vcpu) | |||
249 | ulong smsr = vcpu->arch.shared->msr; | 249 | ulong smsr = vcpu->arch.shared->msr; |
250 | 250 | ||
251 | /* Guest MSR values */ | 251 | /* Guest MSR values */ |
252 | smsr &= MSR_FE0 | MSR_FE1 | MSR_SF | MSR_SE | MSR_BE; | 252 | smsr &= MSR_FE0 | MSR_FE1 | MSR_SF | MSR_SE | MSR_BE | MSR_LE; |
253 | /* Process MSR values */ | 253 | /* Process MSR values */ |
254 | smsr |= MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_PR | MSR_EE; | 254 | smsr |= MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_PR | MSR_EE; |
255 | /* External providers the guest reserved */ | 255 | /* External providers the guest reserved */ |
@@ -1110,6 +1110,15 @@ static int kvmppc_get_one_reg_pr(struct kvm_vcpu *vcpu, u64 id, | |||
1110 | case KVM_REG_PPC_HIOR: | 1110 | case KVM_REG_PPC_HIOR: |
1111 | *val = get_reg_val(id, to_book3s(vcpu)->hior); | 1111 | *val = get_reg_val(id, to_book3s(vcpu)->hior); |
1112 | break; | 1112 | break; |
1113 | case KVM_REG_PPC_LPCR: | ||
1114 | /* | ||
1115 | * We are only interested in the LPCR_ILE bit | ||
1116 | */ | ||
1117 | if (vcpu->arch.intr_msr & MSR_LE) | ||
1118 | *val = get_reg_val(id, LPCR_ILE); | ||
1119 | else | ||
1120 | *val = get_reg_val(id, 0); | ||
1121 | break; | ||
1113 | default: | 1122 | default: |
1114 | r = -EINVAL; | 1123 | r = -EINVAL; |
1115 | break; | 1124 | break; |
@@ -1118,6 +1127,14 @@ static int kvmppc_get_one_reg_pr(struct kvm_vcpu *vcpu, u64 id, | |||
1118 | return r; | 1127 | return r; |
1119 | } | 1128 | } |
1120 | 1129 | ||
1130 | static void kvmppc_set_lpcr_pr(struct kvm_vcpu *vcpu, u64 new_lpcr) | ||
1131 | { | ||
1132 | if (new_lpcr & LPCR_ILE) | ||
1133 | vcpu->arch.intr_msr |= MSR_LE; | ||
1134 | else | ||
1135 | vcpu->arch.intr_msr &= ~MSR_LE; | ||
1136 | } | ||
1137 | |||
1121 | static int kvmppc_set_one_reg_pr(struct kvm_vcpu *vcpu, u64 id, | 1138 | static int kvmppc_set_one_reg_pr(struct kvm_vcpu *vcpu, u64 id, |
1122 | union kvmppc_one_reg *val) | 1139 | union kvmppc_one_reg *val) |
1123 | { | 1140 | { |
@@ -1128,6 +1145,9 @@ static int kvmppc_set_one_reg_pr(struct kvm_vcpu *vcpu, u64 id, | |||
1128 | to_book3s(vcpu)->hior = set_reg_val(id, *val); | 1145 | to_book3s(vcpu)->hior = set_reg_val(id, *val); |
1129 | to_book3s(vcpu)->hior_explicit = true; | 1146 | to_book3s(vcpu)->hior_explicit = true; |
1130 | break; | 1147 | break; |
1148 | case KVM_REG_PPC_LPCR: | ||
1149 | kvmppc_set_lpcr_pr(vcpu, set_reg_val(id, *val)); | ||
1150 | break; | ||
1131 | default: | 1151 | default: |
1132 | r = -EINVAL; | 1152 | r = -EINVAL; |
1133 | break; | 1153 | break; |
@@ -1180,6 +1200,7 @@ static struct kvm_vcpu *kvmppc_core_vcpu_create_pr(struct kvm *kvm, | |||
1180 | vcpu->arch.pvr = 0x3C0301; | 1200 | vcpu->arch.pvr = 0x3C0301; |
1181 | if (mmu_has_feature(MMU_FTR_1T_SEGMENT)) | 1201 | if (mmu_has_feature(MMU_FTR_1T_SEGMENT)) |
1182 | vcpu->arch.pvr = mfspr(SPRN_PVR); | 1202 | vcpu->arch.pvr = mfspr(SPRN_PVR); |
1203 | vcpu->arch.intr_msr = MSR_SF; | ||
1183 | #else | 1204 | #else |
1184 | /* default to book3s_32 (750) */ | 1205 | /* default to book3s_32 (750) */ |
1185 | vcpu->arch.pvr = 0x84202; | 1206 | vcpu->arch.pvr = 0x84202; |