Skip to content

Commit 86954ff

Browse files
AlisonSchofielddavejiang
authored andcommitted
cxl/region: Move cxl_trace_hpa() work to the region driver
This work belongs in the region driver as it is only useful with CONFIG_CXL_REGION. Add a stub in core.h for when the region driver is not built. Signed-off-by: Alison Schofield <[email protected]> Reviewed-by: Jonathan Cameron <[email protected]> Reviewed-by: Ira Weiny <[email protected]> Link: https://lore.kernel.org/r/183222631f11a43c5e6debc42ec22fe1bd4b818a.1714496730.git.alison.schofield@intel.com Signed-off-by: Dave Jiang <[email protected]>
1 parent b98d042 commit 86954ff

File tree

4 files changed

+98
-93
lines changed

4 files changed

+98
-93
lines changed

drivers/cxl/core/core.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,15 @@ int cxl_region_init(void);
2828
void cxl_region_exit(void);
2929
int cxl_get_poison_by_endpoint(struct cxl_port *port);
3030
struct cxl_region *cxl_dpa_to_region(const struct cxl_memdev *cxlmd, u64 dpa);
31+
u64 cxl_trace_hpa(struct cxl_region *cxlr, const struct cxl_memdev *cxlmd,
32+
u64 dpa);
3133

3234
#else
35+
static inline u64
36+
cxl_trace_hpa(struct cxl_region *cxlr, const struct cxl_memdev *cxlmd, u64 dpa)
37+
{
38+
return ULLONG_MAX;
39+
}
3340
static inline
3441
struct cxl_region *cxl_dpa_to_region(const struct cxl_memdev *cxlmd, u64 dpa)
3542
{

drivers/cxl/core/region.c

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2723,6 +2723,97 @@ struct cxl_region *cxl_dpa_to_region(const struct cxl_memdev *cxlmd, u64 dpa)
27232723
return ctx.cxlr;
27242724
}
27252725

2726+
static bool cxl_is_hpa_in_range(u64 hpa, struct cxl_region *cxlr, int pos)
2727+
{
2728+
struct cxl_region_params *p = &cxlr->params;
2729+
int gran = p->interleave_granularity;
2730+
int ways = p->interleave_ways;
2731+
u64 offset;
2732+
2733+
/* Is the hpa within this region at all */
2734+
if (hpa < p->res->start || hpa > p->res->end) {
2735+
dev_dbg(&cxlr->dev,
2736+
"Addr trans fail: hpa 0x%llx not in region\n", hpa);
2737+
return false;
2738+
}
2739+
2740+
/* Is the hpa in an expected chunk for its pos(-ition) */
2741+
offset = hpa - p->res->start;
2742+
offset = do_div(offset, gran * ways);
2743+
if ((offset >= pos * gran) && (offset < (pos + 1) * gran))
2744+
return true;
2745+
2746+
dev_dbg(&cxlr->dev,
2747+
"Addr trans fail: hpa 0x%llx not in expected chunk\n", hpa);
2748+
2749+
return false;
2750+
}
2751+
2752+
static u64 cxl_dpa_to_hpa(u64 dpa, struct cxl_region *cxlr,
2753+
struct cxl_endpoint_decoder *cxled)
2754+
{
2755+
u64 dpa_offset, hpa_offset, bits_upper, mask_upper, hpa;
2756+
struct cxl_region_params *p = &cxlr->params;
2757+
int pos = cxled->pos;
2758+
u16 eig = 0;
2759+
u8 eiw = 0;
2760+
2761+
ways_to_eiw(p->interleave_ways, &eiw);
2762+
granularity_to_eig(p->interleave_granularity, &eig);
2763+
2764+
/*
2765+
* The device position in the region interleave set was removed
2766+
* from the offset at HPA->DPA translation. To reconstruct the
2767+
* HPA, place the 'pos' in the offset.
2768+
*
2769+
* The placement of 'pos' in the HPA is determined by interleave
2770+
* ways and granularity and is defined in the CXL Spec 3.0 Section
2771+
* 8.2.4.19.13 Implementation Note: Device Decode Logic
2772+
*/
2773+
2774+
/* Remove the dpa base */
2775+
dpa_offset = dpa - cxl_dpa_resource_start(cxled);
2776+
2777+
mask_upper = GENMASK_ULL(51, eig + 8);
2778+
2779+
if (eiw < 8) {
2780+
hpa_offset = (dpa_offset & mask_upper) << eiw;
2781+
hpa_offset |= pos << (eig + 8);
2782+
} else {
2783+
bits_upper = (dpa_offset & mask_upper) >> (eig + 8);
2784+
bits_upper = bits_upper * 3;
2785+
hpa_offset = ((bits_upper << (eiw - 8)) + pos) << (eig + 8);
2786+
}
2787+
2788+
/* The lower bits remain unchanged */
2789+
hpa_offset |= dpa_offset & GENMASK_ULL(eig + 7, 0);
2790+
2791+
/* Apply the hpa_offset to the region base address */
2792+
hpa = hpa_offset + p->res->start;
2793+
2794+
if (!cxl_is_hpa_in_range(hpa, cxlr, cxled->pos))
2795+
return ULLONG_MAX;
2796+
2797+
return hpa;
2798+
}
2799+
2800+
u64 cxl_trace_hpa(struct cxl_region *cxlr, const struct cxl_memdev *cxlmd,
2801+
u64 dpa)
2802+
{
2803+
struct cxl_region_params *p = &cxlr->params;
2804+
struct cxl_endpoint_decoder *cxled = NULL;
2805+
2806+
for (int i = 0; i < p->nr_targets; i++) {
2807+
cxled = p->targets[i];
2808+
if (cxlmd == cxled_to_memdev(cxled))
2809+
break;
2810+
}
2811+
if (!cxled || cxlmd != cxled_to_memdev(cxled))
2812+
return ULLONG_MAX;
2813+
2814+
return cxl_dpa_to_hpa(dpa, cxlr, cxled);
2815+
}
2816+
27262817
static struct lock_class_key cxl_pmem_region_key;
27272818

