summaryrefslogtreecommitdiff
path: root/usr/src/uts/sun4v
diff options
context:
space:
mode:
authorSean McEnroe <Sean.McEnroe@Sun.COM>2009-11-23 22:42:23 -0800
committerSean McEnroe <Sean.McEnroe@Sun.COM>2009-11-23 22:42:23 -0800
commitaf4c679f647cf088543c762e33d41a3ac52cfa14 (patch)
tree4311b62e5c03300652116b78f6474c8f020ca7e8 /usr/src/uts/sun4v
parent37b285d61e57561b538d999834714df1f5c2db53 (diff)
downloadillumos-joyent-af4c679f647cf088543c762e33d41a3ac52cfa14.tar.gz
6887924 PP_ISKAS needs to be defined in terms of VN_ISKAS for vnodes
6871169 kphysm_add_memory_dynamic panics testing vmstress + DR 6877160 guest domain panic at platsvc:mdeg_notify_client+10c 6874763 memseg_alloc_meta() incorrectly maps page_t pages 6873569 multiple calls to memlist_read_lock() can cause deadlock hazard 6886354 DR failure with "memory span duplication" error 6886782 panic after pagefault in seg_kpm after LDom add-mem on primary 6887644 domain hang/deadlock during ldom mem DR when trying to grab a write lock
Diffstat (limited to 'usr/src/uts/sun4v')
-rw-r--r--usr/src/uts/sun4v/io/dr_mem.c103
-rw-r--r--usr/src/uts/sun4v/io/drctl.c52
-rw-r--r--usr/src/uts/sun4v/io/vlds.c6
-rw-r--r--usr/src/uts/sun4v/os/memseg.c134
-rw-r--r--usr/src/uts/sun4v/promif/promif_emul.c5
-rw-r--r--usr/src/uts/sun4v/sys/drctl.h7
-rw-r--r--usr/src/uts/sun4v/vm/mach_kpm.c24
7 files changed, 124 insertions, 207 deletions
diff --git a/usr/src/uts/sun4v/io/dr_mem.c b/usr/src/uts/sun4v/io/dr_mem.c
index 2b346a6d48..a32b0af792 100644
--- a/usr/src/uts/sun4v/io/dr_mem.c
+++ b/usr/src/uts/sun4v/io/dr_mem.c
@@ -203,10 +203,6 @@ static mde_cookie_t dr_mem_find_node_md(dr_mem_blk_t *, md_t *, mde_cookie_t *);
static int mem_add(pfn_t, pgcnt_t);
static int mem_del(pfn_t, pgcnt_t);
-static size_t rsvaddsz;
-extern void i_dr_mem_init(uint64_t *);
-extern void i_dr_mem_fini();
-extern void i_dr_mem_update();
extern int kphysm_add_memory_dynamic(pfn_t, pgcnt_t);
int
@@ -261,8 +257,6 @@ dr_mem_init(void)
return (rv);
}
- i_dr_mem_init(&rsvaddsz);
-
return (0);
}
@@ -271,8 +265,6 @@ dr_mem_fini(void)
{
int rv;
- i_dr_mem_fini();
-
if ((rv = ds_cap_fini(&dr_mem_cap)) != 0) {
cmn_err(CE_NOTE, "dr_mem: ds_cap_fini failed: %d", rv);
}
@@ -720,6 +712,8 @@ dr_mem_list_query(dr_mem_hdr_t *req, dr_mem_hdr_t **resp, int *resp_len)
dr_mem_hdr_t *rp;
dr_mem_query_t *stat;
+ drctl_block();
+
/* the incoming array of req_mblks to configure */
req_mblks = DR_MEM_CMD_MBLKS(req);
@@ -764,6 +758,8 @@ dr_mem_list_query(dr_mem_hdr_t *req, dr_mem_hdr_t **resp, int *resp_len)
*resp = rp;
*resp_len = rlen;
+ drctl_unblock();
+
return (0);
}
@@ -832,7 +828,7 @@ static int
dr_mem_configure(dr_mem_blk_t *mbp, int *status)
{
int rv;
- uint64_t addr, size, addsz;
+ uint64_t addr, size;
rv = 0;
addr = mbp->addr;
@@ -854,64 +850,10 @@ dr_mem_configure(dr_mem_blk_t *mbp, int *status)
*status = DR_MEM_STAT_UNCONFIGURED;
rv = DR_MEM_RES_FAILURE;
}
- } else if (rsvaddsz) {
- addr += size;
-
- /*
- * Add up to the first <rsvaddsz> portion of mblock
- * first since that portion has reserved meta pages.
- * This will likely guarantee an additional amount of
- * free pages from which we may have to allocate the
- * rest of the meta pages.
- *
- * Break up the request in descending order (if needed)
- * in order to ensure that cage grows from the high end
- * of the original request.
- */
- for (addsz = MIN(size, rsvaddsz); addsz > 0; addsz = size) {
- ASSERT(addr >= mbp->addr);
- DR_DBG_MEM("addsz=0x%lx size=0x%lx\n", addsz, size);
- if (rv = mem_add(btop(addr - addsz), btop(addsz))) {
- DR_DBG_MEM("failed to configure span"
- " 0x%lx.0x%lx (%d)\n", addr, addsz, rv);
- break;
- } else {
- size -= addsz;
- addr -= addsz;
- }
- }
-
- /*
- * Mark the mblock configured if any span
- * in that mblock was successfully added.
- *
- * In case of partial success:
- *
- * rv != DR_MEM_RES_OK
- * status == DR_MEM_STAT_CONFIGURED
- *
- * mark span actually configured.
- */
- if (size == mbp->size && rv != KPHYSM_ESPAN) {
- *status = DR_MEM_STAT_UNCONFIGURED;
- } else {
- DR_DBG_MEM("failed (partial) to configure span"
- " 0x%lx.0x%lx (%d)\n", addr, addsz, rv);
- *status = DR_MEM_STAT_CONFIGURED;
- mbp->addr = addr;
- mbp->size -= size;
- }
-
- rv = cvt_err(rv);
- i_dr_mem_update();
} else {
- /*
- * The reserved feature is disabled, add whole mblock.
- */
rv = mem_add(btop(addr), btop(size));
DR_DBG_MEM("addr=0x%lx size=0x%lx rv=%d\n", addr, size, rv);
if (rv) {
- rv = cvt_err(rv);
*status = DR_MEM_STAT_UNCONFIGURED;
} else {
*status = DR_MEM_STAT_CONFIGURED;
@@ -934,7 +876,6 @@ dr_mem_unconfigure(dr_mem_blk_t *mbp, int *status)
*status = DR_MEM_STAT_CONFIGURED;
rv = DR_MEM_RES_EINVAL;
} else if (rv = mem_del(btop(mbp->addr), btop(mbp->size))) {
- rv = cvt_err(rv);
*status = DR_MEM_STAT_CONFIGURED;
} else {
*status = DR_MEM_STAT_UNCONFIGURED;
@@ -1117,15 +1058,16 @@ mem_add(pfn_t base, pgcnt_t npgs)
DR_DBG_MEM("%s: begin base=0x%lx npgs=0x%lx\n", __func__, base, npgs);
if (npgs == 0)
- return (0);
+ return (DR_MEM_RES_OK);
rv = kphysm_add_memory_dynamic(base, npgs);
DR_DBG_MEM("%s: kphysm_add(0x%lx, 0x%lx) = %d", __func__, base, npgs,
rv);
- if (!rv) {
+ if (rv == KPHYSM_OK) {
if (rc = kcage_range_add(base, npgs, KCAGE_DOWN))
cmn_err(CE_WARN, "kcage_range_add() = %d", rc);
}
+ rv = cvt_err(rv);
return (rv);
}
@@ -1145,6 +1087,7 @@ static int
mem_del(pfn_t base, pgcnt_t npgs)
{
int rv, err, del_range = 0;
+ int convert = 1;
mem_sync_t ms;
memquery_t mq;
memhandle_t mh;
@@ -1154,10 +1097,11 @@ mem_del(pfn_t base, pgcnt_t npgs)
DR_DBG_MEM("%s: begin base=0x%lx npgs=0x%lx\n", __func__, base, npgs);
if (npgs == 0)
- return (0);
+ return (DR_MEM_RES_OK);
if ((rv = kphysm_del_gethandle(&mh)) != KPHYSM_OK) {
cmn_err(CE_WARN, "%s: del_gethandle() = %d", __func__, rv);
+ rv = cvt_err(rv);
return (rv);
}
if ((rv = kphysm_del_span_query(base, npgs, &mq))
@@ -1168,10 +1112,19 @@ mem_del(pfn_t base, pgcnt_t npgs)
if (mq.nonrelocatable) {
DR_DBG_MEM("%s: non-reloc pages = %ld",
__func__, mq.nonrelocatable);
- rv = KPHYSM_ENONRELOC;
+ rv = KPHYSM_ENONRELOC;
goto done;
}
if (rv = kcage_range_delete(base, npgs)) {
+ switch (rv) {
+ case EBUSY:
+ rv = DR_MEM_RES_ENOTVIABLE;
+ break;
+ default:
+ rv = DR_MEM_RES_FAILURE;
+ break;
+ }
+ convert = 0; /* conversion done */
cmn_err(CE_WARN, "%s: del_range() = %d", __func__, rv);
goto done;
} else {
@@ -1183,6 +1136,18 @@ mem_del(pfn_t base, pgcnt_t npgs)
}
if ((rv = memlist_add_span(ptob(base), ptob(npgs), &d_ml))
!= MEML_SPANOP_OK) {
+ switch (rv) {
+ case MEML_SPANOP_ESPAN:
+ rv = DR_MEM_RES_ESPAN;
+ break;
+ case MEML_SPANOP_EALLOC:
+ rv = DR_MEM_RES_ERESOURCE;
+ break;
+ default:
+ rv = DR_MEM_RES_FAILURE;
+ break;
+ }
+ convert = 0; /* conversion done */
cmn_err(CE_WARN, "%s: add_span() = %d", __func__, rv);
goto done;
}
@@ -1245,6 +1210,8 @@ done:
if ((err = kphysm_del_release(mh)) != KPHYSM_OK)
cmn_err(CE_WARN, "%s: del_release() = %d", __func__, err);
+ if (convert)
+ rv = cvt_err(rv);
DR_DBG_MEM("%s: rv=%d", __func__, rv);
diff --git a/usr/src/uts/sun4v/io/drctl.c b/usr/src/uts/sun4v/io/drctl.c
index 5061b1228c..4ca542716f 100644
--- a/usr/src/uts/sun4v/io/drctl.c
+++ b/usr/src/uts/sun4v/io/drctl.c
@@ -156,6 +156,7 @@ _init(void)
drctlp->drc_inst = -1;
mutex_init(&drctlp->drc_lock, NULL, MUTEX_DRIVER, NULL);
+ cv_init(&drctlp->drc_busy_cv, NULL, CV_DRIVER, NULL);
if ((rv = mod_install(&modlinkage)) != 0)
mutex_destroy(&drctlp->drc_lock);
@@ -171,7 +172,7 @@ _fini(void)
if ((rv = mod_remove(&modlinkage)) != 0)
return (rv);
-
+ cv_destroy(&drctlp->drc_busy_cv);
mutex_destroy(&drctlp->drc_lock);
return (0);
}
@@ -376,7 +377,6 @@ verify_response(int cmd,
return (0);
}
-
static int
drctl_config_common(int cmd, int flags, drctl_rsrc_t *res,
int count, drctl_resp_t **rbuf, size_t *rsize, size_t *rq_size)
@@ -460,7 +460,6 @@ drctl_config_init(int cmd, int flags, drctl_rsrc_t *res,
}
mutex_enter(&drctlp->drc_lock);
-
if (drctlp->drc_busy != NULL) {
mutex_exit(&drctlp->drc_lock);
*rbuf = drctl_generate_err_resp(busy_msg, rsize);
@@ -488,6 +487,7 @@ drctl_config_init(int cmd, int flags, drctl_rsrc_t *res,
kmem_free(*rbuf, *rsize);
*rbuf = drctl_generate_err_resp(rsp_msg, rsize);
drctlp->drc_busy = NULL;
+ cv_broadcast(&drctlp->drc_busy_cv);
} else { /* message format is valid */
drctlp->drc_busy = ck;
drctlp->drc_cmd = cmd;
@@ -511,8 +511,8 @@ drctl_config_init(int cmd, int flags, drctl_rsrc_t *res,
drctlp->drc_cmd = -1;
drctlp->drc_flags = 0;
drctlp->drc_busy = NULL;
+ cv_broadcast(&drctlp->drc_busy_cv);
}
-
return (rv);
}
@@ -528,12 +528,10 @@ drctl_config_fini(drctl_cookie_t ck, drctl_rsrc_t *res, int count)
size_t rq_size;
mutex_enter(&drctlp->drc_lock);
-
if (drctlp->drc_busy != ck) {
mutex_exit(&drctlp->drc_lock);
return (EBUSY);
}
-
mutex_exit(&drctlp->drc_lock);
flags = drctlp->drc_flags;
@@ -579,11 +577,11 @@ drctl_config_fini(drctl_cookie_t ck, drctl_rsrc_t *res, int count)
flags, res, count, NULL, 0, &rq_size);
done:
- drctlp->drc_cmd = -1;
- drctlp->drc_flags = 0;
- drctlp->drc_busy = NULL;
-
- return (rv);
+ drctlp->drc_cmd = -1;
+ drctlp->drc_flags = 0;
+ drctlp->drc_busy = NULL;
+ cv_broadcast(&drctlp->drc_busy_cv);
+ return (rv);
}
static int
@@ -697,3 +695,35 @@ pack_message(int cmd,
return (msgp);
}
+
+/*
+ * Block DR operations
+ */
+void
+drctl_block(void)
+{
+ /* Wait for any in progress DR operation to complete */
+ mutex_enter(&drctlp->drc_lock);
+ while (drctlp->drc_busy != NULL)
+ (void) cv_wait_sig(&drctlp->drc_busy_cv, &drctlp->drc_lock);
+ /* Mark the link busy */
+ drctlp->drc_busy = (drctl_cookie_t)-1;
+ drctlp->drc_cmd = DRCTL_DRC_BLOCK;
+ drctlp->drc_flags = 0;
+ mutex_exit(&drctlp->drc_lock);
+}
+
+/*
+ * Unblock DR operations
+ */
+void
+drctl_unblock(void)
+{
+ /* Mark the link free */
+ mutex_enter(&drctlp->drc_lock);
+ drctlp->drc_cmd = -1;
+ drctlp->drc_flags = 0;
+ drctlp->drc_busy = NULL;
+ cv_broadcast(&drctlp->drc_busy_cv);
+ mutex_exit(&drctlp->drc_lock);
+}
diff --git a/usr/src/uts/sun4v/io/vlds.c b/usr/src/uts/sun4v/io/vlds.c
index 4eedeee56b..a33978680e 100644
--- a/usr/src/uts/sun4v/io/vlds.c
+++ b/usr/src/uts/sun4v/io/vlds.c
@@ -278,7 +278,6 @@ _init(void)
}
vlds_mdeg_init();
- (void) vlds_mdeg_register();
return (s);
}
@@ -293,8 +292,6 @@ _fini(void)
ddi_soft_state_fini(&vlds_statep);
- (void) vlds_mdeg_unregister();
-
return (s);
}
@@ -338,6 +335,8 @@ vlds_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
vlds_minor_init();
+ (void) vlds_mdeg_register();
+
return (DDI_SUCCESS);
}
@@ -352,6 +351,7 @@ vlds_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
vlds_minor_free(vlds_minor_bitmap);
ddi_remove_minor_node(devi, NULL);
+ (void) vlds_mdeg_unregister();
return (DDI_SUCCESS);
}
diff --git a/usr/src/uts/sun4v/os/memseg.c b/usr/src/uts/sun4v/os/memseg.c
index d562905eec..359588150a 100644
--- a/usr/src/uts/sun4v/os/memseg.c
+++ b/usr/src/uts/sun4v/os/memseg.c
@@ -44,9 +44,6 @@ extern struct memseg *memseg_alloc();
extern page_t *ppvm_base;
extern pgcnt_t ppvm_size;
-static vnode_t pp_vn, rsv_vn;
-static pgcnt_t rsv_metapgs;
-static int meta_rsv_enable;
static int sun4v_memseg_debug;
extern struct memseg *memseg_reuse(pgcnt_t);
@@ -77,12 +74,11 @@ extern void remap_to_dummy(caddr_t, pgcnt_t);
int
memseg_alloc_meta(pfn_t base, pgcnt_t npgs, void **ptp, pgcnt_t *metap)
{
- page_t *pp, *opp, *epp, *pgpp;
+ page_t *pp, *opp, *epp;
pgcnt_t metapgs;
- int i, rsv;
+ int i;
struct seg kseg;
caddr_t vaddr;
- u_offset_t off;
/*
* Verify incoming memory is within supported DR range.
@@ -95,7 +91,7 @@ memseg_alloc_meta(pfn_t base, pgcnt_t npgs, void **ptp, pgcnt_t *metap)
metapgs = btopr(npgs * sizeof (page_t));
if (!IS_P2ALIGNED((uint64_t)pp, PAGESIZE) &&
- page_find(&pp_vn, (u_offset_t)pp)) {
+ page_find(&mpvp, (u_offset_t)pp)) {
/*
* Another memseg has page_t's in the same
* page which 'pp' resides. This would happen
@@ -120,7 +116,7 @@ memseg_alloc_meta(pfn_t base, pgcnt_t npgs, void **ptp, pgcnt_t *metap)
}
if (!IS_P2ALIGNED((uint64_t)epp, PAGESIZE) &&
- page_find(&pp_vn, (u_offset_t)epp)) {
+ page_find(&mpvp, (u_offset_t)epp)) {
/*
* Another memseg has page_t's in the same
* page which 'epp' resides. This would happen
@@ -144,59 +140,20 @@ memseg_alloc_meta(pfn_t base, pgcnt_t npgs, void **ptp, pgcnt_t *metap)
vaddr = (caddr_t)pp;
for (i = 0; i < metapgs; i++)
- if (page_find(&pp_vn, (u_offset_t)(vaddr + i * PAGESIZE)))
+ if (page_find(&mpvp, (u_offset_t)(vaddr + i * PAGESIZE)))
panic("page_find(0x%p, %p)\n",
- (void *)&pp_vn, (void *)(vaddr + i * PAGESIZE));
+ (void *)&mpvp, (void *)(vaddr + i * PAGESIZE));
/*
* Allocate the metadata pages; these are the pages that will
* contain the page_t's for the incoming memory.
- *
- * If a normal allocation fails, use the reserved metapgs for
- * a small allocation; otherwise retry with PG_WAIT.
*/
- rsv = off = 0;
- if (metapgs <= rsv_metapgs) {
- MEMSEG_DEBUG("memseg_get: use rsv 0x%lx metapgs", metapgs);
- ASSERT(meta_rsv_enable);
- rsv = 1;
- } else if ((pgpp = page_create_va(&pp_vn, (u_offset_t)pp, ptob(metapgs),
+ if ((page_create_va(&mpvp, (u_offset_t)pp, ptob(metapgs),
PG_NORELOC | PG_EXCL, &kseg, vaddr)) == NULL) {
- cmn_err(CE_WARN, "memseg_get: can't get 0x%ld metapgs",
+ MEMSEG_DEBUG("memseg_alloc_meta: can't get 0x%ld metapgs",
metapgs);
return (KPHYSM_ERESOURCE);
}
- if (rsv) {
- /*
- * The reseve pages must be hashed out of the reserve vnode
- * and rehashed by <pp_vn,vaddr>. The resreved pages also
- * must be replenished immedidately at the end of the add
- * processing.
- */
- for (i = 0; i < metapgs; i++) {
- pgpp = page_find(&rsv_vn, off);
- ASSERT(pgpp);
- page_hashout(pgpp, 0);
- hat_devload(kas.a_hat, vaddr, PAGESIZE,
- page_pptonum(pgpp), PROT_READ | PROT_WRITE,
- HAT_LOAD | HAT_LOAD_REMAP | HAT_LOAD_NOCONSIST);
- ASSERT(!page_find(&pp_vn, (u_offset_t)vaddr));
- if (!page_hashin(pgpp, &pp_vn, (u_offset_t)vaddr, 0))
- panic("memseg_get: page_hashin(0x%p, 0x%p)",
- (void *)pgpp, (void *)vaddr);
- off += PAGESIZE;
- vaddr += PAGESIZE;
- rsv_metapgs--;
- }
- } else {
- for (i = 0; i < metapgs; i++) {
- hat_devload(kas.a_hat, vaddr, PAGESIZE,
- page_pptonum(pgpp), PROT_READ | PROT_WRITE,
- HAT_LOAD | HAT_LOAD_REMAP | HAT_LOAD_NOCONSIST);
- pgpp = pgpp->p_next;
- vaddr += PAGESIZE;
- }
- }
ASSERT(ptp);
ASSERT(metap);
@@ -228,7 +185,7 @@ memseg_free_meta(void *ptp, pgcnt_t metapgs)
* Free pages allocated during add.
*/
for (i = 0; i < metapgs; i++) {
- pp = page_find(&pp_vn, off);
+ pp = page_find(&mpvp, off);
ASSERT(pp);
ASSERT(pp->p_szc == 0);
page_io_unlock(pp);
@@ -248,7 +205,7 @@ memseg_get_metapfn(void *ptp, pgcnt_t metapg)
ASSERT(off);
ASSERT(IS_P2ALIGNED((uint64_t)off, PAGESIZE));
- pp = page_find(&pp_vn, off);
+ pp = page_find(&mpvp, off);
ASSERT(pp);
ASSERT(pp->p_szc == 0);
ASSERT(pp->p_pagenum != PFN_INVALID);
@@ -285,7 +242,7 @@ memseg_remap_meta(struct memseg *seg)
*/
if (!IS_P2ALIGNED((uint64_t)pp, PAGESIZE) &&
- page_find(&pp_vn, (u_offset_t)(pp - 1)) && !page_deleted(pp - 1)) {
+ page_find(&mpvp, (u_offset_t)(pp - 1)) && !page_deleted(pp - 1)) {
/*
* Another memseg has page_t's in the same
* page which 'pp' resides. This would happen
@@ -312,7 +269,7 @@ memseg_remap_meta(struct memseg *seg)
}
if (!IS_P2ALIGNED((uint64_t)epp, PAGESIZE) &&
- page_find(&pp_vn, (u_offset_t)epp) && !page_deleted(epp)) {
+ page_find(&mpvp, (u_offset_t)epp) && !page_deleted(epp)) {
/*
* Another memseg has page_t's in the same
* page which 'epp' resides. This would happen
@@ -333,13 +290,13 @@ memseg_remap_meta(struct memseg *seg)
off = (u_offset_t)pp;
- MEMSEG_DEBUG("memseg_remap: off=0x%lx metapgs=0x%lx\n", (uint64_t)off,
- metapgs);
+ MEMSEG_DEBUG("memseg_remap_meta: off=0x%lx metapgs=0x%lx\n",
+ (uint64_t)off, metapgs);
/*
* Free pages allocated during add.
*/
for (i = 0; i < metapgs; i++) {
- pp = page_find(&pp_vn, off);
+ pp = page_find(&mpvp, off);
ASSERT(pp);
ASSERT(pp->p_szc == 0);
page_io_unlock(pp);
@@ -347,64 +304,3 @@ memseg_remap_meta(struct memseg *seg)
off += PAGESIZE;
}
}
-
-static void
-rsv_alloc()
-{
- int i;
- page_t *pp;
- pgcnt_t metapgs;
- u_offset_t off;
- struct seg kseg;
-
- kseg.s_as = &kas;
-
- /*
- * Reserve enough page_t pages for an add request of
- * RSV_SIZE bytes.
- */
- metapgs = btopr(btop(RSV_SIZE) * sizeof (page_t)) - rsv_metapgs;
-
- for (i = off = 0; i < metapgs; i++, off += PAGESIZE) {
- (void) page_create_va(&rsv_vn, off, PAGESIZE,
- PG_NORELOC | PG_WAIT, &kseg, 0);
- pp = page_find(&rsv_vn, off);
- ASSERT(pp);
- ASSERT(PAGE_EXCL(pp));
- page_iolock_init(pp);
- rsv_metapgs++;
- }
-}
-
-void
-i_dr_mem_init(size_t *hint)
-{
- if (meta_rsv_enable) {
- rsv_alloc();
- if (hint)
- *hint = RSV_SIZE;
- }
-}
-
-void
-i_dr_mem_fini()
-{
- int i;
- page_t *pp;
- u_offset_t off;
-
- for (i = off = 0; i < rsv_metapgs; i++, off += PAGESIZE) {
- if (pp = page_find(&rsv_vn, off)) {
- ASSERT(PAGE_EXCL(pp));
- page_destroy(pp, 0);
- }
- ASSERT(!page_find(&rsv_vn, off));
- }
- rsv_metapgs = 0;
-}
-
-void
-i_dr_mem_update()
-{
- rsv_alloc();
-}
diff --git a/usr/src/uts/sun4v/promif/promif_emul.c b/usr/src/uts/sun4v/promif/promif_emul.c
index 143caa1f9d..1adf719ba6 100644
--- a/usr/src/uts/sun4v/promif/promif_emul.c
+++ b/usr/src/uts/sun4v/promif/promif_emul.c
@@ -36,6 +36,7 @@
#include <sys/mdesc.h>
#include <sys/mach_descrip.h>
#include <sys/cpu_module.h>
+#include <vm/seg_kmem.h>
#ifndef _KMDB
#include <sys/pte.h>
@@ -50,7 +51,7 @@ int cif_cpu_mp_ready;
int (*prom_cif_handler)(void *) = NULL;
extern struct memlist *phys_avail;
-extern struct vnode prom_ppages;
+extern struct vnode promvp;
extern void kdi_tlb_page_unlock(caddr_t, int);
#define COMBINE(hi, lo) (((uint64_t)(uint32_t)(hi) << 32) | (uint32_t)(lo))
@@ -309,7 +310,7 @@ unmap_prom_mappings(struct translation *transroot, size_t ntransroot)
ASSERT(PAGE_EXCL(pp));
ASSERT(PP_ISNORELOC(pp));
ASSERT(!PP_ISFREE(pp));
- ASSERT(page_find(&prom_ppages, pfn));
+ ASSERT(page_find(&promvp, pfn));
ASSERT(page_get_pagecnt(pp->p_szc) == 1);
if (pp->p_mapping) {
diff --git a/usr/src/uts/sun4v/sys/drctl.h b/usr/src/uts/sun4v/sys/drctl.h
index 75299f2c93..26b4970541 100644
--- a/usr/src/uts/sun4v/sys/drctl.h
+++ b/usr/src/uts/sun4v/sys/drctl.h
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -46,7 +46,8 @@ typedef enum {
DRCTL_IO_CONFIG_REQUEST,
DRCTL_IO_CONFIG_NOTIFY,
DRCTL_IO_UNCONFIG_REQUEST,
- DRCTL_IO_UNCONFIG_NOTIFY
+ DRCTL_IO_UNCONFIG_NOTIFY,
+ DRCTL_DRC_BLOCK
} drctl_cmds_t;
/*
@@ -135,6 +136,8 @@ typedef void *drctl_cookie_t;
extern int drctl_config_init(int, int,
drctl_rsrc_t *, int, drctl_resp_t **, size_t *, drctl_cookie_t);
extern int drctl_config_fini(drctl_cookie_t, drctl_rsrc_t *, int);
+extern void drctl_block(void);
+extern void drctl_unblock(void);
/*
* Values for the 2nd arg (flags) of drctl_config_init
diff --git a/usr/src/uts/sun4v/vm/mach_kpm.c b/usr/src/uts/sun4v/vm/mach_kpm.c
index f47e74e001..de3a53f7a4 100644
--- a/usr/src/uts/sun4v/vm/mach_kpm.c
+++ b/usr/src/uts/sun4v/vm/mach_kpm.c
@@ -35,11 +35,15 @@
#include <sys/machsystm.h>
#include <vm/seg_kpm.h>
#include <vm/mach_kpm.h>
+#include <vm/faultcode.h>
+
+extern pfn_t memseg_get_start(struct memseg *);
/*
* Kernel Physical Mapping (kpm) facility
*/
+
void
mach_kpm_init()
{
@@ -226,7 +230,15 @@ hat_kpm_addmem_mseg_update(struct memseg *msp, pgcnt_t nkpmpgs,
* if nkpmpgs needs to be used at some point.
*/
- base = msp->pages_base;
+ /*
+ * The meta (page_t) pages for dynamically added memory are allocated
+ * either from the incoming memory itself or from existing memory.
+ * In the former case the base of the incoming pages will be different
+ * than the base of the dynamic segment so call memseg_get_start() to
+ * get the actual base of the incoming memory for each case.
+ */
+
+ base = memseg_get_start(msp);
end = msp->pages_end;
hat_devload(kas.a_hat, kpm_vbase + mmu_ptob(base),
@@ -259,7 +271,15 @@ hat_kpm_delmem_mseg_update(struct memseg *msp, struct memseg **mspp)
{
pfn_t base, end;
- base = msp->pages_base;
+ /*
+ * The meta (page_t) pages for dynamically added memory are allocated
+ * either from the incoming memory itself or from existing memory.
+ * In the former case the base of the incoming pages will be different
+ * than the base of the dynamic segment so call memseg_get_start() to
+ * get the actual base of the incoming memory for each case.
+ */
+
+ base = memseg_get_start(msp);
end = msp->pages_end;
hat_unload(kas.a_hat, kpm_vbase + mmu_ptob(base), mmu_ptob(end - base),