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 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * Fault-handling routines for page retirement faults 28 */ 29 30 #include <cmd_page.h> 31 #include <cmd.h> 32 #include <cmd_mem.h> 33 34 #include <errno.h> 35 #include <string.h> 36 #include <fm/fmd_api.h> 37 #include <sys/fm/protocol.h> 38 #ifdef sun4v 39 #include <cmd_hc_sun4v.h> 40 #include <cmd_dimm.h> 41 #endif 42 43 void 44 cmd_page_fault(fmd_hdl_t *hdl, nvlist_t *modasru, nvlist_t *modfru, 45 fmd_event_t *ep, uint64_t afar) 46 { 47 cmd_page_t *page = NULL; 48 const char *uuid; 49 nvlist_t *flt; 50 #ifdef sun4v 51 nvlist_t *nvlfru; 52 #endif 53 54 page = cmd_page_lookup(afar); 55 if (page != NULL) { 56 /* 57 * If the page has already been retired then *page 58 * would have been freed and recreated. Thus the 59 * flag would be 0x0 - check to see if the page 60 * is unusable (retired). 61 */ 62 if (page->page_flags & CMD_MEM_F_FAULTING || 63 fmd_nvl_fmri_unusable(hdl, page->page_asru_nvl)) { 64 /* Page already faulted, don't fault again. */ 65 page->page_flags |= CMD_MEM_F_FAULTING; 66 return; 67 } 68 } else { 69 page = cmd_page_create(hdl, modasru, afar); 70 } 71 72 page->page_flags |= CMD_MEM_F_FAULTING; 73 if (page->page_case.cc_cp == NULL) 74 page->page_case.cc_cp = cmd_case_create(hdl, 75 &page->page_header, CMD_PTR_PAGE_CASE, &uuid); 76 77 #ifdef sun4v 78 nvlfru = cmd_mem2hc(hdl, modfru); 79 flt = cmd_nvl_create_fault(hdl, "fault.memory.page", 100, 80 page->page_asru_nvl, nvlfru, NULL); 81 flt = cmd_fault_add_location(hdl, flt, cmd_fmri_get_unum(modfru)); 82 nvlist_free(nvlfru); 83 #else /* sun4v */ 84 flt = cmd_nvl_create_fault(hdl, "fault.memory.page", 100, 85 page->page_asru_nvl, modfru, NULL); 86 #endif /* sun4v */ 87 88 if (nvlist_add_boolean_value(flt, FM_SUSPECT_MESSAGE, B_FALSE) != 0) 89 fmd_hdl_abort(hdl, "failed to add no-message member to fault"); 90 91 fmd_case_add_ereport(hdl, page->page_case.cc_cp, ep); 92 fmd_case_add_suspect(hdl, page->page_case.cc_cp, flt); 93 fmd_case_solve(hdl, page->page_case.cc_cp); 94 } 95 96 void 97 cmd_page_close(fmd_hdl_t *hdl, void *arg) 98 { 99 cmd_page_destroy(hdl, arg); 100 } 101