27282819
static struct cxl_pmem_region *cxl_pmem_region_alloc(struct cxl_region *cxlr)

drivers/cxl/core/trace.c

Lines changed: 0 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -6,94 +6,3 @@
66

77
#define CREATE_TRACE_POINTS
88
#include "trace.h"
9-
10-
static bool cxl_is_hpa_in_range(u64 hpa, struct cxl_region *cxlr, int pos)
11-
{
12-
struct cxl_region_params *p = &cxlr->params;
13-
int gran = p->interleave_granularity;
14-
int ways = p->interleave_ways;
15-
u64 offset;
16-
17-
/* Is the hpa within this region at all */
18-
if (hpa < p->res->start || hpa > p->res->end) {
19-
dev_dbg(&cxlr->dev,
20-
"Addr trans fail: hpa 0x%llx not in region\n", hpa);
21-
return false;
22-
}
23-
24-
/* Is the hpa in an expected chunk for its pos(-ition) */
25-
offset = hpa - p->res->start;
26-
offset = do_div(offset, gran * ways);
27-
if ((offset >= pos * gran) && (offset < (pos + 1) * gran))
28-
return true;
29-
30-
dev_dbg(&cxlr->dev,
31-
"Addr trans fail: hpa 0x%llx not in expected chunk\n", hpa);
32-
33-
return false;
34-
}
35-
36-
static u64 cxl_dpa_to_hpa(u64 dpa, struct cxl_region *cxlr,
37-
struct cxl_endpoint_decoder *cxled)
38-
{
39-
u64 dpa_offset, hpa_offset, bits_upper, mask_upper, hpa;
40-
struct cxl_region_params *p = &cxlr->params;
41-
int pos = cxled->pos;
42-
u16 eig = 0;
43-
u8 eiw = 0;
44-
45-
ways_to_eiw(p->interleave_ways, &eiw);
46-
granularity_to_eig(p->interleave_granularity, &eig);
47-
48-
/*
49-
* The device position in the region interleave set was removed
50-
* from the offset at HPA->DPA translation. To reconstruct the
51-
* HPA, place the 'pos' in the offset.
52-
*
53-
* The placement of 'pos' in the HPA is determined by interleave
54-
* ways and granularity and is defined in the CXL Spec 3.0 Section
55-
* 8.2.4.19.13 Implementation Note: Device Decode Logic
56-
*/
57-
58-
/* Remove the dpa base */
59-
dpa_offset = dpa - cxl_dpa_resource_start(cxled);
60-
61-
mask_upper = GENMASK_ULL(51, eig + 8);
62-
63-
if (eiw < 8) {
64-
hpa_offset = (dpa_offset & mask_upper) << eiw;
65-
hpa_offset |= pos << (eig + 8);
66-
} else {
67-
bits_upper = (dpa_offset & mask_upper) >> (eig + 8);
68-
bits_upper = bits_upper * 3;
69-
hpa_offset = ((bits_upper << (eiw - 8)) + pos) << (eig + 8);
70-
}
71-
72-
/* The lower bits remain unchanged */
73-
hpa_offset |= dpa_offset & GENMASK_ULL(eig + 7, 0);
74-
75-
/* Apply the hpa_offset to the region base address */
76-
hpa = hpa_offset + p->res->start;
77-
78-
if (!cxl_is_hpa_in_range(hpa, cxlr, cxled->pos))
79-
return ULLONG_MAX;
80-
81-
return hpa;
82-
}
83-
84-
u64 cxl_trace_hpa(struct cxl_region *cxlr, struct cxl_memdev *cxlmd,
85-
u64 dpa)
86-
{
87-
struct cxl_region_params *p = &cxlr->params;
88-
struct cxl_endpoint_decoder *cxled = NULL;
89-
90-
for (int i = 0; i < p->nr_targets; i++) {
91-
cxled = p->targets[i];
92-
if (cxlmd == cxled_to_memdev(cxled))
93-
break;
94-
}
95-
if (!cxled || cxlmd != cxled_to_memdev(cxled))
96-
return ULLONG_MAX;
97-
98-
return cxl_dpa_to_hpa(dpa, cxlr, cxled);
99-
}

drivers/cxl/core/trace.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -642,8 +642,6 @@ TRACE_EVENT(cxl_memory_module,
642642
#define cxl_poison_overflow(flags, time) \
643643
(flags & CXL_POISON_FLAG_OVERFLOW ? le64_to_cpu(time) : 0)
644644

645-
u64 cxl_trace_hpa(struct cxl_region *cxlr, struct cxl_memdev *memdev, u64 dpa);
646-
647645
TRACE_EVENT(cxl_poison,
648646

649647
TP_PROTO(struct cxl_memdev *cxlmd, struct cxl_region *cxlr,

0 commit comments

Comments
 (0)