|
@@ -38,7 +38,13 @@ struct vsie_page {
|
|
|
struct gmap *gmap; /* 0x0220 */
|
|
|
/* address of the last reported fault to guest2 */
|
|
|
unsigned long fault_addr; /* 0x0228 */
|
|
|
- __u8 reserved[0x0700 - 0x0230]; /* 0x0230 */
|
|
|
+ /* calculated guest addresses of satellite control blocks */
|
|
|
+ gpa_t sca_gpa; /* 0x0230 */
|
|
|
+ gpa_t itdba_gpa; /* 0x0238 */
|
|
|
+ gpa_t gvrd_gpa; /* 0x0240 */
|
|
|
+ gpa_t riccbd_gpa; /* 0x0248 */
|
|
|
+ gpa_t sdnx_gpa; /* 0x0250 */
|
|
|
+ __u8 reserved[0x0700 - 0x0258]; /* 0x0258 */
|
|
|
struct kvm_s390_crypto_cb crycb; /* 0x0700 */
|
|
|
__u8 fac[S390_ARCH_FAC_LIST_SIZE_BYTE]; /* 0x0800 */
|
|
|
};
|
|
@@ -475,46 +481,42 @@ static void unpin_guest_page(struct kvm *kvm, gpa_t gpa, hpa_t hpa)
|
|
|
/* unpin all blocks previously pinned by pin_blocks(), marking them dirty */
|
|
|
static void unpin_blocks(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
|
|
|
{
|
|
|
- struct kvm_s390_sie_block *scb_o = vsie_page->scb_o;
|
|
|
struct kvm_s390_sie_block *scb_s = &vsie_page->scb_s;
|
|
|
hpa_t hpa;
|
|
|
- gpa_t gpa;
|
|
|
|
|
|
hpa = (u64) scb_s->scaoh << 32 | scb_s->scaol;
|
|
|
if (hpa) {
|
|
|
- gpa = scb_o->scaol & ~0xfUL;
|
|
|
- if (test_kvm_cpu_feat(vcpu->kvm, KVM_S390_VM_CPU_FEAT_64BSCAO))
|
|
|
- gpa |= (u64) scb_o->scaoh << 32;
|
|
|
- unpin_guest_page(vcpu->kvm, gpa, hpa);
|
|
|
+ unpin_guest_page(vcpu->kvm, vsie_page->sca_gpa, hpa);
|
|
|
+ vsie_page->sca_gpa = 0;
|
|
|
scb_s->scaol = 0;
|
|
|
scb_s->scaoh = 0;
|
|
|
}
|
|
|
|
|
|
hpa = scb_s->itdba;
|
|
|
if (hpa) {
|
|
|
- gpa = scb_o->itdba & ~0xffUL;
|
|
|
- unpin_guest_page(vcpu->kvm, gpa, hpa);
|
|
|
+ unpin_guest_page(vcpu->kvm, vsie_page->itdba_gpa, hpa);
|
|
|
+ vsie_page->itdba_gpa = 0;
|
|
|
scb_s->itdba = 0;
|
|
|
}
|
|
|
|
|
|
hpa = scb_s->gvrd;
|
|
|
if (hpa) {
|
|
|
- gpa = scb_o->gvrd & ~0x1ffUL;
|
|
|
- unpin_guest_page(vcpu->kvm, gpa, hpa);
|
|
|
+ unpin_guest_page(vcpu->kvm, vsie_page->gvrd_gpa, hpa);
|
|
|
+ vsie_page->gvrd_gpa = 0;
|
|
|
scb_s->gvrd = 0;
|
|
|
}
|
|
|
|
|
|
hpa = scb_s->riccbd;
|
|
|
if (hpa) {
|
|
|
- gpa = scb_o->riccbd & ~0x3fUL;
|
|
|
- unpin_guest_page(vcpu->kvm, gpa, hpa);
|
|
|
+ unpin_guest_page(vcpu->kvm, vsie_page->riccbd_gpa, hpa);
|
|
|
+ vsie_page->riccbd_gpa = 0;
|
|
|
scb_s->riccbd = 0;
|
|
|
}
|
|
|
|
|
|
hpa = scb_s->sdnxo;
|
|
|
if (hpa) {
|
|
|
- gpa = scb_o->sdnxo;
|
|
|
- unpin_guest_page(vcpu->kvm, gpa, hpa);
|
|
|
+ unpin_guest_page(vcpu->kvm, vsie_page->sdnx_gpa, hpa);
|
|
|
+ vsie_page->sdnx_gpa = 0;
|
|
|
scb_s->sdnxo = 0;
|
|
|
}
|
|
|
}
|
|
@@ -559,6 +561,7 @@ static int pin_blocks(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
|
|
|
}
|
|
|
if (rc)
|
|
|
goto unpin;
|
|
|
+ vsie_page->sca_gpa = gpa;
|
|
|
scb_s->scaoh = (u32)((u64)hpa >> 32);
|
|
|
scb_s->scaol = (u32)(u64)hpa;
|
|
|
}
|
|
@@ -575,6 +578,7 @@ static int pin_blocks(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
|
|
|
rc = set_validity_icpt(scb_s, 0x0080U);
|
|
|
goto unpin;
|
|
|
}
|
|
|
+ vsie_page->itdba_gpa = gpa;
|
|
|
scb_s->itdba = hpa;
|
|
|
}
|
|
|
|
|
@@ -593,6 +597,7 @@ static int pin_blocks(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
|
|
|
rc = set_validity_icpt(scb_s, 0x1310U);
|
|
|
goto unpin;
|
|
|
}
|
|
|
+ vsie_page->gvrd_gpa = gpa;
|
|
|
scb_s->gvrd = hpa;
|
|
|
}
|
|
|
|
|
@@ -609,6 +614,7 @@ static int pin_blocks(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
|
|
|
goto unpin;
|
|
|
}
|
|
|
/* Validity 0x0044 will be checked by SIE */
|
|
|
+ vsie_page->riccbd_gpa = gpa;
|
|
|
scb_s->riccbd = hpa;
|
|
|
}
|
|
|
if ((scb_s->ecb & ECB_GS) && !(scb_s->ecd & ECD_HOSTREGMGMT)) {
|
|
@@ -636,6 +642,7 @@ static int pin_blocks(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
|
|
|
rc = set_validity_icpt(scb_s, 0x10b0U);
|
|
|
goto unpin;
|
|
|
}
|
|
|
+ vsie_page->sdnx_gpa = gpa;
|
|
|
scb_s->sdnxo = hpa | sdnxc;
|
|
|
}
|
|
|
return 0;
|