xref: /onnv-gate/usr/src/cmd/fm/modules/common/cpumem-retire/cma_cache.c (revision 10784:15baf8dd1081)
16330Sjc25722 /*
26330Sjc25722  * CDDL HEADER START
36330Sjc25722  *
46330Sjc25722  * The contents of this file are subject to the terms of the
56330Sjc25722  * Common Development and Distribution License (the "License").
66330Sjc25722  * You may not use this file except in compliance with the License.
76330Sjc25722  *
86330Sjc25722  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96330Sjc25722  * or http://www.opensolaris.org/os/licensing.
106330Sjc25722  * See the License for the specific language governing permissions
116330Sjc25722  * and limitations under the License.
126330Sjc25722  *
136330Sjc25722  * When distributing Covered Code, include this CDDL HEADER in each
146330Sjc25722  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156330Sjc25722  * If applicable, add the following below this CDDL HEADER, with the
166330Sjc25722  * fields enclosed by brackets "[]" replaced with your own identifying
176330Sjc25722  * information: Portions Copyright [yyyy] [name of copyright owner]
186330Sjc25722  *
196330Sjc25722  * CDDL HEADER END
206330Sjc25722  */
216330Sjc25722 /*
22*10784Ssinanallur.balasubramanian@sun.com  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
236330Sjc25722  * Use is subject to license terms.
246330Sjc25722  */
256330Sjc25722 
266330Sjc25722 #include <cma.h>
276330Sjc25722 #include <fcntl.h>
286330Sjc25722 #include <strings.h>
296330Sjc25722 #include <unistd.h>
30*10784Ssinanallur.balasubramanian@sun.com #include <errno.h>
316330Sjc25722 #include <fm/fmd_api.h>
326330Sjc25722 #include <sys/fm/protocol.h>
336330Sjc25722 #include <sys/mem_cache.h>
346330Sjc25722 
356330Sjc25722 int
366330Sjc25722 /* ARGSUSED 4 */
cma_cache_way_retire(fmd_hdl_t * hdl,nvlist_t * nvl,nvlist_t * asru,const char * uuid,boolean_t repair)376330Sjc25722 cma_cache_way_retire(fmd_hdl_t *hdl, nvlist_t *nvl, nvlist_t *asru,
386330Sjc25722     const char *uuid, boolean_t repair)
396330Sjc25722 {
406330Sjc25722 	uint_t 		cpuid;
41*10784Ssinanallur.balasubramanian@sun.com 	uint32_t 	way;
42*10784Ssinanallur.balasubramanian@sun.com 	uint32_t	index;
436330Sjc25722 	uint16_t	bit = 0;
446330Sjc25722 	uint8_t		type;
456330Sjc25722 	cache_info_t    cache_info;
466330Sjc25722 	int ret, fd;
47*10784Ssinanallur.balasubramanian@sun.com 	int	err;
486330Sjc25722 
496330Sjc25722 	fmd_hdl_debug(hdl, "cpu cache *line* fault processing\n");
507256Sjc25722 	fmd_hdl_debug(hdl, "asru %lx\n", asru);
516330Sjc25722 
526330Sjc25722 	/*
536330Sjc25722 	 * This added expansion is needed to cover the situation where a
546330Sjc25722 	 * cpu fault from the resource cache is replayed at fmd restart,
556330Sjc25722 	 * and the cpu resource has been remapped or replaced.  The stored
566330Sjc25722 	 * FMRI is expanded, but may have stale data.
576330Sjc25722 	 */
586330Sjc25722 
596330Sjc25722 	if (fmd_nvl_fmri_expand(hdl, asru) < 0) {
606330Sjc25722 		fmd_hdl_debug(hdl, "failed to expand cpu asru\n");
616330Sjc25722 		cma_stats.bad_flts.fmds_value.ui64++;
626330Sjc25722 		return (CMA_RA_FAILURE);
636330Sjc25722 	}
646330Sjc25722 
656330Sjc25722 	if (nvlist_lookup_uint32(asru, FM_FMRI_CPU_ID, &cpuid) != 0) {
666330Sjc25722 		fmd_hdl_debug(hdl, "cpu cache fault missing '%s'\n",
676330Sjc25722 		    FM_FMRI_CPU_ID);
686330Sjc25722 		cma_stats.bad_flts.fmds_value.ui64++;
696330Sjc25722 		return (CMA_RA_FAILURE);
706330Sjc25722 	}
716330Sjc25722 
726330Sjc25722 	if (nvlist_lookup_uint32(asru, FM_FMRI_CPU_CACHE_INDEX, &index) != 0) {
736330Sjc25722 		fmd_hdl_debug(hdl, "cpu cache fault missing '%s'\n",
74*10784Ssinanallur.balasubramanian@sun.com 		    FM_FMRI_CPU_CACHE_INDEX);
756330Sjc25722 		cma_stats.bad_flts.fmds_value.ui64++;
766330Sjc25722 		return (CMA_RA_FAILURE);
776330Sjc25722 	}
786330Sjc25722 
796330Sjc25722 	if (nvlist_lookup_uint32(asru, FM_FMRI_CPU_CACHE_WAY, &way) != 0) {
806330Sjc25722 		fmd_hdl_debug(hdl, "cpu cache fault missing '%s'\n",
816330Sjc25722 		    FM_FMRI_CPU_CACHE_WAY);
826330Sjc25722 		cma_stats.bad_flts.fmds_value.ui64++;
836330Sjc25722 		return (CMA_RA_FAILURE);
846330Sjc25722 	}
856330Sjc25722 
866330Sjc25722 	if (nvlist_lookup_uint8(asru, FM_FMRI_CPU_CACHE_TYPE, &type) != 0) {
876330Sjc25722 		fmd_hdl_debug(hdl, "cpu cache fault missing '%s'\n",
886330Sjc25722 		    FM_FMRI_CPU_CACHE_TYPE);
896330Sjc25722 		cma_stats.bad_flts.fmds_value.ui64++;
906330Sjc25722 		return (CMA_RA_FAILURE);
916330Sjc25722 	}
926330Sjc25722 
936330Sjc25722 	/*
946330Sjc25722 	 * Tag faults will use it to set the bit to a stable state
956330Sjc25722 	 */
966330Sjc25722 
97*10784Ssinanallur.balasubramanian@sun.com 	if (nvlist_lookup_uint16(asru, FM_FMRI_CPU_CACHE_BIT, &bit) != 0) {
98*10784Ssinanallur.balasubramanian@sun.com 		fmd_hdl_debug(hdl, "cpu cache fault missing '%s'\n",
99*10784Ssinanallur.balasubramanian@sun.com 		    FM_FMRI_CPU_CACHE_BIT);
100*10784Ssinanallur.balasubramanian@sun.com 		cma_stats.bad_flts.fmds_value.ui64++;
101*10784Ssinanallur.balasubramanian@sun.com 		return (CMA_RA_FAILURE);
102*10784Ssinanallur.balasubramanian@sun.com 	}
103*10784Ssinanallur.balasubramanian@sun.com 	if (repair) {
104*10784Ssinanallur.balasubramanian@sun.com 		fmd_hdl_debug(hdl,
105*10784Ssinanallur.balasubramanian@sun.com 		    "cpu %d: Unretire for index %d, way %d\n bit %d"
106*10784Ssinanallur.balasubramanian@sun.com 		    " type 0x%02x is being called now. We will not unretire"
107*10784Ssinanallur.balasubramanian@sun.com 		    " cacheline. This message is for information.\n",
108*10784Ssinanallur.balasubramanian@sun.com 		    cpuid, index, way, bit, type);
109*10784Ssinanallur.balasubramanian@sun.com 		/*
110*10784Ssinanallur.balasubramanian@sun.com 		 * The DE will do the actual unretire.
111*10784Ssinanallur.balasubramanian@sun.com 		 * The agent is called because the DE informs the fmd
112*10784Ssinanallur.balasubramanian@sun.com 		 * that the resource is repaired.
113*10784Ssinanallur.balasubramanian@sun.com 		 */
114*10784Ssinanallur.balasubramanian@sun.com 		return (CMA_RA_SUCCESS);
115*10784Ssinanallur.balasubramanian@sun.com 	}
116*10784Ssinanallur.balasubramanian@sun.com 	fmd_hdl_debug(hdl,
117*10784Ssinanallur.balasubramanian@sun.com 	    "cpu %d: Retiring index %d, way %d\n bit %d"
118*10784Ssinanallur.balasubramanian@sun.com 	    " type 0x%02x", cpuid, index, way, bit, type);
1196330Sjc25722 	fd = open(mem_cache_device, O_RDWR);
1206330Sjc25722 	if (fd == -1) {
1216330Sjc25722 		fmd_hdl_debug(hdl, "Driver open failed\n");
1226330Sjc25722 		return (CMA_RA_FAILURE);
1236330Sjc25722 	}
1246330Sjc25722 	cache_info.cpu_id = cpuid;
1256330Sjc25722 	cache_info.way = way;
1266330Sjc25722 	cache_info.bit = bit;
1276330Sjc25722 	cache_info.index = index;
1286330Sjc25722 	cache_info.cache = type == FM_FMRI_CPU_CACHE_TYPE_L3 ?
1296330Sjc25722 	    L3_CACHE_DATA : L2_CACHE_DATA;
1306330Sjc25722 
131*10784Ssinanallur.balasubramanian@sun.com 	ret = ioctl(fd, MEM_CACHE_RETIRE, &cache_info);
132*10784Ssinanallur.balasubramanian@sun.com 	/*
133*10784Ssinanallur.balasubramanian@sun.com 	 * save errno before we call close.
134*10784Ssinanallur.balasubramanian@sun.com 	 * Need errno to display the error if ioctl fails.
135*10784Ssinanallur.balasubramanian@sun.com 	 */
136*10784Ssinanallur.balasubramanian@sun.com 	err = errno;
137*10784Ssinanallur.balasubramanian@sun.com 	(void) close(fd);
1386330Sjc25722 	if (ret == -1) {
139*10784Ssinanallur.balasubramanian@sun.com 		fmd_hdl_debug(hdl, "Driver call failed errno = %d\n", err);
1406330Sjc25722 		return (CMA_RA_FAILURE);
1416330Sjc25722 	}
1426330Sjc25722 	return (CMA_RA_SUCCESS);
1436330Sjc25722 }
144