Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/misc/sgi-xp/xp_uv.c
15111 views
1
/*
2
* This file is subject to the terms and conditions of the GNU General Public
3
* License. See the file "COPYING" in the main directory of this archive
4
* for more details.
5
*
6
* Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
7
*/
8
9
/*
10
* Cross Partition (XP) uv-based functions.
11
*
12
* Architecture specific implementation of common functions.
13
*
14
*/
15
16
#include <linux/device.h>
17
#include <asm/uv/uv_hub.h>
18
#if defined CONFIG_X86_64
19
#include <asm/uv/bios.h>
20
#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
21
#include <asm/sn/sn_sal.h>
22
#endif
23
#include "../sgi-gru/grukservices.h"
24
#include "xp.h"
25
26
/*
27
* Convert a virtual memory address to a physical memory address.
28
*/
29
static unsigned long
30
xp_pa_uv(void *addr)
31
{
32
return uv_gpa(addr);
33
}
34
35
/*
36
* Convert a global physical to socket physical address.
37
*/
38
static unsigned long
39
xp_socket_pa_uv(unsigned long gpa)
40
{
41
return uv_gpa_to_soc_phys_ram(gpa);
42
}
43
44
static enum xp_retval
45
xp_remote_mmr_read(unsigned long dst_gpa, const unsigned long src_gpa,
46
size_t len)
47
{
48
int ret;
49
unsigned long *dst_va = __va(uv_gpa_to_soc_phys_ram(dst_gpa));
50
51
BUG_ON(!uv_gpa_in_mmr_space(src_gpa));
52
BUG_ON(len != 8);
53
54
ret = gru_read_gpa(dst_va, src_gpa);
55
if (ret == 0)
56
return xpSuccess;
57
58
dev_err(xp, "gru_read_gpa() failed, dst_gpa=0x%016lx src_gpa=0x%016lx "
59
"len=%ld\n", dst_gpa, src_gpa, len);
60
return xpGruCopyError;
61
}
62
63
64
static enum xp_retval
65
xp_remote_memcpy_uv(unsigned long dst_gpa, const unsigned long src_gpa,
66
size_t len)
67
{
68
int ret;
69
70
if (uv_gpa_in_mmr_space(src_gpa))
71
return xp_remote_mmr_read(dst_gpa, src_gpa, len);
72
73
ret = gru_copy_gpa(dst_gpa, src_gpa, len);
74
if (ret == 0)
75
return xpSuccess;
76
77
dev_err(xp, "gru_copy_gpa() failed, dst_gpa=0x%016lx src_gpa=0x%016lx "
78
"len=%ld\n", dst_gpa, src_gpa, len);
79
return xpGruCopyError;
80
}
81
82
static int
83
xp_cpu_to_nasid_uv(int cpuid)
84
{
85
/* ??? Is this same as sn2 nasid in mach/part bitmaps set up by SAL? */
86
return UV_PNODE_TO_NASID(uv_cpu_to_pnode(cpuid));
87
}
88
89
static enum xp_retval
90
xp_expand_memprotect_uv(unsigned long phys_addr, unsigned long size)
91
{
92
int ret;
93
94
#if defined CONFIG_X86_64
95
ret = uv_bios_change_memprotect(phys_addr, size, UV_MEMPROT_ALLOW_RW);
96
if (ret != BIOS_STATUS_SUCCESS) {
97
dev_err(xp, "uv_bios_change_memprotect(,, "
98
"UV_MEMPROT_ALLOW_RW) failed, ret=%d\n", ret);
99
return xpBiosError;
100
}
101
102
#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
103
u64 nasid_array;
104
105
ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_1,
106
&nasid_array);
107
if (ret != 0) {
108
dev_err(xp, "sn_change_memprotect(,, "
109
"SN_MEMPROT_ACCESS_CLASS_1,) failed ret=%d\n", ret);
110
return xpSalError;
111
}
112
#else
113
#error not a supported configuration
114
#endif
115
return xpSuccess;
116
}
117
118
static enum xp_retval
119
xp_restrict_memprotect_uv(unsigned long phys_addr, unsigned long size)
120
{
121
int ret;
122
123
#if defined CONFIG_X86_64
124
ret = uv_bios_change_memprotect(phys_addr, size,
125
UV_MEMPROT_RESTRICT_ACCESS);
126
if (ret != BIOS_STATUS_SUCCESS) {
127
dev_err(xp, "uv_bios_change_memprotect(,, "
128
"UV_MEMPROT_RESTRICT_ACCESS) failed, ret=%d\n", ret);
129
return xpBiosError;
130
}
131
132
#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
133
u64 nasid_array;
134
135
ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_0,
136
&nasid_array);
137
if (ret != 0) {
138
dev_err(xp, "sn_change_memprotect(,, "
139
"SN_MEMPROT_ACCESS_CLASS_0,) failed ret=%d\n", ret);
140
return xpSalError;
141
}
142
#else
143
#error not a supported configuration
144
#endif
145
return xpSuccess;
146
}
147
148
enum xp_retval
149
xp_init_uv(void)
150
{
151
BUG_ON(!is_uv());
152
153
xp_max_npartitions = XP_MAX_NPARTITIONS_UV;
154
xp_partition_id = sn_partition_id;
155
xp_region_size = sn_region_size;
156
157
xp_pa = xp_pa_uv;
158
xp_socket_pa = xp_socket_pa_uv;
159
xp_remote_memcpy = xp_remote_memcpy_uv;
160
xp_cpu_to_nasid = xp_cpu_to_nasid_uv;
161
xp_expand_memprotect = xp_expand_memprotect_uv;
162
xp_restrict_memprotect = xp_restrict_memprotect_uv;
163
164
return xpSuccess;
165
}
166
167
void
168
xp_exit_uv(void)
169
{
170
BUG_ON(!is_uv());
171
}
172
173