7bebe46c240b554f47faeed19186123896281967jc/*
7bebe46c240b554f47faeed19186123896281967jc * CDDL HEADER START
7bebe46c240b554f47faeed19186123896281967jc *
7bebe46c240b554f47faeed19186123896281967jc * The contents of this file are subject to the terms of the
7bebe46c240b554f47faeed19186123896281967jc * Common Development and Distribution License (the "License").
7bebe46c240b554f47faeed19186123896281967jc * You may not use this file except in compliance with the License.
7bebe46c240b554f47faeed19186123896281967jc *
7bebe46c240b554f47faeed19186123896281967jc * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
7bebe46c240b554f47faeed19186123896281967jc * or http://www.opensolaris.org/os/licensing.
7bebe46c240b554f47faeed19186123896281967jc * See the License for the specific language governing permissions
7bebe46c240b554f47faeed19186123896281967jc * and limitations under the License.
7bebe46c240b554f47faeed19186123896281967jc *
7bebe46c240b554f47faeed19186123896281967jc * When distributing Covered Code, include this CDDL HEADER in each
7bebe46c240b554f47faeed19186123896281967jc * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
7bebe46c240b554f47faeed19186123896281967jc * If applicable, add the following below this CDDL HEADER, with the
7bebe46c240b554f47faeed19186123896281967jc * fields enclosed by brackets "[]" replaced with your own identifying
7bebe46c240b554f47faeed19186123896281967jc * information: Portions Copyright [yyyy] [name of copyright owner]
7bebe46c240b554f47faeed19186123896281967jc *
7bebe46c240b554f47faeed19186123896281967jc * CDDL HEADER END
7bebe46c240b554f47faeed19186123896281967jc */
7bebe46c240b554f47faeed19186123896281967jc/*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
7bebe46c240b554f47faeed19186123896281967jc * Use is subject to license terms.
7bebe46c240b554f47faeed19186123896281967jc */
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc#include <cma.h>
7bebe46c240b554f47faeed19186123896281967jc#include <fcntl.h>
7bebe46c240b554f47faeed19186123896281967jc#include <strings.h>
7bebe46c240b554f47faeed19186123896281967jc#include <unistd.h>
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian#include <errno.h>
7bebe46c240b554f47faeed19186123896281967jc#include <fm/fmd_api.h>
7bebe46c240b554f47faeed19186123896281967jc#include <sys/fm/protocol.h>
7bebe46c240b554f47faeed19186123896281967jc#include <sys/mem_cache.h>
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jcint
7bebe46c240b554f47faeed19186123896281967jc/* ARGSUSED 4 */
7bebe46c240b554f47faeed19186123896281967jccma_cache_way_retire(fmd_hdl_t *hdl, nvlist_t *nvl, nvlist_t *asru,
7bebe46c240b554f47faeed19186123896281967jc const char *uuid, boolean_t repair)
7bebe46c240b554f47faeed19186123896281967jc{
7bebe46c240b554f47faeed19186123896281967jc uint_t cpuid;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian uint32_t way;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian uint32_t index;
7bebe46c240b554f47faeed19186123896281967jc uint16_t bit = 0;
7bebe46c240b554f47faeed19186123896281967jc uint8_t type;
7bebe46c240b554f47faeed19186123896281967jc cache_info_t cache_info;
7bebe46c240b554f47faeed19186123896281967jc int ret, fd;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian int err;
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_debug(hdl, "cpu cache *line* fault processing\n");
d69c2551e89e9440043ac6ff5739b58746286f33jc fmd_hdl_debug(hdl, "asru %lx\n", asru);
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc /*
7bebe46c240b554f47faeed19186123896281967jc * This added expansion is needed to cover the situation where a
7bebe46c240b554f47faeed19186123896281967jc * cpu fault from the resource cache is replayed at fmd restart,
7bebe46c240b554f47faeed19186123896281967jc * and the cpu resource has been remapped or replaced. The stored
7bebe46c240b554f47faeed19186123896281967jc * FMRI is expanded, but may have stale data.
7bebe46c240b554f47faeed19186123896281967jc */
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc if (fmd_nvl_fmri_expand(hdl, asru) < 0) {
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_debug(hdl, "failed to expand cpu asru\n");
7bebe46c240b554f47faeed19186123896281967jc cma_stats.bad_flts.fmds_value.ui64++;
7bebe46c240b554f47faeed19186123896281967jc return (CMA_RA_FAILURE);
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc if (nvlist_lookup_uint32(asru, FM_FMRI_CPU_ID, &cpuid) != 0) {
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_debug(hdl, "cpu cache fault missing '%s'\n",
7bebe46c240b554f47faeed19186123896281967jc FM_FMRI_CPU_ID);
7bebe46c240b554f47faeed19186123896281967jc cma_stats.bad_flts.fmds_value.ui64++;
7bebe46c240b554f47faeed19186123896281967jc return (CMA_RA_FAILURE);
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc if (nvlist_lookup_uint32(asru, FM_FMRI_CPU_CACHE_INDEX, &index) != 0) {
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_debug(hdl, "cpu cache fault missing '%s'\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian FM_FMRI_CPU_CACHE_INDEX);
7bebe46c240b554f47faeed19186123896281967jc cma_stats.bad_flts.fmds_value.ui64++;
7bebe46c240b554f47faeed19186123896281967jc return (CMA_RA_FAILURE);
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc if (nvlist_lookup_uint32(asru, FM_FMRI_CPU_CACHE_WAY, &way) != 0) {
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_debug(hdl, "cpu cache fault missing '%s'\n",
7bebe46c240b554f47faeed19186123896281967jc FM_FMRI_CPU_CACHE_WAY);
7bebe46c240b554f47faeed19186123896281967jc cma_stats.bad_flts.fmds_value.ui64++;
7bebe46c240b554f47faeed19186123896281967jc return (CMA_RA_FAILURE);
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc if (nvlist_lookup_uint8(asru, FM_FMRI_CPU_CACHE_TYPE, &type) != 0) {
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_debug(hdl, "cpu cache fault missing '%s'\n",
7bebe46c240b554f47faeed19186123896281967jc FM_FMRI_CPU_CACHE_TYPE);
7bebe46c240b554f47faeed19186123896281967jc cma_stats.bad_flts.fmds_value.ui64++;
7bebe46c240b554f47faeed19186123896281967jc return (CMA_RA_FAILURE);
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc
7bebe46c240b554f47faeed19186123896281967jc /*
7bebe46c240b554f47faeed19186123896281967jc * Tag faults will use it to set the bit to a stable state
7bebe46c240b554f47faeed19186123896281967jc */
7bebe46c240b554f47faeed19186123896281967jc
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (nvlist_lookup_uint16(asru, FM_FMRI_CPU_CACHE_BIT, &bit) != 0) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl, "cpu cache fault missing '%s'\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian FM_FMRI_CPU_CACHE_BIT);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cma_stats.bad_flts.fmds_value.ui64++;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMA_RA_FAILURE);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian if (repair) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "cpu %d: Unretire for index %d, way %d\n bit %d"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " type 0x%02x is being called now. We will not unretire"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " cacheline. This message is for information.\n",
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian cpuid, index, way, bit, type);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * The DE will do the actual unretire.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * The agent is called because the DE informs the fmd
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * that the resource is repaired.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian return (CMA_RA_SUCCESS);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian }
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl,
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian "cpu %d: Retiring index %d, way %d\n bit %d"
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian " type 0x%02x", cpuid, index, way, bit, type);
7bebe46c240b554f47faeed19186123896281967jc fd = open(mem_cache_device, O_RDWR);
7bebe46c240b554f47faeed19186123896281967jc if (fd == -1) {
7bebe46c240b554f47faeed19186123896281967jc fmd_hdl_debug(hdl, "Driver open failed\n");
7bebe46c240b554f47faeed19186123896281967jc return (CMA_RA_FAILURE);
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc cache_info.cpu_id = cpuid;
7bebe46c240b554f47faeed19186123896281967jc cache_info.way = way;
7bebe46c240b554f47faeed19186123896281967jc cache_info.bit = bit;
7bebe46c240b554f47faeed19186123896281967jc cache_info.index = index;
7bebe46c240b554f47faeed19186123896281967jc cache_info.cache = type == FM_FMRI_CPU_CACHE_TYPE_L3 ?
7bebe46c240b554f47faeed19186123896281967jc L3_CACHE_DATA : L2_CACHE_DATA;
7bebe46c240b554f47faeed19186123896281967jc
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian ret = ioctl(fd, MEM_CACHE_RETIRE, &cache_info);
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian /*
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * save errno before we call close.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian * Need errno to display the error if ioctl fails.
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian */
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian err = errno;
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian (void) close(fd);
7bebe46c240b554f47faeed19186123896281967jc if (ret == -1) {
a62774df315360f02521d6470eab7d5080137dadSinanallur Balasubramanian fmd_hdl_debug(hdl, "Driver call failed errno = %d\n", err);
7bebe46c240b554f47faeed19186123896281967jc return (CMA_RA_FAILURE);
7bebe46c240b554f47faeed19186123896281967jc }
7bebe46c240b554f47faeed19186123896281967jc return (CMA_RA_SUCCESS);
7bebe46c240b554f47faeed19186123896281967jc}