/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* bos72V src/bos/kernel/sys/raschk.h 1.41.1.2                            */
/*                                                                        */
/* Licensed Materials - Property of IBM                                   */
/*                                                                        */
/* Restricted Materials of IBM                                            */
/*                                                                        */
/* COPYRIGHT International Business Machines Corp. 2005,2020              */
/* All Rights Reserved                                                    */
/*                                                                        */
/* US Government Users Restricted Rights - Use, duplication or            */
/* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.      */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
/* @(#)64       1.41.1.2  src/bos/kernel/sys/raschk.h, syserrchk, bos72V, v2020_16A1 3/31/20 13:59:36 */

#ifndef _H_RASCHK
#define _H_RASCHK

/*
 * COMPONENT_NAME: (sysras) RAS Component Infrastructure
 *
 * FUNCTIONS: 
 *
 * ORIGINS: 27
 */

/*
 * This is a SHIPPED header file.  
 *
 * This header contains the definitions of the interfaces
 * available to write kdb consistency checkers and run-time error
 * checkers.  The API provides routines to read memory and validate
 * basic data types.
 *
 * In order to be able to use the interfaces contained in this header file one
 * of the following constant must be defined at build time:
 * __RT_RASCHK       if the interfaces are called from run-time environment.
 * __KDB_RASCHK      if the interfaces are called from kernel KDB.
 * __KDB_KEXT_RASCHK if the interfaces are called from a kernext KDB extension.
 */

/*
 * Define __RT_RASCHK as the default
 */
#if !defined(__RT_RASCHK) && !defined(__KDB_RASCHK) && !defined(__KDB_KEXT_RASCHK)
#define __RT_RASCHK
#endif

#ifdef __KDB_KEXT_RASCHK
#define __KDB_RASCHK
#endif /* __KDB_KEXT_RASCHK */

#ifdef __KDB_RASCHK
#ifndef __KDB_KEXT_RASCHK
#include "kdb.h"
#else  /* __KDB_KEXT_RASCHK */
#include <kdb/kdb_kext.h>
#endif /* __KDB_KEXT_RASCHK */
#include "kdb_raschk.h"
#endif /* __KDB_RASCHK */

#include <sys/ras.h>
#include <sys/ras_error.h>
#include <sys/errno.h>
#include <sys/kerrno.h>
#include <sys/kerrors.h>

#include <sys/cred.h>
#include <sys/lock_def.h>
#include <sys/malloc.h>
#include <sys/processor.h>
#include <sys/types.h>

#ifdef __64BIT_KERNEL
#include <sys/skeys.h>
#endif /* __64BIT_KERNEL */

