Skip to content

Commit e5f98a6

Browse files
author
Claudio Imbrenda
committed
KVM: s390: Add some helper functions needed for vSIE
Implement gmap_protect_asce_top_level(), which was a stub. This function was a stub due to cross dependencies with other patches. Acked-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
1 parent e907ae5 commit e5f98a6

1 file changed

Lines changed: 72 additions & 2 deletions

File tree

arch/s390/kvm/gmap.c

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "dat.h"
2323
#include "gmap.h"
2424
#include "kvm-s390.h"
25+
#include "faultin.h"
2526

2627
static inline bool kvm_s390_is_in_sie(struct kvm_vcpu *vcpu)
2728
{
@@ -1091,10 +1092,79 @@ static struct gmap *gmap_find_shadow(struct gmap *parent, union asce asce, int e
10911092
return NULL;
10921093
}
10931094

1095+
#define CRST_TABLE_PAGES (_CRST_TABLE_SIZE / PAGE_SIZE)
1096+
struct gmap_protect_asce_top_level {
1097+
unsigned long seq;
1098+
struct guest_fault f[CRST_TABLE_PAGES];
1099+
};
1100+
1101+
static inline int __gmap_protect_asce_top_level(struct kvm_s390_mmu_cache *mc, struct gmap *sg,
1102+
struct gmap_protect_asce_top_level *context)
1103+
{
1104+
int rc, i;
1105+
1106+
guard(write_lock)(&sg->kvm->mmu_lock);
1107+
1108+
if (kvm_s390_array_needs_retry_safe(sg->kvm, context->seq, context->f))
1109+
return -EAGAIN;
1110+
1111+
scoped_guard(spinlock, &sg->parent->children_lock) {
1112+
for (i = 0; i < CRST_TABLE_PAGES; i++) {
1113+
if (!context->f[i].valid)
1114+
continue;
1115+
rc = gmap_protect_rmap(mc, sg, context->f[i].gfn, 0, context->f[i].pfn,
1116+
TABLE_TYPE_REGION1 + 1, context->f[i].writable);
1117+
if (rc)
1118+
return rc;
1119+
}
1120+
gmap_add_child(sg->parent, sg);
1121+
}
1122+
1123+
kvm_s390_release_faultin_array(sg->kvm, context->f, false);
1124+
return 0;
1125+
}
1126+
1127+
static inline int _gmap_protect_asce_top_level(struct kvm_s390_mmu_cache *mc, struct gmap *sg,
1128+
struct gmap_protect_asce_top_level *context)
1129+
{
1130+
int rc;
1131+
1132+
if (kvm_s390_array_needs_retry_unsafe(sg->kvm, context->seq, context->f))
1133+
return -EAGAIN;
1134+
do {
1135+
rc = kvm_s390_mmu_cache_topup(mc);
1136+
if (rc)
1137+
return rc;
1138+
rc = radix_tree_preload(GFP_KERNEL);
1139+
if (rc)
1140+
return rc;
1141+
rc = __gmap_protect_asce_top_level(mc, sg, context);
1142+
radix_tree_preload_end();
1143+
} while (rc == -ENOMEM);
1144+
1145+
return rc;
1146+
}
1147+
10941148
static int gmap_protect_asce_top_level(struct kvm_s390_mmu_cache *mc, struct gmap *sg)
10951149
{
1096-
KVM_BUG_ON(1, sg->kvm);
1097-
return -EINVAL;
1150+
struct gmap_protect_asce_top_level context = {};
1151+
union asce asce = sg->guest_asce;
1152+
int rc;
1153+
1154+
KVM_BUG_ON(!is_shadow(sg), sg->kvm);
1155+
1156+
context.seq = sg->kvm->mmu_invalidate_seq;
1157+
/* Pairs with the smp_wmb() in kvm_mmu_invalidate_end(). */
1158+
smp_rmb();
1159+
1160+
rc = kvm_s390_get_guest_pages(sg->kvm, context.f, asce.rsto, asce.dt + 1, false);
1161+
if (rc > 0)
1162+
rc = -EFAULT;
1163+
if (!rc)
1164+
rc = _gmap_protect_asce_top_level(mc, sg, &context);
1165+
if (rc)
1166+
kvm_s390_release_faultin_array(sg->kvm, context.f, true);
1167+
return rc;
10981168
}
10991169

11001170
/**

0 commit comments

Comments
 (0)