Date: Mon, 15 Jan 2018 15:20:49 -0800 From: Nathan Whitehorn <nwhitehorn@freebsd.org> To: Konstantin Belousov <kostikbel@gmail.com> Cc: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: Re: svn commit: r327950 - in head/sys/powerpc: aim include powerpc ps3 Message-ID: <bb27ba01-8383-6b85-8b2b-65227ff46efc@freebsd.org> In-Reply-To: <20180115175335.GK1684@kib.kiev.ua> References: <20180114170502.GB1684@kib.kiev.ua> <184ba3ee-a9f7-01ed-bb02-1bcba9acc041@freebsd.org> <20180114175211.GD1684@kib.kiev.ua> <b2b1bf30-177b-af30-54ce-f484224bb2ad@freebsd.org> <f4b44b69-7b06-6b5a-c17c-31bd46ca1af0@freebsd.org> <e04bc7a6-fa77-9ca0-2aff-dc29c543c9a1@freebsd.org> <20180115111812.GF1684@kib.kiev.ua> <f6350c61-55d1-9bf7-c4b3-e10fb329a42a@freebsd.org> <20180115170603.GJ1684@kib.kiev.ua> <9e5554d7-6a0c-5910-8cb6-74f98259536f@freebsd.org> <20180115175335.GK1684@kib.kiev.ua>
next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------082F835BD7FFED1A7DEBEEC2
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit
On 01/15/18 09:53, Konstantin Belousov wrote:
> On Mon, Jan 15, 2018 at 09:32:56AM -0800, Nathan Whitehorn wrote:
>> That seems fine to me. I don't think a less-clumsy way that does not
>> involve extra indirection is possible. The PHYS_TO_DMAP() returning NULL
>> is about the best thing I can come up with from a clumsiness standpoint
>> since plenty of code checks for null pointers already, but doesn't
>> cleanly handle the rarer case where you want to test for the existence
>> of direct maps in general without testing some potemkin address.
>>
>> My one reservation about PMAP_HAS_DMAP or the like as a selector is that
>> it does not encode the full shape of the problem: one could imagine
>> having a direct map that only covers a limited range of RAM (I am not
>> sure whether the existence of dmaplimit on amd64 implies this can happen
>> with non-device memory in real life), for example. These cases are
>> currently covered by an assert() in PHYS_TO_DMAP(), whereas having
>> PHYS_TO_DMAP() return NULL allows a more flexible signalling and the
>> potential for the calling code to do something reasonable to handle the
>> error. A single global flag can't convey information at this kind of
>> granularity. Is this a reasonable concern? Or am I overthinking things?
> IMO it is overreaction. amd64 assumes that all normal memory is covered
> by DMAP. It must never fail. See, for instance, the implementation
> of the sf bufs for it.
>
> If device memory not covered by DMAP can exists, it is the driver problem.
> For instance, for NVDIMMs I wrote specific mapping code which establishes
> kernel mapping for it, when not covered by EFI memory map and correspondingly
> not included into DMAP.
>
Fair enough. Here's a patch with a new flag (DIRECT_MAP_AVAILABLE). I've
also retooled the sfbuf code to use this rather than its own flags that
mean the same things. The sparc64 part of the patch is untested.
-Nathan
--------------082F835BD7FFED1A7DEBEEC2
Content-Type: text/x-patch;
name="dmap_api.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="dmap_api.diff"
Index: amd64/include/vmparam.h
===================================================================
--- amd64/include/vmparam.h (revision 328006)
+++ amd64/include/vmparam.h (working copy)
@@ -190,6 +190,7 @@
* because the result is not actually accessed until later, but the early
* vt fb startup needs to be reworked.
*/
+#define DIRECT_MAP_AVAILABLE 1
#define PHYS_TO_DMAP(x) ({ \
KASSERT(dmaplimit == 0 || (x) < dmaplimit, \
("physical address %#jx not covered by the DMAP", \
Index: arm64/include/vmparam.h
===================================================================
--- arm64/include/vmparam.h (revision 328006)
+++ arm64/include/vmparam.h (working copy)
@@ -176,6 +176,7 @@
#define VIRT_IN_DMAP(va) ((va) >= DMAP_MIN_ADDRESS && \
(va) < (dmap_max_addr))
+#define DIRECT_MAP_AVAILABLE
#define PHYS_TO_DMAP(pa) \
({ \
KASSERT(PHYS_IN_DMAP(pa), \
Index: dev/efidev/efirt.c
===================================================================
--- dev/efidev/efirt.c (revision 328006)
+++ dev/efidev/efirt.c (working copy)
@@ -115,6 +115,11 @@
return (0);
}
efi_systbl = (struct efi_systbl *)PHYS_TO_DMAP(efi_systbl_phys);
+ if (efi_systbl == NULL) {
+ if (bootverbose)
+ printf("EFI systbl not mapped in kernel VA\n");
+ return (0);
+ }
if (efi_systbl->st_hdr.th_sig != EFI_SYSTBL_SIG) {
efi_systbl = NULL;
if (bootverbose)
Index: kern/subr_sfbuf.c
===================================================================
--- kern/subr_sfbuf.c (revision 328006)
+++ kern/subr_sfbuf.c (working copy)
@@ -88,8 +88,8 @@
vm_offset_t sf_base;
int i;
-#ifdef SFBUF_OPTIONAL_DIRECT_MAP
- if (SFBUF_OPTIONAL_DIRECT_MAP)
+#ifdef DIRECT_MAP_AVAILABLE
+ if (DIRECT_MAP_AVAILABLE)
return;
#endif
@@ -119,8 +119,8 @@
struct sf_buf *sf;
int error;
-#ifdef SFBUF_OPTIONAL_DIRECT_MAP
- if (SFBUF_OPTIONAL_DIRECT_MAP)
+#ifdef DIRECT_MAP_AVAILABLE
+ if (DIRECT_MAP_AVAILABLE)
return ((struct sf_buf *)m);
#endif
@@ -181,8 +181,8 @@
sf_buf_free(struct sf_buf *sf)
{
-#ifdef SFBUF_OPTIONAL_DIRECT_MAP
- if (SFBUF_OPTIONAL_DIRECT_MAP)
+#ifdef DIRECT_MAP_AVAILABLE
+ if (DIRECT_MAP_AVAILABLE)
return;
#endif
@@ -205,8 +205,8 @@
sf_buf_ref(struct sf_buf *sf)
{
-#ifdef SFBUF_OPTIONAL_DIRECT_MAP
- if (SFBUF_OPTIONAL_DIRECT_MAP)
+#ifdef DIRECT_MAP_AVAILABLE
+ if (DIRECT_MAP_AVAILABLE)
return;
#endif
Index: powerpc/include/vmparam.h
===================================================================
--- powerpc/include/vmparam.h (revision 328006)
+++ powerpc/include/vmparam.h (working copy)
@@ -37,6 +37,10 @@
#ifndef _MACHINE_VMPARAM_H_
#define _MACHINE_VMPARAM_H_
+#ifndef LOCORE
+#include <machine/md_var.h>
+#endif
+
#define USRSTACK SHAREDPAGE
#ifndef MAXTSIZ
@@ -236,17 +240,21 @@
*/
#define SFBUF
#define SFBUF_NOMD
-#define SFBUF_OPTIONAL_DIRECT_MAP hw_direct_map
-#define SFBUF_PHYS_DMAP(x) (x)
/*
- * We (usually) have a direct map of all physical memory. All
- * uses of this macro must be gated by a check on hw_direct_map!
- * The location of the direct map may not be 1:1 in future, so use
- * of the macro is recommended; it may also grow an assert that hw_direct_map
- * is set.
+ * We (usually) have a direct map of all physical memory, so provide
+ * a macro to use to get the kernel VA address for a given PA. Returns
+ * 0 if the direct map is unavailable. The location of the direct map
+ * may not be 1:1 in future, so use of the macro is recommended.
*/
-#define PHYS_TO_DMAP(x) x
-#define DMAP_TO_PHYS(x) x
-
+#ifdef __powerpc64__
+#define DMAP_ADDRESS 0x0000000000000000UL
+#else
+#define DMAP_ADDRESS 0x00000000UL
+#endif
+
+#define DIRECT_MAP_AVAILABLE (hw_direct_map)
+#define PHYS_TO_DMAP(x) (hw_direct_map ? (x | DMAP_ADDRESS) : 0)
+#define DMAP_TO_PHYS(x) (hw_direct_map ? (x & ~DMAP_ADDRESS) : 0)
+
#endif /* _MACHINE_VMPARAM_H_ */
Index: sparc64/include/vmparam.h
===================================================================
--- sparc64/include/vmparam.h (revision 328006)
+++ sparc64/include/vmparam.h (working copy)
@@ -240,10 +240,12 @@
*/
#define ZERO_REGION_SIZE PAGE_SIZE
+#include <machine/tlb.h>
+
#define SFBUF
#define SFBUF_MAP
-#define SFBUF_OPTIONAL_DIRECT_MAP dcache_color_ignore
-#include <machine/tlb.h>
-#define SFBUF_PHYS_DMAP(x) TLB_PHYS_TO_DIRECT(x)
+#define DIRECT_MAP_AVAILABLE dcache_color_ignore
+#define PHYS_TO_DMAP(x) (DIRECT_MAP_AVAILABLE ? (TLB_PHYS_TO_DIRECT(x) : 0)
+
#endif /* !_MACHINE_VMPARAM_H_ */
Index: sys/sf_buf.h
===================================================================
--- sys/sf_buf.h (revision 328006)
+++ sys/sf_buf.h (working copy)
@@ -77,9 +77,6 @@
* that do no invalidate cache on the rest of CPUs.
* SFBUF_NOMD This machine doesn't have machine/sf_buf.h
*
- * SFBUF_OPTIONAL_DIRECT_MAP Value of this define is used as boolean
- * variable that tells whether machine is
- * capable of direct map or not at runtime.
* SFBUF_MAP This machine provides its own sf_buf_map() and
* sf_buf_unmap().
* SFBUF_PROCESS_PAGE This machine provides sf_buf_process_page()
@@ -109,9 +106,6 @@
#ifndef SFBUF_NOMD
#include <machine/sf_buf.h>
#endif
-#ifdef SFBUF_OPTIONAL_DIRECT_MAP
-#include <machine/md_var.h>
-#endif
#ifdef SFBUF
struct sf_buf *sf_buf_alloc(struct vm_page *, int);
@@ -121,9 +115,9 @@
static inline vm_offset_t
sf_buf_kva(struct sf_buf *sf)
{
-#ifdef SFBUF_OPTIONAL_DIRECT_MAP
- if (SFBUF_OPTIONAL_DIRECT_MAP)
- return (SFBUF_PHYS_DMAP(VM_PAGE_TO_PHYS((vm_page_t)sf)));
+#ifdef DIRECT_MAP_AVAILABLE
+ if (DIRECT_MAP_AVAILABLE)
+ return (PHYS_TO_DMAP(VM_PAGE_TO_PHYS((vm_page_t)sf)));
#endif
return (sf->kva);
@@ -132,8 +126,8 @@
static inline vm_page_t
sf_buf_page(struct sf_buf *sf)
{
-#ifdef SFBUF_OPTIONAL_DIRECT_MAP
- if (SFBUF_OPTIONAL_DIRECT_MAP)
+#ifdef DIRECT_MAP_AVAILABLE
+ if (DIRECT_MAP_AVAILABLE)
return ((vm_page_t)sf);
#endif
Index: vm/vm_page.c
===================================================================
--- vm/vm_page.c (revision 328006)
+++ vm/vm_page.c (working copy)
@@ -2937,7 +2937,8 @@
{
#if defined(DIAGNOSTIC) && defined(PHYS_TO_DMAP)
- if ((m->flags & PG_ZERO) != 0) {
+ if ((m->flags & PG_ZERO) != 0 &&
+ PHYS_TO_DMAP(VM_PAGE_TO_PHYS(m)) != 0) {
uint64_t *p;
int i;
p = (uint64_t *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(m));
--------------082F835BD7FFED1A7DEBEEC2--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bb27ba01-8383-6b85-8b2b-65227ff46efc>
