aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristophe Lombard <clombard@linux.vnet.ibm.com>2016-03-04 06:26:41 -0500
committerMichael Ellerman <mpe@ellerman.id.au>2016-03-09 07:40:00 -0500
commit0d400f77c19e8d2606f8194846bcf18ebdc9df2a (patch)
tree307436d00d93f55e2aa27d2233c91346c14e8961
parentd601ea918b878582e60b773f2f943d8d292b2abf (diff)
cxl: Adapter failure handling
Check the AFU state whenever an API is called. The hypervisor may issue a reset of the adapter when it detects a fault. When it happens, it launches an error recovery which will either move the AFU to a permanent failure state, or in the disabled state. If the AFU is found to be disabled, detach all existing contexts from it before issuing a AFU reset to re-enable it. Before detaching contexts, notify any kernel driver through the EEH callbacks of the AFU pci device. Co-authored-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com> Signed-off-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com> Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com> Reviewed-by: Manoj Kumar <manoj@linux.vnet.ibm.com> Acked-by: Ian Munsie <imunsie@au1.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r--drivers/misc/cxl/context.c2
-rw-r--r--drivers/misc/cxl/cxl.h18
-rw-r--r--drivers/misc/cxl/file.c10
-rw-r--r--drivers/misc/cxl/guest.c167
-rw-r--r--drivers/misc/cxl/main.c2
-rw-r--r--drivers/misc/cxl/native.c32
-rw-r--r--drivers/misc/cxl/vphb.c2
7 files changed, 198 insertions, 35 deletions
diff --git a/drivers/misc/cxl/context.c b/drivers/misc/cxl/context.c
index 180c85a32825..10370f280500 100644
--- a/drivers/misc/cxl/context.c
+++ b/drivers/misc/cxl/context.c
@@ -220,7 +220,7 @@ int __detach_context(struct cxl_context *ctx)
220 * If detach fails when hw is down, we don't care. 220 * If detach fails when hw is down, we don't care.
221 */ 221 */
222 WARN_ON(cxl_ops->detach_process(ctx) && 222 WARN_ON(cxl_ops->detach_process(ctx) &&
223 cxl_ops->link_ok(ctx->afu->adapter)); 223 cxl_ops->link_ok(ctx->afu->adapter, ctx->afu));
224 flush_work(&ctx->fault_work); /* Only needed for dedicated process */ 224 flush_work(&ctx->fault_work); /* Only needed for dedicated process */
225 225
226 /* release the reference to the group leader and mm handling pid */ 226 /* release the reference to the group leader and mm handling pid */
diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
index b388c971810f..e345860c25eb 100644
--- a/drivers/misc/cxl/cxl.h
+++ b/drivers/misc/cxl/cxl.h
@@ -379,6 +379,8 @@ struct cxl_afu_guest {
379 phys_addr_t p2n_phys; 379 phys_addr_t p2n_phys;
380 u64 p2n_size; 380 u64 p2n_size;
381 int max_ints; 381 int max_ints;
382 struct mutex recovery_lock;
383 int previous_state;
382}; 384};
383 385
384struct cxl_afu { 386struct cxl_afu {
@@ -617,7 +619,7 @@ struct cxl_process_element {
617 __be32 software_state; 619 __be32 software_state;
618} __packed; 620} __packed;
619 621
620static inline bool cxl_adapter_link_ok(struct cxl *cxl) 622static inline bool cxl_adapter_link_ok(struct cxl *cxl, struct cxl_afu *afu)
621{ 623{
622 struct pci_dev *pdev; 624 struct pci_dev *pdev;
623 625
@@ -636,13 +638,13 @@ static inline void __iomem *_cxl_p1_addr(struct cxl *cxl, cxl_p1_reg_t reg)
636 638
637static inline void cxl_p1_write(struct cxl *cxl, cxl_p1_reg_t reg, u64 val) 639static inline void cxl_p1_write(struct cxl *cxl, cxl_p1_reg_t reg, u64 val)
638{ 640{
639 if (likely(cxl_adapter_link_ok(cxl))) 641 if (likely(cxl_adapter_link_ok(cxl, NULL)))
640 out_be64(_cxl_p1_addr(cxl, reg), val); 642 out_be64(_cxl_p1_addr(cxl, reg), val);
641} 643}
642 644
643static inline u64 cxl_p1_read(struct cxl *cxl, cxl_p1_reg_t reg) 645static inline u64 cxl_p1_read(struct cxl *cxl, cxl_p1_reg_t reg)
644{ 646{
645 if (likely(cxl_adapter_link_ok(cxl))) 647 if (likely(cxl_adapter_link_ok(cxl, NULL)))
646 return in_be64(_cxl_p1_addr(cxl, reg)); 648 return in_be64(_cxl_p1_addr(cxl, reg));
647 else 649 else
648 return ~0ULL; 650 return ~0ULL;
@@ -656,13 +658,13 @@ static inline void __iomem *_cxl_p1n_addr(struct cxl_afu *afu, cxl_p1n_reg_t reg
656 658
657static inline void cxl_p1n_write(struct cxl_afu *afu, cxl_p1n_reg_t reg, u64 val) 659static inline void cxl_p1n_write(struct cxl_afu *afu, cxl_p1n_reg_t reg, u64 val)
658{ 660{
659 if (likely(cxl_adapter_link_ok(afu->adapter))) 661 if (likely(cxl_adapter_link_ok(afu->adapter, afu)))
660 out_be64(_cxl_p1n_addr(afu, reg), val); 662 out_be64(_cxl_p1n_addr(afu, reg), val);
661} 663}
662 664
663static inline u64 cxl_p1n_read(struct cxl_afu *afu, cxl_p1n_reg_t reg) 665static inline u64 cxl_p1n_read(struct cxl_afu *afu, cxl_p1n_reg_t reg)
664{ 666{
665 if (likely(cxl_adapter_link_ok(afu->adapter))) 667 if (likely(cxl_adapter_link_ok(afu->adapter, afu)))
666 return in_be64(_cxl_p1n_addr(afu, reg)); 668 return in_be64(_cxl_p1n_addr(afu, reg));
667 else 669 else
668 return ~0ULL; 670 return ~0ULL;
@@ -675,13 +677,13 @@ static inline void __iomem *_cxl_p2n_addr(struct cxl_afu *afu, cxl_p2n_reg_t reg
675 677
676static inline void cxl_p2n_write(struct cxl_afu *afu, cxl_p2n_reg_t reg, u64 val) 678static inline void cxl_p2n_write(struct cxl_afu *afu, cxl_p2n_reg_t reg, u64 val)
677{ 679{
678 if (likely(cxl_adapter_link_ok(afu->adapter))) 680 if (likely(cxl_adapter_link_ok(afu->adapter, afu)))
679 out_be64(_cxl_p2n_addr(afu, reg), val); 681 out_be64(_cxl_p2n_addr(afu, reg), val);
680} 682}
681 683
682static inline u64 cxl_p2n_read(struct cxl_afu *afu, cxl_p2n_reg_t reg) 684static inline u64 cxl_p2n_read(struct cxl_afu *afu, cxl_p2n_reg_t reg)
683{ 685{
684 if (likely(cxl_adapter_link_ok(afu->adapter))) 686 if (likely(cxl_adapter_link_ok(afu->adapter, afu)))
685 return in_be64(_cxl_p2n_addr(afu, reg)); 687 return in_be64(_cxl_p2n_addr(afu, reg));
686 else 688 else
687 return ~0ULL; 689 return ~0ULL;
@@ -857,7 +859,7 @@ struct cxl_backend_ops {
857 u64 wed, u64 amr); 859 u64 wed, u64 amr);
858 int (*detach_process)(struct cxl_context *ctx); 860 int (*detach_process)(struct cxl_context *ctx);
859 bool (*support_attributes)(const char *attr_name, enum cxl_attrs type); 861 bool (*support_attributes)(const char *attr_name, enum cxl_attrs type);
860 bool (*link_ok)(struct cxl *cxl); 862 bool (*link_ok)(struct cxl *cxl, struct cxl_afu *afu);
861 void (*release_afu)(struct device *dev); 863 void (*release_afu)(struct device *dev);
862 ssize_t (*afu_read_err_buffer)(struct cxl_afu *afu, char *buf, 864 ssize_t (*afu_read_err_buffer)(struct cxl_afu *afu, char *buf,
863 loff_t off, size_t count); 865 loff_t off, size_t count);
diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c
index e16046292dd6..eec468f1612f 100644
--- a/drivers/misc/cxl/file.c
+++ b/drivers/misc/cxl/file.c
@@ -76,7 +76,7 @@ static int __afu_open(struct inode *inode, struct file *file, bool master)
76 if (!afu->current_mode) 76 if (!afu->current_mode)
77 goto err_put_afu; 77 goto err_put_afu;
78 78
79 if (!cxl_ops->link_ok(adapter)) { 79 if (!cxl_ops->link_ok(adapter, afu)) {
80 rc = -EIO; 80 rc = -EIO;
81 goto err_put_afu; 81 goto err_put_afu;
82 } 82 }
@@ -257,7 +257,7 @@ long afu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
257 if (ctx->status == CLOSED) 257 if (ctx->status == CLOSED)
258 return -EIO; 258 return -EIO;
259 259
260 if (!cxl_ops->link_ok(ctx->afu->adapter)) 260 if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu))
261 return -EIO; 261 return -EIO;
262 262
263 pr_devel("afu_ioctl\n"); 263 pr_devel("afu_ioctl\n");
@@ -287,7 +287,7 @@ int afu_mmap(struct file *file, struct vm_area_struct *vm)
287 if (ctx->status != STARTED) 287 if (ctx->status != STARTED)
288 return -EIO; 288 return -EIO;
289 289
290 if (!cxl_ops->link_ok(ctx->afu->adapter)) 290 if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu))
291 return -EIO; 291 return -EIO;
292 292
293 return cxl_context_iomap(ctx, vm); 293 return cxl_context_iomap(ctx, vm);
@@ -334,7 +334,7 @@ ssize_t afu_read(struct file *file, char __user *buf, size_t count,
334 int rc; 334 int rc;
335 DEFINE_WAIT(wait); 335 DEFINE_WAIT(wait);
336 336
337 if (!cxl_ops->link_ok(ctx->afu->adapter)) 337 if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu))
338 return -EIO; 338 return -EIO;
339 339
340 if (count < CXL_READ_MIN_SIZE) 340 if (count < CXL_READ_MIN_SIZE)
@@ -347,7 +347,7 @@ ssize_t afu_read(struct file *file, char __user *buf, size_t count,
347 if (ctx_event_pending(ctx)) 347 if (ctx_event_pending(ctx))
348 break; 348 break;
349 349
350 if (!cxl_ops->link_ok(ctx->afu->adapter)) { 350 if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu)) {
351 rc = -EIO; 351 rc = -EIO;
352 goto out; 352 goto out;
353 } 353 }
diff --git a/drivers/misc/cxl/guest.c b/drivers/misc/cxl/guest.c
index 2b07ebd2b429..8213372de2b7 100644
--- a/drivers/misc/cxl/guest.c
+++ b/drivers/misc/cxl/guest.c
@@ -15,6 +15,46 @@
15#include "hcalls.h" 15#include "hcalls.h"
16#include "trace.h" 16#include "trace.h"
17 17
18#define CXL_ERROR_DETECTED_EVENT 1
19#define CXL_SLOT_RESET_EVENT 2
20#define CXL_RESUME_EVENT 3
21
22static void pci_error_handlers(struct cxl_afu *afu,
23 int bus_error_event,
24 pci_channel_state_t state)
25{
26 struct pci_dev *afu_dev;
27
28 if (afu->phb == NULL)
29 return;
30
31 list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) {
32 if (!afu_dev->driver)
33 continue;
34
35 switch (bus_error_event) {
36 case CXL_ERROR_DETECTED_EVENT:
37 afu_dev->error_state = state;
38
39 if (afu_dev->driver->err_handler &&
40 afu_dev->driver->err_handler->error_detected)
41 afu_dev->driver->err_handler->error_detected(afu_dev, state);
42 break;
43 case CXL_SLOT_RESET_EVENT:
44 afu_dev->error_state = state;
45
46 if (afu_dev->driver->err_handler &&
47 afu_dev->driver->err_handler->slot_reset)
48 afu_dev->driver->err_handler->slot_reset(afu_dev);
49 break;
50 case CXL_RESUME_EVENT:
51 if (afu_dev->driver->err_handler &&
52 afu_dev->driver->err_handler->resume)
53 afu_dev->driver->err_handler->resume(afu_dev);
54 break;
55 }
56 }
57}
18 58
19static irqreturn_t guest_handle_psl_slice_error(struct cxl_context *ctx, u64 dsisr, 59static irqreturn_t guest_handle_psl_slice_error(struct cxl_context *ctx, u64 dsisr,
20 u64 errstat) 60 u64 errstat)
@@ -133,6 +173,22 @@ static irqreturn_t guest_psl_irq(int irq, void *data)
133 return rc; 173 return rc;
134} 174}
135 175
176static int afu_read_error_state(struct cxl_afu *afu, int *state_out)
177{
178 u64 state;
179 int rc = 0;
180
181 rc = cxl_h_read_error_state(afu->guest->handle, &state);
182 if (!rc) {
183 WARN_ON(state != H_STATE_NORMAL &&
184 state != H_STATE_DISABLE &&
185 state != H_STATE_TEMP_UNAVAILABLE &&
186 state != H_STATE_PERM_UNAVAILABLE);
187 *state_out = state & 0xffffffff;
188 }
189 return rc;
190}
191
136static irqreturn_t guest_slice_irq_err(int irq, void *data) 192static irqreturn_t guest_slice_irq_err(int irq, void *data)
137{ 193{
138 struct cxl_afu *afu = data; 194 struct cxl_afu *afu = data;
@@ -201,10 +257,26 @@ static int irq_free_range(struct cxl *adapter, int irq, int len)
201 257
202static int guest_reset(struct cxl *adapter) 258static int guest_reset(struct cxl *adapter)
203{ 259{
204 int rc; 260 struct cxl_afu *afu = NULL;
261 int i, rc;
205 262
206 pr_devel("Adapter reset request\n"); 263 pr_devel("Adapter reset request\n");
264 for (i = 0; i < adapter->slices; i++) {
265 if ((afu = adapter->afu[i])) {
266 pci_error_handlers(afu, CXL_ERROR_DETECTED_EVENT,
267 pci_channel_io_frozen);
268 cxl_context_detach_all(afu);
269 }
270 }
271
207 rc = cxl_h_reset_adapter(adapter->guest->handle); 272 rc = cxl_h_reset_adapter(adapter->guest->handle);
273 for (i = 0; i < adapter->slices; i++) {
274 if (!rc && (afu = adapter->afu[i])) {
275 pci_error_handlers(afu, CXL_SLOT_RESET_EVENT,
276 pci_channel_io_normal);
277 pci_error_handlers(afu, CXL_RESUME_EVENT, 0);
278 }
279 }
208 return rc; 280 return rc;
209} 281}
210 282
@@ -556,7 +628,7 @@ static int guest_detach_process(struct cxl_context *ctx)
556 pr_devel("in %s\n", __func__); 628 pr_devel("in %s\n", __func__);
557 trace_cxl_detach(ctx); 629 trace_cxl_detach(ctx);
558 630
559 if (!cxl_ops->link_ok(ctx->afu->adapter)) 631 if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu))
560 return -EIO; 632 return -EIO;
561 633
562 if (ctx->afu->current_mode == CXL_MODE_DIRECTED) 634 if (ctx->afu->current_mode == CXL_MODE_DIRECTED)
@@ -730,8 +802,95 @@ static void guest_unmap_slice_regs(struct cxl_afu *afu)
730 iounmap(afu->p2n_mmio); 802 iounmap(afu->p2n_mmio);
731} 803}
732 804
733static bool guest_link_ok(struct cxl *cxl) 805static int afu_update_state(struct cxl_afu *afu)
734{ 806{
807 int rc, cur_state;
808
809 rc = afu_read_error_state(afu, &cur_state);
810 if (rc)
811 return rc;
812
813 if (afu->guest->previous_state == cur_state)
814 return 0;
815
816 pr_devel("AFU(%d) update state to %#x\n", afu->slice, cur_state);
817
818 switch (cur_state) {
819 case H_STATE_NORMAL:
820 afu->guest->previous_state = cur_state;
821 rc = 1;
822 break;
823
824 case H_STATE_DISABLE:
825 pci_error_handlers(afu, CXL_ERROR_DETECTED_EVENT,
826 pci_channel_io_frozen);
827
828 cxl_context_detach_all(afu);
829 if ((rc = cxl_ops->afu_reset(afu)))
830 pr_devel("reset hcall failed %d\n", rc);
831
832 rc = afu_read_error_state(afu, &cur_state);
833 if (!rc && cur_state == H_STATE_NORMAL) {
834 pci_error_handlers(afu, CXL_SLOT_RESET_EVENT,
835 pci_channel_io_normal);
836 pci_error_handlers(afu, CXL_RESUME_EVENT, 0);
837 rc = 1;
838 }
839 afu->guest->previous_state = 0;
840 break;
841
842 case H_STATE_TEMP_UNAVAILABLE:
843 afu->guest->previous_state = cur_state;
844 break;
845
846 case H_STATE_PERM_UNAVAILABLE:
847 dev_err(&afu->dev, "AFU is in permanent error state\n");
848 pci_error_handlers(afu, CXL_ERROR_DETECTED_EVENT,
849 pci_channel_io_perm_failure);
850 afu->guest->previous_state = cur_state;
851 break;
852
853 default:
854 pr_err("Unexpected AFU(%d) error state: %#x\n",
855 afu->slice, cur_state);
856 return -EINVAL;
857 }
858
859 return rc;
860}
861
862static int afu_do_recovery(struct cxl_afu *afu)
863{
864 int rc;
865
866 /* many threads can arrive here, in case of detach_all for example.
867 * Only one needs to drive the recovery
868 */
869 if (mutex_trylock(&afu->guest->recovery_lock)) {
870 rc = afu_update_state(afu);
871 mutex_unlock(&afu->guest->recovery_lock);
872 return rc;
873 }
874 return 0;
875}
876
877static bool guest_link_ok(struct cxl *cxl, struct cxl_afu *afu)
878{
879 int state;
880
881 if (afu) {
882 if (afu_read_error_state(afu, &state) ||
883 state != H_STATE_NORMAL) {
884 if (afu_do_recovery(afu) > 0) {
885 /* check again in case we've just fixed it */
886 if (!afu_read_error_state(afu, &state) &&
887 state == H_STATE_NORMAL)
888 return true;
889 }
890 return false;
891 }
892 }
893
735 return true; 894 return true;
736} 895}
737 896
@@ -770,6 +929,8 @@ int cxl_guest_init_afu(struct cxl *adapter, int slice, struct device_node *afu_n
770 return -ENOMEM; 929 return -ENOMEM;
771 } 930 }
772 931
932 mutex_init(&afu->guest->recovery_lock);
933
773 if ((rc = dev_set_name(&afu->dev, "afu%i.%i", 934 if ((rc = dev_set_name(&afu->dev, "afu%i.%i",
774 adapter->adapter_num, 935 adapter->adapter_num,
775 slice))) 936 slice)))
diff --git a/drivers/misc/cxl/main.c b/drivers/misc/cxl/main.c
index 14b15835dc4a..ae68c3201156 100644
--- a/drivers/misc/cxl/main.c
+++ b/drivers/misc/cxl/main.c
@@ -48,7 +48,7 @@ int cxl_afu_slbia(struct cxl_afu *afu)
48 /* If the adapter has gone down, we can assume that we 48 /* If the adapter has gone down, we can assume that we
49 * will PERST it and that will invalidate everything. 49 * will PERST it and that will invalidate everything.
50 */ 50 */
51 if (!cxl_ops->link_ok(afu->adapter)) 51 if (!cxl_ops->link_ok(afu->adapter, afu))
52 return -EIO; 52 return -EIO;
53 cpu_relax(); 53 cpu_relax();
54 } 54 }
diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c
index e564ae657584..387fcbdf9793 100644
--- a/drivers/misc/cxl/native.c
+++ b/drivers/misc/cxl/native.c
@@ -42,7 +42,7 @@ static int afu_control(struct cxl_afu *afu, u64 command,
42 goto out; 42 goto out;
43 } 43 }
44 44
45 if (!cxl_ops->link_ok(afu->adapter)) { 45 if (!cxl_ops->link_ok(afu->adapter, afu)) {
46 afu->enabled = enabled; 46 afu->enabled = enabled;
47 rc = -EIO; 47 rc = -EIO;
48 goto out; 48 goto out;
@@ -92,7 +92,7 @@ static int native_afu_reset(struct cxl_afu *afu)
92 92
93static int native_afu_check_and_enable(struct cxl_afu *afu) 93static int native_afu_check_and_enable(struct cxl_afu *afu)
94{ 94{
95 if (!cxl_ops->link_ok(afu->adapter)) { 95 if (!cxl_ops->link_ok(afu->adapter, afu)) {
96 WARN(1, "Refusing to enable afu while link down!\n"); 96 WARN(1, "Refusing to enable afu while link down!\n");
97 return -EIO; 97 return -EIO;
98 } 98 }
@@ -114,7 +114,7 @@ int cxl_psl_purge(struct cxl_afu *afu)
114 114
115 pr_devel("PSL purge request\n"); 115 pr_devel("PSL purge request\n");
116 116
117 if (!cxl_ops->link_ok(afu->adapter)) { 117 if (!cxl_ops->link_ok(afu->adapter, afu)) {
118 dev_warn(&afu->dev, "PSL Purge called with link down, ignoring\n"); 118 dev_warn(&afu->dev, "PSL Purge called with link down, ignoring\n");
119 rc = -EIO; 119 rc = -EIO;
120 goto out; 120 goto out;
@@ -136,7 +136,7 @@ int cxl_psl_purge(struct cxl_afu *afu)
136 rc = -EBUSY; 136 rc = -EBUSY;
137 goto out; 137 goto out;
138 } 138 }
139 if (!cxl_ops->link_ok(afu->adapter)) { 139 if (!cxl_ops->link_ok(afu->adapter, afu)) {
140 rc = -EIO; 140 rc = -EIO;
141 goto out; 141 goto out;
142 } 142 }
@@ -250,7 +250,7 @@ int cxl_tlb_slb_invalidate(struct cxl *adapter)
250 dev_warn(&adapter->dev, "WARNING: CXL adapter wide TLBIA timed out!\n"); 250 dev_warn(&adapter->dev, "WARNING: CXL adapter wide TLBIA timed out!\n");
251 return -EBUSY; 251 return -EBUSY;
252 } 252 }
253 if (!cxl_ops->link_ok(adapter)) 253 if (!cxl_ops->link_ok(adapter, NULL))
254 return -EIO; 254 return -EIO;
255 cpu_relax(); 255 cpu_relax();
256 } 256 }
@@ -261,7 +261,7 @@ int cxl_tlb_slb_invalidate(struct cxl *adapter)
261 dev_warn(&adapter->dev, "WARNING: CXL adapter wide SLBIA timed out!\n"); 261 dev_warn(&adapter->dev, "WARNING: CXL adapter wide SLBIA timed out!\n");
262 return -EBUSY; 262 return -EBUSY;
263 } 263 }
264 if (!cxl_ops->link_ok(adapter)) 264 if (!cxl_ops->link_ok(adapter, NULL))
265 return -EIO; 265 return -EIO;
266 cpu_relax(); 266 cpu_relax();
267 } 267 }
@@ -302,7 +302,7 @@ static void slb_invalid(struct cxl_context *ctx)
302 cxl_p1_write(adapter, CXL_PSL_SLBIA, CXL_TLB_SLB_IQ_LPIDPID); 302 cxl_p1_write(adapter, CXL_PSL_SLBIA, CXL_TLB_SLB_IQ_LPIDPID);
303 303
304 while (1) { 304 while (1) {
305 if (!cxl_ops->link_ok(adapter)) 305 if (!cxl_ops->link_ok(adapter, NULL))
306 break; 306 break;
307 slbia = cxl_p1_read(adapter, CXL_PSL_SLBIA); 307 slbia = cxl_p1_read(adapter, CXL_PSL_SLBIA);
308 if (!(slbia & CXL_TLB_SLB_P)) 308 if (!(slbia & CXL_TLB_SLB_P))
@@ -333,7 +333,7 @@ static int do_process_element_cmd(struct cxl_context *ctx,
333 rc = -EBUSY; 333 rc = -EBUSY;
334 goto out; 334 goto out;
335 } 335 }
336 if (!cxl_ops->link_ok(ctx->afu->adapter)) { 336 if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu)) {
337 dev_warn(&ctx->afu->dev, "WARNING: Device link down, aborting Process Element Command!\n"); 337 dev_warn(&ctx->afu->dev, "WARNING: Device link down, aborting Process Element Command!\n");
338 rc = -EIO; 338 rc = -EIO;
339 goto out; 339 goto out;
@@ -389,7 +389,7 @@ static int terminate_process_element(struct cxl_context *ctx)
389 * should always succeed: it's not running if the hw has gone 389 * should always succeed: it's not running if the hw has gone
390 * away and is being reset. 390 * away and is being reset.
391 */ 391 */
392 if (cxl_ops->link_ok(ctx->afu->adapter)) 392 if (cxl_ops->link_ok(ctx->afu->adapter, ctx->afu))
393 rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_TERMINATE, 393 rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_TERMINATE,
394 CXL_PE_SOFTWARE_STATE_V | CXL_PE_SOFTWARE_STATE_T); 394 CXL_PE_SOFTWARE_STATE_V | CXL_PE_SOFTWARE_STATE_T);
395 ctx->elem->software_state = 0; /* Remove Valid bit */ 395 ctx->elem->software_state = 0; /* Remove Valid bit */
@@ -408,7 +408,7 @@ static int remove_process_element(struct cxl_context *ctx)
408 /* We could be asked to remove when the hw is down. Again, if 408 /* We could be asked to remove when the hw is down. Again, if
409 * the hw is down, the PE is gone, so we succeed. 409 * the hw is down, the PE is gone, so we succeed.
410 */ 410 */
411 if (cxl_ops->link_ok(ctx->afu->adapter)) 411 if (cxl_ops->link_ok(ctx->afu->adapter, ctx->afu))
412 rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_REMOVE, 0); 412 rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_REMOVE, 0);
413 413
414 if (!rc) 414 if (!rc)
@@ -650,7 +650,7 @@ static int native_afu_activate_mode(struct cxl_afu *afu, int mode)
650 if (!(mode & afu->modes_supported)) 650 if (!(mode & afu->modes_supported))
651 return -EINVAL; 651 return -EINVAL;
652 652
653 if (!cxl_ops->link_ok(afu->adapter)) { 653 if (!cxl_ops->link_ok(afu->adapter, afu)) {
654 WARN(1, "Device link is down, refusing to activate!\n"); 654 WARN(1, "Device link is down, refusing to activate!\n");
655 return -EIO; 655 return -EIO;
656 } 656 }
@@ -666,7 +666,7 @@ static int native_afu_activate_mode(struct cxl_afu *afu, int mode)
666static int native_attach_process(struct cxl_context *ctx, bool kernel, 666static int native_attach_process(struct cxl_context *ctx, bool kernel,
667 u64 wed, u64 amr) 667 u64 wed, u64 amr)
668{ 668{
669 if (!cxl_ops->link_ok(ctx->afu->adapter)) { 669 if (!cxl_ops->link_ok(ctx->afu->adapter, ctx->afu)) {
670 WARN(1, "Device link is down, refusing to attach process!\n"); 670 WARN(1, "Device link is down, refusing to attach process!\n");
671 return -EIO; 671 return -EIO;
672 } 672 }
@@ -718,7 +718,7 @@ static int native_get_irq_info(struct cxl_afu *afu, struct cxl_irq_info *info)
718 /* If the adapter has gone away, we can't get any meaningful 718 /* If the adapter has gone away, we can't get any meaningful
719 * information. 719 * information.
720 */ 720 */
721 if (!cxl_ops->link_ok(afu->adapter)) 721 if (!cxl_ops->link_ok(afu->adapter, afu))
722 return -EIO; 722 return -EIO;
723 723
724 info->dsisr = cxl_p2n_read(afu, CXL_PSL_DSISR_An); 724 info->dsisr = cxl_p2n_read(afu, CXL_PSL_DSISR_An);
@@ -975,7 +975,7 @@ static bool native_support_attributes(const char *attr_name,
975 975
976static int native_afu_cr_read64(struct cxl_afu *afu, int cr, u64 off, u64 *out) 976static int native_afu_cr_read64(struct cxl_afu *afu, int cr, u64 off, u64 *out)
977{ 977{
978 if (unlikely(!cxl_ops->link_ok(afu->adapter))) 978 if (unlikely(!cxl_ops->link_ok(afu->adapter, afu)))
979 return -EIO; 979 return -EIO;
980 if (unlikely(off >= afu->crs_len)) 980 if (unlikely(off >= afu->crs_len))
981 return -ERANGE; 981 return -ERANGE;
@@ -986,7 +986,7 @@ static int native_afu_cr_read64(struct cxl_afu *afu, int cr, u64 off, u64 *out)
986 986
987static int native_afu_cr_read32(struct cxl_afu *afu, int cr, u64 off, u32 *out) 987static int native_afu_cr_read32(struct cxl_afu *afu, int cr, u64 off, u32 *out)
988{ 988{
989 if (unlikely(!cxl_ops->link_ok(afu->adapter))) 989 if (unlikely(!cxl_ops->link_ok(afu->adapter, afu)))
990 return -EIO; 990 return -EIO;
991 if (unlikely(off >= afu->crs_len)) 991 if (unlikely(off >= afu->crs_len))
992 return -ERANGE; 992 return -ERANGE;
@@ -1021,7 +1021,7 @@ static int native_afu_cr_read8(struct cxl_afu *afu, int cr, u64 off, u8 *out)
1021 1021
1022static int native_afu_cr_write32(struct cxl_afu *afu, int cr, u64 off, u32 in) 1022static int native_afu_cr_write32(struct cxl_afu *afu, int cr, u64 off, u32 in)
1023{ 1023{
1024 if (unlikely(!cxl_ops->link_ok(afu->adapter))) 1024 if (unlikely(!cxl_ops->link_ok(afu->adapter, afu)))
1025 return -EIO; 1025 return -EIO;
1026 if (unlikely(off >= afu->crs_len)) 1026 if (unlikely(off >= afu->crs_len))
1027 return -ERANGE; 1027 return -ERANGE;
diff --git a/drivers/misc/cxl/vphb.c b/drivers/misc/cxl/vphb.c
index c960a09a4232..490b93486451 100644
--- a/drivers/misc/cxl/vphb.c
+++ b/drivers/misc/cxl/vphb.c
@@ -49,7 +49,7 @@ static bool cxl_pci_enable_device_hook(struct pci_dev *dev)
49 phb = pci_bus_to_host(dev->bus); 49 phb = pci_bus_to_host(dev->bus);
50 afu = (struct cxl_afu *)phb->private_data; 50 afu = (struct cxl_afu *)phb->private_data;
51 51
52 if (!cxl_ops->link_ok(afu->adapter)) { 52 if (!cxl_ops->link_ok(afu->adapter, afu)) {
53 dev_warn(&dev->dev, "%s: Device link is down, refusing to enable AFU\n", __func__); 53 dev_warn(&dev->dev, "%s: Device link is down, refusing to enable AFU\n", __func__);
54 return false; 54 return false;
55 } 55 }