9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro/*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * CDDL HEADER START
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro *
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * The contents of this file are subject to the terms of the
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Common Development and Distribution License (the "License").
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * You may not use this file except in compliance with the License.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro *
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * or http://www.opensolaris.org/os/licensing.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * See the License for the specific language governing permissions
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * and limitations under the License.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro *
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * When distributing Covered Code, include this CDDL HEADER in each
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * If applicable, add the following below this CDDL HEADER, with the
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * fields enclosed by brackets "[]" replaced with your own identifying
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * information: Portions Copyright [yyyy] [name of copyright owner]
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro *
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * CDDL HEADER END
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro/*
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro/*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * sun4v Memory DR Module
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/types.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/cmn_err.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/vmem.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/kmem.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/systm.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/machsystm.h> /* for page_freelist_coalesce() */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/errno.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/memnode.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/memlist.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/memlist_impl.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/tuneable.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/proc.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/disp.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/debug.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/vm.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/callb.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/memlist_plat.h> /* for installed_top_size() */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/condvar_impl.h> /* for CV_HAS_WAITERS() */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/dumphdr.h> /* for dump_resize() */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/atomic.h> /* for use in stats collection */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/rwlock.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <vm/seg_kmem.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <vm/seg_kpm.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <vm/page.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <vm/vm_dep.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#define SUNDDI_IMPL /* so sunddi.h will not redefine splx() et al */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/sunddi.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/mem_config.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/mem_cage.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/lgrp.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/ddi.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/modctl.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/sysevent/dr.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/mach_descrip.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/mdesc.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/ds.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/drctl.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/dr_util.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#include <sys/dr_mem.h>
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian#include <sys/suspend.h>
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro/*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * DR operations are subject to Memory Alignment restrictions
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * for both address and the size of the request.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#define MA_ADDR 0x10000000 /* addr alignment 256M */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#define MA_SIZE 0x10000000 /* size alignment 256M */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#define MBLK_IS_VALID(m) \
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro (IS_P2ALIGNED((m)->addr, MA_ADDR) && IS_P2ALIGNED((m)->size, MA_SIZE))
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic memhandle_t dr_mh; /* memory handle for delete */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic struct modlmisc modlmisc = {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro &mod_miscops,
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro "sun4v memory DR"
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro};
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic struct modlinkage modlinkage = {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro MODREV_1,
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro (void *)&modlmisc,
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro NULL
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro};
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int dr_mem_allow_unload = 0;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorotypedef int (*fn_t)(dr_mem_blk_t *, int *);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro/*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Global Domain Services (DS) Handle
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic ds_svc_hdl_t ds_handle;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro/*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Supported DS Capability Versions
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic ds_ver_t dr_mem_vers[] = { { 1, 0 } };
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro#define DR_MEM_NVERS (sizeof (dr_mem_vers) / sizeof (dr_mem_vers[0]))
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro/*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * DS Capability Description
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic ds_capability_t dr_mem_cap = {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_MEM_DS_ID, /* svc_id */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro dr_mem_vers, /* vers */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_MEM_NVERS /* nvers */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro};
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro/*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * DS Callbacks
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic void dr_mem_reg_handler(ds_cb_arg_t, ds_ver_t *, ds_svc_hdl_t);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic void dr_mem_unreg_handler(ds_cb_arg_t arg);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic void dr_mem_data_handler(ds_cb_arg_t arg, void *buf, size_t buflen);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro/*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * DS Client Ops Vector
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic ds_clnt_ops_t dr_mem_ops = {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro dr_mem_reg_handler, /* ds_reg_cb */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro dr_mem_unreg_handler, /* ds_unreg_cb */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro dr_mem_data_handler, /* ds_data_cb */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro NULL /* cb_arg */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro};
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro/*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Operation Results
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro *
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Used internally to gather results while an operation on a
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * list of mblks is in progress. In particular, it is used to
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * keep track of which mblks have already failed so that they are
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * not processed further, and the manner in which they failed.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorotypedef struct {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro uint64_t addr;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro uint64_t size;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro uint32_t result;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro uint32_t status;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro char *string;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro} dr_mem_res_t;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic char *
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorodr_mem_estr[] = {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro "operation succeeded", /* DR_MEM_RES_OK */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro "operation failed", /* DR_MEM_RES_FAILURE */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro "operation was blocked", /* DR_MEM_RES_BLOCKED */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro "memory not defined in MD", /* DR_MEM_RES_NOT_IN_MD */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro "memory already in use", /* DR_MEM_RES_ESPAN */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro "memory access test failed", /* DR_MEM_RES_EFAULT */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro "resource not available", /* DR_MEM_RES_ERESOURCE */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro "permanent pages in span", /* DR_MEM_RES_PERM */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro "memory span busy", /* DR_MEM_RES_EBUSY */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro "VM viability test failed", /* DR_MEM_RES_ENOTVIABLE */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro "no pages to unconfigure", /* DR_MEM_RES_ENOWORK */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro "operation cancelled", /* DR_MEM_RES_ECANCELLED */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro "operation refused", /* DR_MEM_RES_EREFUSED */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro "memory span duplicate", /* DR_MEM_RES_EDUP */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro "invalid argument" /* DR_MEM_RES_EINVAL */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro};
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilianstatic char *
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandiliandr_mem_estr_detail[] = {
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian "", /* DR_MEM_SRES_NONE */
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian "memory DR disabled after migration" /* DR_MEM_SRES_OS_SUSPENDED */
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian};
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorotypedef struct {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro kcondvar_t cond;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro kmutex_t lock;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int error;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int done;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro} mem_sync_t;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro/*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Internal Functions
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int dr_mem_init(void);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int dr_mem_fini(void);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int dr_mem_list_wrk(dr_mem_hdr_t *, dr_mem_hdr_t **, int *);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int dr_mem_list_query(dr_mem_hdr_t *, dr_mem_hdr_t **, int *);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int dr_mem_del_stat(dr_mem_hdr_t *, dr_mem_hdr_t **, int *);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int dr_mem_del_cancel(dr_mem_hdr_t *, dr_mem_hdr_t **, int *);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int dr_mem_unconfigure(dr_mem_blk_t *, int *);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int dr_mem_configure(dr_mem_blk_t *, int *);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic void dr_mem_query(dr_mem_blk_t *, dr_mem_query_t *);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic dr_mem_res_t *dr_mem_res_array_init(dr_mem_hdr_t *, drctl_rsrc_t *, int);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic void dr_mem_res_array_fini(dr_mem_res_t *res, int nres);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic size_t dr_mem_pack_response(dr_mem_hdr_t *req, dr_mem_res_t *res,
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro dr_mem_hdr_t **respp);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int dr_mem_find(dr_mem_blk_t *mbp);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic mde_cookie_t dr_mem_find_node_md(dr_mem_blk_t *, md_t *, mde_cookie_t *);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int mem_add(pfn_t, pgcnt_t);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int mem_del(pfn_t, pgcnt_t);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloroextern int kphysm_add_memory_dynamic(pfn_t, pgcnt_t);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloroint
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro_init(void)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro{
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int status;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* check that Memory DR is enabled */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (dr_is_disabled(DR_TYPE_MEM))
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (ENOTSUP);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if ((status = dr_mem_init()) != 0) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro cmn_err(CE_NOTE, "Memory DR initialization failed");
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (status);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if ((status = mod_install(&modlinkage)) != 0) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro (void) dr_mem_fini();
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (status);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro}
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloroint
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro_info(struct modinfo *modinfop)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro{
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (mod_info(&modlinkage, modinfop));
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro}
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloroint
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro_fini(void)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro{
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int status;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (dr_mem_allow_unload == 0)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (EBUSY);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if ((status = mod_remove(&modlinkage)) == 0) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro (void) dr_mem_fini();
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (status);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro}
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorodr_mem_init(void)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro{
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int rv;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if ((rv = ds_cap_init(&dr_mem_cap, &dr_mem_ops)) != 0) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro cmn_err(CE_NOTE, "dr_mem: ds_cap_init failed: %d", rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (0);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro}
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorodr_mem_fini(void)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro{
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int rv;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if ((rv = ds_cap_fini(&dr_mem_cap)) != 0) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro cmn_err(CE_NOTE, "dr_mem: ds_cap_fini failed: %d", rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro}
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic void
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorodr_mem_reg_handler(ds_cb_arg_t arg, ds_ver_t *ver, ds_svc_hdl_t hdl)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro{
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("reg_handler: arg=0x%p, ver=%d.%d, hdl=0x%lx\n", arg,
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro ver->major, ver->minor, hdl);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro ds_handle = hdl;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro}
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic void
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorodr_mem_unreg_handler(ds_cb_arg_t arg)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro{
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("unreg_handler: arg=0x%p\n", arg);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro ds_handle = DS_INVALID_HDL;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro}
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro/*ARGSUSED*/
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic void
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorodr_mem_data_handler(ds_cb_arg_t arg, void *buf, size_t buflen)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro{
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro dr_mem_hdr_t *req = buf;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro dr_mem_hdr_t err_resp;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro dr_mem_hdr_t *resp = &err_resp;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int resp_len = 0;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int rv = EINVAL;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Sanity check the message
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (buflen < sizeof (dr_mem_hdr_t)) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("incoming message short: expected at least %ld "
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro "bytes, received %ld\n", sizeof (dr_mem_hdr_t), buflen);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro goto done;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (req == NULL) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("empty message: expected at least %ld bytes\n",
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro sizeof (dr_mem_hdr_t));
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro goto done;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("incoming request:\n");
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_DUMP_MSG(buf, buflen);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Process the command
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro switch (req->msg_type) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro case DR_MEM_CONFIGURE:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro case DR_MEM_UNCONFIGURE:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (req->msg_arg == 0) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("No mblks specified for operation\n");
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro goto done;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if ((rv = dr_mem_list_wrk(req, &resp, &resp_len)) != 0) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("%s failed (%d)\n",
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro (req->msg_type == DR_MEM_CONFIGURE) ?
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro "Memory configure" : "Memory unconfigure", rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro break;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro case DR_MEM_UNCONF_STATUS:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if ((rv = dr_mem_del_stat(req, &resp, &resp_len)) != 0)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("Memory delete status failed (%d)\n", rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro break;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro case DR_MEM_UNCONF_CANCEL:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if ((rv = dr_mem_del_cancel(req, &resp, &resp_len)) != 0)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("Memory delete cancel failed (%d)\n", rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro break;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro case DR_MEM_QUERY:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (req->msg_arg == 0) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("No mblks specified for operation\n");
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro goto done;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if ((rv = dr_mem_list_query(req, &resp, &resp_len)) != 0)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("Memory query failed (%d)\n", rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro break;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro default:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro cmn_err(CE_NOTE, "unsupported memory DR operation (%d)",
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro req->msg_type);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro break;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorodone:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* check if an error occurred */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (resp == &err_resp) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro resp->req_num = (req) ? req->req_num : 0;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro resp->msg_type = DR_MEM_ERROR;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro resp->msg_arg = rv;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro resp_len = sizeof (dr_mem_hdr_t);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("outgoing response:\n");
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_DUMP_MSG(resp, resp_len);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* send back the response */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (ds_cap_send(ds_handle, resp, resp_len) != 0) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("ds_send failed\n");
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* free any allocated memory */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (resp != &err_resp) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro kmem_free(resp, resp_len);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro}
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilianstatic char *
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandiliandr_mem_get_errstr(int result, int subresult)
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian{
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian size_t len;
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian char *errstr;
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian const char *separator = ": ";
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian if (subresult == DR_MEM_SRES_NONE)
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian return (i_ddi_strdup(dr_mem_estr[result], KM_SLEEP));
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian len = snprintf(NULL, 0, "%s%s%s", dr_mem_estr[result],
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian separator, dr_mem_estr_detail[subresult]) + 1;
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian errstr = kmem_alloc(len, KM_SLEEP);
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian (void) snprintf(errstr, len, "%s%s%s", dr_mem_estr[result],
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian separator, dr_mem_estr_detail[subresult]);
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian return (errstr);
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian}
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro/*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Common routine to config or unconfig multiple mblks.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro *
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Note: Do not modify result buffer or length on error.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorodr_mem_list_wrk(dr_mem_hdr_t *req, dr_mem_hdr_t **resp, int *resp_len)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro{
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int rv;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int idx;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int count;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int result;
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian int subresult;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int status;
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian boolean_t suspend_allows_dr;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro fn_t dr_fn;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int se_hint;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro dr_mem_blk_t *req_mblks;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro dr_mem_res_t *res;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int drctl_cmd;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int drctl_flags = 0;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drctl_rsrc_t *drctl_req;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro size_t drctl_req_len;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drctl_resp_t *drctl_resp;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drctl_rsrc_t *drctl_rsrc;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro size_t drctl_resp_len = 0;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drctl_cookie_t drctl_res_ck;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro ASSERT((req != NULL) && (req->msg_arg != 0));
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro count = req->msg_arg;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Extract all information that is specific
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * to the various types of operations.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro switch (req->msg_type) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro case DR_MEM_CONFIGURE:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro dr_fn = dr_mem_configure;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drctl_cmd = DRCTL_MEM_CONFIG_REQUEST;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro se_hint = SE_HINT_INSERT;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro break;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro case DR_MEM_UNCONFIGURE:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro dr_fn = dr_mem_unconfigure;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drctl_cmd = DRCTL_MEM_UNCONFIG_REQUEST;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro se_hint = SE_HINT_REMOVE;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro break;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro default:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* Programming error if we reach this. */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro cmn_err(CE_NOTE, "%s: bad msg_type %d\n",
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro __func__, req->msg_type);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro ASSERT(0);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (-1);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* the incoming array of mblks to operate on */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro req_mblks = DR_MEM_CMD_MBLKS(req);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* allocate drctl request msg based on incoming resource count */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drctl_req_len = sizeof (drctl_rsrc_t) * count;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drctl_req = kmem_zalloc(drctl_req_len, KM_SLEEP);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* copy the size for the drctl call from the incoming request msg */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro for (idx = 0; idx < count; idx++) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drctl_req[idx].res_mem_addr = req_mblks[idx].addr;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drctl_req[idx].res_mem_size = req_mblks[idx].size;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = drctl_config_init(drctl_cmd, drctl_flags, drctl_req,
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro count, &drctl_resp, &drctl_resp_len, &drctl_res_ck);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro ASSERT((drctl_resp != NULL) && (drctl_resp_len != 0));
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (rv != 0) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("%s: drctl_config_init returned: %d\n",
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro __func__, rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro kmem_free(drctl_resp, drctl_resp_len);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro kmem_free(drctl_req, drctl_req_len);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro ASSERT(drctl_resp->resp_type == DRCTL_RESP_OK);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drctl_rsrc = drctl_resp->resp_resources;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* create the result scratch array */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro res = dr_mem_res_array_init(req, drctl_rsrc, count);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian /*
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian * Memory DR operations are not safe if we have been suspended and
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian * resumed. Until this limitation is lifted, check to see if memory
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian * DR operations are permitted at this time by the suspend subsystem.
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian */
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian if ((suspend_allows_dr = suspend_memdr_allowed()) == B_FALSE) {
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian result = DR_MEM_RES_BLOCKED;
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian subresult = DR_MEM_SRES_OS_SUSPENDED;
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian } else {
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian subresult = DR_MEM_SRES_NONE;
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian }
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* perform the specified operation on each of the mblks */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro for (idx = 0; idx < count; idx++) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * If no action will be taken against the current
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * mblk, update the drctl resource information to
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * ensure that it gets recovered properly during
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * the drctl fini() call.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (res[idx].result != DR_MEM_RES_OK) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drctl_req[idx].status = DRCTL_STATUS_CONFIG_FAILURE;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro continue;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian /*
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian * If memory DR operations are permitted at this time by
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian * the suspend subsystem, call the function to perform the
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian * operation, otherwise return a result indicating that the
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian * operation was blocked.
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian */
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian if (suspend_allows_dr)
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian result = (*dr_fn)(&req_mblks[idx], &status);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* save off results of the operation */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro res[idx].result = result;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro res[idx].status = status;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro res[idx].addr = req_mblks[idx].addr; /* for partial case */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro res[idx].size = req_mblks[idx].size; /* for partial case */
02b4e56ca3a4e4a4fe9e52fca9c2972101f0e57fHaik Aftandilian res[idx].string = dr_mem_get_errstr(result, subresult);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* save result for drctl fini() reusing init() msg memory */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drctl_req[idx].status = (result != DR_MEM_RES_OK) ?
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DRCTL_STATUS_CONFIG_FAILURE : DRCTL_STATUS_CONFIG_SUCCESS;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("%s: mblk 0x%lx.0x%lx stat %d result %d off '%s'\n",
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro __func__, req_mblks[idx].addr, req_mblks[idx].size,
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro drctl_req[idx].status, result,
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro (res[idx].string) ? res[idx].string : "");
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if ((rv = drctl_config_fini(&drctl_res_ck, drctl_req, count)) != 0)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("%s: drctl_config_fini returned: %d\n",
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro __func__, rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Operation completed without any fatal errors.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Pack the response for transmission.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro *resp_len = dr_mem_pack_response(req, res, resp);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* notify interested parties about the operation */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro dr_generate_event(DR_TYPE_MEM, se_hint);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Deallocate any scratch memory.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro kmem_free(drctl_resp, drctl_resp_len);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro kmem_free(drctl_req, drctl_req_len);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro dr_mem_res_array_fini(res, count);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (0);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro}
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro/*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Allocate and initialize a result array based on the initial
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * drctl operation. A valid result array is always returned.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic dr_mem_res_t *
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorodr_mem_res_array_init(dr_mem_hdr_t *req, drctl_rsrc_t *rsrc, int nrsrc)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro{
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int idx;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro dr_mem_res_t *res;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro char *err_str;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro size_t err_len;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* allocate zero filled buffer to initialize fields */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro res = kmem_zalloc(nrsrc * sizeof (dr_mem_res_t), KM_SLEEP);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Fill in the result information for each resource.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro for (idx = 0; idx < nrsrc; idx++) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro res[idx].addr = rsrc[idx].res_mem_addr;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro res[idx].size = rsrc[idx].res_mem_size;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro res[idx].result = DR_MEM_RES_OK;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (rsrc[idx].status == DRCTL_STATUS_ALLOW)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro continue;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Update the state information for this mblk.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro res[idx].result = DR_MEM_RES_BLOCKED;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro res[idx].status = (req->msg_type == DR_MEM_CONFIGURE) ?
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_MEM_STAT_UNCONFIGURED : DR_MEM_STAT_CONFIGURED;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * If an error string exists, copy it out of the
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * message buffer. This eliminates any dependency
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * on the memory allocated for the message buffer
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * itself.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (rsrc[idx].offset != NULL) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro err_str = (char *)rsrc + rsrc[idx].offset;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro err_len = strlen(err_str) + 1;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro res[idx].string = kmem_alloc(err_len, KM_SLEEP);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro bcopy(err_str, res[idx].string, err_len);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (res);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro}
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic void
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorodr_mem_res_array_fini(dr_mem_res_t *res, int nres)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro{
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int idx;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro size_t str_len;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro for (idx = 0; idx < nres; idx++) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* deallocate the error string if present */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (res[idx].string) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro str_len = strlen(res[idx].string) + 1;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro kmem_free(res[idx].string, str_len);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* deallocate the result array itself */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro kmem_free(res, sizeof (dr_mem_res_t) * nres);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro}
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro/*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Allocate and pack a response message for transmission based
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * on the specified result array. A valid response message and
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * valid size information is always returned.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic size_t
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorodr_mem_pack_response(dr_mem_hdr_t *req, dr_mem_res_t *res, dr_mem_hdr_t **respp)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro{
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int idx;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro dr_mem_hdr_t *resp;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro dr_mem_stat_t *resp_stat;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro size_t resp_len;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro uint32_t curr_off;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro caddr_t curr_str;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro size_t str_len;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro size_t stat_len;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int nstat = req->msg_arg;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Calculate the size of the response message
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * and allocate an appropriately sized buffer.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro resp_len = sizeof (dr_mem_hdr_t);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* add the stat array size */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro stat_len = sizeof (dr_mem_stat_t) * nstat;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro resp_len += stat_len;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* add the size of any error strings */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro for (idx = 0; idx < nstat; idx++) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (res[idx].string != NULL) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro resp_len += strlen(res[idx].string) + 1;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* allocate the message buffer */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro resp = kmem_zalloc(resp_len, KM_SLEEP);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Fill in the header information.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro resp->req_num = req->req_num;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro resp->msg_type = DR_MEM_OK;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro resp->msg_arg = nstat;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Fill in the stat information.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro resp_stat = DR_MEM_RESP_STATS(resp);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* string offsets start immediately after stat array */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro curr_off = sizeof (dr_mem_hdr_t) + stat_len;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro curr_str = (char *)resp_stat + stat_len;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro for (idx = 0; idx < nstat; idx++) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro resp_stat[idx].addr = res[idx].addr;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro resp_stat[idx].size = res[idx].size;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro resp_stat[idx].result = res[idx].result;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro resp_stat[idx].status = res[idx].status;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (res[idx].string != NULL) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* copy over the error string */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro str_len = strlen(res[idx].string) + 1;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro bcopy(res[idx].string, curr_str, str_len);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro resp_stat[idx].string_off = curr_off;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro curr_off += str_len;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro curr_str += str_len;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* buffer should be exactly filled */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro ASSERT(curr_off == resp_len);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro *respp = resp;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (resp_len);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro}
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic void
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorodr_mem_query(dr_mem_blk_t *mbp, dr_mem_query_t *mqp)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro{
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro memquery_t mq;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("dr_mem_query...\n");
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro (void) kphysm_del_span_query(btop(mbp->addr), btop(mbp->size), &mq);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (!mq.phys_pages)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro mqp->addr = mbp->addr;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro mqp->mq.phys_pages = ptob(mq.phys_pages);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro mqp->mq.managed = ptob(mq.managed);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro mqp->mq.nonrelocatable = ptob(mq.nonrelocatable);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro mqp->mq.first_nonrelocatable = ptob(mq.first_nonrelocatable);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro mqp->mq.last_nonrelocatable = ptob(mq.last_nonrelocatable);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Set to the max byte offset within the page.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (mqp->mq.nonrelocatable)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro mqp->mq.last_nonrelocatable += PAGESIZE - 1;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro}
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro/*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Do not modify result buffer or length on error.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorodr_mem_list_query(dr_mem_hdr_t *req, dr_mem_hdr_t **resp, int *resp_len)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro{
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int idx;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int rlen;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int nml;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro struct memlist *ml;
79afa7fba66c808623862442107f913bce5ea783Sean McEnroe struct memlist *phys_copy = NULL;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro dr_mem_blk_t *req_mblks, mb;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro dr_mem_hdr_t *rp;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro dr_mem_query_t *stat;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe drctl_block();
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* the incoming array of req_mblks to configure */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro req_mblks = DR_MEM_CMD_MBLKS(req);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* allocate a response message, should be freed by caller */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro nml = 0;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rlen = sizeof (dr_mem_hdr_t);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (req_mblks->addr == NULL && req_mblks->size == 0) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Request is for domain's full view of it's memory.
79afa7fba66c808623862442107f913bce5ea783Sean McEnroe * place a copy in phys_copy then release the memlist lock.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro memlist_read_lock();
79afa7fba66c808623862442107f913bce5ea783Sean McEnroe phys_copy = dr_memlist_dup(phys_install);
79afa7fba66c808623862442107f913bce5ea783Sean McEnroe memlist_read_unlock();
79afa7fba66c808623862442107f913bce5ea783Sean McEnroe
79afa7fba66c808623862442107f913bce5ea783Sean McEnroe for (ml = phys_copy; ml; ml = ml->ml_next)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro nml++;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rlen += nml * sizeof (dr_mem_query_t);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro } else {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rlen += req->msg_arg * sizeof (dr_mem_query_t);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rp = kmem_zalloc(rlen, KM_SLEEP);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* fill in the known data */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rp->req_num = req->req_num;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rp->msg_type = DR_MEM_OK;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rp->msg_arg = nml ? nml : req->msg_arg;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* stat array for the response */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro stat = DR_MEM_RESP_QUERY(rp);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* get the status for each of the mblocks */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (nml) {
79afa7fba66c808623862442107f913bce5ea783Sean McEnroe for (idx = 0, ml = phys_copy; ml; ml = ml->ml_next, idx++) {
56f33205c9ed776c3c909e07d52e94610a675740Jonathan Adams mb.addr = ml->ml_address;
56f33205c9ed776c3c909e07d52e94610a675740Jonathan Adams mb.size = ml->ml_size;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro dr_mem_query(&mb, &stat[idx]);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro } else {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro for (idx = 0; idx < req->msg_arg; idx++)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro dr_mem_query(&req_mblks[idx], &stat[idx]);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro *resp = rp;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro *resp_len = rlen;
79afa7fba66c808623862442107f913bce5ea783Sean McEnroe if (phys_copy != NULL) {
79afa7fba66c808623862442107f913bce5ea783Sean McEnroe dr_memlist_delete(phys_copy);
79afa7fba66c808623862442107f913bce5ea783Sean McEnroe }
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe drctl_unblock();
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (0);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro}
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorocvt_err(int err)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro{
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int rv;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro switch (err) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro case KPHYSM_OK:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = DR_MEM_RES_OK;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro break;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro case KPHYSM_ESPAN:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = DR_MEM_RES_ESPAN;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro break;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro case KPHYSM_EFAULT:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = DR_MEM_RES_EFAULT;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro break;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro case KPHYSM_ERESOURCE:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = DR_MEM_RES_ERESOURCE;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro break;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro case KPHYSM_ENOTSUP:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro case KPHYSM_ENOHANDLES:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = DR_MEM_RES_FAILURE;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro break;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro case KPHYSM_ENONRELOC:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = DR_MEM_RES_PERM;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro break;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro case KPHYSM_EHANDLE:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = DR_MEM_RES_FAILURE;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro break;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro case KPHYSM_EBUSY:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = DR_MEM_RES_EBUSY;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro break;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro case KPHYSM_ENOTVIABLE:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = DR_MEM_RES_ENOTVIABLE;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro break;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro case KPHYSM_ESEQUENCE:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = DR_MEM_RES_FAILURE;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro break;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro case KPHYSM_ENOWORK:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = DR_MEM_RES_ENOWORK;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro break;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro case KPHYSM_ECANCELLED:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = DR_MEM_RES_ECANCELLED;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro break;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro case KPHYSM_EREFUSED:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = DR_MEM_RES_EREFUSED;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro break;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro case KPHYSM_ENOTFINISHED:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro case KPHYSM_ENOTRUNNING:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = DR_MEM_RES_FAILURE;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro break;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro case KPHYSM_EDUP:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = DR_MEM_RES_EDUP;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro break;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro default:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = DR_MEM_RES_FAILURE;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro break;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro}
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorodr_mem_configure(dr_mem_blk_t *mbp, int *status)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro{
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int rv;
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe uint64_t addr, size;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = 0;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro addr = mbp->addr;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro size = mbp->size;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("dr_mem_configure...\n");
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (!MBLK_IS_VALID(mbp)) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("invalid mblk 0x%lx.0x%lx\n", addr, size);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro *status = DR_MEM_STAT_UNCONFIGURED;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = DR_MEM_RES_EINVAL;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro } else if (rv = dr_mem_find(mbp)) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("failed to find mblk 0x%lx.0x%lx (%d)\n",
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro addr, size, rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (rv == EINVAL) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro *status = DR_MEM_STAT_NOT_PRESENT;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = DR_MEM_RES_NOT_IN_MD;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro } else {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro *status = DR_MEM_STAT_UNCONFIGURED;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = DR_MEM_RES_FAILURE;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro } else {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = mem_add(btop(addr), btop(size));
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("addr=0x%lx size=0x%lx rv=%d\n", addr, size, rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (rv) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro *status = DR_MEM_STAT_UNCONFIGURED;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro } else {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro *status = DR_MEM_STAT_CONFIGURED;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro}
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorodr_mem_unconfigure(dr_mem_blk_t *mbp, int *status)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro{
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int rv;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("dr_mem_unconfigure...\n");
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (!MBLK_IS_VALID(mbp)) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("invalid mblk 0x%lx.0x%lx\n",
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro mbp->addr, mbp->size);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro *status = DR_MEM_STAT_CONFIGURED;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = DR_MEM_RES_EINVAL;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro } else if (rv = mem_del(btop(mbp->addr), btop(mbp->size))) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro *status = DR_MEM_STAT_CONFIGURED;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro } else {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro *status = DR_MEM_STAT_UNCONFIGURED;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = DR_MEM_RES_OK;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("mblk 0x%lx.0x%lx unconfigured\n",
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro mbp->addr, mbp->size);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro}
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorodr_mem_del_stat(dr_mem_hdr_t *req, dr_mem_hdr_t **resp, int *resp_len)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro{
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int status;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int rlen;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro memdelstat_t del_stat, *stat;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro dr_mem_hdr_t *rp;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * If a mem delete is in progress, get its status.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro status = (dr_mh && (kphysm_del_status(dr_mh, &del_stat) == KPHYSM_OK));
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* allocate a response message, should be freed by caller */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rlen = sizeof (dr_mem_hdr_t);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rlen += status * sizeof (memdelstat_t);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rp = kmem_zalloc(rlen, KM_SLEEP);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* fill in the known data */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rp->req_num = req->req_num;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rp->msg_type = DR_MEM_OK;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rp->msg_arg = status;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (status) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* stat struct for the response */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro stat = DR_MEM_RESP_DEL_STAT(rp);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro stat->phys_pages = ptob(del_stat.phys_pages);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro stat->managed = ptob(del_stat.managed);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro stat->collected = ptob(del_stat.collected);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro *resp = rp;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro *resp_len = rlen;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (0);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro}
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorodr_mem_del_cancel(dr_mem_hdr_t *req, dr_mem_hdr_t **resp, int *resp_len)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro{
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int rlen;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro dr_mem_hdr_t *rp;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* allocate a response message, should be freed by caller */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rlen = sizeof (dr_mem_hdr_t);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rp = kmem_zalloc(rlen, KM_SLEEP);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* fill in the known data */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rp->req_num = req->req_num;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rp->msg_type = DR_MEM_OK;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rp->msg_arg = (dr_mh && kphysm_del_cancel(dr_mh) != KPHYSM_OK) ?
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_MEM_RES_EINVAL : DR_MEM_RES_OK;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro *resp = rp;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro *resp_len = rlen;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (0);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro}
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorodr_mem_find(dr_mem_blk_t *mbp)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro{
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro md_t *mdp = NULL;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int num_nodes;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int rv = 0;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int listsz;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro mde_cookie_t *listp = NULL;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro mde_cookie_t memnode;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro char *found = "found";
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if ((mdp = md_get_handle()) == NULL) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("unable to initialize machine description\n");
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (-1);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro num_nodes = md_node_count(mdp);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro ASSERT(num_nodes > 0);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro listsz = num_nodes * sizeof (mde_cookie_t);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro listp = kmem_zalloc(listsz, KM_SLEEP);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro memnode = dr_mem_find_node_md(mbp, mdp, listp);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (memnode == MDE_INVAL_ELEM_COOKIE) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = EINVAL;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro found = "not found";
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("mblk 0x%lx.0x%lx %s\n", mbp->addr, mbp->size, found);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro kmem_free(listp, listsz);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro (void) md_fini_handle(mdp);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro}
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro/*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Look up a particular mblk in the MD. Returns the mde_cookie_t
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * representing that mblk if present, and MDE_INVAL_ELEM_COOKIE
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * otherwise. It is assumed the scratch array has already been
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * allocated so that it can accommodate the worst case scenario,
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * every node in the MD.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic mde_cookie_t
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorodr_mem_find_node_md(dr_mem_blk_t *mbp, md_t *mdp, mde_cookie_t *listp)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro{
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int idx;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int nnodes;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro mde_cookie_t rootnode;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro uint64_t base_prop;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro uint64_t size_prop;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro mde_cookie_t result = MDE_INVAL_ELEM_COOKIE;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rootnode = md_root_node(mdp);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro ASSERT(rootnode != MDE_INVAL_ELEM_COOKIE);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Scan the DAG for all the mem nodes
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro nnodes = md_scan_dag(mdp, rootnode, md_find_name(mdp, "mblock"),
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro md_find_name(mdp, "fwd"), listp);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (nnodes < 0) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("Scan for mblks failed\n");
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (result);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("dr_mem_find_node_md: found %d mblks in the MD\n", nnodes);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Find the mblk of interest
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro for (idx = 0; idx < nnodes; idx++) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (md_get_prop_val(mdp, listp[idx], "base", &base_prop)) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("Missing 'base' property for mblk node %d\n",
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro idx);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro break;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (md_get_prop_val(mdp, listp[idx], "size", &size_prop)) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("Missing 'size' property for mblk node %d\n",
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro idx);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro break;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (base_prop <= mbp->addr &&
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro (base_prop + size_prop) >= (mbp->addr + mbp->size)) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /* found a match */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("dr_mem_find_node_md: found mblk "
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro "0x%lx.0x%lx in MD\n", mbp->addr, mbp->size);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro result = listp[idx];
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro break;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (result == MDE_INVAL_ELEM_COOKIE) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("mblk 0x%lx.0x%lx not in MD\n",
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro mbp->addr, mbp->size);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (result);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro}
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloromem_add(pfn_t base, pgcnt_t npgs)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro{
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int rv, rc;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("%s: begin base=0x%lx npgs=0x%lx\n", __func__, base, npgs);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (npgs == 0)
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe return (DR_MEM_RES_OK);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = kphysm_add_memory_dynamic(base, npgs);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("%s: kphysm_add(0x%lx, 0x%lx) = %d", __func__, base, npgs,
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv);
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe if (rv == KPHYSM_OK) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (rc = kcage_range_add(base, npgs, KCAGE_DOWN))
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro cmn_err(CE_WARN, "kcage_range_add() = %d", rc);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe rv = cvt_err(rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro}
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic void
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorodel_done(void *arg, int error)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro{
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro mem_sync_t *ms = arg;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro mutex_enter(&ms->lock);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro ms->error = error;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro ms->done = 1;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro cv_signal(&ms->cond);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro mutex_exit(&ms->lock);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro}
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorostatic int
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloromem_del(pfn_t base, pgcnt_t npgs)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro{
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro int rv, err, del_range = 0;
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe int convert = 1;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro mem_sync_t ms;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro memquery_t mq;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro memhandle_t mh;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro struct memlist *ml;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro struct memlist *d_ml = NULL;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("%s: begin base=0x%lx npgs=0x%lx\n", __func__, base, npgs);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (npgs == 0)
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe return (DR_MEM_RES_OK);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if ((rv = kphysm_del_gethandle(&mh)) != KPHYSM_OK) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro cmn_err(CE_WARN, "%s: del_gethandle() = %d", __func__, rv);
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe rv = cvt_err(rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if ((rv = kphysm_del_span_query(base, npgs, &mq))
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro != KPHYSM_OK) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro cmn_err(CE_WARN, "%s: del_span_query() = %d", __func__, rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro goto done;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (mq.nonrelocatable) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("%s: non-reloc pages = %ld",
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro __func__, mq.nonrelocatable);
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe rv = KPHYSM_ENONRELOC;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro goto done;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (rv = kcage_range_delete(base, npgs)) {
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe switch (rv) {
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe case EBUSY:
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe rv = DR_MEM_RES_ENOTVIABLE;
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe break;
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe default:
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe rv = DR_MEM_RES_FAILURE;
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe break;
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe }
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe convert = 0; /* conversion done */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro cmn_err(CE_WARN, "%s: del_range() = %d", __func__, rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro goto done;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro } else {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro del_range++;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if ((rv = kphysm_del_span(mh, base, npgs)) != KPHYSM_OK) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro cmn_err(CE_WARN, "%s: del_span() = %d", __func__, rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro goto done;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if ((rv = memlist_add_span(ptob(base), ptob(npgs), &d_ml))
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro != MEML_SPANOP_OK) {
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe switch (rv) {
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe case MEML_SPANOP_ESPAN:
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe rv = DR_MEM_RES_ESPAN;
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe break;
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe case MEML_SPANOP_EALLOC:
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe rv = DR_MEM_RES_ERESOURCE;
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe break;
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe default:
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe rv = DR_MEM_RES_FAILURE;
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe break;
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe }
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe convert = 0; /* conversion done */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro cmn_err(CE_WARN, "%s: add_span() = %d", __func__, rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro goto done;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("%s: reserved=0x%lx", __func__, npgs);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro bzero((void *) &ms, sizeof (ms));
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro mutex_init(&ms.lock, NULL, MUTEX_DRIVER, NULL);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro cv_init(&ms.cond, NULL, CV_DRIVER, NULL);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro mutex_enter(&ms.lock);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if ((rv = kphysm_del_start(mh, del_done, (void *) &ms)) == KPHYSM_OK) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Since we've called drctl_config_init, we are the only
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * DR ctl operation in progress. Set dr_mh to the
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * delete memhandle for use by stat and cancel.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro ASSERT(dr_mh == NULL);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro dr_mh = mh;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Wait for completion or interrupt.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro while (!ms.done) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (cv_wait_sig(&ms.cond, &ms.lock) == 0) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * There is a pending signal.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro (void) kphysm_del_cancel(mh);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("%s: cancel", __func__);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Wait for completion.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro while (!ms.done)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro cv_wait(&ms.cond, &ms.lock);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro dr_mh = NULL;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro rv = ms.error;
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro } else {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("%s: del_start() = %d", __func__, rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro mutex_exit(&ms.lock);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro cv_destroy(&ms.cond);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro mutex_destroy(&ms.lock);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Belorodone:
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if (rv && del_range) {
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro /*
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro * Add back the spans to the kcage growth list.
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro */
56f33205c9ed776c3c909e07d52e94610a675740Jonathan Adams for (ml = d_ml; ml; ml = ml->ml_next)
56f33205c9ed776c3c909e07d52e94610a675740Jonathan Adams if (err = kcage_range_add(btop(ml->ml_address),
56f33205c9ed776c3c909e07d52e94610a675740Jonathan Adams btop(ml->ml_size), KCAGE_DOWN))
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro cmn_err(CE_WARN, "kcage_range_add() = %d", err);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro }
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro memlist_free_list(d_ml);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro if ((err = kphysm_del_release(mh)) != KPHYSM_OK)
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro cmn_err(CE_WARN, "%s: del_release() = %d", __func__, err);
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe if (convert)
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe rv = cvt_err(rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro DR_DBG_MEM("%s: rv=%d", __func__, rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro return (rv);
9853d9e82e7a067a2b88dae2fd257207e6be5f94Jason Beloro}