aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/cxl/fault.c
diff options
context:
space:
mode:
authorChristophe Lombard <clombard@linux.vnet.ibm.com>2017-06-22 09:07:27 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2017-07-03 09:07:03 -0400
commit3ced8d73006321bd2a0412fa0ff4b065a02e7514 (patch)
treeeb6c13f48f53960574756c5fc7edfe0519f9e443 /drivers/misc/cxl/fault.c
parent218ea31039e84901b449c3769035456688f6e17d (diff)
cxl: Export library to support IBM XSL
This patch exports a in-kernel 'library' API which can be called by other drivers to help interacting with an IBM XSL on a POWER9 system. The XSL (Translation Service Layer) is a stripped down version of the PSL (Power Service Layer) used in some cards such as the Mellanox CX5. Like the PSL, it implements the CAIA architecture, but has a number of differences, mostly in it's implementation dependent registers. The XSL also uses a special DMA cxl mode, which uses a slightly different init sequence for the CAPP and PHB. Signed-off-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com> Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com> Acked-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'drivers/misc/cxl/fault.c')
-rw-r--r--drivers/misc/cxl/fault.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/drivers/misc/cxl/fault.c b/drivers/misc/cxl/fault.c
index c79e39bad7a4..6eed7d03e2b5 100644
--- a/drivers/misc/cxl/fault.c
+++ b/drivers/misc/cxl/fault.c
@@ -132,18 +132,15 @@ static int cxl_handle_segment_miss(struct cxl_context *ctx,
132 return IRQ_HANDLED; 132 return IRQ_HANDLED;
133} 133}
134 134
135static void cxl_handle_page_fault(struct cxl_context *ctx, 135int cxl_handle_mm_fault(struct mm_struct *mm, u64 dsisr, u64 dar)
136 struct mm_struct *mm, u64 dsisr, u64 dar)
137{ 136{
138 unsigned flt = 0; 137 unsigned flt = 0;
139 int result; 138 int result;
140 unsigned long access, flags, inv_flags = 0; 139 unsigned long access, flags, inv_flags = 0;
141 140
142 trace_cxl_pte_miss(ctx, dsisr, dar);
143
144 if ((result = copro_handle_mm_fault(mm, dar, dsisr, &flt))) { 141 if ((result = copro_handle_mm_fault(mm, dar, dsisr, &flt))) {
145 pr_devel("copro_handle_mm_fault failed: %#x\n", result); 142 pr_devel("copro_handle_mm_fault failed: %#x\n", result);
146 return cxl_ack_ae(ctx); 143 return result;
147 } 144 }
148 145
149 if (!radix_enabled()) { 146 if (!radix_enabled()) {
@@ -155,9 +152,8 @@ static void cxl_handle_page_fault(struct cxl_context *ctx,
155 if (dsisr & CXL_PSL_DSISR_An_S) 152 if (dsisr & CXL_PSL_DSISR_An_S)
156 access |= _PAGE_WRITE; 153 access |= _PAGE_WRITE;
157 154
158 access |= _PAGE_PRIVILEGED; 155 if (!mm && (REGION_ID(dar) != USER_REGION_ID))
159 if ((!ctx->kernel) || (REGION_ID(dar) == USER_REGION_ID)) 156 access |= _PAGE_PRIVILEGED;
160 access &= ~_PAGE_PRIVILEGED;
161 157
162 if (dsisr & DSISR_NOHPTE) 158 if (dsisr & DSISR_NOHPTE)
163 inv_flags |= HPTE_NOHPTE_UPDATE; 159 inv_flags |= HPTE_NOHPTE_UPDATE;
@@ -166,8 +162,21 @@ static void cxl_handle_page_fault(struct cxl_context *ctx,
166 hash_page_mm(mm, dar, access, 0x300, inv_flags); 162 hash_page_mm(mm, dar, access, 0x300, inv_flags);
167 local_irq_restore(flags); 163 local_irq_restore(flags);
168 } 164 }
169 pr_devel("Page fault successfully handled for pe: %i!\n", ctx->pe); 165 return 0;
170 cxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_R, 0); 166}
167
168static void cxl_handle_page_fault(struct cxl_context *ctx,
169 struct mm_struct *mm,
170 u64 dsisr, u64 dar)
171{
172 trace_cxl_pte_miss(ctx, dsisr, dar);
173
174 if (cxl_handle_mm_fault(mm, dsisr, dar)) {
175 cxl_ack_ae(ctx);
176 } else {
177 pr_devel("Page fault successfully handled for pe: %i!\n", ctx->pe);
178 cxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_R, 0);
179 }
171} 180}
172 181
173/* 182/*