xref: /titanic_51/usr/src/cmd/fm/modules/common/cpumem-retire/cma_cache.c (revision a62774df315360f02521d6470eab7d5080137dad)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include <cma.h>
27 #include <fcntl.h>
28 #include <strings.h>
29 #include <unistd.h>
30 #include <errno.h>
31 #include <fm/fmd_api.h>
32 #include <sys/fm/protocol.h>
33 #include <sys/mem_cache.h>
34 
35 int
36 /* ARGSUSED 4 */
37 cma_cache_way_retire(fmd_hdl_t *hdl, nvlist_t *nvl, nvlist_t *asru,
38     const char *uuid, boolean_t repair)
39 {
40 	uint_t 		cpuid;
41 	uint32_t 	way;
42 	uint32_t	index;
43 	uint16_t	bit = 0;
44 	uint8_t		type;
45 	cache_info_t    cache_info;
46 	int ret, fd;
47 	int	err;
48 
49 	fmd_hdl_debug(hdl, "cpu cache *line* fault processing\n");
50 	fmd_hdl_debug(hdl, "asru %lx\n", asru);
51 
52 	/*
53 	 * This added expansion is needed to cover the situation where a
54 	 * cpu fault from the resource cache is replayed at fmd restart,
55 	 * and the cpu resource has been remapped or replaced.  The stored
56 	 * FMRI is expanded, but may have stale data.
57 	 */
58 
59 	if (fmd_nvl_fmri_expand(hdl, asru) < 0) {
60 		fmd_hdl_debug(hdl, "failed to expand cpu asru\n");
61 		cma_stats.bad_flts.fmds_value.ui64++;
62 		return (CMA_RA_FAILURE);
63 	}
64 
65 	if (nvlist_lookup_uint32(asru, FM_FMRI_CPU_ID, &cpuid) != 0) {
66 		fmd_hdl_debug(hdl, "cpu cache fault missing '%s'\n",
67 		    FM_FMRI_CPU_ID);
68 		cma_stats.bad_flts.fmds_value.ui64++;
69 		return (CMA_RA_FAILURE);
70 	}
71 
72 	if (nvlist_lookup_uint32(asru, FM_FMRI_CPU_CACHE_INDEX, &index) != 0) {
73 		fmd_hdl_debug(hdl, "cpu cache fault missing '%s'\n",
74 		    FM_FMRI_CPU_CACHE_INDEX);
75 		cma_stats.bad_flts.fmds_value.ui64++;
76 		return (CMA_RA_FAILURE);
77 	}
78 
79 	if (nvlist_lookup_uint32(asru, FM_FMRI_CPU_CACHE_WAY, &way) != 0) {
80 		fmd_hdl_debug(hdl, "cpu cache fault missing '%s'\n",
81 		    FM_FMRI_CPU_CACHE_WAY);
82 		cma_stats.bad_flts.fmds_value.ui64++;
83 		return (CMA_RA_FAILURE);
84 	}
85 
86 	if (nvlist_lookup_uint8(asru, FM_FMRI_CPU_CACHE_TYPE, &type) != 0) {
87 		fmd_hdl_debug(hdl, "cpu cache fault missing '%s'\n",
88 		    FM_FMRI_CPU_CACHE_TYPE);
89 		cma_stats.bad_flts.fmds_value.ui64++;
90 		return (CMA_RA_FAILURE);
91 	}
92 
93 	/*
94 	 * Tag faults will use it to set the bit to a stable state
95 	 */
96 
97 	if (nvlist_lookup_uint16(asru, FM_FMRI_CPU_CACHE_BIT, &bit) != 0) {
98 		fmd_hdl_debug(hdl, "cpu cache fault missing '%s'\n",
99 		    FM_FMRI_CPU_CACHE_BIT);
100 		cma_stats.bad_flts.fmds_value.ui64++;
101 		return (CMA_RA_FAILURE);
102 	}
103 	if (repair) {
104 		fmd_hdl_debug(hdl,
105 		    "cpu %d: Unretire for index %d, way %d\n bit %d"
106 		    " type 0x%02x is being called now. We will not unretire"
107 		    " cacheline. This message is for information.\n",
108 		    cpuid, index, way, bit, type);
109 		/*
110 		 * The DE will do the actual unretire.
111 		 * The agent is called because the DE informs the fmd
112 		 * that the resource is repaired.
113 		 */
114 		return (CMA_RA_SUCCESS);
115 	}
116 	fmd_hdl_debug(hdl,
117 	    "cpu %d: Retiring index %d, way %d\n bit %d"
118 	    " type 0x%02x", cpuid, index, way, bit, type);
119 	fd = open(mem_cache_device, O_RDWR);
120 	if (fd == -1) {
121 		fmd_hdl_debug(hdl, "Driver open failed\n");
122 		return (CMA_RA_FAILURE);
123 	}
124 	cache_info.cpu_id = cpuid;
125 	cache_info.way = way;
126 	cache_info.bit = bit;
127 	cache_info.index = index;
128 	cache_info.cache = type == FM_FMRI_CPU_CACHE_TYPE_L3 ?
129 	    L3_CACHE_DATA : L2_CACHE_DATA;
130 
131 	ret = ioctl(fd, MEM_CACHE_RETIRE, &cache_info);
132 	/*
133 	 * save errno before we call close.
134 	 * Need errno to display the error if ioctl fails.
135 	 */
136 	err = errno;
137 	(void) close(fd);
138 	if (ret == -1) {
139 		fmd_hdl_debug(hdl, "Driver call failed errno = %d\n", err);
140 		return (CMA_RA_FAILURE);
141 	}
142 	return (CMA_RA_SUCCESS);
143 }
144