Skip to content

Commit 084ea4d

Browse files
Vasily Gorbikborntraeger
authored andcommitted
s390/mm: add (non)secure page access exceptions handlers
Add exceptions handlers performing transparent transition of non-secure pages to secure (import) upon guest access and secure pages to non-secure (export) upon hypervisor access. Signed-off-by: Vasily Gorbik <[email protected]> [[email protected]: adding checks for failures] Signed-off-by: Janosch Frank <[email protected]> [[email protected]: adding a check for gmap fault] Signed-off-by: Claudio Imbrenda <[email protected]> Acked-by: David Hildenbrand <[email protected]> Acked-by: Cornelia Huck <[email protected]> Reviewed-by: Christian Borntraeger <[email protected]> [[email protected]: patch merging, splitting, fixing] Signed-off-by: Christian Borntraeger <[email protected]>
1 parent 214d9bb commit 084ea4d

File tree

3 files changed

+82
-2
lines changed

3 files changed

+82
-2
lines changed

arch/s390/kernel/entry.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ asmlinkage void do_syscall_trace_exit(struct pt_regs *regs);
2424

2525
void do_protection_exception(struct pt_regs *regs);
2626
void do_dat_exception(struct pt_regs *regs);
27+
void do_secure_storage_access(struct pt_regs *regs);
28+
void do_non_secure_storage_access(struct pt_regs *regs);
2729

2830
void addressing_exception(struct pt_regs *regs);
2931
void data_exception(struct pt_regs *regs);

arch/s390/kernel/pgm_check.S

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ PGM_CHECK(do_dat_exception) /* 39 */
7878
PGM_CHECK(do_dat_exception) /* 3a */
7979
PGM_CHECK(do_dat_exception) /* 3b */
8080
PGM_CHECK_DEFAULT /* 3c */
81-
PGM_CHECK_DEFAULT /* 3d */
82-
PGM_CHECK_DEFAULT /* 3e */
81+
PGM_CHECK(do_secure_storage_access) /* 3d */
82+
PGM_CHECK(do_non_secure_storage_access) /* 3e */
8383
PGM_CHECK_DEFAULT /* 3f */
8484
PGM_CHECK(monitor_event_exception) /* 40 */
8585
PGM_CHECK_DEFAULT /* 41 */

arch/s390/mm/fault.c

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include <asm/irq.h>
3939
#include <asm/mmu_context.h>
4040
#include <asm/facility.h>
41+
#include <asm/uv.h>
4142
#include "../kernel/entry.h"
4243

4344
#define __FAIL_ADDR_MASK -4096L
@@ -816,3 +817,80 @@ static int __init pfault_irq_init(void)
816817
early_initcall(pfault_irq_init);
817818

818819
#endif /* CONFIG_PFAULT */
820+
821+
#if IS_ENABLED(CONFIG_PGSTE)
822+
void do_secure_storage_access(struct pt_regs *regs)
823+
{
824+
unsigned long addr = regs->int_parm_long & __FAIL_ADDR_MASK;
825+
struct vm_area_struct *vma;
826+
struct mm_struct *mm;
827+
struct page *page;
828+
int rc;
829+
830+
switch (get_fault_type(regs)) {
831+
case USER_FAULT:
832+
mm = current->mm;
833+
down_read(&mm->mmap_sem);
834+
vma = find_vma(mm, addr);
835+
if (!vma) {
836+
up_read(&mm->mmap_sem);
837+
do_fault_error(regs, VM_READ | VM_WRITE, VM_FAULT_BADMAP);
838+
break;
839+
}
840+
page = follow_page(vma, addr, FOLL_WRITE | FOLL_GET);
841+
if (IS_ERR_OR_NULL(page)) {
842+
up_read(&mm->mmap_sem);
843+
break;
844+
}
845+
if (arch_make_page_accessible(page))
846+
send_sig(SIGSEGV, current, 0);
847+
put_page(page);
848+
up_read(&mm->mmap_sem);
849+
break;
850+
case KERNEL_FAULT:
851+
page = phys_to_page(addr);
852+
if (unlikely(!try_get_page(page)))
853+
break;
854+
rc = arch_make_page_accessible(page);
855+
put_page(page);
856+
if (rc)
857+
BUG();
858+
break;
859+
case VDSO_FAULT:
860+
/* fallthrough */
861+
case GMAP_FAULT:
862+
/* fallthrough */
863+
default:
864+
do_fault_error(regs, VM_READ | VM_WRITE, VM_FAULT_BADMAP);
865+
WARN_ON_ONCE(1);
866+
}
867+
}
868+
NOKPROBE_SYMBOL(do_secure_storage_access);
869+
870+
void do_non_secure_storage_access(struct pt_regs *regs)
871+
{
872+
unsigned long gaddr = regs->int_parm_long & __FAIL_ADDR_MASK;
873+
struct gmap *gmap = (struct gmap *)S390_lowcore.gmap;
874+
875+
if (get_fault_type(regs) != GMAP_FAULT) {
876+
do_fault_error(regs, VM_READ | VM_WRITE, VM_FAULT_BADMAP);
877+
WARN_ON_ONCE(1);
878+
return;
879+
}
880+
881+
if (gmap_convert_to_secure(gmap, gaddr) == -EINVAL)
882+
send_sig(SIGSEGV, current, 0);
883+
}
884+
NOKPROBE_SYMBOL(do_non_secure_storage_access);
885+
886+
#else
887+
void do_secure_storage_access(struct pt_regs *regs)
888+
{
889+
default_trap_handler(regs);
890+
}
891+
892+
void do_non_secure_storage_access(struct pt_regs *regs)
893+
{
894+
default_trap_handler(regs);
895+
}
896+
#endif

0 commit comments

Comments
 (0)