Print this page
patch as-lock-macro-simplification


1070                         if (rd)
1071                                 inst &= ~(0x1f << 25);
1072                         if (i == 0 && ignor)
1073                                 inst &= ~(0xff << 5);
1074                         break;
1075                 default:
1076                         if (optype == OP_V8_LDSTR && !IS_LDST_ALT(op3) &&
1077                             i == 0 && ignor)
1078                                 inst &= ~(0xff << 5);
1079                         else
1080                                 return (SIMU_ILLEGAL);
1081                         break;
1082                 }
1083                 break;
1084         default:
1085                 return (SIMU_ILLEGAL);
1086         }
1087 
1088         as = p->p_as;
1089 
1090         AS_LOCK_ENTER(as, &as->a_lock, RW_READER);
1091         mapseg = as_findseg(as, (caddr_t)rp->r_pc, 0);
1092         ASSERT(mapseg != NULL);
1093         svd = (struct segvn_data *)mapseg->s_data;
1094 
1095         /*
1096          * We only create COW page for MAP_PRIVATE mappings.
1097          */
1098         SEGVN_LOCK_ENTER(as, &svd->lock, RW_READER);
1099         if ((svd->type & MAP_TYPE) & MAP_SHARED) {
1100                 SEGVN_LOCK_EXIT(as, &svd->lock);
1101                 AS_LOCK_EXIT(as, &as->a_lock);
1102                 return (SIMU_ILLEGAL);
1103         }
1104         SEGVN_LOCK_EXIT(as, &svd->lock);
1105         AS_LOCK_EXIT(as, &as->a_lock);
1106 
1107         /*
1108          * A "flush" instruction using the user PC's vaddr will not work
1109          * here, at least on Spitfire. Instead we create a temporary kernel
1110          * mapping to the user's text page, then modify and flush that.
1111          * Break COW by locking user page.
1112          */
1113         if (as_fault(as->a_hat, as, (caddr_t)(rp->r_pc & PAGEMASK), PAGESIZE,
1114             F_SOFTLOCK, S_READ))
1115                 return (SIMU_FAULT);
1116 
1117         AS_LOCK_ENTER(as, &as->a_lock, RW_READER);
1118         pfnum = hat_getpfnum(as->a_hat, (caddr_t)rp->r_pc);
1119         AS_LOCK_EXIT(as, &as->a_lock);
1120         if (pf_is_memory(pfnum)) {
1121                 pp = page_numtopp_nolock(pfnum);
1122                 ASSERT(pp == NULL || PAGE_LOCKED(pp));
1123         } else {
1124                 (void) as_fault(as->a_hat, as, (caddr_t)(rp->r_pc & PAGEMASK),
1125                     PAGESIZE, F_SOFTUNLOCK, S_READ);
1126                 return (SIMU_FAULT);
1127         }
1128 
1129         AS_LOCK_ENTER(as, &as->a_lock, RW_READER);
1130         ka = ppmapin(pp, PROT_READ|PROT_WRITE, (caddr_t)rp->r_pc);
1131         *(uint_t *)(ka + (uintptr_t)(rp->r_pc % PAGESIZE)) = inst;
1132         doflush(ka + (uintptr_t)(rp->r_pc % PAGESIZE));
1133         ppmapout(ka);
1134         AS_LOCK_EXIT(as, &as->a_lock);
1135 
1136         (void) as_fault(as->a_hat, as, (caddr_t)(rp->r_pc & PAGEMASK),
1137             PAGESIZE, F_SOFTUNLOCK, S_READ);
1138         return (SIMU_RETRY);
1139 }
1140 
1141 /*
1142  * Simulate a "rd %tick" or "rd %stick" (%asr24) instruction.
1143  */
1144 int
1145 simulate_rdtick(struct regs *rp)
1146 {
1147         uint_t  inst, op, op3, rd, rs1, i;
1148         caddr_t badaddr;
1149 
1150         inst = fetch_user_instr((caddr_t)rp->r_pc);
1151         op   = (inst >> 30) & 0x3;
1152         rd   = (inst >> 25) & 0x1F;
1153         op3  = (inst >> 19) & 0x3F;
1154         i    = (inst >> 13) & 0x1;




1070                         if (rd)
1071                                 inst &= ~(0x1f << 25);
1072                         if (i == 0 && ignor)
1073                                 inst &= ~(0xff << 5);
1074                         break;
1075                 default:
1076                         if (optype == OP_V8_LDSTR && !IS_LDST_ALT(op3) &&
1077                             i == 0 && ignor)
1078                                 inst &= ~(0xff << 5);
1079                         else
1080                                 return (SIMU_ILLEGAL);
1081                         break;
1082                 }
1083                 break;
1084         default:
1085                 return (SIMU_ILLEGAL);
1086         }
1087 
1088         as = p->p_as;
1089 
1090         AS_LOCK_ENTER(as, RW_READER);
1091         mapseg = as_findseg(as, (caddr_t)rp->r_pc, 0);
1092         ASSERT(mapseg != NULL);
1093         svd = (struct segvn_data *)mapseg->s_data;
1094 
1095         /*
1096          * We only create COW page for MAP_PRIVATE mappings.
1097          */
1098         SEGVN_LOCK_ENTER(as, &svd->lock, RW_READER);
1099         if ((svd->type & MAP_TYPE) & MAP_SHARED) {
1100                 SEGVN_LOCK_EXIT(as, &svd->lock);
1101                 AS_LOCK_EXIT(as);
1102                 return (SIMU_ILLEGAL);
1103         }
1104         SEGVN_LOCK_EXIT(as, &svd->lock);
1105         AS_LOCK_EXIT(as);
1106 
1107         /*
1108          * A "flush" instruction using the user PC's vaddr will not work
1109          * here, at least on Spitfire. Instead we create a temporary kernel
1110          * mapping to the user's text page, then modify and flush that.
1111          * Break COW by locking user page.
1112          */
1113         if (as_fault(as->a_hat, as, (caddr_t)(rp->r_pc & PAGEMASK), PAGESIZE,
1114             F_SOFTLOCK, S_READ))
1115                 return (SIMU_FAULT);
1116 
1117         AS_LOCK_ENTER(as, RW_READER);
1118         pfnum = hat_getpfnum(as->a_hat, (caddr_t)rp->r_pc);
1119         AS_LOCK_EXIT(as);
1120         if (pf_is_memory(pfnum)) {
1121                 pp = page_numtopp_nolock(pfnum);
1122                 ASSERT(pp == NULL || PAGE_LOCKED(pp));
1123         } else {
1124                 (void) as_fault(as->a_hat, as, (caddr_t)(rp->r_pc & PAGEMASK),
1125                     PAGESIZE, F_SOFTUNLOCK, S_READ);
1126                 return (SIMU_FAULT);
1127         }
1128 
1129         AS_LOCK_ENTER(as, RW_READER);
1130         ka = ppmapin(pp, PROT_READ|PROT_WRITE, (caddr_t)rp->r_pc);
1131         *(uint_t *)(ka + (uintptr_t)(rp->r_pc % PAGESIZE)) = inst;
1132         doflush(ka + (uintptr_t)(rp->r_pc % PAGESIZE));
1133         ppmapout(ka);
1134         AS_LOCK_EXIT(as);
1135 
1136         (void) as_fault(as->a_hat, as, (caddr_t)(rp->r_pc & PAGEMASK),
1137             PAGESIZE, F_SOFTUNLOCK, S_READ);
1138         return (SIMU_RETRY);
1139 }
1140 
1141 /*
1142  * Simulate a "rd %tick" or "rd %stick" (%asr24) instruction.
1143  */
1144 int
1145 simulate_rdtick(struct regs *rp)
1146 {
1147         uint_t  inst, op, op3, rd, rs1, i;
1148         caddr_t badaddr;
1149 
1150         inst = fetch_user_instr((caddr_t)rp->r_pc);
1151         op   = (inst >> 30) & 0x3;
1152         rd   = (inst >> 25) & 0x1F;
1153         op3  = (inst >> 19) & 0x3F;
1154         i    = (inst >> 13) & 0x1;