@@ -125,18 +125,45 @@ static struct cxl_region_ref *cxl_rr_load(struct cxl_port *port,
125125 return xa_load (& port -> regions , (unsigned long )cxlr );
126126}
127127
128+ static int cxl_region_invalidate_memregion (struct cxl_region * cxlr )
129+ {
130+ if (!cpu_cache_has_invalidate_memregion ()) {
131+ if (IS_ENABLED (CONFIG_CXL_REGION_INVALIDATION_TEST )) {
132+ dev_warn_once (
133+ & cxlr -> dev ,
134+ "Bypassing cpu_cache_invalidate_memregion() for testing!\n" );
135+ return 0 ;
136+ } else {
137+ dev_err (& cxlr -> dev ,
138+ "Failed to synchronize CPU cache state\n" );
139+ return - ENXIO ;
140+ }
141+ }
142+
143+ cpu_cache_invalidate_memregion (IORES_DESC_CXL );
144+ return 0 ;
145+ }
146+
128147static int cxl_region_decode_reset (struct cxl_region * cxlr , int count )
129148{
130149 struct cxl_region_params * p = & cxlr -> params ;
131- int i ;
150+ int i , rc = 0 ;
151+
152+ /*
153+ * Before region teardown attempt to flush, and if the flush
154+ * fails cancel the region teardown for data consistency
155+ * concerns
156+ */
157+ rc = cxl_region_invalidate_memregion (cxlr );
158+ if (rc )
159+ return rc ;
132160
133161 for (i = count - 1 ; i >= 0 ; i -- ) {
134162 struct cxl_endpoint_decoder * cxled = p -> targets [i ];
135163 struct cxl_memdev * cxlmd = cxled_to_memdev (cxled );
136164 struct cxl_port * iter = cxled_to_port (cxled );
137165 struct cxl_dev_state * cxlds = cxlmd -> cxlds ;
138166 struct cxl_ep * ep ;
139- int rc = 0 ;
140167
141168 if (cxlds -> rcd )
142169 goto endpoint_reset ;
@@ -155,14 +182,19 @@ static int cxl_region_decode_reset(struct cxl_region *cxlr, int count)
155182 rc = cxld -> reset (cxld );
156183 if (rc )
157184 return rc ;
185+ set_bit (CXL_REGION_F_NEEDS_RESET , & cxlr -> flags );
158186 }
159187
160188endpoint_reset :
161189 rc = cxled -> cxld .reset (& cxled -> cxld );
162190 if (rc )
163191 return rc ;
192+ set_bit (CXL_REGION_F_NEEDS_RESET , & cxlr -> flags );
164193 }
165194
195+ /* all decoders associated with this region have been torn down */
196+ clear_bit (CXL_REGION_F_NEEDS_RESET , & cxlr -> flags );
197+
166198 return 0 ;
167199}
168200
@@ -256,9 +288,19 @@ static ssize_t commit_store(struct device *dev, struct device_attribute *attr,
256288 goto out ;
257289 }
258290
259- if (commit )
291+ /*
292+ * Invalidate caches before region setup to drop any speculative
293+ * consumption of this address space
294+ */
295+ rc = cxl_region_invalidate_memregion (cxlr );
296+ if (rc )
297+ return rc ;
298+
299+ if (commit ) {
260300 rc = cxl_region_decode_commit (cxlr );
261- else {
301+ if (rc == 0 )
302+ p -> state = CXL_CONFIG_COMMIT ;
303+ } else {
262304 p -> state = CXL_CONFIG_RESET_PENDING ;
263305 up_write (& cxl_region_rwsem );
264306 device_release_driver (& cxlr -> dev );
@@ -268,18 +310,20 @@ static ssize_t commit_store(struct device *dev, struct device_attribute *attr,
268310 * The lock was dropped, so need to revalidate that the reset is
269311 * still pending.
270312 */
271- if (p -> state == CXL_CONFIG_RESET_PENDING )
313+ if (p -> state == CXL_CONFIG_RESET_PENDING ) {
272314 rc = cxl_region_decode_reset (cxlr , p -> interleave_ways );
315+ /*
316+ * Revert to committed since there may still be active
317+ * decoders associated with this region, or move forward
318+ * to active to mark the reset successful
319+ */
320+ if (rc )
321+ p -> state = CXL_CONFIG_COMMIT ;
322+ else
323+ p -> state = CXL_CONFIG_ACTIVE ;
324+ }
273325 }
274326
275- if (rc )
276- goto out ;
277-
278- if (commit )
279- p -> state = CXL_CONFIG_COMMIT ;
280- else if (p -> state == CXL_CONFIG_RESET_PENDING )
281- p -> state = CXL_CONFIG_ACTIVE ;
282-
283327out :
284328 up_write (& cxl_region_rwsem );
285329
@@ -1686,7 +1730,6 @@ static int cxl_region_attach(struct cxl_region *cxlr,
16861730 if (rc )
16871731 goto err_decrement ;
16881732 p -> state = CXL_CONFIG_ACTIVE ;
1689- set_bit (CXL_REGION_F_INCOHERENT , & cxlr -> flags );
16901733 }
16911734
16921735 cxled -> cxld .interleave_ways = p -> interleave_ways ;
@@ -2815,30 +2858,6 @@ int cxl_add_to_region(struct cxl_port *root, struct cxl_endpoint_decoder *cxled)
28152858}
28162859EXPORT_SYMBOL_NS_GPL (cxl_add_to_region , CXL );
28172860
2818- static int cxl_region_invalidate_memregion (struct cxl_region * cxlr )
2819- {
2820- if (!test_bit (CXL_REGION_F_INCOHERENT , & cxlr -> flags ))
2821- return 0 ;
2822-
2823- if (!cpu_cache_has_invalidate_memregion ()) {
2824- if (IS_ENABLED (CONFIG_CXL_REGION_INVALIDATION_TEST )) {
2825- dev_warn_once (
2826- & cxlr -> dev ,
2827- "Bypassing cpu_cache_invalidate_memregion() for testing!\n" );
2828- clear_bit (CXL_REGION_F_INCOHERENT , & cxlr -> flags );
2829- return 0 ;
2830- } else {
2831- dev_err (& cxlr -> dev ,
2832- "Failed to synchronize CPU cache state\n" );
2833- return - ENXIO ;
2834- }
2835- }
2836-
2837- cpu_cache_invalidate_memregion (IORES_DESC_CXL );
2838- clear_bit (CXL_REGION_F_INCOHERENT , & cxlr -> flags );
2839- return 0 ;
2840- }
2841-
28422861static int is_system_ram (struct resource * res , void * arg )
28432862{
28442863 struct cxl_region * cxlr = arg ;
@@ -2866,7 +2885,12 @@ static int cxl_region_probe(struct device *dev)
28662885 goto out ;
28672886 }
28682887
2869- rc = cxl_region_invalidate_memregion (cxlr );
2888+ if (test_bit (CXL_REGION_F_NEEDS_RESET , & cxlr -> flags )) {
2889+ dev_err (& cxlr -> dev ,
2890+ "failed to activate, re-commit region and retry\n" );
2891+ rc = - ENXIO ;
2892+ goto out ;
2893+ }
28702894
28712895 /*
28722896 * From this point on any path that changes the region's state away from
0 commit comments