|
@@ -821,6 +821,7 @@ static int do_vsie_run(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
|
|
|
{
|
|
|
struct kvm_s390_sie_block *scb_s = &vsie_page->scb_s;
|
|
|
struct kvm_s390_sie_block *scb_o = vsie_page->scb_o;
|
|
|
+ int guest_bp_isolation;
|
|
|
int rc;
|
|
|
|
|
|
handle_last_fault(vcpu, vsie_page);
|
|
@@ -831,6 +832,20 @@ static int do_vsie_run(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
|
|
|
s390_handle_mcck();
|
|
|
|
|
|
srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
|
|
|
+
|
|
|
+ /* save current guest state of bp isolation override */
|
|
|
+ guest_bp_isolation = test_thread_flag(TIF_ISOLATE_BP_GUEST);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * The guest is running with BPBC, so we have to force it on for our
|
|
|
+ * nested guest. This is done by enabling BPBC globally, so the BPBC
|
|
|
+ * control in the SCB (which the nested guest can modify) is simply
|
|
|
+ * ignored.
|
|
|
+ */
|
|
|
+ if (test_kvm_facility(vcpu->kvm, 82) &&
|
|
|
+ vcpu->arch.sie_block->fpf & FPF_BPBC)
|
|
|
+ set_thread_flag(TIF_ISOLATE_BP_GUEST);
|
|
|
+
|
|
|
local_irq_disable();
|
|
|
guest_enter_irqoff();
|
|
|
local_irq_enable();
|
|
@@ -840,6 +855,11 @@ static int do_vsie_run(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
|
|
|
local_irq_disable();
|
|
|
guest_exit_irqoff();
|
|
|
local_irq_enable();
|
|
|
+
|
|
|
+ /* restore guest state for bp isolation override */
|
|
|
+ if (!guest_bp_isolation)
|
|
|
+ clear_thread_flag(TIF_ISOLATE_BP_GUEST);
|
|
|
+
|
|
|
vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
|
|
|
|
|
|
if (rc == -EINTR) {
|