book3s_emulate.c (b7d3622a39fde7658170b7f3cf6c6889bb8db30d) book3s_emulate.c (5deb8e7ad8ac7e3fcdfa042acff617f461b361c2)
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License, version 2, as
4 * published by the Free Software Foundation.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

--- 66 unchanged lines hidden (view full) ---

75
76static bool spr_allowed(struct kvm_vcpu *vcpu, enum priv_level level)
77{
78 /* PAPR VMs only access supervisor SPRs */
79 if (vcpu->arch.papr_enabled && (level > PRIV_SUPER))
80 return false;
81
82 /* Limit user space to its own small SPR set */
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License, version 2, as
4 * published by the Free Software Foundation.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

--- 66 unchanged lines hidden (view full) ---

75
76static bool spr_allowed(struct kvm_vcpu *vcpu, enum priv_level level)
77{
78 /* PAPR VMs only access supervisor SPRs */
79 if (vcpu->arch.papr_enabled && (level > PRIV_SUPER))
80 return false;
81
82 /* Limit user space to its own small SPR set */
83 if ((vcpu->arch.shared->msr & MSR_PR) && level > PRIV_PROBLEM)
83 if ((kvmppc_get_msr(vcpu) & MSR_PR) && level > PRIV_PROBLEM)
84 return false;
85
86 return true;
87}
88
89int kvmppc_core_emulate_op_pr(struct kvm_run *run, struct kvm_vcpu *vcpu,
90 unsigned int inst, int *advance)
91{
92 int emulated = EMULATE_DONE;
93 int rt = get_rt(inst);
94 int rs = get_rs(inst);
95 int ra = get_ra(inst);
96 int rb = get_rb(inst);
97
98 switch (get_op(inst)) {
99 case 19:
100 switch (get_xop(inst)) {
101 case OP_19_XOP_RFID:
102 case OP_19_XOP_RFI:
84 return false;
85
86 return true;
87}
88
89int kvmppc_core_emulate_op_pr(struct kvm_run *run, struct kvm_vcpu *vcpu,
90 unsigned int inst, int *advance)
91{
92 int emulated = EMULATE_DONE;
93 int rt = get_rt(inst);
94 int rs = get_rs(inst);
95 int ra = get_ra(inst);
96 int rb = get_rb(inst);
97
98 switch (get_op(inst)) {
99 case 19:
100 switch (get_xop(inst)) {
101 case OP_19_XOP_RFID:
102 case OP_19_XOP_RFI:
103 kvmppc_set_pc(vcpu, vcpu->arch.shared->srr0);
104 kvmppc_set_msr(vcpu, vcpu->arch.shared->srr1);
103 kvmppc_set_pc(vcpu, kvmppc_get_srr0(vcpu));
104 kvmppc_set_msr(vcpu, kvmppc_get_srr1(vcpu));
105 *advance = 0;
106 break;
107
108 default:
109 emulated = EMULATE_FAIL;
110 break;
111 }
112 break;
113 case 31:
114 switch (get_xop(inst)) {
115 case OP_31_XOP_MFMSR:
105 *advance = 0;
106 break;
107
108 default:
109 emulated = EMULATE_FAIL;
110 break;
111 }
112 break;
113 case 31:
114 switch (get_xop(inst)) {
115 case OP_31_XOP_MFMSR:
116 kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->msr);
116 kvmppc_set_gpr(vcpu, rt, kvmppc_get_msr(vcpu));
117 break;
118 case OP_31_XOP_MTMSRD:
119 {
120 ulong rs_val = kvmppc_get_gpr(vcpu, rs);
121 if (inst & 0x10000) {
117 break;
118 case OP_31_XOP_MTMSRD:
119 {
120 ulong rs_val = kvmppc_get_gpr(vcpu, rs);
121 if (inst & 0x10000) {
122 ulong new_msr = vcpu->arch.shared->msr;
122 ulong new_msr = kvmppc_get_msr(vcpu);
123 new_msr &= ~(MSR_RI | MSR_EE);
124 new_msr |= rs_val & (MSR_RI | MSR_EE);
123 new_msr &= ~(MSR_RI | MSR_EE);
124 new_msr |= rs_val & (MSR_RI | MSR_EE);
125 vcpu->arch.shared->msr = new_msr;
125 kvmppc_set_msr_fast(vcpu, new_msr);
126 } else
127 kvmppc_set_msr(vcpu, rs_val);
128 break;
129 }
130 case OP_31_XOP_MTMSR:
131 kvmppc_set_msr(vcpu, kvmppc_get_gpr(vcpu, rs));
132 break;
133 case OP_31_XOP_MFSR:

--- 40 unchanged lines hidden (view full) ---

174 }
175#ifdef CONFIG_PPC_BOOK3S_64
176 case OP_31_XOP_FAKE_SC1:
177 {
178 /* SC 1 papr hypercalls */
179 ulong cmd = kvmppc_get_gpr(vcpu, 3);
180 int i;
181
126 } else
127 kvmppc_set_msr(vcpu, rs_val);
128 break;
129 }
130 case OP_31_XOP_MTMSR:
131 kvmppc_set_msr(vcpu, kvmppc_get_gpr(vcpu, rs));
132 break;
133 case OP_31_XOP_MFSR:

--- 40 unchanged lines hidden (view full) ---

174 }
175#ifdef CONFIG_PPC_BOOK3S_64
176 case OP_31_XOP_FAKE_SC1:
177 {
178 /* SC 1 papr hypercalls */
179 ulong cmd = kvmppc_get_gpr(vcpu, 3);
180 int i;
181
182 if ((vcpu->arch.shared->msr & MSR_PR) ||
182 if ((kvmppc_get_msr(vcpu) & MSR_PR) ||
183 !vcpu->arch.papr_enabled) {
184 emulated = EMULATE_FAIL;
185 break;
186 }
187
188 if (kvmppc_h_pr(vcpu, cmd) == EMULATE_DONE)
189 break;
190

--- 65 unchanged lines hidden (view full) ---

256 u32 zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
257 u32 dsisr;
258 int r;
259
260 if (ra)
261 ra_val = kvmppc_get_gpr(vcpu, ra);
262
263 addr = (ra_val + rb_val) & ~31ULL;
183 !vcpu->arch.papr_enabled) {
184 emulated = EMULATE_FAIL;
185 break;
186 }
187
188 if (kvmppc_h_pr(vcpu, cmd) == EMULATE_DONE)
189 break;
190

--- 65 unchanged lines hidden (view full) ---

256 u32 zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
257 u32 dsisr;
258 int r;
259
260 if (ra)
261 ra_val = kvmppc_get_gpr(vcpu, ra);
262
263 addr = (ra_val + rb_val) & ~31ULL;
264 if (!(vcpu->arch.shared->msr & MSR_SF))
264 if (!(kvmppc_get_msr(vcpu) & MSR_SF))
265 addr &= 0xffffffff;
266 vaddr = addr;
267
268 r = kvmppc_st(vcpu, &addr, 32, zeros, true);
269 if ((r == -ENOENT) || (r == -EPERM)) {
270 *advance = 0;
265 addr &= 0xffffffff;
266 vaddr = addr;
267
268 r = kvmppc_st(vcpu, &addr, 32, zeros, true);
269 if ((r == -ENOENT) || (r == -EPERM)) {
270 *advance = 0;
271 vcpu->arch.shared->dar = vaddr;
271 kvmppc_set_dar(vcpu, vaddr);
272 vcpu->arch.fault_dar = vaddr;
273
274 dsisr = DSISR_ISSTORE;
275 if (r == -ENOENT)
276 dsisr |= DSISR_NOHPTE;
277 else if (r == -EPERM)
278 dsisr |= DSISR_PROTFAULT;
279
272 vcpu->arch.fault_dar = vaddr;
273
274 dsisr = DSISR_ISSTORE;
275 if (r == -ENOENT)
276 dsisr |= DSISR_NOHPTE;
277 else if (r == -EPERM)
278 dsisr |= DSISR_PROTFAULT;
279
280 vcpu->arch.shared->dsisr = dsisr;
280 kvmppc_set_dsisr(vcpu, dsisr);
281 vcpu->arch.fault_dsisr = dsisr;
282
283 kvmppc_book3s_queue_irqprio(vcpu,
284 BOOK3S_INTERRUPT_DATA_STORAGE);
285 }
286
287 break;
288 }

--- 62 unchanged lines hidden (view full) ---

351
352 switch (sprn) {
353 case SPRN_SDR1:
354 if (!spr_allowed(vcpu, PRIV_HYPER))
355 goto unprivileged;
356 to_book3s(vcpu)->sdr1 = spr_val;
357 break;
358 case SPRN_DSISR:
281 vcpu->arch.fault_dsisr = dsisr;
282
283 kvmppc_book3s_queue_irqprio(vcpu,
284 BOOK3S_INTERRUPT_DATA_STORAGE);
285 }
286
287 break;
288 }

--- 62 unchanged lines hidden (view full) ---

351
352 switch (sprn) {
353 case SPRN_SDR1:
354 if (!spr_allowed(vcpu, PRIV_HYPER))
355 goto unprivileged;
356 to_book3s(vcpu)->sdr1 = spr_val;
357 break;
358 case SPRN_DSISR:
359 vcpu->arch.shared->dsisr = spr_val;
359 kvmppc_set_dsisr(vcpu, spr_val);
360 break;
361 case SPRN_DAR:
360 break;
361 case SPRN_DAR:
362 vcpu->arch.shared->dar = spr_val;
362 kvmppc_set_dar(vcpu, spr_val);
363 break;
364 case SPRN_HIOR:
365 to_book3s(vcpu)->hior = spr_val;
366 break;
367 case SPRN_IBAT0U ... SPRN_IBAT3L:
368 case SPRN_IBAT4U ... SPRN_IBAT7L:
369 case SPRN_DBAT0U ... SPRN_DBAT3L:
370 case SPRN_DBAT4U ... SPRN_DBAT7L:

--- 117 unchanged lines hidden (view full) ---

488 break;
489 }
490 case SPRN_SDR1:
491 if (!spr_allowed(vcpu, PRIV_HYPER))
492 goto unprivileged;
493 *spr_val = to_book3s(vcpu)->sdr1;
494 break;
495 case SPRN_DSISR:
363 break;
364 case SPRN_HIOR:
365 to_book3s(vcpu)->hior = spr_val;
366 break;
367 case SPRN_IBAT0U ... SPRN_IBAT3L:
368 case SPRN_IBAT4U ... SPRN_IBAT7L:
369 case SPRN_DBAT0U ... SPRN_DBAT3L:
370 case SPRN_DBAT4U ... SPRN_DBAT7L:

--- 117 unchanged lines hidden (view full) ---

488 break;
489 }
490 case SPRN_SDR1:
491 if (!spr_allowed(vcpu, PRIV_HYPER))
492 goto unprivileged;
493 *spr_val = to_book3s(vcpu)->sdr1;
494 break;
495 case SPRN_DSISR:
496 *spr_val = vcpu->arch.shared->dsisr;
496 *spr_val = kvmppc_get_dsisr(vcpu);
497 break;
498 case SPRN_DAR:
497 break;
498 case SPRN_DAR:
499 *spr_val = vcpu->arch.shared->dar;
499 *spr_val = kvmppc_get_dar(vcpu);
500 break;
501 case SPRN_HIOR:
502 *spr_val = to_book3s(vcpu)->hior;
503 break;
504 case SPRN_HID0:
505 *spr_val = to_book3s(vcpu)->hid[0];
506 break;
507 case SPRN_HID1:

--- 131 unchanged lines hidden ---
500 break;
501 case SPRN_HIOR:
502 *spr_val = to_book3s(vcpu)->hior;
503 break;
504 case SPRN_HID0:
505 *spr_val = to_book3s(vcpu)->hid[0];
506 break;
507 case SPRN_HID1:

--- 131 unchanged lines hidden ---