sgi-xp: define xp_expand_memprotect() and xp_restrict_memprotect()
Define xp_expand_memprotect() and xp_restrict_memprotect() so they can be tailered to the hardware they are run on. Signed-off-by: Dean Nelson <dcn@sgi.com> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
committed by
H. Peter Anvin
parent
23c357003b
commit
6c1c325de9
@@ -190,9 +190,10 @@ enum xp_retval {
|
|||||||
xpGruSendMqError, /* 59: gru send message queue related error */
|
xpGruSendMqError, /* 59: gru send message queue related error */
|
||||||
|
|
||||||
xpBadChannelNumber, /* 60: invalid channel number */
|
xpBadChannelNumber, /* 60: invalid channel number */
|
||||||
xpBadMsgType, /* 60: invalid message type */
|
xpBadMsgType, /* 61: invalid message type */
|
||||||
|
xpBiosError, /* 62: BIOS error */
|
||||||
|
|
||||||
xpUnknownReason /* 61: unknown reason - must be last in enum */
|
xpUnknownReason /* 63: unknown reason - must be last in enum */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -341,6 +342,8 @@ extern unsigned long (*xp_pa) (void *);
|
|||||||
extern enum xp_retval (*xp_remote_memcpy) (unsigned long, const unsigned long,
|
extern enum xp_retval (*xp_remote_memcpy) (unsigned long, const unsigned long,
|
||||||
size_t);
|
size_t);
|
||||||
extern int (*xp_cpu_to_nasid) (int);
|
extern int (*xp_cpu_to_nasid) (int);
|
||||||
|
extern enum xp_retval (*xp_expand_memprotect) (unsigned long, unsigned long);
|
||||||
|
extern enum xp_retval (*xp_restrict_memprotect) (unsigned long, unsigned long);
|
||||||
|
|
||||||
extern u64 xp_nofault_PIOR_target;
|
extern u64 xp_nofault_PIOR_target;
|
||||||
extern int xp_nofault_PIOR(void *);
|
extern int xp_nofault_PIOR(void *);
|
||||||
|
@@ -51,6 +51,13 @@ EXPORT_SYMBOL_GPL(xp_remote_memcpy);
|
|||||||
int (*xp_cpu_to_nasid) (int cpuid);
|
int (*xp_cpu_to_nasid) (int cpuid);
|
||||||
EXPORT_SYMBOL_GPL(xp_cpu_to_nasid);
|
EXPORT_SYMBOL_GPL(xp_cpu_to_nasid);
|
||||||
|
|
||||||
|
enum xp_retval (*xp_expand_memprotect) (unsigned long phys_addr,
|
||||||
|
unsigned long size);
|
||||||
|
EXPORT_SYMBOL_GPL(xp_expand_memprotect);
|
||||||
|
enum xp_retval (*xp_restrict_memprotect) (unsigned long phys_addr,
|
||||||
|
unsigned long size);
|
||||||
|
EXPORT_SYMBOL_GPL(xp_restrict_memprotect);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* xpc_registrations[] keeps track of xpc_connect()'s done by the kernel-level
|
* xpc_registrations[] keeps track of xpc_connect()'s done by the kernel-level
|
||||||
* users of XPC.
|
* users of XPC.
|
||||||
|
@@ -120,6 +120,38 @@ xp_cpu_to_nasid_sn2(int cpuid)
|
|||||||
return cpuid_to_nasid(cpuid);
|
return cpuid_to_nasid(cpuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum xp_retval
|
||||||
|
xp_expand_memprotect_sn2(unsigned long phys_addr, unsigned long size)
|
||||||
|
{
|
||||||
|
u64 nasid_array = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_1,
|
||||||
|
&nasid_array);
|
||||||
|
if (ret != 0) {
|
||||||
|
dev_err(xp, "sn_change_memprotect(,, "
|
||||||
|
"SN_MEMPROT_ACCESS_CLASS_1,) failed ret=%d\n", ret);
|
||||||
|
return xpSalError;
|
||||||
|
}
|
||||||
|
return xpSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum xp_retval
|
||||||
|
xp_restrict_memprotect_sn2(unsigned long phys_addr, unsigned long size)
|
||||||
|
{
|
||||||
|
u64 nasid_array = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_0,
|
||||||
|
&nasid_array);
|
||||||
|
if (ret != 0) {
|
||||||
|
dev_err(xp, "sn_change_memprotect(,, "
|
||||||
|
"SN_MEMPROT_ACCESS_CLASS_0,) failed ret=%d\n", ret);
|
||||||
|
return xpSalError;
|
||||||
|
}
|
||||||
|
return xpSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
enum xp_retval
|
enum xp_retval
|
||||||
xp_init_sn2(void)
|
xp_init_sn2(void)
|
||||||
{
|
{
|
||||||
@@ -132,6 +164,8 @@ xp_init_sn2(void)
|
|||||||
xp_pa = xp_pa_sn2;
|
xp_pa = xp_pa_sn2;
|
||||||
xp_remote_memcpy = xp_remote_memcpy_sn2;
|
xp_remote_memcpy = xp_remote_memcpy_sn2;
|
||||||
xp_cpu_to_nasid = xp_cpu_to_nasid_sn2;
|
xp_cpu_to_nasid = xp_cpu_to_nasid_sn2;
|
||||||
|
xp_expand_memprotect = xp_expand_memprotect_sn2;
|
||||||
|
xp_restrict_memprotect = xp_restrict_memprotect_sn2;
|
||||||
|
|
||||||
return xp_register_nofault_code_sn2();
|
return xp_register_nofault_code_sn2();
|
||||||
}
|
}
|
||||||
|
@@ -15,6 +15,11 @@
|
|||||||
|
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <asm/uv/uv_hub.h>
|
#include <asm/uv/uv_hub.h>
|
||||||
|
#if defined CONFIG_X86_64
|
||||||
|
#include <asm/uv/bios.h>
|
||||||
|
#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
|
||||||
|
#include <asm/sn/sn_sal.h>
|
||||||
|
#endif
|
||||||
#include "../sgi-gru/grukservices.h"
|
#include "../sgi-gru/grukservices.h"
|
||||||
#include "xp.h"
|
#include "xp.h"
|
||||||
|
|
||||||
@@ -49,6 +54,65 @@ xp_cpu_to_nasid_uv(int cpuid)
|
|||||||
return UV_PNODE_TO_NASID(uv_cpu_to_pnode(cpuid));
|
return UV_PNODE_TO_NASID(uv_cpu_to_pnode(cpuid));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum xp_retval
|
||||||
|
xp_expand_memprotect_uv(unsigned long phys_addr, unsigned long size)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
#if defined CONFIG_X86_64
|
||||||
|
ret = uv_bios_change_memprotect(phys_addr, size, UV_MEMPROT_ALLOW_RW);
|
||||||
|
if (ret != BIOS_STATUS_SUCCESS) {
|
||||||
|
dev_err(xp, "uv_bios_change_memprotect(,, "
|
||||||
|
"UV_MEMPROT_ALLOW_RW) failed, ret=%d\n", ret);
|
||||||
|
return xpBiosError;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
|
||||||
|
u64 nasid_array;
|
||||||
|
|
||||||
|
ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_1,
|
||||||
|
&nasid_array);
|
||||||
|
if (ret != 0) {
|
||||||
|
dev_err(xp, "sn_change_memprotect(,, "
|
||||||
|
"SN_MEMPROT_ACCESS_CLASS_1,) failed ret=%d\n", ret);
|
||||||
|
return xpSalError;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#error not a supported configuration
|
||||||
|
#endif
|
||||||
|
return xpSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum xp_retval
|
||||||
|
xp_restrict_memprotect_uv(unsigned long phys_addr, unsigned long size)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
#if defined CONFIG_X86_64
|
||||||
|
ret = uv_bios_change_memprotect(phys_addr, size,
|
||||||
|
UV_MEMPROT_RESTRICT_ACCESS);
|
||||||
|
if (ret != BIOS_STATUS_SUCCESS) {
|
||||||
|
dev_err(xp, "uv_bios_change_memprotect(,, "
|
||||||
|
"UV_MEMPROT_RESTRICT_ACCESS) failed, ret=%d\n", ret);
|
||||||
|
return xpBiosError;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
|
||||||
|
u64 nasid_array;
|
||||||
|
|
||||||
|
ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_0,
|
||||||
|
&nasid_array);
|
||||||
|
if (ret != 0) {
|
||||||
|
dev_err(xp, "sn_change_memprotect(,, "
|
||||||
|
"SN_MEMPROT_ACCESS_CLASS_0,) failed ret=%d\n", ret);
|
||||||
|
return xpSalError;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#error not a supported configuration
|
||||||
|
#endif
|
||||||
|
return xpSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
enum xp_retval
|
enum xp_retval
|
||||||
xp_init_uv(void)
|
xp_init_uv(void)
|
||||||
{
|
{
|
||||||
@@ -61,6 +125,8 @@ xp_init_uv(void)
|
|||||||
xp_pa = xp_pa_uv;
|
xp_pa = xp_pa_uv;
|
||||||
xp_remote_memcpy = xp_remote_memcpy_uv;
|
xp_remote_memcpy = xp_remote_memcpy_uv;
|
||||||
xp_cpu_to_nasid = xp_cpu_to_nasid_uv;
|
xp_cpu_to_nasid = xp_cpu_to_nasid_uv;
|
||||||
|
xp_expand_memprotect = xp_expand_memprotect_uv;
|
||||||
|
xp_restrict_memprotect = xp_restrict_memprotect_uv;
|
||||||
|
|
||||||
return xpSuccess;
|
return xpSuccess;
|
||||||
}
|
}
|
||||||
|
@@ -553,22 +553,17 @@ static u64 xpc_prot_vec_sn2[MAX_NUMNODES];
|
|||||||
static enum xp_retval
|
static enum xp_retval
|
||||||
xpc_allow_amo_ops_sn2(struct amo *amos_page)
|
xpc_allow_amo_ops_sn2(struct amo *amos_page)
|
||||||
{
|
{
|
||||||
u64 nasid_array = 0;
|
enum xp_retval ret = xpSuccess;
|
||||||
int ret;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* On SHUB 1.1, we cannot call sn_change_memprotect() since the BIST
|
* On SHUB 1.1, we cannot call sn_change_memprotect() since the BIST
|
||||||
* collides with memory operations. On those systems we call
|
* collides with memory operations. On those systems we call
|
||||||
* xpc_allow_amo_ops_shub_wars_1_1_sn2() instead.
|
* xpc_allow_amo_ops_shub_wars_1_1_sn2() instead.
|
||||||
*/
|
*/
|
||||||
if (!enable_shub_wars_1_1()) {
|
if (!enable_shub_wars_1_1())
|
||||||
ret = sn_change_memprotect(ia64_tpa((u64)amos_page), PAGE_SIZE,
|
ret = xp_expand_memprotect(ia64_tpa((u64)amos_page), PAGE_SIZE);
|
||||||
SN_MEMPROT_ACCESS_CLASS_1,
|
|
||||||
&nasid_array);
|
return ret;
|
||||||
if (ret != 0)
|
|
||||||
return xpSalError;
|
|
||||||
}
|
|
||||||
return xpSuccess;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user