440 static faultcode_t
441 segkmem_fault(struct hat *hat, struct seg *seg, caddr_t addr, size_t size,
442 enum fault_type type, enum seg_rw rw)
443 {
444 pgcnt_t npages;
445 spgcnt_t pg;
446 page_t *pp;
447 struct vnode *vp = seg->s_data;
448
449 ASSERT(RW_READ_HELD(&seg->s_as->a_lock));
450
451 if (seg->s_as != &kas || size > seg->s_size ||
452 addr < seg->s_base || addr + size > seg->s_base + seg->s_size)
453 panic("segkmem_fault: bad args");
454
455 /*
456 * If it is one of segkp pages, call segkp_fault.
457 */
458 if (segkp_bitmap && seg == &kvseg &&
459 BT_TEST(segkp_bitmap, btop((uintptr_t)(addr - seg->s_base))))
460 return (SEGOP_FAULT(hat, segkp, addr, size, type, rw));
461
462 if (rw != S_READ && rw != S_WRITE && rw != S_OTHER)
463 return (FC_NOSUPPORT);
464
465 npages = btopr(size);
466
467 switch (type) {
468 case F_SOFTLOCK: /* lock down already-loaded translations */
469 for (pg = 0; pg < npages; pg++) {
470 pp = page_lookup(vp, (u_offset_t)(uintptr_t)addr,
471 SE_SHARED);
472 if (pp == NULL) {
473 /*
474 * Hmm, no page. Does a kernel mapping
475 * exist for it?
476 */
477 if (!hat_probe(kas.a_hat, addr)) {
478 addr -= PAGESIZE;
479 while (--pg >= 0) {
480 pp = page_find(vp, (u_offset_t)
502 default:
503 return (FC_NOSUPPORT);
504 }
505 /*NOTREACHED*/
506 }
507
508 static int
509 segkmem_setprot(struct seg *seg, caddr_t addr, size_t size, uint_t prot)
510 {
511 ASSERT(RW_LOCK_HELD(&seg->s_as->a_lock));
512
513 if (seg->s_as != &kas || size > seg->s_size ||
514 addr < seg->s_base || addr + size > seg->s_base + seg->s_size)
515 panic("segkmem_setprot: bad args");
516
517 /*
518 * If it is one of segkp pages, call segkp.
519 */
520 if (segkp_bitmap && seg == &kvseg &&
521 BT_TEST(segkp_bitmap, btop((uintptr_t)(addr - seg->s_base))))
522 return (SEGOP_SETPROT(segkp, addr, size, prot));
523
524 if (prot == 0)
525 hat_unload(kas.a_hat, addr, size, HAT_UNLOAD);
526 else
527 hat_chgprot(kas.a_hat, addr, size, prot);
528 return (0);
529 }
530
531 /*
532 * This is a dummy segkmem function overloaded to call segkp
533 * when segkp is under the heap.
534 */
535 /* ARGSUSED */
536 static int
537 segkmem_checkprot(struct seg *seg, caddr_t addr, size_t size, uint_t prot)
538 {
539 ASSERT(RW_LOCK_HELD(&seg->s_as->a_lock));
540
541 if (seg->s_as != &kas)
542 segkmem_badop();
543
544 /*
545 * If it is one of segkp pages, call into segkp.
546 */
547 if (segkp_bitmap && seg == &kvseg &&
548 BT_TEST(segkp_bitmap, btop((uintptr_t)(addr - seg->s_base))))
549 return (SEGOP_CHECKPROT(segkp, addr, size, prot));
550
551 segkmem_badop();
552 return (0);
553 }
554
555 /*
556 * This is a dummy segkmem function overloaded to call segkp
557 * when segkp is under the heap.
558 */
559 /* ARGSUSED */
560 static int
561 segkmem_kluster(struct seg *seg, caddr_t addr, ssize_t delta)
562 {
563 ASSERT(RW_LOCK_HELD(&seg->s_as->a_lock));
564
565 if (seg->s_as != &kas)
566 segkmem_badop();
567
568 /*
569 * If it is one of segkp pages, call into segkp.
570 */
571 if (segkp_bitmap && seg == &kvseg &&
572 BT_TEST(segkp_bitmap, btop((uintptr_t)(addr - seg->s_base))))
573 return (SEGOP_KLUSTER(segkp, addr, delta));
574
575 segkmem_badop();
576 return (0);
577 }
578
579 static void
580 segkmem_xdump_range(void *arg, void *start, size_t size)
581 {
582 struct as *as = arg;
583 caddr_t addr = start;
584 caddr_t addr_end = addr + size;
585
586 while (addr < addr_end) {
587 pfn_t pfn = hat_getpfnum(kas.a_hat, addr);
588 if (pfn != PFN_INVALID && pfn <= physmax && pf_is_memory(pfn))
589 dump_addpage(as, addr, pfn);
590 addr += PAGESIZE;
591 dump_timeleft = dump_timeout;
592 }
593 }
674 * will handle the range via as_fault(F_SOFTLOCK).
675 */
676 /*ARGSUSED*/
677 static int
678 segkmem_pagelock(struct seg *seg, caddr_t addr, size_t len,
679 page_t ***ppp, enum lock_type type, enum seg_rw rw)
680 {
681 page_t **pplist, *pp;
682 pgcnt_t npages;
683 spgcnt_t pg;
684 size_t nb;
685 struct vnode *vp = seg->s_data;
686
687 ASSERT(ppp != NULL);
688
689 /*
690 * If it is one of segkp pages, call into segkp.
691 */
692 if (segkp_bitmap && seg == &kvseg &&
693 BT_TEST(segkp_bitmap, btop((uintptr_t)(addr - seg->s_base))))
694 return (SEGOP_PAGELOCK(segkp, addr, len, ppp, type, rw));
695
696 npages = btopr(len);
697 nb = sizeof (page_t *) * npages;
698
699 if (type == L_PAGEUNLOCK) {
700 pplist = *ppp;
701 ASSERT(pplist != NULL);
702
703 for (pg = 0; pg < npages; pg++) {
704 pp = pplist[pg];
705 page_unlock(pp);
706 }
707 kmem_free(pplist, nb);
708 return (0);
709 }
710
711 ASSERT(type == L_PAGELOCK);
712
713 pplist = kmem_alloc(nb, KM_NOSLEEP);
714 if (pplist == NULL) {
734 }
735
736 /*
737 * This is a dummy segkmem function overloaded to call segkp
738 * when segkp is under the heap.
739 */
740 /* ARGSUSED */
741 static int
742 segkmem_getmemid(struct seg *seg, caddr_t addr, memid_t *memidp)
743 {
744 ASSERT(RW_LOCK_HELD(&seg->s_as->a_lock));
745
746 if (seg->s_as != &kas)
747 segkmem_badop();
748
749 /*
750 * If it is one of segkp pages, call into segkp.
751 */
752 if (segkp_bitmap && seg == &kvseg &&
753 BT_TEST(segkp_bitmap, btop((uintptr_t)(addr - seg->s_base))))
754 return (SEGOP_GETMEMID(segkp, addr, memidp));
755
756 segkmem_badop();
757 return (0);
758 }
759
760 /*ARGSUSED*/
761 static lgrp_mem_policy_info_t *
762 segkmem_getpolicy(struct seg *seg, caddr_t addr)
763 {
764 return (NULL);
765 }
766
767 /*ARGSUSED*/
768 static int
769 segkmem_capable(struct seg *seg, segcapability_t capability)
770 {
771 if (capability == S_CAPABILITY_NOMINFLT)
772 return (1);
773 return (0);
774 }
|
440 static faultcode_t
441 segkmem_fault(struct hat *hat, struct seg *seg, caddr_t addr, size_t size,
442 enum fault_type type, enum seg_rw rw)
443 {
444 pgcnt_t npages;
445 spgcnt_t pg;
446 page_t *pp;
447 struct vnode *vp = seg->s_data;
448
449 ASSERT(RW_READ_HELD(&seg->s_as->a_lock));
450
451 if (seg->s_as != &kas || size > seg->s_size ||
452 addr < seg->s_base || addr + size > seg->s_base + seg->s_size)
453 panic("segkmem_fault: bad args");
454
455 /*
456 * If it is one of segkp pages, call segkp_fault.
457 */
458 if (segkp_bitmap && seg == &kvseg &&
459 BT_TEST(segkp_bitmap, btop((uintptr_t)(addr - seg->s_base))))
460 return (segop_fault(hat, segkp, addr, size, type, rw));
461
462 if (rw != S_READ && rw != S_WRITE && rw != S_OTHER)
463 return (FC_NOSUPPORT);
464
465 npages = btopr(size);
466
467 switch (type) {
468 case F_SOFTLOCK: /* lock down already-loaded translations */
469 for (pg = 0; pg < npages; pg++) {
470 pp = page_lookup(vp, (u_offset_t)(uintptr_t)addr,
471 SE_SHARED);
472 if (pp == NULL) {
473 /*
474 * Hmm, no page. Does a kernel mapping
475 * exist for it?
476 */
477 if (!hat_probe(kas.a_hat, addr)) {
478 addr -= PAGESIZE;
479 while (--pg >= 0) {
480 pp = page_find(vp, (u_offset_t)
502 default:
503 return (FC_NOSUPPORT);
504 }
505 /*NOTREACHED*/
506 }
507
508 static int
509 segkmem_setprot(struct seg *seg, caddr_t addr, size_t size, uint_t prot)
510 {
511 ASSERT(RW_LOCK_HELD(&seg->s_as->a_lock));
512
513 if (seg->s_as != &kas || size > seg->s_size ||
514 addr < seg->s_base || addr + size > seg->s_base + seg->s_size)
515 panic("segkmem_setprot: bad args");
516
517 /*
518 * If it is one of segkp pages, call segkp.
519 */
520 if (segkp_bitmap && seg == &kvseg &&
521 BT_TEST(segkp_bitmap, btop((uintptr_t)(addr - seg->s_base))))
522 return (segop_setprot(segkp, addr, size, prot));
523
524 if (prot == 0)
525 hat_unload(kas.a_hat, addr, size, HAT_UNLOAD);
526 else
527 hat_chgprot(kas.a_hat, addr, size, prot);
528 return (0);
529 }
530
531 /*
532 * This is a dummy segkmem function overloaded to call segkp
533 * when segkp is under the heap.
534 */
535 /* ARGSUSED */
536 static int
537 segkmem_checkprot(struct seg *seg, caddr_t addr, size_t size, uint_t prot)
538 {
539 ASSERT(RW_LOCK_HELD(&seg->s_as->a_lock));
540
541 if (seg->s_as != &kas)
542 segkmem_badop();
543
544 /*
545 * If it is one of segkp pages, call into segkp.
546 */
547 if (segkp_bitmap && seg == &kvseg &&
548 BT_TEST(segkp_bitmap, btop((uintptr_t)(addr - seg->s_base))))
549 return (segop_checkprot(segkp, addr, size, prot));
550
551 segkmem_badop();
552 return (0);
553 }
554
555 /*
556 * This is a dummy segkmem function overloaded to call segkp
557 * when segkp is under the heap.
558 */
559 /* ARGSUSED */
560 static int
561 segkmem_kluster(struct seg *seg, caddr_t addr, ssize_t delta)
562 {
563 ASSERT(RW_LOCK_HELD(&seg->s_as->a_lock));
564
565 if (seg->s_as != &kas)
566 segkmem_badop();
567
568 /*
569 * If it is one of segkp pages, call into segkp.
570 */
571 if (segkp_bitmap && seg == &kvseg &&
572 BT_TEST(segkp_bitmap, btop((uintptr_t)(addr - seg->s_base))))
573 return (segop_kluster(segkp, addr, delta));
574
575 segkmem_badop();
576 return (0);
577 }
578
579 static void
580 segkmem_xdump_range(void *arg, void *start, size_t size)
581 {
582 struct as *as = arg;
583 caddr_t addr = start;
584 caddr_t addr_end = addr + size;
585
586 while (addr < addr_end) {
587 pfn_t pfn = hat_getpfnum(kas.a_hat, addr);
588 if (pfn != PFN_INVALID && pfn <= physmax && pf_is_memory(pfn))
589 dump_addpage(as, addr, pfn);
590 addr += PAGESIZE;
591 dump_timeleft = dump_timeout;
592 }
593 }
674 * will handle the range via as_fault(F_SOFTLOCK).
675 */
676 /*ARGSUSED*/
677 static int
678 segkmem_pagelock(struct seg *seg, caddr_t addr, size_t len,
679 page_t ***ppp, enum lock_type type, enum seg_rw rw)
680 {
681 page_t **pplist, *pp;
682 pgcnt_t npages;
683 spgcnt_t pg;
684 size_t nb;
685 struct vnode *vp = seg->s_data;
686
687 ASSERT(ppp != NULL);
688
689 /*
690 * If it is one of segkp pages, call into segkp.
691 */
692 if (segkp_bitmap && seg == &kvseg &&
693 BT_TEST(segkp_bitmap, btop((uintptr_t)(addr - seg->s_base))))
694 return (segop_pagelock(segkp, addr, len, ppp, type, rw));
695
696 npages = btopr(len);
697 nb = sizeof (page_t *) * npages;
698
699 if (type == L_PAGEUNLOCK) {
700 pplist = *ppp;
701 ASSERT(pplist != NULL);
702
703 for (pg = 0; pg < npages; pg++) {
704 pp = pplist[pg];
705 page_unlock(pp);
706 }
707 kmem_free(pplist, nb);
708 return (0);
709 }
710
711 ASSERT(type == L_PAGELOCK);
712
713 pplist = kmem_alloc(nb, KM_NOSLEEP);
714 if (pplist == NULL) {
734 }
735
736 /*
737 * This is a dummy segkmem function overloaded to call segkp
738 * when segkp is under the heap.
739 */
740 /* ARGSUSED */
741 static int
742 segkmem_getmemid(struct seg *seg, caddr_t addr, memid_t *memidp)
743 {
744 ASSERT(RW_LOCK_HELD(&seg->s_as->a_lock));
745
746 if (seg->s_as != &kas)
747 segkmem_badop();
748
749 /*
750 * If it is one of segkp pages, call into segkp.
751 */
752 if (segkp_bitmap && seg == &kvseg &&
753 BT_TEST(segkp_bitmap, btop((uintptr_t)(addr - seg->s_base))))
754 return (segop_getmemid(segkp, addr, memidp));
755
756 segkmem_badop();
757 return (0);
758 }
759
760 /*ARGSUSED*/
761 static lgrp_mem_policy_info_t *
762 segkmem_getpolicy(struct seg *seg, caddr_t addr)
763 {
764 return (NULL);
765 }
766
767 /*ARGSUSED*/
768 static int
769 segkmem_capable(struct seg *seg, segcapability_t capability)
770 {
771 if (capability == S_CAPABILITY_NOMINFLT)
772 return (1);
773 return (0);
774 }
|