aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/mm
diff options
context:
space:
mode:
authorDavid Hildenbrand <dahi@linux.vnet.ibm.com>2016-03-08 06:17:40 -0500
committerChristian Borntraeger <borntraeger@de.ibm.com>2016-06-20 03:54:47 -0400
commit5b062bd4940f81e0bd26b0d75f56d7abebf0309f (patch)
tree02e7105eed7848d8b88fb3cc1fbefbe40de2b04e /arch/s390/mm
parent00fc062d5364174b94e3b5780c22e95c0fb4b60a (diff)
s390/mm: prepare for EDAT1/EDAT2 support in gmap shadow
In preparation for EDAT1/EDAT2 support for gmap shadows, we have to store the requested edat level in the gmap shadow. The edat level used during shadow translation is a property of the gmap shadow. Depending on that level, the gmap shadow will look differently for the same guest tables. We have to store it internally in order to support it later. Acked-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'arch/s390/mm')
-rw-r--r--arch/s390/mm/gmap.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c
index a7dfb337e133..f0b2a531c599 100644
--- a/arch/s390/mm/gmap.c
+++ b/arch/s390/mm/gmap.c
@@ -1382,17 +1382,20 @@ static void gmap_unshadow(struct gmap *sg)
1382 * gmap_find_shadow - find a specific asce in the list of shadow tables 1382 * gmap_find_shadow - find a specific asce in the list of shadow tables
1383 * @parent: pointer to the parent gmap 1383 * @parent: pointer to the parent gmap
1384 * @asce: ASCE for which the shadow table is created 1384 * @asce: ASCE for which the shadow table is created
1385 * @edat_level: edat level to be used for the shadow translation
1385 * 1386 *
1386 * Returns the pointer to a gmap if a shadow table with the given asce is 1387 * Returns the pointer to a gmap if a shadow table with the given asce is
1387 * already available, ERR_PTR(-EAGAIN) if another one is just being created, 1388 * already available, ERR_PTR(-EAGAIN) if another one is just being created,
1388 * otherwise NULL 1389 * otherwise NULL
1389 */ 1390 */
1390static struct gmap *gmap_find_shadow(struct gmap *parent, unsigned long asce) 1391static struct gmap *gmap_find_shadow(struct gmap *parent, unsigned long asce,
1392 int edat_level)
1391{ 1393{
1392 struct gmap *sg; 1394 struct gmap *sg;
1393 1395
1394 list_for_each_entry(sg, &parent->children, list) { 1396 list_for_each_entry(sg, &parent->children, list) {
1395 if (sg->orig_asce != asce || sg->removed) 1397 if (sg->orig_asce != asce || sg->edat_level != edat_level ||
1398 sg->removed)
1396 continue; 1399 continue;
1397 if (!sg->initialized) 1400 if (!sg->initialized)
1398 return ERR_PTR(-EAGAIN); 1401 return ERR_PTR(-EAGAIN);
@@ -1406,6 +1409,7 @@ static struct gmap *gmap_find_shadow(struct gmap *parent, unsigned long asce)
1406 * gmap_shadow - create/find a shadow guest address space 1409 * gmap_shadow - create/find a shadow guest address space
1407 * @parent: pointer to the parent gmap 1410 * @parent: pointer to the parent gmap
1408 * @asce: ASCE for which the shadow table is created 1411 * @asce: ASCE for which the shadow table is created
1412 * @edat_level: edat level to be used for the shadow translation
1409 * 1413 *
1410 * The pages of the top level page table referred by the asce parameter 1414 * The pages of the top level page table referred by the asce parameter
1411 * will be set to read-only and marked in the PGSTEs of the kvm process. 1415 * will be set to read-only and marked in the PGSTEs of the kvm process.
@@ -1416,7 +1420,8 @@ static struct gmap *gmap_find_shadow(struct gmap *parent, unsigned long asce)
1416 * ERR_PTR(-EAGAIN) if the caller has to retry and ERR_PTR(-EFAULT) if the 1420 * ERR_PTR(-EAGAIN) if the caller has to retry and ERR_PTR(-EFAULT) if the
1417 * parent gmap table could not be protected. 1421 * parent gmap table could not be protected.
1418 */ 1422 */
1419struct gmap *gmap_shadow(struct gmap *parent, unsigned long asce) 1423struct gmap *gmap_shadow(struct gmap *parent, unsigned long asce,
1424 int edat_level)
1420{ 1425{
1421 struct gmap *sg, *new; 1426 struct gmap *sg, *new;
1422 unsigned long limit; 1427 unsigned long limit;
@@ -1424,7 +1429,7 @@ struct gmap *gmap_shadow(struct gmap *parent, unsigned long asce)
1424 1429
1425 BUG_ON(gmap_is_shadow(parent)); 1430 BUG_ON(gmap_is_shadow(parent));
1426 spin_lock(&parent->shadow_lock); 1431 spin_lock(&parent->shadow_lock);
1427 sg = gmap_find_shadow(parent, asce); 1432 sg = gmap_find_shadow(parent, asce, edat_level);
1428 spin_unlock(&parent->shadow_lock); 1433 spin_unlock(&parent->shadow_lock);
1429 if (sg) 1434 if (sg)
1430 return sg; 1435 return sg;
@@ -1436,10 +1441,11 @@ struct gmap *gmap_shadow(struct gmap *parent, unsigned long asce)
1436 new->mm = parent->mm; 1441 new->mm = parent->mm;
1437 new->parent = gmap_get(parent); 1442 new->parent = gmap_get(parent);
1438 new->orig_asce = asce; 1443 new->orig_asce = asce;
1444 new->edat_level = edat_level;
1439 new->initialized = false; 1445 new->initialized = false;
1440 spin_lock(&parent->shadow_lock); 1446 spin_lock(&parent->shadow_lock);
1441 /* Recheck if another CPU created the same shadow */ 1447 /* Recheck if another CPU created the same shadow */
1442 sg = gmap_find_shadow(parent, asce); 1448 sg = gmap_find_shadow(parent, asce, edat_level);
1443 if (sg) { 1449 if (sg) {
1444 spin_unlock(&parent->shadow_lock); 1450 spin_unlock(&parent->shadow_lock);
1445 gmap_free(new); 1451 gmap_free(new);