Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 13 Jan 2019 23:29:46 +0000 (UTC)
From:      Olivier Houchard <cognet@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r343006 - in head/sys/arm64: arm64 include
Message-ID:  <201901132329.x0DNTkJs012724@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: cognet
Date: Sun Jan 13 23:29:46 2019
New Revision: 343006
URL: https://svnweb.freebsd.org/changeset/base/343006

Log:
  Introduce cpu_icache_sync_range_checked(), that does the same thing as
  cpu_icache_sync_range(), except that it sets pcb_onfault to catch any page
  fault, as doing cache maintenance operations for non-mapped generates a
  data abort, and use it in freebsd32_sysarch(), so that a userland program
  attempting to sync the icache with unmapped addresses doesn't crash the
  kernel.
  
  Spotted out by:	andrew

Modified:
  head/sys/arm64/arm64/cpufunc_asm.S
  head/sys/arm64/arm64/freebsd32_machdep.c
  head/sys/arm64/include/cpufunc.h

Modified: head/sys/arm64/arm64/cpufunc_asm.S
==============================================================================
--- head/sys/arm64/arm64/cpufunc_asm.S	Sun Jan 13 20:33:54 2019	(r343005)
+++ head/sys/arm64/arm64/cpufunc_asm.S	Sun Jan 13 23:29:46 2019	(r343006)
@@ -147,3 +147,24 @@ ENTRY(arm64_icache_sync_range)
 	ic	ialluis
 	dsb	ish
 END(arm64_icache_sync_range)
+
+/*
+ * int arm64_icache_sync_range_checked(vm_offset_t, vm_size_t)
+ */
+ENTRY(arm64_icache_sync_range_checked)
+	adr	x5, cache_maint_fault
+	SET_FAULT_HANDLER(x5, x6)
+	/* XXX: See comment in arm64_icache_sync_range */
+	cache_handle_range	dcop = cvau
+	ic	ialluis
+	dsb ish
+	SET_FAULT_HANDLER(xzr, x6)
+	mov	x0, #0
+	ret
+END(arm64_icache_sync_range_checked)
+
+ENTRY(cache_maint_fault)
+	SET_FAULT_HANDLER(xzr, x1)
+	mov	x0, #EFAULT
+	ret
+END(cache_maint_fault)

Modified: head/sys/arm64/arm64/freebsd32_machdep.c
==============================================================================
--- head/sys/arm64/arm64/freebsd32_machdep.c	Sun Jan 13 20:33:54 2019	(r343005)
+++ head/sys/arm64/arm64/freebsd32_machdep.c	Sun Jan 13 23:29:46 2019	(r343006)
@@ -85,7 +85,7 @@ freebsd32_sysarch(struct thread *td, struct freebsd32_
 				return (error);
 			if ((uint64_t)args.addr + (uint64_t)args.size > 0xffffffff)
 				return (EINVAL);
-			cpu_icache_sync_range(args.addr, args.size);
+			cpu_icache_sync_range_checked(args.addr, args.size);
 			return 0;
 		}
 	case ARM_GET_VFPSTATE:

Modified: head/sys/arm64/include/cpufunc.h
==============================================================================
--- head/sys/arm64/include/cpufunc.h	Sun Jan 13 20:33:54 2019	(r343005)
+++ head/sys/arm64/include/cpufunc.h	Sun Jan 13 23:29:46 2019	(r343006)
@@ -138,12 +138,14 @@ extern int64_t dczva_line_size;
 
 #define	cpu_idcache_wbinv_range(a, s)	arm64_idcache_wbinv_range((a), (s))
 #define	cpu_icache_sync_range(a, s)	arm64_icache_sync_range((a), (s))
+#define cpu_icache_sync_range_checked(a, s) arm64_icache_sync_range_checked((a), (s))
 
 void arm64_nullop(void);
 void arm64_setttb(vm_offset_t);
 void arm64_tlb_flushID(void);
 void arm64_tlb_flushID_SE(vm_offset_t);
 void arm64_icache_sync_range(vm_offset_t, vm_size_t);
+int arm64_icache_sync_range_checked(vm_offset_t, vm_size_t);
 void arm64_idcache_wbinv_range(vm_offset_t, vm_size_t);
 void arm64_dcache_wbinv_range(vm_offset_t, vm_size_t);
 void arm64_dcache_inv_range(vm_offset_t, vm_size_t);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201901132329.x0DNTkJs012724>