diff options
author | Sean McEnroe <Sean.McEnroe@Sun.COM> | 2009-11-23 22:42:23 -0800 |
---|---|---|
committer | Sean McEnroe <Sean.McEnroe@Sun.COM> | 2009-11-23 22:42:23 -0800 |
commit | af4c679f647cf088543c762e33d41a3ac52cfa14 (patch) | |
tree | 4311b62e5c03300652116b78f6474c8f020ca7e8 /usr/src/uts/sun4v | |
parent | 37b285d61e57561b538d999834714df1f5c2db53 (diff) | |
download | illumos-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.c | 103 | ||||
-rw-r--r-- | usr/src/uts/sun4v/io/drctl.c | 52 | ||||
-rw-r--r-- | usr/src/uts/sun4v/io/vlds.c | 6 | ||||
-rw-r--r-- | usr/src/uts/sun4v/os/memseg.c | 134 | ||||
-rw-r--r-- | usr/src/uts/sun4v/promif/promif_emul.c | 5 | ||||
-rw-r--r-- | usr/src/uts/sun4v/sys/drctl.h | 7 | ||||
-rw-r--r-- | usr/src/uts/sun4v/vm/mach_kpm.c | 24 |
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), |