diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-24 15:01:20 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-24 15:01:20 -0400 |
commit | 5fecc9d8f59e765c2a48379dd7c6f5cf88c7d75a (patch) | |
tree | d1fc25d9650d3ac24591bba6f5e2e7a1afc54796 /arch/powerpc/kvm | |
parent | 3c4cfadef6a1665d9cd02a543782d03d3e6740c6 (diff) | |
parent | 1a577b72475d161b6677c05abe57301362023bb2 (diff) |
Merge tag 'kvm-3.6-1' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull KVM updates from Avi Kivity:
"Highlights include
- full big real mode emulation on pre-Westmere Intel hosts (can be
disabled with emulate_invalid_guest_state=0)
- relatively small ppc and s390 updates
- PCID/INVPCID support in guests
- EOI avoidance; 3.6 guests should perform better on 3.6 hosts on
interrupt intensive workloads)
- Lockless write faults during live migration
- EPT accessed/dirty bits support for new Intel processors"
Fix up conflicts in:
- Documentation/virtual/kvm/api.txt:
Stupid subchapter numbering, added next to each other.
- arch/powerpc/kvm/booke_interrupts.S:
PPC asm changes clashing with the KVM fixes
- arch/s390/include/asm/sigp.h, arch/s390/kvm/sigp.c:
Duplicated commits through the kvm tree and the s390 tree, with
subsequent edits in the KVM tree.
* tag 'kvm-3.6-1' of git://git.kernel.org/pub/scm/virt/kvm/kvm: (93 commits)
KVM: fix race with level interrupts
x86, hyper: fix build with !CONFIG_KVM_GUEST
Revert "apic: fix kvm build on UP without IOAPIC"
KVM guest: switch to apic_set_eoi_write, apic_write
apic: add apic_set_eoi_write for PV use
KVM: VMX: Implement PCID/INVPCID for guests with EPT
KVM: Add x86_hyper_kvm to complete detect_hypervisor_platform check
KVM: PPC: Critical interrupt emulation support
KVM: PPC: e500mc: Fix tlbilx emulation for 64-bit guests
KVM: PPC64: booke: Set interrupt computation mode for 64-bit host
KVM: PPC: bookehv: Add ESR flag to Data Storage Interrupt
KVM: PPC: bookehv64: Add support for std/ld emulation.
booke: Added crit/mc exception handler for e500v2
booke/bookehv: Add host crit-watchdog exception support
KVM: MMU: document mmu-lock and fast page fault
KVM: MMU: fix kvm_mmu_pagetable_walk tracepoint
KVM: MMU: trace fast page fault
KVM: MMU: fast path of handling guest page fault
KVM: MMU: introduce SPTE_MMU_WRITEABLE bit
KVM: MMU: fold tlb flush judgement into mmu_spte_update
...
Diffstat (limited to 'arch/powerpc/kvm')
-rw-r--r-- | arch/powerpc/kvm/book3s_64_mmu_hv.c | 123 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_hv.c | 40 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_hv_builtin.c | 5 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_hv_rm_mmu.c | 15 | ||||
-rw-r--r-- | arch/powerpc/kvm/booke.c | 26 | ||||
-rw-r--r-- | arch/powerpc/kvm/booke_emulate.c | 28 | ||||
-rw-r--r-- | arch/powerpc/kvm/booke_interrupts.S | 55 | ||||
-rw-r--r-- | arch/powerpc/kvm/bookehv_interrupts.S | 2 | ||||
-rw-r--r-- | arch/powerpc/kvm/e500_emulate.c | 3 | ||||
-rw-r--r-- | arch/powerpc/kvm/e500mc.c | 8 | ||||
-rw-r--r-- | arch/powerpc/kvm/emulate.c | 16 | ||||
-rw-r--r-- | arch/powerpc/kvm/powerpc.c | 18 |
12 files changed, 260 insertions, 79 deletions
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index 80a577517584..d03eb6f7b058 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c | |||
@@ -37,56 +37,121 @@ | |||
37 | /* POWER7 has 10-bit LPIDs, PPC970 has 6-bit LPIDs */ | 37 | /* POWER7 has 10-bit LPIDs, PPC970 has 6-bit LPIDs */ |
38 | #define MAX_LPID_970 63 | 38 | #define MAX_LPID_970 63 |
39 | 39 | ||
40 | long kvmppc_alloc_hpt(struct kvm *kvm) | 40 | /* Power architecture requires HPT is at least 256kB */ |
41 | #define PPC_MIN_HPT_ORDER 18 | ||
42 | |||
43 | long kvmppc_alloc_hpt(struct kvm *kvm, u32 *htab_orderp) | ||
41 | { | 44 | { |
42 | unsigned long hpt; | 45 | unsigned long hpt; |
43 | long lpid; | ||
44 | struct revmap_entry *rev; | 46 | struct revmap_entry *rev; |
45 | struct kvmppc_linear_info *li; | 47 | struct kvmppc_linear_info *li; |
48 | long order = kvm_hpt_order; | ||
46 | 49 | ||
47 | /* Allocate guest's hashed page table */ | 50 | if (htab_orderp) { |
48 | li = kvm_alloc_hpt(); | 51 | order = *htab_orderp; |
49 | if (li) { | 52 | if (order < PPC_MIN_HPT_ORDER) |
50 | /* using preallocated memory */ | 53 | order = PPC_MIN_HPT_ORDER; |
51 | hpt = (ulong)li->base_virt; | 54 | } |
52 | kvm->arch.hpt_li = li; | 55 | |
53 | } else { | 56 | /* |
54 | /* using dynamic memory */ | 57 | * If the user wants a different size from default, |
58 | * try first to allocate it from the kernel page allocator. | ||
59 | */ | ||
60 | hpt = 0; | ||
61 | if (order != kvm_hpt_order) { | ||
55 | hpt = __get_free_pages(GFP_KERNEL|__GFP_ZERO|__GFP_REPEAT| | 62 | hpt = __get_free_pages(GFP_KERNEL|__GFP_ZERO|__GFP_REPEAT| |
56 | __GFP_NOWARN, HPT_ORDER - PAGE_SHIFT); | 63 | __GFP_NOWARN, order - PAGE_SHIFT); |
64 | if (!hpt) | ||
65 | --order; | ||
57 | } | 66 | } |
58 | 67 | ||
68 | /* Next try to allocate from the preallocated pool */ | ||
59 | if (!hpt) { | 69 | if (!hpt) { |
60 | pr_err("kvm_alloc_hpt: Couldn't alloc HPT\n"); | 70 | li = kvm_alloc_hpt(); |
61 | return -ENOMEM; | 71 | if (li) { |
72 | hpt = (ulong)li->base_virt; | ||
73 | kvm->arch.hpt_li = li; | ||
74 | order = kvm_hpt_order; | ||
75 | } | ||
62 | } | 76 | } |
77 | |||
78 | /* Lastly try successively smaller sizes from the page allocator */ | ||
79 | while (!hpt && order > PPC_MIN_HPT_ORDER) { | ||
80 | hpt = __get_free_pages(GFP_KERNEL|__GFP_ZERO|__GFP_REPEAT| | ||
81 | __GFP_NOWARN, order - PAGE_SHIFT); | ||
82 | if (!hpt) | ||
83 | --order; | ||
84 | } | ||
85 | |||
86 | if (!hpt) | ||
87 | return -ENOMEM; | ||
88 | |||
63 | kvm->arch.hpt_virt = hpt; | 89 | kvm->arch.hpt_virt = hpt; |
90 | kvm->arch.hpt_order = order; | ||
91 | /* HPTEs are 2**4 bytes long */ | ||
92 | kvm->arch.hpt_npte = 1ul << (order - 4); | ||
93 | /* 128 (2**7) bytes in each HPTEG */ | ||
94 | kvm->arch.hpt_mask = (1ul << (order - 7)) - 1; | ||
64 | 95 | ||
65 | /* Allocate reverse map array */ | 96 | /* Allocate reverse map array */ |
66 | rev = vmalloc(sizeof(struct revmap_entry) * HPT_NPTE); | 97 | rev = vmalloc(sizeof(struct revmap_entry) * kvm->arch.hpt_npte); |
67 | if (!rev) { | 98 | if (!rev) { |
68 | pr_err("kvmppc_alloc_hpt: Couldn't alloc reverse map array\n"); | 99 | pr_err("kvmppc_alloc_hpt: Couldn't alloc reverse map array\n"); |
69 | goto out_freehpt; | 100 | goto out_freehpt; |
70 | } | 101 | } |
71 | kvm->arch.revmap = rev; | 102 | kvm->arch.revmap = rev; |
103 | kvm->arch.sdr1 = __pa(hpt) | (order - 18); | ||
72 | 104 | ||
73 | lpid = kvmppc_alloc_lpid(); | 105 | pr_info("KVM guest htab at %lx (order %ld), LPID %x\n", |
74 | if (lpid < 0) | 106 | hpt, order, kvm->arch.lpid); |
75 | goto out_freeboth; | ||
76 | 107 | ||
77 | kvm->arch.sdr1 = __pa(hpt) | (HPT_ORDER - 18); | 108 | if (htab_orderp) |
78 | kvm->arch.lpid = lpid; | 109 | *htab_orderp = order; |
79 | |||
80 | pr_info("KVM guest htab at %lx, LPID %lx\n", hpt, lpid); | ||
81 | return 0; | 110 | return 0; |
82 | 111 | ||
83 | out_freeboth: | ||
84 | vfree(rev); | ||
85 | out_freehpt: | 112 | out_freehpt: |
86 | free_pages(hpt, HPT_ORDER - PAGE_SHIFT); | 113 | if (kvm->arch.hpt_li) |
114 | kvm_release_hpt(kvm->arch.hpt_li); | ||
115 | else | ||
116 | free_pages(hpt, order - PAGE_SHIFT); | ||
87 | return -ENOMEM; | 117 | return -ENOMEM; |
88 | } | 118 | } |
89 | 119 | ||
120 | long kvmppc_alloc_reset_hpt(struct kvm *kvm, u32 *htab_orderp) | ||
121 | { | ||
122 | long err = -EBUSY; | ||
123 | long order; | ||
124 | |||
125 | mutex_lock(&kvm->lock); | ||
126 | if (kvm->arch.rma_setup_done) { | ||
127 | kvm->arch.rma_setup_done = 0; | ||
128 | /* order rma_setup_done vs. vcpus_running */ | ||
129 | smp_mb(); | ||
130 | if (atomic_read(&kvm->arch.vcpus_running)) { | ||
131 | kvm->arch.rma_setup_done = 1; | ||
132 | goto out; | ||
133 | } | ||
134 | } | ||
135 | if (kvm->arch.hpt_virt) { | ||
136 | order = kvm->arch.hpt_order; | ||
137 | /* Set the entire HPT to 0, i.e. invalid HPTEs */ | ||
138 | memset((void *)kvm->arch.hpt_virt, 0, 1ul << order); | ||
139 | /* | ||
140 | * Set the whole last_vcpu array to an invalid vcpu number. | ||
141 | * This ensures that each vcpu will flush its TLB on next entry. | ||
142 | */ | ||
143 | memset(kvm->arch.last_vcpu, 0xff, sizeof(kvm->arch.last_vcpu)); | ||
144 | *htab_orderp = order; | ||
145 | err = 0; | ||
146 | } else { | ||
147 | err = kvmppc_alloc_hpt(kvm, htab_orderp); | ||
148 | order = *htab_orderp; | ||
149 | } | ||
150 | out: | ||
151 | mutex_unlock(&kvm->lock); | ||
152 | return err; | ||
153 | } | ||
154 | |||
90 | void kvmppc_free_hpt(struct kvm *kvm) | 155 | void kvmppc_free_hpt(struct kvm *kvm) |
91 | { | 156 | { |
92 | kvmppc_free_lpid(kvm->arch.lpid); | 157 | kvmppc_free_lpid(kvm->arch.lpid); |
@@ -94,7 +159,8 @@ void kvmppc_free_hpt(struct kvm *kvm) | |||
94 | if (kvm->arch.hpt_li) | 159 | if (kvm->arch.hpt_li) |
95 | kvm_release_hpt(kvm->arch.hpt_li); | 160 | kvm_release_hpt(kvm->arch.hpt_li); |
96 | else | 161 | else |
97 | free_pages(kvm->arch.hpt_virt, HPT_ORDER - PAGE_SHIFT); | 162 | free_pages(kvm->arch.hpt_virt, |
163 | kvm->arch.hpt_order - PAGE_SHIFT); | ||
98 | } | 164 | } |
99 | 165 | ||
100 | /* Bits in first HPTE dword for pagesize 4k, 64k or 16M */ | 166 | /* Bits in first HPTE dword for pagesize 4k, 64k or 16M */ |
@@ -119,6 +185,7 @@ void kvmppc_map_vrma(struct kvm_vcpu *vcpu, struct kvm_memory_slot *memslot, | |||
119 | unsigned long psize; | 185 | unsigned long psize; |
120 | unsigned long hp0, hp1; | 186 | unsigned long hp0, hp1; |
121 | long ret; | 187 | long ret; |
188 | struct kvm *kvm = vcpu->kvm; | ||
122 | 189 | ||
123 | psize = 1ul << porder; | 190 | psize = 1ul << porder; |
124 | npages = memslot->npages >> (porder - PAGE_SHIFT); | 191 | npages = memslot->npages >> (porder - PAGE_SHIFT); |
@@ -127,8 +194,8 @@ void kvmppc_map_vrma(struct kvm_vcpu *vcpu, struct kvm_memory_slot *memslot, | |||
127 | if (npages > 1ul << (40 - porder)) | 194 | if (npages > 1ul << (40 - porder)) |
128 | npages = 1ul << (40 - porder); | 195 | npages = 1ul << (40 - porder); |
129 | /* Can't use more than 1 HPTE per HPTEG */ | 196 | /* Can't use more than 1 HPTE per HPTEG */ |
130 | if (npages > HPT_NPTEG) | 197 | if (npages > kvm->arch.hpt_mask + 1) |
131 | npages = HPT_NPTEG; | 198 | npages = kvm->arch.hpt_mask + 1; |
132 | 199 | ||
133 | hp0 = HPTE_V_1TB_SEG | (VRMA_VSID << (40 - 16)) | | 200 | hp0 = HPTE_V_1TB_SEG | (VRMA_VSID << (40 - 16)) | |
134 | HPTE_V_BOLTED | hpte0_pgsize_encoding(psize); | 201 | HPTE_V_BOLTED | hpte0_pgsize_encoding(psize); |
@@ -138,7 +205,7 @@ void kvmppc_map_vrma(struct kvm_vcpu *vcpu, struct kvm_memory_slot *memslot, | |||
138 | for (i = 0; i < npages; ++i) { | 205 | for (i = 0; i < npages; ++i) { |
139 | addr = i << porder; | 206 | addr = i << porder; |
140 | /* can't use hpt_hash since va > 64 bits */ | 207 | /* can't use hpt_hash since va > 64 bits */ |
141 | hash = (i ^ (VRMA_VSID ^ (VRMA_VSID << 25))) & HPT_HASH_MASK; | 208 | hash = (i ^ (VRMA_VSID ^ (VRMA_VSID << 25))) & kvm->arch.hpt_mask; |
142 | /* | 209 | /* |
143 | * We assume that the hash table is empty and no | 210 | * We assume that the hash table is empty and no |
144 | * vcpus are using it at this stage. Since we create | 211 | * vcpus are using it at this stage. Since we create |
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 3abe1b86e583..83e929e66f9d 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c | |||
@@ -56,7 +56,7 @@ | |||
56 | /* #define EXIT_DEBUG_INT */ | 56 | /* #define EXIT_DEBUG_INT */ |
57 | 57 | ||
58 | static void kvmppc_end_cede(struct kvm_vcpu *vcpu); | 58 | static void kvmppc_end_cede(struct kvm_vcpu *vcpu); |
59 | static int kvmppc_hv_setup_rma(struct kvm_vcpu *vcpu); | 59 | static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu); |
60 | 60 | ||
61 | void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | 61 | void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) |
62 | { | 62 | { |
@@ -1104,11 +1104,15 @@ int kvmppc_vcpu_run(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
1104 | return -EINTR; | 1104 | return -EINTR; |
1105 | } | 1105 | } |
1106 | 1106 | ||
1107 | /* On the first time here, set up VRMA or RMA */ | 1107 | atomic_inc(&vcpu->kvm->arch.vcpus_running); |
1108 | /* Order vcpus_running vs. rma_setup_done, see kvmppc_alloc_reset_hpt */ | ||
1109 | smp_mb(); | ||
1110 | |||
1111 | /* On the first time here, set up HTAB and VRMA or RMA */ | ||
1108 | if (!vcpu->kvm->arch.rma_setup_done) { | 1112 | if (!vcpu->kvm->arch.rma_setup_done) { |
1109 | r = kvmppc_hv_setup_rma(vcpu); | 1113 | r = kvmppc_hv_setup_htab_rma(vcpu); |
1110 | if (r) | 1114 | if (r) |
1111 | return r; | 1115 | goto out; |
1112 | } | 1116 | } |
1113 | 1117 | ||
1114 | flush_fp_to_thread(current); | 1118 | flush_fp_to_thread(current); |
@@ -1126,6 +1130,9 @@ int kvmppc_vcpu_run(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
1126 | kvmppc_core_prepare_to_enter(vcpu); | 1130 | kvmppc_core_prepare_to_enter(vcpu); |
1127 | } | 1131 | } |
1128 | } while (r == RESUME_GUEST); | 1132 | } while (r == RESUME_GUEST); |
1133 | |||
1134 | out: | ||
1135 | atomic_dec(&vcpu->kvm->arch.vcpus_running); | ||
1129 | return r; | 1136 | return r; |
1130 | } | 1137 | } |
1131 | 1138 | ||
@@ -1341,7 +1348,7 @@ void kvmppc_core_commit_memory_region(struct kvm *kvm, | |||
1341 | { | 1348 | { |
1342 | } | 1349 | } |
1343 | 1350 | ||
1344 | static int kvmppc_hv_setup_rma(struct kvm_vcpu *vcpu) | 1351 | static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu) |
1345 | { | 1352 | { |
1346 | int err = 0; | 1353 | int err = 0; |
1347 | struct kvm *kvm = vcpu->kvm; | 1354 | struct kvm *kvm = vcpu->kvm; |
@@ -1360,6 +1367,15 @@ static int kvmppc_hv_setup_rma(struct kvm_vcpu *vcpu) | |||
1360 | if (kvm->arch.rma_setup_done) | 1367 | if (kvm->arch.rma_setup_done) |
1361 | goto out; /* another vcpu beat us to it */ | 1368 | goto out; /* another vcpu beat us to it */ |
1362 | 1369 | ||
1370 | /* Allocate hashed page table (if not done already) and reset it */ | ||
1371 | if (!kvm->arch.hpt_virt) { | ||
1372 | err = kvmppc_alloc_hpt(kvm, NULL); | ||
1373 | if (err) { | ||
1374 | pr_err("KVM: Couldn't alloc HPT\n"); | ||
1375 | goto out; | ||
1376 | } | ||
1377 | } | ||
1378 | |||
1363 | /* Look up the memslot for guest physical address 0 */ | 1379 | /* Look up the memslot for guest physical address 0 */ |
1364 | memslot = gfn_to_memslot(kvm, 0); | 1380 | memslot = gfn_to_memslot(kvm, 0); |
1365 | 1381 | ||
@@ -1471,13 +1487,14 @@ static int kvmppc_hv_setup_rma(struct kvm_vcpu *vcpu) | |||
1471 | 1487 | ||
1472 | int kvmppc_core_init_vm(struct kvm *kvm) | 1488 | int kvmppc_core_init_vm(struct kvm *kvm) |
1473 | { | 1489 | { |
1474 | long r; | 1490 | unsigned long lpcr, lpid; |
1475 | unsigned long lpcr; | ||
1476 | 1491 | ||
1477 | /* Allocate hashed page table */ | 1492 | /* Allocate the guest's logical partition ID */ |
1478 | r = kvmppc_alloc_hpt(kvm); | 1493 | |
1479 | if (r) | 1494 | lpid = kvmppc_alloc_lpid(); |
1480 | return r; | 1495 | if (lpid < 0) |
1496 | return -ENOMEM; | ||
1497 | kvm->arch.lpid = lpid; | ||
1481 | 1498 | ||
1482 | INIT_LIST_HEAD(&kvm->arch.spapr_tce_tables); | 1499 | INIT_LIST_HEAD(&kvm->arch.spapr_tce_tables); |
1483 | 1500 | ||
@@ -1487,7 +1504,6 @@ int kvmppc_core_init_vm(struct kvm *kvm) | |||
1487 | 1504 | ||
1488 | if (cpu_has_feature(CPU_FTR_ARCH_201)) { | 1505 | if (cpu_has_feature(CPU_FTR_ARCH_201)) { |
1489 | /* PPC970; HID4 is effectively the LPCR */ | 1506 | /* PPC970; HID4 is effectively the LPCR */ |
1490 | unsigned long lpid = kvm->arch.lpid; | ||
1491 | kvm->arch.host_lpid = 0; | 1507 | kvm->arch.host_lpid = 0; |
1492 | kvm->arch.host_lpcr = lpcr = mfspr(SPRN_HID4); | 1508 | kvm->arch.host_lpcr = lpcr = mfspr(SPRN_HID4); |
1493 | lpcr &= ~((3 << HID4_LPID1_SH) | (0xful << HID4_LPID5_SH)); | 1509 | lpcr &= ~((3 << HID4_LPID1_SH) | (0xful << HID4_LPID5_SH)); |
diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c index e1b60f56f2a1..fb4eac290fef 100644 --- a/arch/powerpc/kvm/book3s_hv_builtin.c +++ b/arch/powerpc/kvm/book3s_hv_builtin.c | |||
@@ -25,6 +25,9 @@ static void __init kvm_linear_init_one(ulong size, int count, int type); | |||
25 | static struct kvmppc_linear_info *kvm_alloc_linear(int type); | 25 | static struct kvmppc_linear_info *kvm_alloc_linear(int type); |
26 | static void kvm_release_linear(struct kvmppc_linear_info *ri); | 26 | static void kvm_release_linear(struct kvmppc_linear_info *ri); |
27 | 27 | ||
28 | int kvm_hpt_order = KVM_DEFAULT_HPT_ORDER; | ||
29 | EXPORT_SYMBOL_GPL(kvm_hpt_order); | ||
30 | |||
28 | /*************** RMA *************/ | 31 | /*************** RMA *************/ |
29 | 32 | ||
30 | /* | 33 | /* |
@@ -209,7 +212,7 @@ static void kvm_release_linear(struct kvmppc_linear_info *ri) | |||
209 | void __init kvm_linear_init(void) | 212 | void __init kvm_linear_init(void) |
210 | { | 213 | { |
211 | /* HPT */ | 214 | /* HPT */ |
212 | kvm_linear_init_one(1 << HPT_ORDER, kvm_hpt_count, KVM_LINEAR_HPT); | 215 | kvm_linear_init_one(1 << kvm_hpt_order, kvm_hpt_count, KVM_LINEAR_HPT); |
213 | 216 | ||
214 | /* RMA */ | 217 | /* RMA */ |
215 | /* Only do this on PPC970 in HV mode */ | 218 | /* Only do this on PPC970 in HV mode */ |
diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c index cec4daddbf31..5c70d19494f9 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c +++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c | |||
@@ -237,7 +237,7 @@ long kvmppc_h_enter(struct kvm_vcpu *vcpu, unsigned long flags, | |||
237 | 237 | ||
238 | /* Find and lock the HPTEG slot to use */ | 238 | /* Find and lock the HPTEG slot to use */ |
239 | do_insert: | 239 | do_insert: |
240 | if (pte_index >= HPT_NPTE) | 240 | if (pte_index >= kvm->arch.hpt_npte) |
241 | return H_PARAMETER; | 241 | return H_PARAMETER; |
242 | if (likely((flags & H_EXACT) == 0)) { | 242 | if (likely((flags & H_EXACT) == 0)) { |
243 | pte_index &= ~7UL; | 243 | pte_index &= ~7UL; |
@@ -352,7 +352,7 @@ long kvmppc_h_remove(struct kvm_vcpu *vcpu, unsigned long flags, | |||
352 | unsigned long v, r, rb; | 352 | unsigned long v, r, rb; |
353 | struct revmap_entry *rev; | 353 | struct revmap_entry *rev; |
354 | 354 | ||
355 | if (pte_index >= HPT_NPTE) | 355 | if (pte_index >= kvm->arch.hpt_npte) |
356 | return H_PARAMETER; | 356 | return H_PARAMETER; |
357 | hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4)); | 357 | hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4)); |
358 | while (!try_lock_hpte(hpte, HPTE_V_HVLOCK)) | 358 | while (!try_lock_hpte(hpte, HPTE_V_HVLOCK)) |
@@ -419,7 +419,8 @@ long kvmppc_h_bulk_remove(struct kvm_vcpu *vcpu) | |||
419 | i = 4; | 419 | i = 4; |
420 | break; | 420 | break; |
421 | } | 421 | } |
422 | if (req != 1 || flags == 3 || pte_index >= HPT_NPTE) { | 422 | if (req != 1 || flags == 3 || |
423 | pte_index >= kvm->arch.hpt_npte) { | ||
423 | /* parameter error */ | 424 | /* parameter error */ |
424 | args[j] = ((0xa0 | flags) << 56) + pte_index; | 425 | args[j] = ((0xa0 | flags) << 56) + pte_index; |
425 | ret = H_PARAMETER; | 426 | ret = H_PARAMETER; |
@@ -521,7 +522,7 @@ long kvmppc_h_protect(struct kvm_vcpu *vcpu, unsigned long flags, | |||
521 | struct revmap_entry *rev; | 522 | struct revmap_entry *rev; |
522 | unsigned long v, r, rb, mask, bits; | 523 | unsigned long v, r, rb, mask, bits; |
523 | 524 | ||
524 | if (pte_index >= HPT_NPTE) | 525 | if (pte_index >= kvm->arch.hpt_npte) |
525 | return H_PARAMETER; | 526 | return H_PARAMETER; |
526 | 527 | ||
527 | hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4)); | 528 | hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4)); |
@@ -583,7 +584,7 @@ long kvmppc_h_read(struct kvm_vcpu *vcpu, unsigned long flags, | |||
583 | int i, n = 1; | 584 | int i, n = 1; |
584 | struct revmap_entry *rev = NULL; | 585 | struct revmap_entry *rev = NULL; |
585 | 586 | ||
586 | if (pte_index >= HPT_NPTE) | 587 | if (pte_index >= kvm->arch.hpt_npte) |
587 | return H_PARAMETER; | 588 | return H_PARAMETER; |
588 | if (flags & H_READ_4) { | 589 | if (flags & H_READ_4) { |
589 | pte_index &= ~3; | 590 | pte_index &= ~3; |
@@ -678,7 +679,7 @@ long kvmppc_hv_find_lock_hpte(struct kvm *kvm, gva_t eaddr, unsigned long slb_v, | |||
678 | somask = (1UL << 28) - 1; | 679 | somask = (1UL << 28) - 1; |
679 | vsid = (slb_v & ~SLB_VSID_B) >> SLB_VSID_SHIFT; | 680 | vsid = (slb_v & ~SLB_VSID_B) >> SLB_VSID_SHIFT; |
680 | } | 681 | } |
681 | hash = (vsid ^ ((eaddr & somask) >> pshift)) & HPT_HASH_MASK; | 682 | hash = (vsid ^ ((eaddr & somask) >> pshift)) & kvm->arch.hpt_mask; |
682 | avpn = slb_v & ~(somask >> 16); /* also includes B */ | 683 | avpn = slb_v & ~(somask >> 16); /* also includes B */ |
683 | avpn |= (eaddr & somask) >> 16; | 684 | avpn |= (eaddr & somask) >> 16; |
684 | 685 | ||
@@ -723,7 +724,7 @@ long kvmppc_hv_find_lock_hpte(struct kvm *kvm, gva_t eaddr, unsigned long slb_v, | |||
723 | if (val & HPTE_V_SECONDARY) | 724 | if (val & HPTE_V_SECONDARY) |
724 | break; | 725 | break; |
725 | val |= HPTE_V_SECONDARY; | 726 | val |= HPTE_V_SECONDARY; |
726 | hash = hash ^ HPT_HASH_MASK; | 727 | hash = hash ^ kvm->arch.hpt_mask; |
727 | } | 728 | } |
728 | return -1; | 729 | return -1; |
729 | } | 730 | } |
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index 72f13f4a06e0..d25a097c852b 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c | |||
@@ -612,6 +612,12 @@ static void kvmppc_fill_pt_regs(struct pt_regs *regs) | |||
612 | regs->link = lr; | 612 | regs->link = lr; |
613 | } | 613 | } |
614 | 614 | ||
615 | /* | ||
616 | * For interrupts needed to be handled by host interrupt handlers, | ||
617 | * corresponding host handler are called from here in similar way | ||
618 | * (but not exact) as they are called from low level handler | ||
619 | * (such as from arch/powerpc/kernel/head_fsl_booke.S). | ||
620 | */ | ||
615 | static void kvmppc_restart_interrupt(struct kvm_vcpu *vcpu, | 621 | static void kvmppc_restart_interrupt(struct kvm_vcpu *vcpu, |
616 | unsigned int exit_nr) | 622 | unsigned int exit_nr) |
617 | { | 623 | { |
@@ -639,6 +645,17 @@ static void kvmppc_restart_interrupt(struct kvm_vcpu *vcpu, | |||
639 | kvmppc_fill_pt_regs(®s); | 645 | kvmppc_fill_pt_regs(®s); |
640 | performance_monitor_exception(®s); | 646 | performance_monitor_exception(®s); |
641 | break; | 647 | break; |
648 | case BOOKE_INTERRUPT_WATCHDOG: | ||
649 | kvmppc_fill_pt_regs(®s); | ||
650 | #ifdef CONFIG_BOOKE_WDT | ||
651 | WatchdogException(®s); | ||
652 | #else | ||
653 | unknown_exception(®s); | ||
654 | #endif | ||
655 | break; | ||
656 | case BOOKE_INTERRUPT_CRITICAL: | ||
657 | unknown_exception(®s); | ||
658 | break; | ||
642 | } | 659 | } |
643 | } | 660 | } |
644 | 661 | ||
@@ -683,6 +700,10 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
683 | r = RESUME_GUEST; | 700 | r = RESUME_GUEST; |
684 | break; | 701 | break; |
685 | 702 | ||
703 | case BOOKE_INTERRUPT_WATCHDOG: | ||
704 | r = RESUME_GUEST; | ||
705 | break; | ||
706 | |||
686 | case BOOKE_INTERRUPT_DOORBELL: | 707 | case BOOKE_INTERRUPT_DOORBELL: |
687 | kvmppc_account_exit(vcpu, DBELL_EXITS); | 708 | kvmppc_account_exit(vcpu, DBELL_EXITS); |
688 | r = RESUME_GUEST; | 709 | r = RESUME_GUEST; |
@@ -1267,6 +1288,11 @@ void kvmppc_decrementer_func(unsigned long data) | |||
1267 | { | 1288 | { |
1268 | struct kvm_vcpu *vcpu = (struct kvm_vcpu *)data; | 1289 | struct kvm_vcpu *vcpu = (struct kvm_vcpu *)data; |
1269 | 1290 | ||
1291 | if (vcpu->arch.tcr & TCR_ARE) { | ||
1292 | vcpu->arch.dec = vcpu->arch.decar; | ||
1293 | kvmppc_emulate_dec(vcpu); | ||
1294 | } | ||
1295 | |||
1270 | kvmppc_set_tsr_bits(vcpu, TSR_DIS); | 1296 | kvmppc_set_tsr_bits(vcpu, TSR_DIS); |
1271 | } | 1297 | } |
1272 | 1298 | ||
diff --git a/arch/powerpc/kvm/booke_emulate.c b/arch/powerpc/kvm/booke_emulate.c index 6c76397f2af4..12834bb608ab 100644 --- a/arch/powerpc/kvm/booke_emulate.c +++ b/arch/powerpc/kvm/booke_emulate.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include "booke.h" | 24 | #include "booke.h" |
25 | 25 | ||
26 | #define OP_19_XOP_RFI 50 | 26 | #define OP_19_XOP_RFI 50 |
27 | #define OP_19_XOP_RFCI 51 | ||
27 | 28 | ||
28 | #define OP_31_XOP_MFMSR 83 | 29 | #define OP_31_XOP_MFMSR 83 |
29 | #define OP_31_XOP_WRTEE 131 | 30 | #define OP_31_XOP_WRTEE 131 |
@@ -36,6 +37,12 @@ static void kvmppc_emul_rfi(struct kvm_vcpu *vcpu) | |||
36 | kvmppc_set_msr(vcpu, vcpu->arch.shared->srr1); | 37 | kvmppc_set_msr(vcpu, vcpu->arch.shared->srr1); |
37 | } | 38 | } |
38 | 39 | ||
40 | static void kvmppc_emul_rfci(struct kvm_vcpu *vcpu) | ||
41 | { | ||
42 | vcpu->arch.pc = vcpu->arch.csrr0; | ||
43 | kvmppc_set_msr(vcpu, vcpu->arch.csrr1); | ||
44 | } | ||
45 | |||
39 | int kvmppc_booke_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, | 46 | int kvmppc_booke_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, |
40 | unsigned int inst, int *advance) | 47 | unsigned int inst, int *advance) |
41 | { | 48 | { |
@@ -52,6 +59,12 @@ int kvmppc_booke_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
52 | *advance = 0; | 59 | *advance = 0; |
53 | break; | 60 | break; |
54 | 61 | ||
62 | case OP_19_XOP_RFCI: | ||
63 | kvmppc_emul_rfci(vcpu); | ||
64 | kvmppc_set_exit_type(vcpu, EMULATED_RFCI_EXITS); | ||
65 | *advance = 0; | ||
66 | break; | ||
67 | |||
55 | default: | 68 | default: |
56 | emulated = EMULATE_FAIL; | 69 | emulated = EMULATE_FAIL; |
57 | break; | 70 | break; |
@@ -113,6 +126,12 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) | |||
113 | case SPRN_ESR: | 126 | case SPRN_ESR: |
114 | vcpu->arch.shared->esr = spr_val; | 127 | vcpu->arch.shared->esr = spr_val; |
115 | break; | 128 | break; |
129 | case SPRN_CSRR0: | ||
130 | vcpu->arch.csrr0 = spr_val; | ||
131 | break; | ||
132 | case SPRN_CSRR1: | ||
133 | vcpu->arch.csrr1 = spr_val; | ||
134 | break; | ||
116 | case SPRN_DBCR0: | 135 | case SPRN_DBCR0: |
117 | vcpu->arch.dbcr0 = spr_val; | 136 | vcpu->arch.dbcr0 = spr_val; |
118 | break; | 137 | break; |
@@ -129,6 +148,9 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) | |||
129 | kvmppc_set_tcr(vcpu, spr_val); | 148 | kvmppc_set_tcr(vcpu, spr_val); |
130 | break; | 149 | break; |
131 | 150 | ||
151 | case SPRN_DECAR: | ||
152 | vcpu->arch.decar = spr_val; | ||
153 | break; | ||
132 | /* | 154 | /* |
133 | * Note: SPRG4-7 are user-readable. | 155 | * Note: SPRG4-7 are user-readable. |
134 | * These values are loaded into the real SPRGs when resuming the | 156 | * These values are loaded into the real SPRGs when resuming the |
@@ -229,6 +251,12 @@ int kvmppc_booke_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val) | |||
229 | case SPRN_ESR: | 251 | case SPRN_ESR: |
230 | *spr_val = vcpu->arch.shared->esr; | 252 | *spr_val = vcpu->arch.shared->esr; |
231 | break; | 253 | break; |
254 | case SPRN_CSRR0: | ||
255 | *spr_val = vcpu->arch.csrr0; | ||
256 | break; | ||
257 | case SPRN_CSRR1: | ||
258 | *spr_val = vcpu->arch.csrr1; | ||
259 | break; | ||
232 | case SPRN_DBCR0: | 260 | case SPRN_DBCR0: |
233 | *spr_val = vcpu->arch.dbcr0; | 261 | *spr_val = vcpu->arch.dbcr0; |
234 | break; | 262 | break; |
diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S index 8fd4b2a0911b..bb46b32f9813 100644 --- a/arch/powerpc/kvm/booke_interrupts.S +++ b/arch/powerpc/kvm/booke_interrupts.S | |||
@@ -52,16 +52,21 @@ | |||
52 | (1<<BOOKE_INTERRUPT_PROGRAM) | \ | 52 | (1<<BOOKE_INTERRUPT_PROGRAM) | \ |
53 | (1<<BOOKE_INTERRUPT_DTLB_MISS)) | 53 | (1<<BOOKE_INTERRUPT_DTLB_MISS)) |
54 | 54 | ||
55 | .macro KVM_HANDLER ivor_nr | 55 | .macro KVM_HANDLER ivor_nr scratch srr0 |
56 | _GLOBAL(kvmppc_handler_\ivor_nr) | 56 | _GLOBAL(kvmppc_handler_\ivor_nr) |
57 | /* Get pointer to vcpu and record exit number. */ | 57 | /* Get pointer to vcpu and record exit number. */ |
58 | mtspr SPRN_SPRG_WSCRATCH0, r4 | 58 | mtspr \scratch , r4 |
59 | mfspr r4, SPRN_SPRG_RVCPU | 59 | mfspr r4, SPRN_SPRG_RVCPU |
60 | stw r3, VCPU_GPR(R3)(r4) | ||
60 | stw r5, VCPU_GPR(R5)(r4) | 61 | stw r5, VCPU_GPR(R5)(r4) |
61 | stw r6, VCPU_GPR(R6)(r4) | 62 | stw r6, VCPU_GPR(R6)(r4) |
63 | mfspr r3, \scratch | ||
62 | mfctr r5 | 64 | mfctr r5 |
63 | lis r6, kvmppc_resume_host@h | 65 | stw r3, VCPU_GPR(R4)(r4) |
64 | stw r5, VCPU_CTR(r4) | 66 | stw r5, VCPU_CTR(r4) |
67 | mfspr r3, \srr0 | ||
68 | lis r6, kvmppc_resume_host@h | ||
69 | stw r3, VCPU_PC(r4) | ||
65 | li r5, \ivor_nr | 70 | li r5, \ivor_nr |
66 | ori r6, r6, kvmppc_resume_host@l | 71 | ori r6, r6, kvmppc_resume_host@l |
67 | mtctr r6 | 72 | mtctr r6 |
@@ -69,37 +74,35 @@ _GLOBAL(kvmppc_handler_\ivor_nr) | |||
69 | .endm | 74 | .endm |
70 | 75 | ||
71 | _GLOBAL(kvmppc_handlers_start) | 76 | _GLOBAL(kvmppc_handlers_start) |
72 | KVM_HANDLER BOOKE_INTERRUPT_CRITICAL | 77 | KVM_HANDLER BOOKE_INTERRUPT_CRITICAL SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0 |
73 | KVM_HANDLER BOOKE_INTERRUPT_MACHINE_CHECK | 78 | KVM_HANDLER BOOKE_INTERRUPT_MACHINE_CHECK SPRN_SPRG_RSCRATCH_MC SPRN_MCSRR0 |
74 | KVM_HANDLER BOOKE_INTERRUPT_DATA_STORAGE | 79 | KVM_HANDLER BOOKE_INTERRUPT_DATA_STORAGE SPRN_SPRG_RSCRATCH0 SPRN_SRR0 |
75 | KVM_HANDLER BOOKE_INTERRUPT_INST_STORAGE | 80 | KVM_HANDLER BOOKE_INTERRUPT_INST_STORAGE SPRN_SPRG_RSCRATCH0 SPRN_SRR0 |
76 | KVM_HANDLER BOOKE_INTERRUPT_EXTERNAL | 81 | KVM_HANDLER BOOKE_INTERRUPT_EXTERNAL SPRN_SPRG_RSCRATCH0 SPRN_SRR0 |
77 | KVM_HANDLER BOOKE_INTERRUPT_ALIGNMENT | 82 | KVM_HANDLER BOOKE_INTERRUPT_ALIGNMENT SPRN_SPRG_RSCRATCH0 SPRN_SRR0 |
78 | KVM_HANDLER BOOKE_INTERRUPT_PROGRAM | 83 | KVM_HANDLER BOOKE_INTERRUPT_PROGRAM SPRN_SPRG_RSCRATCH0 SPRN_SRR0 |
79 | KVM_HANDLER BOOKE_INTERRUPT_FP_UNAVAIL | 84 | KVM_HANDLER BOOKE_INTERRUPT_FP_UNAVAIL SPRN_SPRG_RSCRATCH0 SPRN_SRR0 |
80 | KVM_HANDLER BOOKE_INTERRUPT_SYSCALL | 85 | KVM_HANDLER BOOKE_INTERRUPT_SYSCALL SPRN_SPRG_RSCRATCH0 SPRN_SRR0 |
81 | KVM_HANDLER BOOKE_INTERRUPT_AP_UNAVAIL | 86 | KVM_HANDLER BOOKE_INTERRUPT_AP_UNAVAIL SPRN_SPRG_RSCRATCH0 SPRN_SRR0 |
82 | KVM_HANDLER BOOKE_INTERRUPT_DECREMENTER | 87 | KVM_HANDLER BOOKE_INTERRUPT_DECREMENTER SPRN_SPRG_RSCRATCH0 SPRN_SRR0 |
83 | KVM_HANDLER BOOKE_INTERRUPT_FIT | 88 | KVM_HANDLER BOOKE_INTERRUPT_FIT SPRN_SPRG_RSCRATCH0 SPRN_SRR0 |
84 | KVM_HANDLER BOOKE_INTERRUPT_WATCHDOG | 89 | KVM_HANDLER BOOKE_INTERRUPT_WATCHDOG SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0 |
85 | KVM_HANDLER BOOKE_INTERRUPT_DTLB_MISS | 90 | KVM_HANDLER BOOKE_INTERRUPT_DTLB_MISS SPRN_SPRG_RSCRATCH0 SPRN_SRR0 |
86 | KVM_HANDLER BOOKE_INTERRUPT_ITLB_MISS | 91 | KVM_HANDLER BOOKE_INTERRUPT_ITLB_MISS SPRN_SPRG_RSCRATCH0 SPRN_SRR0 |
87 | KVM_HANDLER BOOKE_INTERRUPT_DEBUG | 92 | KVM_HANDLER BOOKE_INTERRUPT_DEBUG SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0 |
88 | KVM_HANDLER BOOKE_INTERRUPT_SPE_UNAVAIL | 93 | KVM_HANDLER BOOKE_INTERRUPT_SPE_UNAVAIL SPRN_SPRG_RSCRATCH0 SPRN_SRR0 |
89 | KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_DATA | 94 | KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_DATA SPRN_SPRG_RSCRATCH0 SPRN_SRR0 |
90 | KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_ROUND | 95 | KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_ROUND SPRN_SPRG_RSCRATCH0 SPRN_SRR0 |
91 | 96 | ||
92 | _GLOBAL(kvmppc_handler_len) | 97 | _GLOBAL(kvmppc_handler_len) |
93 | .long kvmppc_handler_1 - kvmppc_handler_0 | 98 | .long kvmppc_handler_1 - kvmppc_handler_0 |
94 | 99 | ||
95 | |||
96 | /* Registers: | 100 | /* Registers: |
97 | * SPRG_SCRATCH0: guest r4 | 101 | * SPRG_SCRATCH0: guest r4 |
98 | * r4: vcpu pointer | 102 | * r4: vcpu pointer |
99 | * r5: KVM exit number | 103 | * r5: KVM exit number |
100 | */ | 104 | */ |
101 | _GLOBAL(kvmppc_resume_host) | 105 | _GLOBAL(kvmppc_resume_host) |
102 | stw r3, VCPU_GPR(R3)(r4) | ||
103 | mfcr r3 | 106 | mfcr r3 |
104 | stw r3, VCPU_CR(r4) | 107 | stw r3, VCPU_CR(r4) |
105 | stw r7, VCPU_GPR(R7)(r4) | 108 | stw r7, VCPU_GPR(R7)(r4) |
@@ -180,10 +183,6 @@ _GLOBAL(kvmppc_resume_host) | |||
180 | stw r3, VCPU_LR(r4) | 183 | stw r3, VCPU_LR(r4) |
181 | mfxer r3 | 184 | mfxer r3 |
182 | stw r3, VCPU_XER(r4) | 185 | stw r3, VCPU_XER(r4) |
183 | mfspr r3, SPRN_SPRG_RSCRATCH0 | ||
184 | stw r3, VCPU_GPR(R4)(r4) | ||
185 | mfspr r3, SPRN_SRR0 | ||
186 | stw r3, VCPU_PC(r4) | ||
187 | 186 | ||
188 | /* Restore host stack pointer and PID before IVPR, since the host | 187 | /* Restore host stack pointer and PID before IVPR, since the host |
189 | * exception handlers use them. */ | 188 | * exception handlers use them. */ |
diff --git a/arch/powerpc/kvm/bookehv_interrupts.S b/arch/powerpc/kvm/bookehv_interrupts.S index 1685dc43bcf2..d28c2d43ac1b 100644 --- a/arch/powerpc/kvm/bookehv_interrupts.S +++ b/arch/powerpc/kvm/bookehv_interrupts.S | |||
@@ -262,7 +262,7 @@ kvm_lvl_handler BOOKE_INTERRUPT_CRITICAL, \ | |||
262 | kvm_lvl_handler BOOKE_INTERRUPT_MACHINE_CHECK, \ | 262 | kvm_lvl_handler BOOKE_INTERRUPT_MACHINE_CHECK, \ |
263 | SPRN_SPRG_RSCRATCH_MC, SPRN_MCSRR0, SPRN_MCSRR1, 0 | 263 | SPRN_SPRG_RSCRATCH_MC, SPRN_MCSRR0, SPRN_MCSRR1, 0 |
264 | kvm_handler BOOKE_INTERRUPT_DATA_STORAGE, \ | 264 | kvm_handler BOOKE_INTERRUPT_DATA_STORAGE, \ |
265 | SPRN_SRR0, SPRN_SRR1, (NEED_EMU | NEED_DEAR) | 265 | SPRN_SRR0, SPRN_SRR1, (NEED_EMU | NEED_DEAR | NEED_ESR) |
266 | kvm_handler BOOKE_INTERRUPT_INST_STORAGE, SPRN_SRR0, SPRN_SRR1, NEED_ESR | 266 | kvm_handler BOOKE_INTERRUPT_INST_STORAGE, SPRN_SRR0, SPRN_SRR1, NEED_ESR |
267 | kvm_handler BOOKE_INTERRUPT_EXTERNAL, SPRN_SRR0, SPRN_SRR1, 0 | 267 | kvm_handler BOOKE_INTERRUPT_EXTERNAL, SPRN_SRR0, SPRN_SRR1, 0 |
268 | kvm_handler BOOKE_INTERRUPT_ALIGNMENT, \ | 268 | kvm_handler BOOKE_INTERRUPT_ALIGNMENT, \ |
diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c index 8b99e076dc81..e04b0ef55ce0 100644 --- a/arch/powerpc/kvm/e500_emulate.c +++ b/arch/powerpc/kvm/e500_emulate.c | |||
@@ -269,6 +269,9 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val) | |||
269 | *spr_val = vcpu->arch.shared->mas7_3 >> 32; | 269 | *spr_val = vcpu->arch.shared->mas7_3 >> 32; |
270 | break; | 270 | break; |
271 | #endif | 271 | #endif |
272 | case SPRN_DECAR: | ||
273 | *spr_val = vcpu->arch.decar; | ||
274 | break; | ||
272 | case SPRN_TLB0CFG: | 275 | case SPRN_TLB0CFG: |
273 | *spr_val = vcpu->arch.tlbcfg[0]; | 276 | *spr_val = vcpu->arch.tlbcfg[0]; |
274 | break; | 277 | break; |
diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c index fe6c1de6b701..1f89d26e65fb 100644 --- a/arch/powerpc/kvm/e500mc.c +++ b/arch/powerpc/kvm/e500mc.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2010 Freescale Semiconductor, Inc. All rights reserved. | 2 | * Copyright (C) 2010,2012 Freescale Semiconductor, Inc. All rights reserved. |
3 | * | 3 | * |
4 | * Author: Varun Sethi, <varun.sethi@freescale.com> | 4 | * Author: Varun Sethi, <varun.sethi@freescale.com> |
5 | * | 5 | * |
@@ -57,7 +57,8 @@ void kvmppc_e500_tlbil_one(struct kvmppc_vcpu_e500 *vcpu_e500, | |||
57 | struct kvm_book3e_206_tlb_entry *gtlbe) | 57 | struct kvm_book3e_206_tlb_entry *gtlbe) |
58 | { | 58 | { |
59 | unsigned int tid, ts; | 59 | unsigned int tid, ts; |
60 | u32 val, eaddr, lpid; | 60 | gva_t eaddr; |
61 | u32 val, lpid; | ||
61 | unsigned long flags; | 62 | unsigned long flags; |
62 | 63 | ||
63 | ts = get_tlb_ts(gtlbe); | 64 | ts = get_tlb_ts(gtlbe); |
@@ -183,6 +184,9 @@ int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu) | |||
183 | 184 | ||
184 | vcpu->arch.shadow_epcr = SPRN_EPCR_DSIGS | SPRN_EPCR_DGTMI | \ | 185 | vcpu->arch.shadow_epcr = SPRN_EPCR_DSIGS | SPRN_EPCR_DGTMI | \ |
185 | SPRN_EPCR_DUVD; | 186 | SPRN_EPCR_DUVD; |
187 | #ifdef CONFIG_64BIT | ||
188 | vcpu->arch.shadow_epcr |= SPRN_EPCR_ICM; | ||
189 | #endif | ||
186 | vcpu->arch.shadow_msrp = MSRP_UCLEP | MSRP_DEP | MSRP_PMMP; | 190 | vcpu->arch.shadow_msrp = MSRP_UCLEP | MSRP_DEP | MSRP_PMMP; |
187 | vcpu->arch.eplc = EPC_EGS | (vcpu->kvm->arch.lpid << EPC_ELPID_SHIFT); | 191 | vcpu->arch.eplc = EPC_EGS | (vcpu->kvm->arch.lpid << EPC_ELPID_SHIFT); |
188 | vcpu->arch.epsc = vcpu->arch.eplc; | 192 | vcpu->arch.epsc = vcpu->arch.eplc; |
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c index f90e86dea7a2..ee04abaefe23 100644 --- a/arch/powerpc/kvm/emulate.c +++ b/arch/powerpc/kvm/emulate.c | |||
@@ -59,11 +59,13 @@ | |||
59 | #define OP_31_XOP_STHBRX 918 | 59 | #define OP_31_XOP_STHBRX 918 |
60 | 60 | ||
61 | #define OP_LWZ 32 | 61 | #define OP_LWZ 32 |
62 | #define OP_LD 58 | ||
62 | #define OP_LWZU 33 | 63 | #define OP_LWZU 33 |
63 | #define OP_LBZ 34 | 64 | #define OP_LBZ 34 |
64 | #define OP_LBZU 35 | 65 | #define OP_LBZU 35 |
65 | #define OP_STW 36 | 66 | #define OP_STW 36 |
66 | #define OP_STWU 37 | 67 | #define OP_STWU 37 |
68 | #define OP_STD 62 | ||
67 | #define OP_STB 38 | 69 | #define OP_STB 38 |
68 | #define OP_STBU 39 | 70 | #define OP_STBU 39 |
69 | #define OP_LHZ 40 | 71 | #define OP_LHZ 40 |
@@ -392,6 +394,12 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
392 | emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1); | 394 | emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1); |
393 | break; | 395 | break; |
394 | 396 | ||
397 | /* TBD: Add support for other 64 bit load variants like ldu, ldux, ldx etc. */ | ||
398 | case OP_LD: | ||
399 | rt = get_rt(inst); | ||
400 | emulated = kvmppc_handle_load(run, vcpu, rt, 8, 1); | ||
401 | break; | ||
402 | |||
395 | case OP_LWZU: | 403 | case OP_LWZU: |
396 | emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1); | 404 | emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1); |
397 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); | 405 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed); |
@@ -412,6 +420,14 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
412 | 4, 1); | 420 | 4, 1); |
413 | break; | 421 | break; |
414 | 422 | ||
423 | /* TBD: Add support for other 64 bit store variants like stdu, stdux, stdx etc. */ | ||
424 | case OP_STD: | ||
425 | rs = get_rs(inst); | ||
426 | emulated = kvmppc_handle_store(run, vcpu, | ||
427 | kvmppc_get_gpr(vcpu, rs), | ||
428 | 8, 1); | ||
429 | break; | ||
430 | |||
415 | case OP_STWU: | 431 | case OP_STWU: |
416 | emulated = kvmppc_handle_store(run, vcpu, | 432 | emulated = kvmppc_handle_store(run, vcpu, |
417 | kvmppc_get_gpr(vcpu, rs), | 433 | kvmppc_get_gpr(vcpu, rs), |
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 1493c8de947b..87f4dc886076 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c | |||
@@ -246,6 +246,7 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
246 | #endif | 246 | #endif |
247 | #ifdef CONFIG_PPC_BOOK3S_64 | 247 | #ifdef CONFIG_PPC_BOOK3S_64 |
248 | case KVM_CAP_SPAPR_TCE: | 248 | case KVM_CAP_SPAPR_TCE: |
249 | case KVM_CAP_PPC_ALLOC_HTAB: | ||
249 | r = 1; | 250 | r = 1; |
250 | break; | 251 | break; |
251 | #endif /* CONFIG_PPC_BOOK3S_64 */ | 252 | #endif /* CONFIG_PPC_BOOK3S_64 */ |
@@ -802,6 +803,23 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
802 | r = -EFAULT; | 803 | r = -EFAULT; |
803 | break; | 804 | break; |
804 | } | 805 | } |
806 | |||
807 | case KVM_PPC_ALLOCATE_HTAB: { | ||
808 | struct kvm *kvm = filp->private_data; | ||
809 | u32 htab_order; | ||
810 | |||
811 | r = -EFAULT; | ||
812 | if (get_user(htab_order, (u32 __user *)argp)) | ||
813 | break; | ||
814 | r = kvmppc_alloc_reset_hpt(kvm, &htab_order); | ||
815 | if (r) | ||
816 | break; | ||
817 | r = -EFAULT; | ||
818 | if (put_user(htab_order, (u32 __user *)argp)) | ||
819 | break; | ||
820 | r = 0; | ||
821 | break; | ||
822 | } | ||
805 | #endif /* CONFIG_KVM_BOOK3S_64_HV */ | 823 | #endif /* CONFIG_KVM_BOOK3S_64_HV */ |
806 | 824 | ||
807 | #ifdef CONFIG_PPC_BOOK3S_64 | 825 | #ifdef CONFIG_PPC_BOOK3S_64 |