|
@@ -147,6 +147,20 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
|
|
|
int allowed = 0;
|
|
|
ulong uninitialized_var(msr_mask);
|
|
|
bool update_esr = false, update_dear = false;
|
|
|
+ ulong crit_raw = vcpu->arch.shared->critical;
|
|
|
+ ulong crit_r1 = kvmppc_get_gpr(vcpu, 1);
|
|
|
+ bool crit;
|
|
|
+
|
|
|
+ /* Truncate crit indicators in 32 bit mode */
|
|
|
+ if (!(vcpu->arch.shared->msr & MSR_SF)) {
|
|
|
+ crit_raw &= 0xffffffff;
|
|
|
+ crit_r1 &= 0xffffffff;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Critical section when crit == r1 */
|
|
|
+ crit = (crit_raw == crit_r1);
|
|
|
+ /* ... and we're in supervisor mode */
|
|
|
+ crit = crit && !(vcpu->arch.shared->msr & MSR_PR);
|
|
|
|
|
|
switch (priority) {
|
|
|
case BOOKE_IRQPRIO_DTLB_MISS:
|
|
@@ -181,6 +195,7 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
|
|
|
case BOOKE_IRQPRIO_DECREMENTER:
|
|
|
case BOOKE_IRQPRIO_FIT:
|
|
|
allowed = vcpu->arch.shared->msr & MSR_EE;
|
|
|
+ allowed = allowed && !crit;
|
|
|
msr_mask = MSR_CE|MSR_ME|MSR_DE;
|
|
|
break;
|
|
|
case BOOKE_IRQPRIO_DEBUG:
|