#ifdef __cplusplus
extern "C" {
#endif

/*
 * flags values for raschk_safe_read() service.
 */
typedef long ras_sr_flags_t;

#if defined(_KERNEL) || defined(__KDB_RASCHK)
#define RAS_SR_NOFAULT		0x00000002
#define RAS_SR_NOPAGEIN		0x00000004
#define	RAS_SR_FLAGS_MASK	(RAS_SR_NOPAGEIN | RAS_SR_NOFAULT)
#endif /* _KERNEL || __KDB_RASCHK */

/* 
 * This file can sometimes be included with _KERNEL defined in command
 * kdb (see for example the path kdb.h -> vmsys.h -> vmpfhdata.h ->
 * ras_static.h -> ras_priv.h -> raschk.h).  So this #ifdef ensures that
 * the kernel mode stuff doesn't get pulled into command kdb.  This
 * is done several times throught this file.  
 */
#if defined (_KERNEL) && !defined(__KDB_USER)

#ifdef __RT_RASCHK
/* 
 * This flag is defined here because it is the only RASCHK_ flag that is
 * valid to be used in the flags parameter for ras_elemchkr_t.  It is
 * also defined in kdb/kdb_raschk.h, but that file is not available to
 * the checkers that are part of the main kernel.  This flag, along with
 * the RAS_SR flags above, are the only flags that are allowed to be
 * passed to raschk_queue_verify and queue_repair.  This definition must
 * be kept in sync with kdb/kdb_raschk.h. Maintain uniqueness of 
 * checker flags.  Do not use the same flag value for different 
 * purposes in runtime and kdb checkers.  */
#define RASCHK_VERBOSE_MODE   0x00000001 /* Turn on verbosity in checker */
#endif

/*
 *  flags values for raschk_stktrace() service
 */
#define RAS_STK_DO_CURMST	0x00000001ull
#define RAS_STK_DO_PREVMST	0x00000002ull
#define RAS_STK_DO_ONEMST	0x00000004ull
#define RAS_STK_GET_SYMBOLS	0x00000008ull
#define RAS_STK_DO_CURRWA	0x00000010ull

#define RAS_STKTRACE_FLAGS_MASK		\
		(RAS_STK_DO_CURMST | RAS_STK_DO_PREVMST		\
		 | RAS_STK_DO_ONEMST | RAS_STK_GET_SYMBOLS	\
		 | RAS_STK_DO_CURRWA)

/*
 * flags values for raschk_errhook() service
 */
#define	RAS_NO_TRACE		0x000000001ull
#define	RAS_NO_STKTRACE		0x000000002ull

/*
 * Safe getcaller macros
 */
#define RASCHK_GET1CALLER(_caller_ptr) 			 	 	 \
	do {							 	 \
		uintptr_t stktrace_buf[2];			 	 \
		kerrno_t rc;						 \
		rc = raschk_stktrace(sizeof stktrace_buf, 0,		 \
				     stktrace_buf);			 \
		if (rc != 0) {						 \
			*((uintptr_t *)(_caller_ptr)) = 0;		 \
		} else {						 \
			*((uintptr_t *)(_caller_ptr)) = stktrace_buf[0]; \
		}							 \
	} while (0)

#define RASCHK_GET2CALLER(_two_callers_array_ptr)			\
	do {							 	\
		uintptr_t stktrace_buf[3];			 	\
		kerrno_t rc;						\
		rc = raschk_stktrace(sizeof stktrace_buf, 0, 		\
				     stktrace_buf);			\
		if (rc != 0) {						\
			((uintptr_t *)(_two_callers_array_ptr))[0] = 0;	\
			((uintptr_t *)(_two_callers_array_ptr))[1] = 0;	\
		} else {						\
			((uintptr_t *)(_two_callers_array_ptr))[0] =    \
				stktrace_buf[0];			\
			((uintptr_t *)(_two_callers_array_ptr))[1] =    \
				stktrace_buf[1];			\
		}							\
	} while (0)

#endif /* _KERNEL && !__KDB_USER */

/*
 * Kerrnos returned by interfaces declared in this file
 */

/* 
 * raschk_safe_read service 
 */
#define	EFAULT_SAFE_READ_FAULT		KERROR(EFAULT, sysras_BLOCK_00, 10)
#define	EFAULT_SAFE_READ_PAGEIN		KERROR(EFAULT, sysras_BLOCK_00, 11)
#define	EFAULT_SAFE_READ_INVAL		KERROR(EFAULT, sysras_BLOCK_00, 12)
#define	EAGAIN_SAFE_READ_DESTMIG	KERROR(EAGAIN, sysras_BLOCK_00, 10)
#define	EFAULT_SAFE_READ_DESTBAD	KERROR(EFAULT, sysras_BLOCK_02, 0x11F)
#define	EFAULT_SAFE_READ_UNEXPECTED_EXCEPTION \
 					KERROR(EFAULT, sysras_BLOCK_02, 0x120)
	

/* 
 * RASCHK_SAFE_MAP_INVAL - KDB implemetation 
 */
#define	EFAULT_SAFE_MAP_INVAL           KERROR(EFAULT, sysras_BLOCK_00, 13)

/* 
 * raschk_executable_eaddr service
 */
#define	EINVAL_RAS_EXE_ADDR_ALIGN	KERROR(EINVAL, sysras_BLOCK_02, 0x121)
#define	EFAULT_RAS_EXE_ADDR_SFREAD	KERROR(EFAULT, sysras_BLOCK_02, 0x122)
#define	EINVAL_RAS_EXE_ADDR_OPCODE1	KERROR(EINVAL, sysras_BLOCK_02, 0x123)
#define	EINVAL_RAS_EXE_ADDR_OPCODE2	KERROR(EINVAL, sysras_BLOCK_02, 0x124)
#define	EFAULT_RAS_EXE_ADDR_PAGEIN	KERROR(EFAULT, sysras_BLOCK_02, 0x125)

/* 
 * raschk_xmalloc_eaddr service
 */
#define	ERANGE_RAS_XM_ADDR_LEVEL	KERROR(ERANGE, sysras_BLOCK_02, 0x131)
#define	EINVAL_RAS_XM_ADDR_HEAPP	KERROR(EINVAL, sysras_BLOCK_02, 0x132)
#define	EFAULT_RAS_XM_ADDR_SFREAD1	KERROR(EFAULT, sysras_BLOCK_02, 0x133)
#define	EFAULT_RAS_XM_ADDR_SFREAD2	KERROR(EFAULT, sysras_BLOCK_02, 0x134)
#define	EFAULT_RAS_XM_ADDR_SFREAD3	KERROR(EFAULT, sysras_BLOCK_02, 0x135)
#define	EFAULT_RAS_XM_ADDR_SFREAD4	KERROR(EFAULT, sysras_BLOCK_02, 0x136)
#define	EFAULT_RAS_XM_ADDR_SFREAD5	KERROR(EFAULT, sysras_BLOCK_02, 0x137)
#define	EFAULT_RAS_XM_ADDR_SFREAD6	KERROR(EFAULT, sysras_BLOCK_02, 0x138)
#define	EFAULT_RAS_XM_ADDR_SFREAD7	KERROR(EFAULT, sysras_BLOCK_02, 0x139)
#define	EFAULT_RAS_XM_ADDR_SFREAD8	KERROR(EFAULT, sysras_BLOCK_02, 0x13A)
#define	EINVAL_RAS_XM_ADDR_INVAL      	KERROR(EINVAL, sysras_BLOCK_02, 0x13B)

/* 
 * raschk_stktrace service 
 */
#define	EFAULT_STKTRACE_INVAL           KERROR(EFAULT, sysras_BLOCK_00, 14)
#define	EINVAL_STKTRACE_INVAL           KERROR(EINVAL, sysras_BLOCK_00, 15)
#define	EINVAL_STKTRACE_ALIGN	        KERROR(EINVAL, sysras_BLOCK_00, 16)
#define	EINVAL_STKTRACE_TRCBUF	        KERROR(EINVAL, sysras_BLOCK_00, 17)
#define	ENOMEM_STKTRACE_NOMEM	        KERROR(ENOMEM, sysras_BLOCK_00, 18)
#define	EINVAL_STKTRACE_FLAGS           KERROR(EINVAL, sysras_BLOCK_00, 119)
#define	EINVAL_STKTRACE_SIZE1           KERROR(EINVAL, sysras_BLOCK_00, 120)
#define	EINVAL_STKTRACE_SIZE2	        KERROR(EINVAL, sysras_BLOCK_00, 121)
#define	EINVAL_STKTRACE_OVERRUN1       	KERROR(EINVAL, sysras_BLOCK_00, 122)
#define	EINVAL_STKTRACE_OVERRUN2       	KERROR(EINVAL, sysras_BLOCK_00, 123)

/* 
 * raschk_addr2sym service 
 */
#define	EFAULT_ADDR2SYM_INVAL	        KERROR(EFAULT, sysras_BLOCK_00, 19)
#define	ESRCH_ADDR2SYM_NOSYM	        KERROR(ESRCH, sysras_BLOCK_00, 20)
#define	EFAULT_ADDR2SYM_PAGEIN	        KERROR(EFAULT, sysras_BLOCK_00, 21)
#define	EINVAL_ADDR2SYM_INVAL	        KERROR(EINVAL, sysras_BLOCK_00, 22)
#define	EINVAL_ADDR2SYM_ALIGN	        KERROR(EINVAL, sysras_BLOCK_00, 23)
#define	ENOMEM_ADDR2SYM_BUF2SML	        KERROR(ENOMEM, sysras_BLOCK_00, 24)

/* 
 * raschk_dev() service 
 */
#define	EINVAL_RASCHK_DEV_MAJOR_NUM     KERROR(EINVAL, sysras_BLOCK_02, 0x141)
#define	EINVAL_RASCHK_DEV_DEFINED_OFF   KERROR(EINVAL, sysras_BLOCK_02, 0x142)

/* 
 * raschk_string() service 
 */
#define	EFAULT_RASCHK_STR_ADDR		KERROR(EFAULT, sysras_BLOCK_02, 0x151)
#define	EINVAL_RASCHK_STR_CHAR		KERROR(EINVAL, sysras_BLOCK_02, 0x152)
#define	EINVAL_RASCHK_STR_LEN 		KERROR(EINVAL, sysras_BLOCK_02, 0x153)

/* 
 * raschk_pid() service 
 */
#define	EINVAL_RASCHK_PID 		KERROR(EINVAL, sysras_BLOCK_02, 0x161)

/* 
 * raschk_tid() service 
 */
#define	EINVAL_RASCHK_TID 		KERROR(EINVAL, sysras_BLOCK_02, 0x171)

/* 
 * raschk_mode() service 
 */
#define	EINVAL_RASCHK_MODE_TYPE		KERROR(EINVAL, sysras_BLOCK_02, 0x181)
#define	EINVAL_RASCHK_MODE_HIGH_BITS	KERROR(EINVAL, sysras_BLOCK_02, 0x182)

/* 
 * raschk_vmid() service 
 */
#define	EINVAL_RASCHK_VMID		KERROR(EINVAL, sysras_BLOCK_02, 0x191)

/* 
 * raschk_raschk_vmhandle() service 
 */
#define	EINVAL_RASCHK_VMHANDLE_UNUSED_BITS1 \
 					KERROR(EINVAL, sysras_BLOCK_02, 0x1a1)
#define	EINVAL_RASCHK_VMHANDLE_UNUSED_BITS2 \
 					KERROR(EINVAL, sysras_BLOCK_02, 0x1a2)
#define	EINVAL_RASCHK_VMHANDLE_UNUSED_BITS3 \
 					KERROR(EINVAL, sysras_BLOCK_02, 0x1a3)

/* 
 * raschk_chan() service 
 */
#define	EINVAL_RASCHK_CHAN		KERROR(EINVAL, sysras_BLOCK_02, 0x1b1)

/* 
 * raschk_complex_lock() service 
 */
#define	EINVAL_RASCHK_COMPLEX_LOCK_ALIGN \
 					KERROR(EINVAL, sysras_BLOCK_02, 0x1c1)
#define	EINVAL_RASCHK_COMPLEX_LOCK_ADDR \
 					KERROR(EINVAL, sysras_BLOCK_02, 0x1c2)
#define	EFAULT_RASCHK_COMPLEX_LOCK_SAFE_MAP \
 					KERROR(EFAULT, sysras_BLOCK_02, 0x1c3)
#define	EINVAL_RASCHK_COMPLEX_LOCK_SAFE_READ \
 					KERROR(EINVAL, sysras_BLOCK_02, 0x1c4)
#define	EFAULT_RASCHK_COMPLEX_LOCK_DATA_SAFE_MAP \
 					KERROR(EFAULT, sysras_BLOCK_02, 0x1c5)
#define	EINVAL_RASCHK_COMPLEX_LOCK_DATA_SAFE_READ \
 					KERROR(EINVAL, sysras_BLOCK_02, 0x1c6)
#define	EINVAL_RASCHK_COMPLEX_LOCK_OWNER \
 					KERROR(EINVAL, sysras_BLOCK_02, 0x1c7)
#define	EINVAL_RASCHK_COMPLEX_LOCK_FLAGS \
 					KERROR(EINVAL, sysras_BLOCK_02, 0x1c8)

/* 
 * raschk_time() service 
 */
#define	EINVAL_RASCHK_TIME 		KERROR(EINVAL, sysras_BLOCK_02, 0x1d1)

/* 
 * raschk_timestruc() service 
 */
#define	EINVAL_RASCHK_TIMESTRUC		KERROR(EINVAL, sysras_BLOCK_02, 0x1e1)

/* 
 * raschk_timeval() service 
 */
#define	EINVAL_RASCHK_TIMEVAL		KERROR(EINVAL, sysras_BLOCK_02, 0x1f1)

/* 
 * raschk_cred() service 
 */
#define	EINVAL_RASCHK_CRED_ALIGN	KERROR(EINVAL, sysras_BLOCK_02, 0x201)
#define	EFAULT_RASCHK_CRED_SAFE_MAP	KERROR(EFAULT, sysras_BLOCK_02, 0x202)
#define	EINVAL_RASCHK_CRED_SAFE_READ	KERROR(EINVAL, sysras_BLOCK_02, 0x203)
#define	EINVAL_RASCHK_CRED_DATA		KERROR(EINVAL, sysras_BLOCK_02, 0x204)

/* 
 * raschk_xmem() service 
 */
#define	EINVAL_RASCHK_XMEM_ALIGN	KERROR(EINVAL, sysras_BLOCK_02, 0x211)
#define	EFAULT_RASCHK_XMEM_SAFE_MAP	KERROR(EFAULT, sysras_BLOCK_02, 0x212)
#define	EINVAL_RASCHK_XMEM_SAFE_READ	KERROR(EINVAL, sysras_BLOCK_02, 0x213)
#define	EINVAL_RASCHK_XMEM_ASPACEID	KERROR(EINVAL, sysras_BLOCK_02, 0x214)
#define	EINVAL_RASCHK_XMEM_PREXFLAGS	KERROR(EINVAL, sysras_BLOCK_02, 0x215)
#define	EINVAL_RASCHK_XMEM_NUM_SIDS	KERROR(EINVAL, sysras_BLOCK_02, 0x216)
#define	EINVAL_RASCHK_XMEM_LW		KERROR(EINVAL, sysras_BLOCK_02, 0x217)
#define	EFAULT_RASCHK_XMEM_SAFE_MAP2	KERROR(EFAULT, sysras_BLOCK_02, 0x218)
#define	EINVAL_RASCHK_XMEM_VMHANDLE	KERROR(EINVAL, sysras_BLOCK_02, 0x219)
#define	EINVAL_RASCHK_XMEM_VMHANDLE2	KERROR(EINVAL, sysras_BLOCK_02, 0x21a)
#define	EINVAL_RASCHK_XMEM_XMEMFLAGS	KERROR(EINVAL, sysras_BLOCK_02, 0x21b)
#define	EINVAL_RASCHK_XMEM_L2PSIZE	KERROR(EINVAL, sysras_BLOCK_02, 0x21c)
#define	EINVAL_RASCHK_XMEM_VMHANDLE3	KERROR(EINVAL, sysras_BLOCK_02, 0x21d)

/* 
 * raschk_sockaddr_in() service 
 */
#define	EINVAL_RASCHK_SOCKADDR_IN_ALIGN	KERROR(EINVAL, sysras_BLOCK_02, 0x221)
#define	EFAULT_RASCHK_SOCKADDR_IN_SAFE_MAP \
 					KERROR(EFAULT, sysras_BLOCK_02, 0x222)
#define	EFAULT_RASCHK_SOCKADDR_IN_SAFE_READ \
 					KERROR(EFAULT, sysras_BLOCK_02, 0x223)
#define	EFAULT_RASCHK_SOCKADDR_IN_DATA \
 					KERROR(EFAULT, sysras_BLOCK_02, 0x224)

/* 
 * raschk_sockaddr_in6() service 
 */
#define	EINVAL_RASCHK_SOCKADDR_IN6_ALIGN \
 					KERROR(EINVAL, sysras_BLOCK_02, 0x231)
#define	EFAULT_RASCHK_SOCKADDR_IN6_SAFE_MAP \
 					KERROR(EFAULT, sysras_BLOCK_02, 0x232)
#define	EFAULT_RASCHK_SOCKADDR_IN6_SAFE_READ \
 					KERROR(EFAULT, sysras_BLOCK_02, 0x233)
#define	EFAULT_RASCHK_SOCKADDR_IN6_DATA \
 					KERROR(EFAULT, sysras_BLOCK_02, 0x234)

/* 
 * raschk_cpu() service 
 */
#define	EFAULT_RASCHK_CPU_SAFE_MAP	KERROR(EFAULT, sysras_BLOCK_02, 0x241)
#define	ERANGE_RASCHK_CPU		KERROR(ERANGE, sysras_BLOCK_02, 0x242)

/* 
 * raschk_event_list() service 
 */
#define	EINVAL_RASCHK_EVENT_LIST_ADDR	KERROR(EINVAL, sysras_BLOCK_02, 0x251)
#define	EINVAL_RASCHK_EVENT_LIST_ALIGN	KERROR(EINVAL, sysras_BLOCK_02, 0x252)
#define	EFAULT_RASCHK_EVENT_LIST_SAFE_MAP \
 					KERROR(EFAULT, sysras_BLOCK_02, 0x253)
#define	EINVAL_RASCHK_EVENT_LIST_SAFE_READ \
					KERROR(EINVAL, sysras_BLOCK_02, 0x254)
#define	EINVAL_RASCHK_EVENT_LIST_DATA	KERROR(EINVAL, sysras_BLOCK_02, 0x255)

/* 
 * RAS basic data types checkers 
 */
#define	EINVAL_RAS_TYPES_VALID	        KERROR(EINVAL, sysras_BLOCK_00, 25)
#define	EINVAL_RAS_TYPES_ALIGN	        KERROR(EINVAL, sysras_BLOCK_00, 26)
#define	EFAULT_RAS_TYPES_VALID	        KERROR(EFAULT, sysras_BLOCK_00, 27)
#define	EFAULT_RAS_TYPES_PAGEIN	        KERROR(EFAULT, sysras_BLOCK_00, 28)
#define	ERANGE_RAS_TYPES_VALID          KERROR(ERANGE, sysras_BLOCK_00, 29)

/* 
 * raschk_vm_att service 
 */
#define	ENOMEM_RAS_VM_ATT_MAP		KERROR(ENOMEM, sysras_BLOCK_00, 34)
#define	EINVAL_RAS_VM_ATT_ALIGN		KERROR(EINVAL, sysras_BLOCK_00, 35)
#define	EINVAL_RAS_VM_ATT_OFFSET	KERROR(ENOMEM, sysras_BLOCK_00, 50)
#define	EFAULT_RAS_VM_ATT_PAGEIN	KERROR(EFAULT, sysras_BLOCK_00, 51)

/* 
 * raschk_vm_det service 
 */
#define	ENODEV_RAS_VM_DET		KERROR(ENODEV, sysras_BLOCK_00, 36)
#define	EINVAL_RAS_VM_DET_RESRV		KERROR(EINVAL, sysras_BLOCK_00, 37)

/*
 * raschk_kernel_eaddr() service
 */
#define	EINVAL_RAS_KERNEL_ADDR      	KERROR(EINVAL, sysras_BLOCK_02, 101)

/*
 * raschk_user_eaddr() service
 */
#define	EINVAL_RAS_USER_ADDR      	KERROR(EINVAL, sysras_BLOCK_02, 102)

/*
 * RASCHK_POINTER_ALIGNMENT() macro
 */
#define	EINVAL_RAS_ADDR_ALIGN    	KERROR(EINVAL, sysras_BLOCK_00, 38)

/*
 * raschk_eaddr() service
 */
#define	EINVAL_RAS_ADDR_VALID      	KERROR(EINVAL, sysras_BLOCK_00, 39)
#define	EFAULT_RAS_ADDR_PAGEIN     	KERROR(EFAULT, sysras_BLOCK_00, 40)
#define	EINVAL_RAS_SYMBOL_NAME    	KERROR(EINVAL, sysras_BLOCK_00, 41)

/* NOTE: 42-45 defined in kdb_ci_exp.h */
/* 
 * KDB raschk_dlist()
 */
#define	EINVAL_RAS_LIST_PREVLINK 	KERROR(EINVAL, sysras_BLOCK_00, 46)
#define	EINVAL_RAS_LIST_NEXTLINK  	KERROR(EINVAL, sysras_BLOCK_00, 47)
#define	EINVAL_RAS_LIST_LOOP		KERROR(EINVAL, sysras_BLOCK_00, 48)

/*
 * KDB raschk_is_paged_out
 */
#define	ENOSYS_RAS_KDB_NOTAVAIL 	KERROR(ENOSYS, sysras_BLOCK_00, 49)

/* 
 * raschk_function_pointer service 
 */
#define	EINVAL_RAS_FP_ADDR_ALIGN	KERROR(EINVAL, sysras_BLOCK_00, 50)
#define	EINVAL_RAS_FP_ADDR_READ 	KERROR(EINVAL, sysras_BLOCK_00, 51)
#define	EINVAL_RAS_FP_BAD_INSTR 	KERROR(EINVAL, sysras_BLOCK_00, 52)

/* 
 * Kerrnos returned by raschk_simple_lock()
 */
#define	EINVAL_RASCHK_SLOCK_ALIGN \
 	KERROR(EINVAL, sysras_BLOCK_02, 0x011)
#define	EINVAL_RASCHK_SLOCK_KADDR \
	KERROR(EINVAL, sysras_BLOCK_02, 0x012)
#define	EINVAL_RASCHK_SLOCK_KERN_ADDR \
	KERROR(EINVAL, sysras_BLOCK_02, 0x013)
#define	EINVAL_RASCHK_SLOCK_SAFE_READ \
	KERROR(EINVAL, sysras_BLOCK_02, 0x014)
#define	EINVAL_RASCHK_SLOCK_KERN_ADDR2 \
	KERROR(EINVAL, sysras_BLOCK_02, 0x015)
#define	EINVAL_RASCHK_SLOCK_SAFE_READ2 \
	KERROR(EINVAL, sysras_BLOCK_02, 0x016)
#define	EINVAL_RASCHK_SLOCK_BAD_RESERVED_BITS \
	KERROR(EINVAL, sysras_BLOCK_02, 0x017)
#define	EINVAL_RASCHK_SLOCK_BAD_THREAD_ID \
	KERROR(EINVAL, sysras_BLOCK_02, 0x018)
#define	EINVAL_RASCHK_SLOCK_BAD_OWNER \
	KERROR(EINVAL, sysras_BLOCK_02, 0x019)

/*
 * RAS kernel executable address validation services
 */
#define	EINVAL_RAS_EXECUTABLE_ADDR_ALIGN KERROR(EINVAL, sysras_BLOCK_00, 53)
#define	EINVAL_RAS_EXECUTABLE_ADDR_VALID KERROR(EINVAL, sysras_BLOCK_00, 54)
#define	EFAULT_RAS_EXECUTABLE_ADDR_PAGEIN KERROR(EFAULT, sysras_BLOCK_00, 55)

#if defined (_KERNEL) && !defined(__KDB_USER)

/*
 * Error Checking Framework Services:
 */
kerrno_t raschk_stktrace(size_t trcbufsz, long flags, void *trcbuf);
kerrno_t raschk_addr2sym(long addr, char *sym, size_t symsz);
long     raschk_lockcount(void);
kerrno_t raschk_errhook(ras_block_t rbp, long comp_data, 
						long errcode, long flags);
long     raschk_intpri(void);
long     raschk_process_env(void);
long	 raschk_random(void);

/*
 * We use raschk_random to check probabilities often, so let's make a macro.
 * What this does is to first see if the probability (first parameter) is
 * non-zero (i.e., function is enabled), and if it is, generate a random
 * number, AND it with the mask (second parameter), and compare to the
 * specified probability.
 */
#define RAS_PROB_CHECK(_prob, _mask)   \
    (((_prob) > 0) && ((raschk_random() & (_mask)) < (_prob)))

#endif /* _KERNEL && !__KDB_USER */

#if defined(_KERNEL) || defined(__KDB_RASCHK)

/*****************************************************************************/
/*********************** Queue Verify & Repair Declarations ******************/
/*****************************************************************************/
/*
 * queue verify, queue repair, and element checker codes
 */
#define EINVAL_ELEMCHKR_BAD_DATA \
                KERROR(EINVAL, sysras_BLOCK_02, 0x000)
#define EINVAL_ELEMCHKR_NOT_ELEMENT \
                KERROR(EINVAL, sysras_BLOCK_02, 0x001)
#define EINVAL_QR_INVALID_PARMS \
                KERROR(EINVAL, sysras_BLOCK_02, 0x002)
#define EINVAL_QR_UNDEFINED_ELEMCHKR_RETCODE \
                KERROR(EINVAL, sysras_BLOCK_02, 0x003)
#define EINVAL_QVR_BAD_DATA \
                KERROR(EINVAL, sysras_BLOCK_02, 0x004)
#define EINVAL_QVR_QUEUE_DAMAGE \
                KERROR(EINVAL, sysras_BLOCK_02, 0x005)
#define EINVAL_QVR_INVALID_PARMS \
                KERROR(EINVAL, sysras_BLOCK_02, 0x006)
#define EINVAL_QVR_UNDEFINED_ELEMCHKR_RETCODE \
                KERROR(EINVAL, sysras_BLOCK_02, 0x007)
#define EINVAL_QR_RECORD_ILLOGIC \
                KERROR(EINVAL, sysras_BLOCK_02, 0x008)
/*
 * Interface to queue element checker routine.  
 */
typedef kerrno_t (*ras_elemchkr_t)(
        void *element,              /* queue element to be verified */
        long errchk_level,          /* error checking level */        
        long flags,                 /* The following flags from the 
                                     * raschk_queue_verify() caller are 
                                     * passed through to the element 
                                     * checker.
                                     *    
                                     *  RASCHK_VERBOSE_MODE (0x00000001) 
                                     *  RAS_SR_NOFAULT      (0x00000002) 
                                     *  RAS_SR_NOPAGEIN     (0x00000004)
                                     *
                                     * queue_repair() passes 0 for these
                                     * three flags to the element checker.
                                     *
                                     * Other flags are:             */
#define ELEMCHKR_FLAGS_QUEUE_REPAIR 0x80000000   
                                    /* queue repair is caller */
                                            
        void *token,                /* component provided value from caller */
        long depth,           
        long *status);              

/*
 * Element checker routine return codes.  
 */
#define ELEMCHKR_VALID_ELEMENT 0    /* element address contains a valid 
                                     * queue element */
/*      EINVAL_ELEMCHKR_BAD_DATA     * element address contains a queue 
                                     * element but the element contains
                                     * bad data */
/*      EINVAL_ELEMCHKR_NOT_ELEMENT  * element address is not a queue 
                                     * element */      
/* All other negative return codes are treated the same as the 
 * EINVAL_ELEMCHKR_NOT_ELEMENT, that is the element address is not 
 * a queue element. */   
 
                                       
/*
 * Input parameter list to queue_repair() and raschk_queue_verify()
 */ 
typedef struct qvrin  
{
        eye_catch8b_t eyec;             /* eyecatcher */
#define EYEC_QVRIN 0x717672696E524153LL /* "qvrinRAS" */
                                    
        unsigned short version;     /* version of structure provided 
                                     * by the caller */
    
        unsigned short queue_type;
#define QVRIN_SINGLE            1   /* single link with header */ 
#define QVRIN_SINGLE_CIRCULAR   2   /* single link circular with header */ 
#define QVRIN_SINGLE_TRAILER    3   /* single link with header and trailer */ 
#define QVRIN_DOUBLE            4   /* double link with header and trailer */ 
#define QVRIN_DOUBLE_CIRCULAR   5   /* double link circular with header */
#define QVRIN_DOUBLE_NO_TRAILER 6   /* double link with header */
    
        int qvr_flags;  
#define QVRIN_HEADER_IS_ELEMENT 0x80000000
	                            /* The header is actually the first element -
				     * used for KDB when the address of the first
				     * element was specified on the command line 
				     * (so we can't provide an address for it).
				     * Note that we assume if it is true for the
				     * header, it is also true for the trailer.
                                     * Only valid for raschk_queue_verify()
				     *
                                     * All other flags reserved for 
                                     * future use. */   
#define QVRIN_QVR_FLAGS_MASK 0x80000000
  
        ras_elemchkr_t elemchkr;    /* element checker function pointer */
        
        int elemchkr_errchk_level;  /* element checker error checking level.
                                     * Passed through to element checker */ 
        
        int elemchkr_flags;         /* input flags passed through to element 
                                     * checker routine. 
                                     * 
                                     * raschk_queue_verify() passes the 
                                     * following three flags from this 
                                     * field to the element checker.
                                     *  RASCHK_VERBOSE_MODE (0x00000001) 
                                     *  RAS_SR_NOFAULT      (0x00000002) 
                                     *  RAS_SR_NOPAGEIN     (0x00000004)
                                     * 
                                     * queue_repair() passes 0 for these
                                     * three flags to the element checker.
                                     *
                                     * All other flags reserved for 
                                     * future use. */   
#define QVRIN_ELEMCHKR_FLAGS_MASK 0x00000007  
    
        void *elemchkr_token;       /* value from caller passed to element
                                     * checker routine */

        void *no_element;           /* value in queue header or trailer that
                                     * indicates no element on the queue */
    
        void **header;              /* address of queue header */
        void *flink_eoq;            /* forward link end of queue value.
                                     * This value in forward link indicates 
                                     * last element on the queue */
        int flink_offset;           /* offset into element containing the 
                                     * forward link */
    
        void **trailer;             /* address of queue trailer */
        void *blink_eoq;            /* backward link start of queue value.
                                     * This value in backward link indicates 
                                     * first element on the queue. */
        int blink_offset;           /* offset into element containing the 
                                       backward link */

        size_t number_elements;     /* number of elements to be verified by 
                                     * raschk_queue_verify().  This field
                                     * is ignored by queue_repair(). */                                       
    /* end of QVRIN_VERSION_1 fields */  
#define QVRIN_VERSION_1         1
} qvrin_t;

/*
 * raschk_queue_verify() return codes
 */
#define QVR_NO_ERRORS 0             /* no errors were detected,
                                     * this return code also returned when 
                                     * specified number of elements were
                                     * examined without an error */
/*      EINVAL_QVR_BAD_DATA          * an element containing bad
                                     * data was found on the queue */
/*      EINVAL_QVR_QUEUE_DAMAGE      * the queue is damaged, an element
                                     * address was found on the queue
                                     * but that address is not a 
                                     * queue element */
/*      EINVAL_QVR_INVALID_PARMS     * invalid parameter data was 
                                     * provided by caller */
/*      EINVAL_QVR_UNDEFINED_ELEMCHKR_RETCODE 
                                     * an undefined return code was 
                                     * returned by the element checker */ 
/* All negative kerrno_t return values from the element checker
 * are returned as is from by raschk_queue_verify().  This includes
 * the EFAULT raschk_safe_read() return codes. */

#endif /* _KERNEL || __KDB_RASCHK */

#if defined (_KERNEL) || defined(__KDB_USER)
/*
 * queue_repair() output data structure
 */ 
typedef struct qrout
{
        eye_catch4b_t eyec;         /* eyecatcher */
#define EYEC_QROUT 0x71726F74       /* "qrot" */
        unsigned short in_version;  /* version of structure provided 
                                     * by the caller */
        unsigned short out_version; /* version of structure returned 
                                     * by the queue_repair() service */
        void *oda;                  /* address of output data area buffer 
                                     * provided by the caller */
        size_t oda_size;            /* size of output data area buffer
                                     * provided by the caller */
        size_t good_elements;       /* number of good elements remaining  
                                       on the queue */
        size_t detected_errors;     /* number of detected errors */
        size_t recorded_errors;     /* number of errors recorded in the 
                                     * output data area */ 
    /* end of QROUT_VERSION_1 fields */
#define QROUT_VERSION_1         1    
} qrout_t;
    

typedef struct qroda_hdr            /* queue_repair() output data area header */
{
        eye_catch4b_t qroda_eyec; 
#define EYEC_QRODA_HDR 0x71726F64   /* "qrod" */
    
        unsigned short qroda_hdr_version; /* version of qroda returned by 
                                     * the queue_repair() service */
    
        unsigned short qroda_hdr_size; /* size of the qvoda header.  This is 
                                     * also the offset from the start of the 
                                     * buffer to the first record in the
                                     * output data buffer */
        size_t qroda_used;          /* number of bytes used in the ODA buffer 
                                     * including the header */
        /* end of QRODA_HDR_VERSION_1 fields */
#define QRODA_HDR_VERSION_1 1    
#define QRODA_HDR_VERSION_1_SIZE  (sizeof(qroda_hdr_t))
} qroda_hdr_t;    


typedef struct qroda_record         /* queue_repair() ODA error record */ 
{
        unsigned char qrrcd_code;   /* error code denoting type of record */
        unsigned char qrrcd_extended_code;  /* extended error code */
        unsigned short qrrcd_size; /* size of this record */
        int _rsvd;                  /* align to 8 byte boundary */
        void *qrrcd_addr1;          /* variable data address 1 */
        void *qrrcd_addr2;          /* variable data address 2 */
        void *qrrcd_addr3;          /* variable data address 3 */
} qroda_record_t;

/*
 * Values for qrrcd_code field
 */ 
#define QRRCD_CODE_DATA     4       /* queue element with bad data not related
                                     * to links has been removed from queue */
#define QRRCD_CODE_HEADER   8       /* queue header contains bad address */
#define QRRCD_CODE_TRAILER  12      /* queue trailer contains bad address */
#define QRRCD_CODE_FLINK    16      /* forward link has bad address */
#define QRRCD_CODE_BLINK    20      /* backward link has badd address */

/*
 * Values for qvrcd_extended_code field
 */  
#define QRRCD_EXCODE_DATA           4   /* queue element has bad data */    
#define QRRCD_EXCODE_LINK           8   /* queue link contains bad addresss */
#define QRRCD_EXCODE_CIRCULAR       12  /* queue is circular */
#define QRRCD_EXCODE_SEQUENCE       16  /* combined name for next two values */
#define QRRCD_EXCODE_BACKWARD_PREVIOUS 16 /* on backward scan, the flink of 
                                           * the previous element does not 
                                           * point to current element */
#define QRRCD_EXCODE_FORWARD_NEXT   16    /* on forward scan, the blink of the 
                                           * next element does not point to  
                                           * the current element */  
#define QRRCD_EXCODE_END            20  /* combined name for next two values */        
#define QRRCD_EXCODE_LAST_FORWARD   20  /* forward link of last element does
                                         * not contain end of queue value */    
#define QRRCD_EXCODE_FIRST_BACKWARD 20  /* backward link of the first element
                                         * does not contain end of queue 
                                         * value */   
#endif  /* _KERNEL || __KDB_USER */

#if defined (_KERNEL) || defined(__KDB_RASCHK)

/*
 * queue_repair() interface
 */ 
kerrno_t queue_repair(
        struct qvrin *qvrin,
        struct qrout *qrout);

#define QR_RETCODE_NO_ERRORS 0      /* queue repair completed its processing 
                                     * and no errors were detected */
#define QR_RETCODE_BAD_DATA  4      /* queue repair completed its processing
                                     * and elements with bad data were 
                                     * removed from the queue */
#define QR_RETCODE_DAMAGE    8      /* queue repair completed its processing 
                                     * and there was damage to the queue.  An 
                                     * indeterminate number of elements were 
                                     * removed from the queue */
/*      EINVAL_QR_INVALID_PARMS      * queue repair did not occur, bad 
                                     * parameter data was provided by the caller */

/*
 * raschk_queue_verify() prototype
 */
kerrno_t raschk_queue_verify(
        qvrin_t *qvrin);            /* queue verify/repair input structure */ 

#endif  /* _KERNEL || __KDB_RASCHK */

/*
 * Signature for data type consistency checkers:
 * kerrno_t (*ras_checker_func_t)(void *p, 
 *                                 long level, long flags, 
 *                                 long depth, long *status);
 */
typedef kerrno_t (*ras_checker_func_t)(void *, long, long, long, long *);

/* 
 * The following macros are used to share code between run-time error 
 * checking and kdb consistency checking. 
 * For each interface there are 3 macros: one for __RT_RASCHK, 
 * one for __KDB_RASCHK and one for __KDB_KEXT_RASCHK.
 * Complete definitions of these interfaces can be found at the end of 
 * this file.
 */

/*
 * Queue verification routine - there's a KDB version and a runtime (i.e. kernel)
 * version.
 */
#ifdef __RT_RASCHK
#define RASCHK_QUEUE_VERIFY(_q)	     \
	     raschk_queue_verify(_q)
/* The prototype is defined above */
#endif /*__RT_RASCHK  */

#ifdef __KDB_RASCHK
#define RASCHK_QUEUE_VERIFY(_q)	     \
	     kdb_raschk_queue_verify(_q)
/*
 * kdb_raschk_queue_verify() prototype (for KDB only)
 */
kerrno_t kdb_raschk_queue_verify(
        qvrin_t *qvrin);            /* queue verify/repair input structure */ 

#endif /* __KDB_RASCHK */

/*
 * Checkers
 */
#ifdef __RT_RASCHK
#define RASCHK_SAFE_MAP_ELEM(_elem, _var)  \
    (_var = _elem, 0)
#endif

#ifdef __KDB_RASCHK
#define RASCHK_SAFE_MAP_ELEM(_elem, _var)  \
    raschk_safe_read((void *)&(_elem), (void *)&(_var), sizeof(_elem), 0)
#endif
/* 
 * Memory addresses validation 
 */
#ifdef __RT_RASCHK

#define raschk_kernel_eaddr(_ad) rt_raschk_kernel_eaddr(_ad)
#define raschk_user_eaddr(_ad)   rt_raschk_user_eaddr(_ad)
#define raschk_eaddr(_ad)        rt_raschk_eaddr(_ad)

#define raschk_xmalloc_eaddr(_ad, _hp, _lvl, _flg) \
			rt_raschk_xmalloc_eaddr(_ad, _hp, _lvl, _flg)

#define raschk_netmalloc_eaddr(_ad, _lvl, _flg) \
			rt_raschk_netmalloc_eaddr(_ad, _lvl, _flg)

#define raschk_executable_eaddr(_ad, _flg) \
			rt_raschk_executable_eaddr(_ad, _flg)

#define raschk_function_pointer(_addr) \
		rt_raschk_function_pointer(_addr)

#define raschk_executable_kernel_eaddr(_ad, _flg) \
			rt_raschk_executable_kernel_eaddr(_ad, _flg)

#define raschk_kext_eaddr(_ad, _flg) \
			rt_raschk_kext_eaddr(_ad, _flg)

/* 
 * Safe memory access 
 */

/* values for mst no_pfault flag */
#define NO_PFAULT_PFAULTOK 0 /* page faults permitted */
#define NO_PFAULT_RELOAD  1  /* only reload faults allowed */
#define NO_PFAULT_INTSAFE 2  /* only interrupt safe faults allowed */
#define NO_PFAULT_PAGEIN  4  /* no page-ins allowed */
#define NO_PFAULT_THRPGIO 8  /* no THRPGIO paging device page faults */

#define raschk_safe_read(_src, _dst, _sz, _flg) \
			rt_raschk_safe_read(_src, _dst, _sz, _flg)

	/* XXX - could be raschk_safe_read with SR_NOPAGEIN */
#define raschk_is_paged_out(_ad, _sz) \
			rt_raschk_is_paged_out(_ad, _sz)

#define RASCHK_SAFE_MAP_MEM(__src, __size, __local_storage, __map_addr) \
			((*(ulong **)(__map_addr)) = (ulong *)(__src), 0)

#define RASCHK_GET_SYMBOLADDR(__value, __symbol) \
			((void **)__value = (void **)&(__symbol))

#define raschk_vm_att(_vmh, _off, _map_addr) \
			rt_raschk_vm_att(_vmh, _off, _map_addr)

#define raschk_vm_det(_addr)	rt_raschk_vm_det(_addr)

/* Basic data types checkers */
#define raschk_chan(_channel)	 rt_raschk_chan(_channel)
#define raschk_cpu(_cpu)	 rt_raschk_cpu(_cpu)
#define raschk_dev(_devno)	 rt_raschk_dev(_devno)
#define raschk_mode(_mode)	 rt_raschk_mode(_mode)
#define raschk_pid(_pid)         rt_raschk_pid(_pid)
#define raschk_tid(_tid)	 rt_raschk_tid(_tid)
#define raschk_time(_time)	 rt_raschk_time(_time)
#define raschk_timestruc(_ts)	 rt_raschk_timestruc(_ts)
#define raschk_timeval(_tv)	 rt_raschk_timeval(_tv)
#define raschk_vmid(_sid)	 rt_raschk_vmid(_sid)
#define raschk_vmhandle(_handle) rt_raschk_vmhandle(_handle)

#define raschk_string(_str, _len, _flags) \
		rt_raschk_string(_str, _len, _flags)

#define raschk_simple_lock(_lock, _level, _flags) \
		rt_raschk_simple_lock(_lock, _level, _flags)

#define raschk_complex_lock(_lock, _level, _flags) \
		rt_raschk_complex_lock(_lock, _level, _flags)

#define raschk_cred(_cred, _level, _flags) \
		rt_raschk_cred(_cred, _level, _flags)

#define raschk_xmem(_xmem, _level, _flags) \
		rt_raschk_xmem(_xmem, _level, _flags)

#define raschk_sockaddr_in(_sin, _level, _flags) \
		rt_raschk_sockaddr_in(_sin, _level, _flags)

#define raschk_sockaddr_in6(_sin6, _level, _flags) \
		rt_raschk_sockaddr_in6(_sin6, _level, _flags)

#define raschk_event_list(_event_list, _level, _flags) \
		rt_raschk_event_list(_event_list, _level, _flags)

#define raschk_get_tbtable(_addr, _tb) \
		rt_raschk_get_tbtable(_addr, _tb)

/* Interfaces not available to run-time error checking */

#define raschk_pinned_eaddr(_ad, _flg)			       (0)
#define raschk_user_interrupt(_last, _message, _flags)         (0)
#define raschk_report_error(_sn, _fn, _addr, _off, _err, _msg) (0)
#define raschk_printf(...)                                     (0)

#endif /* __RT_RASCHK */

/*
 * For kdb consistency checking 
 */
#ifdef __KDB_RASCHK

#ifndef __KDB_KEXT_RASCHK

/* Memory addresses validation */
#define raschk_kernel_eaddr(_ad) kdb_raschk_kernel_eaddr(_ad)
#define raschk_user_eaddr(_ad)   kdb_raschk_user_eaddr(_ad)
#define raschk_eaddr(_ad)        kdb_raschk_eaddr(_ad)

#define raschk_pinned_eaddr(_ad, _flg) \
		kdb_raschk_pinned_eaddr(_ad, _flg)
#define raschk_executable_eaddr(_ad, _flg) \
		kdb_raschk_executable_eaddr(_ad, _flg)
#define raschk_function_pointer(_addr) \
		kdb_raschk_function_pointer(_addr)
#define raschk_executable_kernel_eaddr(_ad, _flg) \
		kdb_raschk_executable_kernel_eaddr(_ad, _flg)
#define raschk_kext_eaddr(_ad, _flg) \
		kdb_raschk_kext_eaddr(_ad, _flg)
#define raschk_xmalloc_eaddr(_ad, _hp, _lvl, _flg) \
		kdb_raschk_xmalloc_eaddr(_ad, _hp, _lvl, _flg)
#define raschk_netmalloc_eaddr(_ad, _lvl, _flg) \
		kdb_raschk_netmalloc_eaddr(_ad, _lvl, _flg)

/* Safe memory access */
#define raschk_is_paged_out(_ad, _sz) \
		kdb_raschk_is_paged_out(_ad, _sz)

#define raschk_safe_read(_src, _dst, _sz, _flg) \
		kdb_raschk_safe_read(_src, _dst, _sz, _flg)

#define RASCHK_SAFE_MAP_MEM(_src, _size, _local_storage, _map_addr) \
		kdb_raschk_safe_map_mem(_src, _size, _local_storage, _map_addr)


#if defined (_KERNEL) && !defined(__KDB_USER)
#define RASCHK_GET_SYMBOLADDR(__value, __symbol) \
		((void **)__value = (void **)&__symbol)
#else /* _KERNEL && !__KDB_USER */
#define RASCHK_GET_SYMBOLADDR(__value, __symbol) \
	(kdb_symboladdr(__value, #__symbol) ? 0 : EINVAL_RAS_SYMBOL_NAME)
#endif /* _KERNEL && !__KDB_USER */

#define raschk_vm_att(_vmh, _off, _map_addr) \
		kdb_raschk_vm_att(_vmh, _off, _map_addr)

#define raschk_vm_det(_addr) \
		kdb_raschk_vm_det(_addr)

/* Basic data types checkers */
#define raschk_chan(_channel)	 kdb_raschk_chan(_channel)
#define raschk_cpu(_cpu)	 kdb_raschk_cpu(_cpu)
#define raschk_dev(_devno)	 kdb_raschk_dev(_devno)
#define raschk_mode(_mode)	 kdb_raschk_mode(_mode)
#define raschk_pid(_pid)         kdb_raschk_pid(_pid)
#define raschk_tid(_tid)	 kdb_raschk_tid(_tid)
#define raschk_time(_time)	 kdb_raschk_time(_time)
#define raschk_timestruc(_ts)	 kdb_raschk_timestruc(_ts)
#define raschk_timeval(_tv)	 kdb_raschk_timeval(_tv)
#define raschk_vmid(_sid)	 kdb_raschk_vmid(_sid)
#define raschk_vmhandle(_handle) kdb_raschk_vmhandle(_handle)

#define raschk_string(_str, _len, _flags) \
		kdb_raschk_string(_str, _len, _flags)

#define raschk_simple_lock(_lock, _level, _flags) \
		kdb_raschk_simple_lock(_lock, _level, _flags)

#define raschk_complex_lock(_lock, _level, _flags) \
		kdb_raschk_complex_lock(_lock, _level, _flags)

#define raschk_cred(_cred, _level, _flags) \
		kdb_raschk_cred(_cred, _level, _flags)

#define raschk_xmem(_xmem, _level, _flags) \
		kdb_raschk_xmem(_xmem, _level, _flags)

#define raschk_sockaddr_in(_sin, _level, _flags) \
		kdb_raschk_sockaddr_in(_sin, _level, _flags)

#define raschk_sockaddr_in6(_sin6, _level, _flags) \
		kdb_raschk_sockaddr_in6(_sin6, _level, _flags)

#define raschk_event_list(_event_list, _level, _flags) \
		kdb_raschk_event_list(_event_list, _level, _flags)

#define raschk_get_tbtable(_addr, _tb) \
		kdb_raschk_get_tbtable(_addr, _tb)

/* Interfaces only available for kdb consistency checkers */
#define raschk_user_interrupt(_last, _message, _flags) \
		kdb_raschk_user_interrupt(_last, _message, _flags)

#define raschk_report_error(_sn, _fn, _addr, _off, _err, _msg) \
		kdb_raschk_report_error(_sn, _fn, _addr, _off, _err, _msg)

#define raschk_printf(...) kdb_printf(__VA_ARGS__)

#define raschk_slist(_addr, _off, _cb, _nb, _fl, _lvl, _last) \
		kdb_raschk_slist(_addr, _off, _cb, _nb, _fl, _lvl, _last)

#define raschk_dlist(_addr, _nof, _pof, _cb, _nb, _fl, _lvl, _last) \
		kdb_raschk_dlist(_addr, _nof, _pof, _cb, _nb, _fl, _lvl, _last)

#else /* __KDB_KEXT_RASCHK */

/*
 * For kdb consistency checking from a kernel extension
 */

/* Memory addresses validation */
#define raschk_kernel_eaddr(_ad) kdb_kext_raschk_kernel_eaddr(_ad)
#define raschk_user_eaddr(_ad)   kdb_kext_raschk_user_eaddr(_ad)
#define raschk_eaddr(_ad)        kdb_kext_raschk_eaddr(_ad)

#define raschk_pinned_eaddr(_ad, _flg) \
		kdb_kext_raschk_pinned_eaddr(_ad, _flg)
#define raschk_executable_eaddr(_ad, _flg) \
		kdb_kext_raschk_executable_eaddr(_ad, _flg)
#define raschk_function_pointer(_addr) \
		kdb_kext_raschk_function_pointer(_addr)
#define raschk_executable_kernel_eaddr(_ad, _flg) \
		kdb_kext_raschk_executable_kernel_eaddr(_ad, _flg)
#define raschk_kext_eaddr(_ad, _flg) \
		kdb_kext_raschk_kext_eaddr(_ad, _flg)
#define raschk_xmalloc_eaddr(_ad, _hp, _lvl, _flg) \
		kdb_kext_raschk_xmalloc_eaddr(_ad, _hp, _lvl, _flg)
#define raschk_netmalloc_eaddr(_ad, _lvl, _flg) \
		kdb_kext_raschk_netmalloc_eaddr(_ad, _lvl, _flg)

/* Safe memory access */
#define raschk_is_paged_out(_ad, _sz) \
		kdb_kext_raschk_is_paged_out(_ad, _sz)

#define raschk_safe_read(_src, _dst, _sz, _flg) \
		kdb_kext_raschk_safe_read(_src, _dst, _sz, _flg)

#define RASCHK_SAFE_MAP_MEM(_src, _size, _local_storage, _map_addr) \
		kdb_kext_raschk_safe_map_mem(_src, _size, _local_storage, _map_addr)

#if defined (_KERNEL) && !defined(__KDB_USER)
#define RASCHK_GET_SYMBOLADDR(__value, __symbol)           \
		(((void **)__value = (void **)&__symbol) ? \
		 0 : EINVAL_RAS_SYMBOL_NAME)
#else /* _KERNEL && !__KDB_USER */
#define RASCHK_GET_SYMBOLADDR(_value, _symbol) \
		(db_symboladdr((void **)&_value, #_symbol) ? \
		 0 : EINVAL_RAS_SYMBOL_NAME)
#endif /* _KERNEL && !__KDB_USER */

#define raschk_vm_att(_vmh, _off, _map_addr) \
		kdb_kext_raschk_vm_att(_vmh, _off, _map_addr)

#define raschk_vm_det(_addr) \
		kdb_kext_raschk_vm_det(_addr)

/* Basic data types checkers */
#define raschk_chan(_channel)	 kdb_kext_raschk_chan(_channel)
#define raschk_cpu(_cpu)	 kdb_kext_raschk_cpu(_cpu)
#define raschk_dev(_devno)	 kdb_kext_raschk_dev(_devno)
#define raschk_mode(_mode)	 kdb_kext_raschk_mode(_mode)
#define raschk_pid(_pid)         kdb_kext_raschk_pid(_pid)
#define raschk_tid(_tid)	 kdb_kext_raschk_tid(_tid)
#define raschk_time(_time)	 kdb_kext_raschk_time(_time)
#define raschk_timestruc(_ts)	 kdb_kext_raschk_timestruc(_ts)
#define raschk_timeval(_tv)	 kdb_kext_raschk_timeval(_tv)
#define raschk_vmid(_sid)	 kdb_kext_raschk_vmid(_sid)
#define raschk_vmhandle(_handle) kdb_kext_raschk_vmhandle(_handle)

#define raschk_string(_str, _len, _flags) \
		kdb_kext_raschk_string(_str, _len, _flags)

#define raschk_simple_lock(_lock, _level, _flags) \
		kdb_kext_raschk_simple_lock(_lock, _level, _flags)

#define raschk_complex_lock(_lock, _level, _flags) \
		kdb_kext_raschk_complex_lock(_lock, _level, _flags)

#define raschk_cred(_cred, _level, _flags) \
		kdb_kext_raschk_cred(_cred, _level, _flags)

#define raschk_xmem(_xmem, _level, _flags) \
		kdb_kext_raschk_xmem(_xmem, _level, _flags)

#define raschk_sockaddr_in(_sin, _level, _flags) \
		kdb_kext_raschk_sockaddr_in(_sin, _level, _flags)

#define raschk_sockaddr_in6(_sin6, _level, _flags) \
		kdb_kext_raschk_sockaddr_in6(_sin6, _level, _flags)

#define raschk_event_list(_event_list, _level, _flags) \
		kdb_kext_raschk_event_list(_event_list, _level, _flags)

#define raschk_get_tbtable(_addr, _tb) \
		kdb_kext_raschk_get_tbtable(_addr, _tb)

/* Interfaces only available for kdb consistency checkers */
#define raschk_user_interrupt(_last, _message, _flags) \
		kdb_kext_raschk_user_interrupt(_last, _message, _flags)

#define raschk_report_error(_sn, _fn, _addr, _off, _err, _msg) \
		kdb_kext_raschk_report_error(_sn, _fn, _addr, _off, _err, _msg)

#define raschk_printf(...) db_printf(__VA_ARGS__)

#define raschk_slist(_addr, _off, _cb, _nb, _fl, _lvl, _last) \
		kdb_kext_raschk_slist(_addr, _off, _cb, _nb, _fl, _lvl, _last)

#define raschk_dlist(_addr, _nof, _pof, _cb, _nb, _fl, _lvl, _last) \
		kdb_kext_raschk_dlist(_addr, _nof, _pof, _cb, _nb, _fl, _lvl, _last)

#endif /* __KDB_KEXT_RASCHK */


#endif /* __KDB_RASCHK */


/* 
 * Macros common to both KDB and Runtime environment. 
 */
#define RASCHK_RANGE(__val, __min, __max) \
	( ((__val) >= (__min) && (__val) <= (__max) ? \
				0 : ERANGE_RAS_TYPES_VALID))

#define RASCHK_ENUM(__val, __min, __max) \
				RASCHK_RANGE(__val, __min, __max)

#define RASCHK_BITFIELD(__bits, __valid_bits) \
	(! ((__bits) & ~(__valid_bits)) ? 0 : ERANGE_RAS_TYPES_VALID)

#define RASCHK_POINTER_ALIGNMENT(__addr, __size) \
	( (((ulong)(__addr) % (ulong)(__size)) == 0) ? \
				0 : EINVAL_RAS_ADDR_ALIGN)

/* 
 * Functions prototypes 
 */
struct sockaddr_in;
struct sockaddr_in6;
kerrno_t raschk_is_paged_out(void *, size_t);
kerrno_t raschk_safe_read(void *, void *, size_t, ras_sr_flags_t);
kerrno_t raschk_vm_att(vmhandle_t, off_t, void **);
kerrno_t raschk_vm_det(void *);
kerrno_t raschk_kernel_eaddr(void *);
kerrno_t raschk_user_eaddr(void *);
kerrno_t raschk_eaddr(void *);
kerrno_t raschk_executable_eaddr(void *, ras_sr_flags_t);
kerrno_t raschk_function_pointer(void *);
kerrno_t raschk_executable_kernel_eaddr(void *, ras_sr_flags_t);
kerrno_t raschk_kext_eaddr(void *, ras_sr_flags_t);
kerrno_t raschk_xmalloc_eaddr(void *, heapaddr_t, long, ras_sr_flags_t);
kerrno_t raschk_netmalloc_eaddr(void *, long, ras_sr_flags_t);
kerrno_t raschk_chan(chan_t);
kerrno_t raschk_cpu(cpu_t);
kerrno_t raschk_dev(dev_t);
kerrno_t raschk_mode(mode_t);
kerrno_t raschk_pid(pid_t);
kerrno_t raschk_string(const char *, long, long);
kerrno_t raschk_tid(tid_t);
kerrno_t raschk_time(time_t);

struct timestruc_t;
kerrno_t raschk_timestruc(struct timestruc_t);

struct timeval;
kerrno_t raschk_timeval(struct timeval);
kerrno_t raschk_vmid(vmid_t);
kerrno_t raschk_vmhandle(vmhandle_t);
kerrno_t raschk_simple_lock(simple_lock_t, long, ras_sr_flags_t);
kerrno_t raschk_complex_lock(complex_lock_t, long, ras_sr_flags_t);
kerrno_t raschk_cred(cred_t *, long, ras_sr_flags_t);

struct xmem;
kerrno_t raschk_xmem(struct xmem *, long, ras_sr_flags_t);
kerrno_t raschk_sockaddr_in(struct sockaddr_in *, long, ras_sr_flags_t);
kerrno_t raschk_sockaddr_in6(struct sockaddr_in6 *, long, ras_sr_flags_t);
kerrno_t raschk_event_list(tid_t *, long, ras_sr_flags_t);
long	 raschk_get_tbtable(void *addr, struct tbtable_short *tb);

#ifdef __64BIT_KERNEL
#define RCHK_EK_NOFAULT		0x00000002
#define RCHK_EK_NOPAGEIN	0x00000004
#define	RCHK_EK_FLAGS_MASK	(RCHK_EK_NOFAULT | RCHK_EK_NOPAGEIN)

kerrno_t raschk_eaddr_kkey(void *, kkey_t, ulong);

/* raschk_eaddr_kkey returns */
#define EINVAL_RASCHK_EADDR_KKEY        KERROR(EINVAL, sysras_BLOCK_02, 9)
#define EINVAL_RASCHK_EADDR_KKEY_PROT   KERROR(EINVAL, sysras_BLOCK_02, 0xA)
#define EFAULT_RASCHK_EADDR_KKEY        KERROR(EFAULT, sysras_BLOCK_02, 0xB)

#define RCHK_EHK_NOFAULT	0x00000002
#define RCHK_EHK_NOPAGEIN	0x00000004
#define RCHK_EHK_READ           0x00000008
#define RCHK_EHK_WRITE          0x00000010
#define	RCHK_EHK_FLAGS_MASK   \
  (RCHK_EHK_NOFAULT | RCHK_EHK_NOPAGEIN | RCHK_EHK_READ | RCHK_EHK_WRITE)

kerrno_t raschk_eaddr_hkeyset(void *, hkeyset_t, ulong);

/* raschk_eaddr_hkeyset returns */
#define EINVAL_RASCHK_EADDR_HKEYSET     KERROR(EINVAL, sysras_BLOCK_02, 0xC)
#define EFAULT_RASCHK_EADDR_HKEYSET     KERROR(EFAULT, sysras_BLOCK_02, 0xD)
#define EFAULT_RASCHK_EADDR_HKEYSET_PROT KERROR(EFAULT, sysras_BLOCK_02, 0xE)

#endif /* __64BIT_KERNEL */

#ifdef __KDB_RASCHK

/* RASCHK_SAFE_MAP_MEM is a macro in __RT_RASCHK */
kerrno_t RASCHK_SAFE_MAP_MEM(void *, size_t, void *, void **);

/* The following interfaces are only available for kdb consistency checkers */
kerrno_t raschk_pinned_eaddr(void *, long);
kerrno_t raschk_user_interrupt(void *, char *, long);
kerrno_t raschk_report_error(char *, char *, void *, size_t, long, char *);

kerrno_t raschk_slist(void *, size_t, ras_checker_func_t,
		       long, long, long, void *);

kerrno_t raschk_dlist(void *, size_t, size_t, ras_checker_func_t,
		       long, long, long, void *);

#endif /* __KDB_RASCHK */

/* Flags for raschk_string() */
#define RASCHK_FIXED_SIZE	0x1

/* 
 * Return values for raschk_get_tbtable. Odd to allow these to be 
 * distinguished from actual addresses that might be returned. 
 */
#define RASCHK_NO_TRACEBACK_TABLE	KERROR(EFAULT, sysras_BLOCK_02, 0xF)
#define RASCHK_ADDR_PAGED_OUT		KERROR(EFAULT, sysras_BLOCK_02, 0x11)
#define RASCHK_ADDR_INVALID		KERROR(EFAULT, sysras_BLOCK_02, 0x13)

#ifdef __cplusplus
}
#endif

#endif /* _H_RASCHK */