diff options
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/cxl/fault.c | 74 | ||||
-rw-r--r-- | drivers/misc/cxl/native.c | 4 |
2 files changed, 41 insertions, 37 deletions
diff --git a/drivers/misc/cxl/fault.c b/drivers/misc/cxl/fault.c index 69506ebd4d07..c99e896604ee 100644 --- a/drivers/misc/cxl/fault.c +++ b/drivers/misc/cxl/fault.c | |||
@@ -21,60 +21,64 @@ | |||
21 | 21 | ||
22 | #include "cxl.h" | 22 | #include "cxl.h" |
23 | 23 | ||
24 | static struct cxl_sste* find_free_sste(struct cxl_sste *primary_group, | 24 | static bool sste_matches(struct cxl_sste *sste, struct copro_slb *slb) |
25 | bool sec_hash, | ||
26 | struct cxl_sste *secondary_group, | ||
27 | unsigned int *lru) | ||
28 | { | 25 | { |
29 | unsigned int i, entry; | 26 | return ((sste->vsid_data == cpu_to_be64(slb->vsid)) && |
30 | struct cxl_sste *sste, *group = primary_group; | 27 | (sste->esid_data == cpu_to_be64(slb->esid))); |
31 | 28 | } | |
32 | for (i = 0; i < 2; i++) { | 29 | |
33 | for (entry = 0; entry < 8; entry++) { | 30 | /* |
34 | sste = group + entry; | 31 | * This finds a free SSTE for the given SLB, or returns NULL if it's already in |
35 | if (!(be64_to_cpu(sste->esid_data) & SLB_ESID_V)) | 32 | * the segment table. |
36 | return sste; | 33 | */ |
37 | } | 34 | static struct cxl_sste* find_free_sste(struct cxl_context *ctx, |
38 | if (!sec_hash) | 35 | struct copro_slb *slb) |
39 | break; | 36 | { |
40 | group = secondary_group; | 37 | struct cxl_sste *primary, *sste, *ret = NULL; |
38 | unsigned int mask = (ctx->sst_size >> 7) - 1; /* SSTP0[SegTableSize] */ | ||
39 | unsigned int entry; | ||
40 | unsigned int hash; | ||
41 | |||
42 | if (slb->vsid & SLB_VSID_B_1T) | ||
43 | hash = (slb->esid >> SID_SHIFT_1T) & mask; | ||
44 | else /* 256M */ | ||
45 | hash = (slb->esid >> SID_SHIFT) & mask; | ||
46 | |||
47 | primary = ctx->sstp + (hash << 3); | ||
48 | |||
49 | for (entry = 0, sste = primary; entry < 8; entry++, sste++) { | ||
50 | if (!ret && !(be64_to_cpu(sste->esid_data) & SLB_ESID_V)) | ||
51 | ret = sste; | ||
52 | if (sste_matches(sste, slb)) | ||
53 | return NULL; | ||
41 | } | 54 | } |
55 | if (ret) | ||
56 | return ret; | ||
57 | |||
42 | /* Nothing free, select an entry to cast out */ | 58 | /* Nothing free, select an entry to cast out */ |
43 | if (sec_hash && (*lru & 0x8)) | 59 | ret = primary + ctx->sst_lru; |
44 | sste = secondary_group + (*lru & 0x7); | 60 | ctx->sst_lru = (ctx->sst_lru + 1) & 0x7; |
45 | else | ||
46 | sste = primary_group + (*lru & 0x7); | ||
47 | *lru = (*lru + 1) & 0xf; | ||
48 | 61 | ||
49 | return sste; | 62 | return ret; |
50 | } | 63 | } |
51 | 64 | ||
52 | static void cxl_load_segment(struct cxl_context *ctx, struct copro_slb *slb) | 65 | static void cxl_load_segment(struct cxl_context *ctx, struct copro_slb *slb) |
53 | { | 66 | { |
54 | /* mask is the group index, we search primary and secondary here. */ | 67 | /* mask is the group index, we search primary and secondary here. */ |
55 | unsigned int mask = (ctx->sst_size >> 7)-1; /* SSTP0[SegTableSize] */ | ||
56 | bool sec_hash = 1; | ||
57 | struct cxl_sste *sste; | 68 | struct cxl_sste *sste; |
58 | unsigned int hash; | ||
59 | unsigned long flags; | 69 | unsigned long flags; |
60 | 70 | ||
61 | |||
62 | sec_hash = !!(cxl_p1n_read(ctx->afu, CXL_PSL_SR_An) & CXL_PSL_SR_An_SC); | ||
63 | |||
64 | if (slb->vsid & SLB_VSID_B_1T) | ||
65 | hash = (slb->esid >> SID_SHIFT_1T) & mask; | ||
66 | else /* 256M */ | ||
67 | hash = (slb->esid >> SID_SHIFT) & mask; | ||
68 | |||
69 | spin_lock_irqsave(&ctx->sste_lock, flags); | 71 | spin_lock_irqsave(&ctx->sste_lock, flags); |
70 | sste = find_free_sste(ctx->sstp + (hash << 3), sec_hash, | 72 | sste = find_free_sste(ctx, slb); |
71 | ctx->sstp + ((~hash & mask) << 3), &ctx->sst_lru); | 73 | if (!sste) |
74 | goto out_unlock; | ||
72 | 75 | ||
73 | pr_devel("CXL Populating SST[%li]: %#llx %#llx\n", | 76 | pr_devel("CXL Populating SST[%li]: %#llx %#llx\n", |
74 | sste - ctx->sstp, slb->vsid, slb->esid); | 77 | sste - ctx->sstp, slb->vsid, slb->esid); |
75 | 78 | ||
76 | sste->vsid_data = cpu_to_be64(slb->vsid); | 79 | sste->vsid_data = cpu_to_be64(slb->vsid); |
77 | sste->esid_data = cpu_to_be64(slb->esid); | 80 | sste->esid_data = cpu_to_be64(slb->esid); |
81 | out_unlock: | ||
78 | spin_unlock_irqrestore(&ctx->sste_lock, flags); | 82 | spin_unlock_irqrestore(&ctx->sste_lock, flags); |
79 | } | 83 | } |
80 | 84 | ||
diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c index 623286a77114..d47532e8f4f1 100644 --- a/drivers/misc/cxl/native.c +++ b/drivers/misc/cxl/native.c | |||
@@ -417,7 +417,7 @@ static int attach_afu_directed(struct cxl_context *ctx, u64 wed, u64 amr) | |||
417 | ctx->elem->haurp = 0; /* disable */ | 417 | ctx->elem->haurp = 0; /* disable */ |
418 | ctx->elem->sdr = cpu_to_be64(mfspr(SPRN_SDR1)); | 418 | ctx->elem->sdr = cpu_to_be64(mfspr(SPRN_SDR1)); |
419 | 419 | ||
420 | sr = CXL_PSL_SR_An_SC; | 420 | sr = 0; |
421 | if (ctx->master) | 421 | if (ctx->master) |
422 | sr |= CXL_PSL_SR_An_MP; | 422 | sr |= CXL_PSL_SR_An_MP; |
423 | if (mfspr(SPRN_LPCR) & LPCR_TC) | 423 | if (mfspr(SPRN_LPCR) & LPCR_TC) |
@@ -508,7 +508,7 @@ static int attach_dedicated(struct cxl_context *ctx, u64 wed, u64 amr) | |||
508 | u64 sr; | 508 | u64 sr; |
509 | int rc; | 509 | int rc; |
510 | 510 | ||
511 | sr = CXL_PSL_SR_An_SC; | 511 | sr = 0; |
512 | set_endian(sr); | 512 | set_endian(sr); |
513 | if (ctx->master) | 513 | if (ctx->master) |
514 | sr |= CXL_PSL_SR_An_MP; | 514 | sr |= CXL_PSL_SR_An_MP; |