1600Stsien /*
2600Stsien * CDDL HEADER START
3600Stsien *
4600Stsien * The contents of this file are subject to the terms of the
53325Ssd77468 * Common Development and Distribution License (the "License").
63325Ssd77468 * You may not use this file except in compliance with the License.
7600Stsien *
8600Stsien * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9600Stsien * or http://www.opensolaris.org/os/licensing.
10600Stsien * See the License for the specific language governing permissions
11600Stsien * and limitations under the License.
12600Stsien *
13600Stsien * When distributing Covered Code, include this CDDL HEADER in each
14600Stsien * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15600Stsien * If applicable, add the following below this CDDL HEADER, with the
16600Stsien * fields enclosed by brackets "[]" replaced with your own identifying
17600Stsien * information: Portions Copyright [yyyy] [name of copyright owner]
18600Stsien *
19600Stsien * CDDL HEADER END
20600Stsien */
21600Stsien /*
22*8006STom.Pothier@Sun.COM * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23600Stsien * Use is subject to license terms.
24600Stsien */
25600Stsien
26600Stsien /*
27600Stsien * Fault-handling routines for page retirement faults
28600Stsien */
29600Stsien
30600Stsien #include <cmd_page.h>
31600Stsien #include <cmd.h>
323325Ssd77468 #include <cmd_mem.h>
33600Stsien
34600Stsien #include <errno.h>
35600Stsien #include <string.h>
36600Stsien #include <fm/fmd_api.h>
37600Stsien #include <sys/fm/protocol.h>
383657Stsien #ifdef sun4v
393657Stsien #include <cmd_hc_sun4v.h>
403657Stsien #include <cmd_dimm.h>
413657Stsien #endif
42600Stsien
43600Stsien void
cmd_page_fault(fmd_hdl_t * hdl,nvlist_t * modasru,nvlist_t * modfru,fmd_event_t * ep,uint64_t afar)44600Stsien cmd_page_fault(fmd_hdl_t *hdl, nvlist_t *modasru, nvlist_t *modfru,
45600Stsien fmd_event_t *ep, uint64_t afar)
46600Stsien {
47*8006STom.Pothier@Sun.COM cmd_page_t *page = NULL;
48600Stsien const char *uuid;
493763Std122701 nvlist_t *flt;
503763Std122701 #ifdef sun4v
513763Std122701 nvlist_t *nvlfru;
523763Std122701 #endif
53600Stsien
54*8006STom.Pothier@Sun.COM page = cmd_page_lookup(afar);
55*8006STom.Pothier@Sun.COM if (page != NULL) {
56600Stsien /*
57*8006STom.Pothier@Sun.COM * If the page has already been retired then *page
58*8006STom.Pothier@Sun.COM * would have been freed and recreated. Thus the
59*8006STom.Pothier@Sun.COM * flag would be 0x0 - check to see if the page
60*8006STom.Pothier@Sun.COM * is unusable (retired).
61600Stsien */
62*8006STom.Pothier@Sun.COM if (page->page_flags & CMD_MEM_F_FAULTING ||
63*8006STom.Pothier@Sun.COM fmd_nvl_fmri_unusable(hdl, page->page_asru_nvl)) {
64*8006STom.Pothier@Sun.COM /* Page already faulted, don't fault again. */
65*8006STom.Pothier@Sun.COM page->page_flags |= CMD_MEM_F_FAULTING;
66*8006STom.Pothier@Sun.COM return;
67*8006STom.Pothier@Sun.COM }
68*8006STom.Pothier@Sun.COM } else {
69*8006STom.Pothier@Sun.COM page = cmd_page_create(hdl, modasru, afar);
70600Stsien }
71600Stsien
72*8006STom.Pothier@Sun.COM page->page_flags |= CMD_MEM_F_FAULTING;
733325Ssd77468 if (page->page_case.cc_cp == NULL)
744934Stsien page->page_case.cc_cp = cmd_case_create(hdl,
754934Stsien &page->page_header, CMD_PTR_PAGE_CASE, &uuid);
76600Stsien
773657Stsien #ifdef sun4v
783730Std122701 nvlfru = cmd_mem2hc(hdl, modfru);
794934Stsien flt = cmd_nvl_create_fault(hdl, "fault.memory.page", 100,
803730Std122701 page->page_asru_nvl, nvlfru, NULL);
813657Stsien flt = cmd_fault_add_location(hdl, flt, cmd_fmri_get_unum(modfru));
823730Std122701 if (nvlfru != NULL)
833730Std122701 nvlist_free(nvlfru);
843657Stsien #else /* sun4v */
854934Stsien flt = cmd_nvl_create_fault(hdl, "fault.memory.page", 100,
86600Stsien page->page_asru_nvl, modfru, NULL);
873657Stsien #endif /* sun4v */
88600Stsien
89600Stsien if (nvlist_add_boolean_value(flt, FM_SUSPECT_MESSAGE, B_FALSE) != 0)
90600Stsien fmd_hdl_abort(hdl, "failed to add no-message member to fault");
91600Stsien
923325Ssd77468 fmd_case_add_ereport(hdl, page->page_case.cc_cp, ep);
933325Ssd77468 fmd_case_add_suspect(hdl, page->page_case.cc_cp, flt);
943325Ssd77468 fmd_case_solve(hdl, page->page_case.cc_cp);
95600Stsien }
96600Stsien
97600Stsien void
cmd_page_close(fmd_hdl_t * hdl,void * arg)98600Stsien cmd_page_close(fmd_hdl_t *hdl, void *arg)
99600Stsien {
100600Stsien cmd_page_destroy(hdl, arg);
101600Stsien }
102