void handle_mmu_bus_fault(struct pt_regs *regs) { int cause; int select; #ifdef DEBUG int index; int page_id; int acc, inv; #endif pgd_t* pgd = (pgd_t*)per_cpu(current_pgd, smp_processor_id()); pmd_t *pmd; pte_t pte; int miss, we, writeac; unsigned long address; unsigned long flags; cause = *R_MMU_CAUSE; address = cause & PAGE_MASK; /* get faulting address */ select = *R_TLB_SELECT; #ifdef DEBUG page_id = IO_EXTRACT(R_MMU_CAUSE, page_id, cause); acc = IO_EXTRACT(R_MMU_CAUSE, acc_excp, cause); inv = IO_EXTRACT(R_MMU_CAUSE, inv_excp, cause); index = IO_EXTRACT(R_TLB_SELECT, index, select); #endif miss = IO_EXTRACT(R_MMU_CAUSE, miss_excp, cause); we = IO_EXTRACT(R_MMU_CAUSE, we_excp, cause); writeac = IO_EXTRACT(R_MMU_CAUSE, wr_rd, cause); D(printk("bus_fault from IRP 0x%lx: addr 0x%lx, miss %d, inv %d, we %d, acc %d, dx %d pid %d\n", regs->irp, address, miss, inv, we, acc, index, page_id)); /* leave it to the MM system fault handler */ if (miss) do_page_fault(address, regs, 0, writeac); else do_page_fault(address, regs, 1, we); /* Reload TLB with new entry to avoid an extra miss exception. * do_page_fault may have flushed the TLB so we have to restore * the MMU registers. */ local_save_flags(flags); local_irq_disable(); pmd = (pmd_t *)(pgd + pgd_index(address)); if (pmd_none(*pmd)) goto exit; pte = *pte_offset_kernel(pmd, address); if (!pte_present(pte)) goto exit; *R_TLB_SELECT = select; *R_TLB_HI = cause; *R_TLB_LO = pte_val(pte); exit: local_irq_restore(flags); }
int main() { #ifdef CONFIG_ARM_LPAE do_page_fault(); #else do_page_fault(); do_sect_fault(); #endif return 0; }
void handle_mmu_bus_fault(struct pt_regs *regs) { int cause; int select; #ifdef DEBUG int index; int page_id; int acc, inv; #endif pgd_t* pgd = (pgd_t*)per_cpu(current_pgd, smp_processor_id()); pmd_t *pmd; pte_t pte; int miss, we, writeac; unsigned long address; unsigned long flags; cause = *R_MMU_CAUSE; address = cause & PAGE_MASK; select = *R_TLB_SELECT; #ifdef DEBUG page_id = IO_EXTRACT(R_MMU_CAUSE, page_id, cause); acc = IO_EXTRACT(R_MMU_CAUSE, acc_excp, cause); inv = IO_EXTRACT(R_MMU_CAUSE, inv_excp, cause); index = IO_EXTRACT(R_TLB_SELECT, index, select); #endif miss = IO_EXTRACT(R_MMU_CAUSE, miss_excp, cause); we = IO_EXTRACT(R_MMU_CAUSE, we_excp, cause); writeac = IO_EXTRACT(R_MMU_CAUSE, wr_rd, cause); D(printk("bus_fault from IRP 0x%lx: addr 0x%lx, miss %d, inv %d, we %d, acc %d, dx %d pid %d\n", regs->irp, address, miss, inv, we, acc, index, page_id)); if (miss) do_page_fault(address, regs, 0, writeac); else do_page_fault(address, regs, 1, we); local_irq_save(flags); pmd = (pmd_t *)(pgd + pgd_index(address)); if (pmd_none(*pmd)) goto exit; pte = *pte_offset_kernel(pmd, address); if (!pte_present(pte)) goto exit; *R_TLB_SELECT = select; *R_TLB_HI = cause; *R_TLB_LO = pte_val(pte); exit: local_irq_restore(flags); }
main() { pthread_t pt; int ret; /* allocate a shared area for concurrent page fault / madvise() */ ret = posix_memalign(&mem_addr, HUGE_PAGE_SIZE, MEM_ALLOC_SIZE); if (ret) { printf("posix_memalign: ret=%d\n", ret); _exit(1); } /* start a separate thread that does madvise() on the shared area */ ret = pthread_create(&pt, NULL, do_madvise, NULL); if (ret) { printf("pthread_create: ret=%d\n", ret); _exit(1); } /* force page faults on the shared area in parallel to madvise() */ do_page_fault(); /* allocate and initialize a huge area to force page reclamation */ do_reclaim(); }
asmlinkage void xtlb_tlbs_debug(struct pt_regs *regs) { unsigned long addr; addr = regs->cp0_badvaddr; do_page_fault(regs, 1, addr); }
asmlinkage void do_tlbs(struct pt_regs *regs) { // printk("do_tlbs status %p, cause %p, epc %p,bd %p.\n", // regs->cp0_status, // regs->cp0_cause, // regs->cp0_epc, // read_c0_badvaddr()); do_page_fault(regs, 1, read_c0_badvaddr()); }
/* * First Level Translation Fault Handler * * We enter here because the first level page table doesn't contain a valid * entry for the address. * * If the address is in kernel space (>= TASK_SIZE), then we are probably * faulting in the vmalloc() area. * * If the init_task's first level page tables contains the relevant entry, we * copy the it to this task. If not, we send the process a signal, fixup the * exception, or oops the kernel. * * NOTE! We MUST NOT take any locks for this case. We may be in an interrupt * or a critical region, and should only copy the information from the master * page table, nothing more. */ static int __kprobes do_translation_fault(unsigned long addr, unsigned int esr, struct pt_regs *regs) { if (addr < TASK_SIZE) return do_page_fault(addr, esr, regs); do_bad_area(addr, esr, regs); return 0; }
/* * First Level Translation Fault Handler * * We enter here because the first level page table doesn't contain * a valid entry for the address. * * If the address is in kernel space (>= TASK_SIZE), then we are * probably faulting in the vmalloc() area. * * If the init_task's first level page tables contains the relevant * entry, we copy the it to this task. If not, we send the process * a signal, fixup the exception, or oops the kernel. * * NOTE! We MUST NOT take any locks for this case. We may be in an * interrupt or a critical region, and should only copy the information * from the master page table, nothing more. */ int do_translation_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { struct task_struct *tsk; int offset; pgd_t *pgd, *pgd_k; pmd_t *pmd, *pmd_k; if (addr < TASK_SIZE) return do_page_fault(addr, fsr, regs); offset = __pgd_offset(addr); /* * FIXME: CP15 C1 is write only on ARMv3 architectures. * You really need to read the value in the page table * register, not a copy. */ pgd = cpu_get_pgd() + offset; pgd_k = init_mm.pgd + offset; if (pgd_none(*pgd_k)) goto bad_area; #if 0 /* note that we are two-level */ if (!pgd_present(*pgd)) set_pgd(pgd, *pgd_k); #endif pmd_k = pmd_offset(pgd_k, addr); pmd = pmd_offset(pgd, addr); if (pmd_none(*pmd_k)) goto bad_area; set_pmd(pmd, *pmd_k); return 0; bad_area: tsk = current; do_bad_area(tsk, tsk->active_mm, addr, fsr, regs); return 0; }
/* * First Level Translation Fault Handler * * We enter here because the first level page table doesn't contain * a valid entry for the address. * * If the address is in kernel space (>= TASK_SIZE), then we are * probably faulting in the vmalloc() area. * * If the init_task's first level page tables contains the relevant * entry, we copy the it to this task. If not, we send the process * a signal, fixup the exception, or oops the kernel. * * NOTE! We MUST NOT take any locks for this case. We may be in an * interrupt or a critical region, and should only copy the information * from the master page table, nothing more. */ int do_translation_fault(unsigned long addr, int error_code, struct pt_regs *regs) { struct task_struct *tsk; struct mm_struct *mm; int offset; pgd_t *pgd, *pgd_k; pmd_t *pmd, *pmd_k; if (addr < TASK_SIZE) return do_page_fault(addr, error_code, regs); offset = __pgd_offset(addr); /* * FIXME: CP15 C1 is write only on ARMv3 architectures. */ pgd = cpu_get_pgd() + offset; pgd_k = init_mm.pgd + offset; if (pgd_none(*pgd_k)) goto bad_area; #if 0 /* note that we are two-level */ if (!pgd_present(*pgd)) set_pgd(pgd, *pgd_k); #endif pmd_k = pmd_offset(pgd_k, addr); pmd = pmd_offset(pgd, addr); if (pmd_none(*pmd_k)) goto bad_area; set_pmd(pmd, *pmd_k); return 0; bad_area: tsk = current; mm = tsk->active_mm; do_bad_area(tsk, mm, addr, error_code, regs); return 0; }
int main(int argc, char *argv[]) { void *addr; size_t length; struct stat sb; struct tms tms; struct rusage r1, r2; int fd, next_opt; long hz, tvali, tvalf; double elapsed, us_time, sy_time; int fault_mode = PG_FAULT_NONE, mmap_mode = MMAP_MODE_NONE; int exit_wait = 0; int print_stats = 0; signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); prg_name = argv[0]; do { next_opt = getopt_long(argc, argv, short_opts, long_opts, NULL); switch (next_opt) { case 'p': fault_mode = PG_FAULT_NONE; if (optarg) { if (strcmp(optarg, "write") == 0) fault_mode = PG_FAULT_WRITE; if (strcmp(optarg, "read") == 0) fault_mode = PG_FAULT_READ; if (strcmp(optarg, "loop") == 0) fault_mode = PG_FAULT_RWLOOP; } break; case 'a': mmap_mode = MMAP_MODE_ANON; length = atol(optarg) * MB; fd = -1; break; case 'f': mmap_mode = MMAP_MODE_FILE; fd = open (optarg, O_RDWR); if (fd == -1) { perror ("open"); return 1; } if (fstat (fd, &sb) == -1) { perror ("fstat"); return 1; } length = sb.st_size; break; case 's': print_stats = 1; break; case 'w': exit_wait = 1; break; case 'h': print_usage(stdout, 0); case '?': print_usage(stderr, 1); case -1: break; default: abort(); } } while (next_opt != -1); if (argc == 1 || mmap_mode == MMAP_MODE_NONE) print_usage(stderr, 2); addr = do_mmap(fd, length); if (mmap_mode == MMAP_MODE_FILE) close(fd); if (addr == MAP_FAILED) { perror("mmap"); return 1; } if (print_stats) { hz = sysconf(_SC_CLK_TCK); if (hz == -1) { perror("sysconf"); return 1; } tvali = times(&tms); if (getrusage(RUSAGE_SELF, &r1)) { perror("getrusage"); return 1; } } do_page_fault(addr, length, fault_mode); if (print_stats) { if (getrusage(RUSAGE_SELF, &r2)) { perror("getrusage"); return 1; } tvalf = times(&tms); elapsed = (double) (tvalf - tvali) / hz; us_time = (double) tms.tms_utime / hz; sy_time = (double) tms.tms_stime / hz; fprintf(stderr, "page faults: %lu minor; %lu major\n", r2.ru_minflt - r1.ru_minflt, r2.ru_majflt - r1.ru_majflt); fprintf(stderr, "time (secs): %0.3lf wall; " "%0.3lf user; %0.3lf system\n", elapsed, us_time, sy_time); fprintf(stderr, "throughput : %0.3lf kB/s \n", length / KB / elapsed); } if (exit_wait) wait_loop(); return 0; }
//已更新二级页表 void do_response() { Ptr_PageTableItem ptr_pageTabIt; unsigned int RootPageSum, ChildPageSum,offAddr,SinglePageSum; unsigned int actAddr; /* 检查地址是否越界*/ if (ptr_memAccReq->virAddr < 0 || ptr_memAccReq->virAddr >= VIRTUAL_MEMORY_SIZE) { do_error(ERROR_OVER_BOUNDARY); return; } /*检查进程编号是否符合要求*/ if(ptr_memAccReq->processNum < 0||ptr_memAccReq->processNum >= PROCESSNUM){ do_error(ERROR_PROCESS_NOT_FOUND); return; } /* 计算页号和页内偏移值 */ SinglePageSum = PAGE_SIZE*CHILD_PAGE_SUM; RootPageSum = ptr_memAccReq->virAddr / SinglePageSum; ChildPageSum = (ptr_memAccReq->virAddr % SinglePageSum) / PAGE_SIZE; offAddr = ptr_memAccReq->virAddr % PAGE_SIZE; printf("页目录号为:%u\t,二级目录页号为:%u\t,页内偏移为:%u\n", RootPageSum,ChildPageSum, offAddr); /* 获取对应页表项 */ ptr_pageTabIt = &pageTable[RootPageSum][ChildPageSum]; /* 根据特征位决定是否产生缺页中断 */ if (!ptr_pageTabIt->filled) { do_page_fault(ptr_pageTabIt); }else{ LRU_ChangeAdd(ptr_pageTabIt->blockNum); } actAddr = ptr_pageTabIt->blockNum * PAGE_SIZE + offAddr; printf("实地址为%u\n", actAddr); if (ptr_pageTabIt->processNum != ptr_memAccReq->processNum) { do_error(ERROR_PROCESS_DISMATCH); return; } /*检查进程编号是否匹配*/ if(ptr_memAccReq->processNum != ptr_pageTabIt->processNum){ do_error(ERROR_PROCESS_DISMATCH); return; } /* 检查页面访问权限并处理访存请求 */ switch (ptr_memAccReq->reqType) { case REQUEST_READ: //读请求 { //ptr_pageTabIt->count++; //else 的地方已经加过了;这个count只是为了LFU代码,现在不需要了; if (!(ptr_pageTabIt->proType & READABLE)) //页面不可读 { do_error(ERROR_READ_DENY); return; } /* 读取实存中的内容 */ printf("读操作成功%02X\n", actMem[actAddr]); break; } case REQUEST_WRITE: //写请求 { //ptr_pageTabIt->count++; if (!(ptr_pageTabIt->proType & WRITABLE)) //页面不可写 { do_error(ERROR_WRITE_DENY); return; } /* 向实存中写入请求的内容 */ actMem[actAddr] = ptr_memAccReq->value; ptr_pageTabIt->edited = TRUE; printf("写操作成功\n"); break; } case REQUEST_EXECUTE: //执行请求 { //ptr_pageTabIt->count++; if (!(ptr_pageTabIt->proType & EXECUTABLE)) //页面不可执行 { do_error(ERROR_EXECUTE_DENY); return; } printf("执行成功\n"); break; } default: //非法请求类型 { do_error(ERROR_INVALID_REQUEST); return; } } }
/* 响应请求 */ void do_response() { Ptr_PageTableItem ptr_pageTabIt; Ptr_PageCatalogueItem ptr_pageCatalogueItem; unsigned int JGpageCatalogueNum, JGpageCatalogueOffset, pageNum, offAddr; unsigned int actAddr; /* 检查地址是否越界 */ if (ptr_memAccReq->virAddr < 0 || ptr_memAccReq->virAddr >= VIRTUAL_MEMORY_SIZE) { do_error(ERROR_OVER_BOUNDARY); return; } /* 计算页号和页内偏移值 */ //pageNum = ptr_memAccReq->virAddr / PAGE_SIZE; JGpageCatalogueNum = JGcalPageCatalogueNum(); JGpageCatalogueOffset = JGcalPageCatalogueOffset(); offAddr = ptr_memAccReq->virAddr % PAGE_SIZE; //printf("页号为:%u\t页内偏移为:%u\n", pageNum, offAddr); JGresponsePrint(JGpageCatalogueNum, JGpageCatalogueOffset, offAddr); /* 获取对应页表项 */ ptr_pageCatalogueItem = &JGpageCatalogue[JGpageCatalogueNum]; if (!ptr_pageCatalogueItem->filled) JGdo_page_catalogue_fault(ptr_pageCatalogueItem); pageNum = ptr_pageCatalogueItem->pageNum * PAGE_SIZE + JGpageCatalogueOffset; ptr_pageTabIt = &pageTable[pageNum]; /* 根据特征位决定是否产生缺页中断 */ if (!ptr_pageTabIt->filled) { do_page_fault(ptr_pageTabIt); } actAddr = ptr_pageTabIt->blockNum * PAGE_SIZE + offAddr; printf("实地址为:%u\n", actAddr); /* 检查页面访问权限并处理访存请求 */ switch (ptr_memAccReq->reqType) { case REQUEST_READ: //读请求 { ptr_pageTabIt->count++; if (!(ptr_pageTabIt->proType & READABLE)) //页面不可读 { do_error(ERROR_READ_DENY); return; } /* 读取实存中的内容 */ printf("读操作成功:值为%02X\n", actMem[actAddr]); break; } case REQUEST_WRITE: //写请求 { ptr_pageTabIt->count++; if (!(ptr_pageTabIt->proType & WRITABLE)) //页面不可写 { do_error(ERROR_WRITE_DENY); return; } /* 向实存中写入请求的内容 */ actMem[actAddr] = ptr_memAccReq->value; ptr_pageTabIt->edited = TRUE; printf("写操作成功\n"); break; } case REQUEST_EXECUTE: //执行请求 { ptr_pageTabIt->count++; if (!(ptr_pageTabIt->proType & EXECUTABLE)) //页面不可执行 { do_error(ERROR_EXECUTE_DENY); return; } printf("执行成功\n"); break; } default: //非法请求类型 { do_error(ERROR_INVALID_REQUEST); return; } } }
/* 响应请求 */ void do_response() { Ptr_PageTableItem ptr_pageTabIt; unsigned int pageNum1, offAddr ,pageNum2; unsigned int actAddr; int i,k; /* 检查地址是否越界 */ if (ptr_memAccReq->virAddr < 0 || ptr_memAccReq->virAddr >= VIRTUAL_MEMORY_SIZE) { do_error(ERROR_OVER_BOUNDARY); return; } /* 计算页号和页内偏移值 */ pageNum2 = ptr_memAccReq->virAddr / (PAGE_SIZE*PAGE_SUM1); pageNum1 = (ptr_memAccReq->virAddr - pageNum2*PAGE_SIZE*PAGE_SUM1 )/ PAGE_SIZE; offAddr = ptr_memAccReq->virAddr % PAGE_SIZE; printf("2级页号为:%u\t1级页号为: %u\t页内偏移为:%u\n", pageNum2 , pageNum1 , offAddr); /* 获取对应页表项 */ ptr_pageTabIt = &pageTable[pageNum2][pageNum1]; printf("请求的进程号为:%u\t页表的进程号为:%u\n",ptr_memAccReq->reqProcess,ptr_pageTabIt->processNum); if(ptr_pageTabIt->processNum!=ptr_memAccReq->reqProcess){ // printf("%u %u\n",ptr_pageTabIt->processNum,ptr_memAccReq->reqProcess); do_error(ERROR_VISIT_FAILED); } else{ /* 根据特征位决定是否产生缺页中断 */ if (!ptr_pageTabIt->filled) { do_page_fault(ptr_pageTabIt); } actAddr = ptr_pageTabIt->blockNum * PAGE_SIZE + offAddr; //虚实地址转换 printf("实地址为:%u\n", actAddr); /* 检查页面访问权限并处理访存请求 */ switch (ptr_memAccReq->reqType) { case REQUEST_READ: //读请求 { for(k=0;k<PAGE_SUM2;k++) for(i=0;i<PAGE_SUM1;i++) pageTable[k][i].count=pageTable[k][i].count/10; ptr_pageTabIt->count=ptr_pageTabIt->count+1000000; // ptr_pageTabIt->count++; if (!(ptr_pageTabIt->proType & READABLE)) //页面不可读 { do_error(ERROR_READ_DENY); return; } /* 读取实存中的内容 */ printf("读操作成功:值为%c\n", actMem[actAddr]); break; } case REQUEST_WRITE: //写请求 { for(k=0;k<PAGE_SUM2;k++) for(i=0;i<PAGE_SUM1;i++) pageTable[k][i].count=pageTable[k][i].count/10; ptr_pageTabIt->count=ptr_pageTabIt->count+1000000; // ptr_pageTabIt->count++; if (!(ptr_pageTabIt->proType & WRITABLE)) //页面不可写 { do_error(ERROR_WRITE_DENY); return; } /* 向实存中写入请求的内容 */ actMem[actAddr] = ptr_memAccReq->value; ptr_pageTabIt->edited = TRUE; printf("写操作成功\n"); break; } case REQUEST_EXECUTE: //执行请求 { for(k=0;k<PAGE_SUM2;k++) for(i=0;i<PAGE_SUM1;i++) pageTable[k][i].count=pageTable[k][i].count/10; ptr_pageTabIt->count=ptr_pageTabIt->count+1000000; // ptr_pageTabIt->count++; if (!(ptr_pageTabIt->proType & EXECUTABLE)) //页面不可执行 { do_error(ERROR_EXECUTE_DENY); return; } printf("执行成功\n"); break; } default: //非法请求类型 { do_error(ERROR_INVALID_REQUEST); return; } } } }
void execute_protection_fault(struct pt_regs *regs) { unsigned long badvadr = pt_badva(regs); do_page_fault(badvadr, FLT_IFETCH, regs); }
void read_protection_fault(struct pt_regs *regs) { unsigned long badvadr = pt_badva(regs); do_page_fault(badvadr, FLT_LOAD, regs); }
static void trap_dispatch(struct frame *tf) { switch(tf->tf_trapno) { case T_PGFLT: { //print_frame(tf); do_page_fault(tf); break; } case T_GPFLT: { panic("GPFLT!\n"); do_exit(curtask); break; } case T_BRKPT : { print_frame(tf); panic("break point handler not implemented!\n"); break; } case T_DIVIDE: { printk("CPU:%d USER T_DIVIDE\n",get_cpuid()); do_exit(curtask); } case T_SYSCALL: { tf->tf_regs.reg_eax = syscall_handler(tf); break; } case IRQ_SPURIOUS: { printk("CPU:%d Spurious interrupt on irq 7\n",get_cpuid()); print_frame(tf); return; } case IRQ_TIMER : { lapic_eoi(); schedule_tick(); break; } case IRQ_KBD : { irq_eoi(); printk("CPU:%d IRQ_KBD \n",get_cpuid()); inb(0x60); break; } case IRQ_SERIAL : { panic("SERIAL handler not implemented!\n"); break; } case IRQ_IDE0 : case IRQ_IDE1 : { irq_eoi(); do_hd_interrupt(tf); break; } case IRQ_ERROR : { print_frame(tf); panic("ERROR handler not implemented!\n"); break; } default: { if (tf->tf_cs == _KERNEL_CS_) panic("unhandled trap in kernel"); else { print_frame(tf); return; } break; } } }
/* 响应请求 */ void do_response() { Ptr_PageTableItem ptr_pageTabIt; unsigned int pageNum, offAddr; /************************************************************************************/ unsigned int firstPageNum, firstOffAddr; /************************************************************************************/ unsigned int actAddr; /* 检查地址是否越界 */ if (ptr_memAccReq->virAddr < 0 || ptr_memAccReq->virAddr >= VIRTUAL_MEMORY_SIZE) { do_error(ERROR_OVER_BOUNDARY); return; } /************************************************************************************/ printf("请求进程号: %u\n", ptr_memAccReq->proccessNum); /************************************************************************************/ /* 计算页号和页内偏移值 */ // pageNum = ptr_memAccReq->virAddr / PAGE_SIZE; // offAddr = ptr_memAccReq->virAddr % PAGE_SIZE; // printf("页号为:%u\t页内偏移为:%u\n", pageNum, offAddr); /************************************************************************************/ firstPageNum = ptr_memAccReq->virAddr / 32; firstOffAddr = (ptr_memAccReq->virAddr % 32) / PAGE_SIZE; offAddr = ptr_memAccReq->virAddr % PAGE_SIZE; printf("一级页表页号为:%u\t一级页表页内偏移为:%u\n", firstPageNum, firstOffAddr); printf("二级页表页号为:%u\t二级页表页内偏移为:%u\n", firstPageTable[firstPageNum].secondPageNum[firstOffAddr], offAddr); /************************************************************************************/ /* 获取对应页表项 */ //ptr_pageTabIt = &pageTable[pageNum]; ptr_pageTabIt = &pageTable[firstPageTable[firstPageNum].secondPageNum[firstOffAddr]]; /***********************************************************************************/ if (ptr_memAccReq->proccessNum != ptr_pageTabIt->proccessNum) { ptr_pageTabIt->count++; ptr_pageTabIt->LRU_flag = 1; printf("权限不够,无法操作其他进程数据\n"); return; } /***********************************************************************************/ /* 根据特征位决定是否产生缺页中断 */ //当前页表为空 if (!ptr_pageTabIt->filled) { do_page_fault(ptr_pageTabIt); } actAddr = ptr_pageTabIt->blockNum * PAGE_SIZE + offAddr; printf("实地址为:%u\n", actAddr); /* 检查页面访问权限并处理访存请求 */ switch (ptr_memAccReq->reqType) { case REQUEST_READ: //读请求 { ptr_pageTabIt->count++; ptr_pageTabIt->LRU_flag = 1; if (!(ptr_pageTabIt->proType & READABLE)) //页面不可读 { do_error(ERROR_READ_DENY); return; } /* 读取实存中的内容 */ printf("读操作成功:值为%02X\n", actMem[actAddr]); break; } case REQUEST_WRITE: //写请求 { ptr_pageTabIt->count++; ptr_pageTabIt->LRU_flag = 1; if (!(ptr_pageTabIt->proType & WRITABLE)) //页面不可写 { do_error(ERROR_WRITE_DENY); return; } /* 向实存中写入请求的内容 */ actMem[actAddr] = ptr_memAccReq->value; ptr_pageTabIt->edited = TRUE; printf("写操作成功\n"); break; } case REQUEST_EXECUTE: //执行请求 { ptr_pageTabIt->count++; ptr_pageTabIt->LRU_flag = 1; if (!(ptr_pageTabIt->proType & EXECUTABLE)) //页面不可执行 { do_error(ERROR_EXECUTE_DENY); return; } printf("执行成功\n"); break; } default: //非法请求类型 { do_error(ERROR_INVALID_REQUEST); return; } } }
/* 响应请求 */ void do_response() { Ptr_PageTableItem ptr_pageTabIt; unsigned int pageNum, offAddr; unsigned int pageNum_1,pageNum_2; Ptr_PageTableItem ptr_pageTabIt_1,ptr_pageTabIt_2; unsigned int actAddr; int i=0; char s[4],str[4]; /* 检查地址是否越界 */ if (ptr_memAccReq->virAddr < 0 || ptr_memAccReq->virAddr >= VIRTUAL_MEMORY_SIZE) { do_error(ERROR_OVER_BOUNDARY); return; } /* 计算页号和页内偏移值 */ pageNum = ptr_memAccReq->virAddr / PAGE_SIZE; pageNum_1=pageNum/8;//一级页表索引 pageNum_2=pageNum%8;//二级页表索引 offAddr = ptr_memAccReq->virAddr % PAGE_SIZE; printf("一级页表:%u 二级页表:%u 页内偏移为:%u\n",pageNum_1,pageNum_2,offAddr); printf("页号为:%u\t页内偏移为:%u\n", pageNum, offAddr); /* 获取对应页表项 */ ptr_pageTabIt = &pageTable[pageNum]; ptr_pageTabIt_1=prt_pageTable_1[pageNum_1];//一级页表 ptr_pageTabIt=&ptr_pageTabIt_1[pageNum_2];//二级页表 /*if(ptr_pageTabIt==ptr_pageTabIt_2) printf("%d %d yes\n",ptr_pageTabIt,ptr_pageTabIt_2); else printf("%d %d no\n",ptr_pageTabIt,ptr_pageTabIt_2);*/ /* 根据特征位决定是否产生缺页中断 */ if (!ptr_pageTabIt->filled) { do_page_fault(ptr_pageTabIt); } actAddr = ptr_pageTabIt->blockNum * PAGE_SIZE + offAddr; printf("实地址为:%u\n", actAddr); if(!(ptr_memAccReq->proccessNum&ptr_pageTabIt->proccessNum))//判断请求能否访问该页面 { printf("该页属于进程:%s 进程%s不能访问\n", get_proNum_str(s,ptr_pageTabIt->proccessNum),get_proNum_str(str,ptr_memAccReq->proccessNum)); return; } for(i = 0; i < PAGE_SUM; i++) { if(pageTable[i].filled) { pageTable[i].count_LRU++; } } ptr_pageTabIt->count_LRU=0;//更新LRU计数 /* 检查页面访问权限并处理访存请求 */ switch (ptr_memAccReq->reqType) { case REQUEST_READ: //读请求 { ptr_pageTabIt->count++; ptr_pageTabIt->R=1; if (!(ptr_pageTabIt->proType & READABLE)) //页面不可读 { do_error(ERROR_READ_DENY); return; } /* 读取实存中的内容 */ printf("读操作成功:值为%c\n", actMem[actAddr]); break; } case REQUEST_WRITE: //写请求 { ptr_pageTabIt->count++; ptr_pageTabIt->R=1; if (!(ptr_pageTabIt->proType & WRITABLE)) //页面不可写 { do_error(ERROR_WRITE_DENY); return; } /* 向实存中写入请求的内容 */ actMem[actAddr] = ptr_memAccReq->value; ptr_pageTabIt->edited = TRUE; printf("写操作成功\n"); break; } case REQUEST_EXECUTE: //执行请求 { ptr_pageTabIt->count++; ptr_pageTabIt->R=1; if (!(ptr_pageTabIt->proType & EXECUTABLE)) //页面不可执行 { do_error(ERROR_EXECUTE_DENY); return; } printf("执行成功\n"); break; } default: //非法请求类型 { do_error(ERROR_INVALID_REQUEST); return; } } }
void handle_interruption(int code, struct pt_regs *regs) { unsigned long fault_address = 0; unsigned long fault_space = 0; struct siginfo si; switch(code) { case 1: /* High-priority machine check (HPMC) */ pdc_console_restart(); /* switch back to pdc if HPMC */ /* set up a new led state on systems shipped with a LED State panel */ pdc_chassis_send_status(PDC_CHASSIS_DIRECT_HPMC); parisc_terminate("High Priority Machine Check (HPMC)", regs, code, 0); /* NOT REACHED */ case 2: /* Power failure interrupt */ printk(KERN_CRIT "Power failure interrupt !\n"); return; case 3: /* Recovery counter trap */ regs->gr[0] &= ~PSW_R; if (regs->iasq[0]) handle_gdb_break(regs, TRAP_TRACE); /* else this must be the start of a syscall - just let it run */ return; case 5: /* Low-priority machine check */ pdc_chassis_send_status(PDC_CHASSIS_DIRECT_LPMC); flush_all_caches(); cpu_lpmc(5, regs); return; case 6: /* Instruction TLB miss fault/Instruction page fault */ fault_address = regs->iaoq[0]; fault_space = regs->iasq[0]; break; case 8: /* Illegal instruction trap */ die_if_kernel("Illegal instruction", regs, code); si.si_code = ILL_ILLOPC; goto give_sigill; case 9: /* Break instruction trap */ handle_break(regs->iir,regs); return; case 10: /* Privileged operation trap */ die_if_kernel("Privileged operation", regs, code); si.si_code = ILL_PRVOPC; goto give_sigill; case 11: /* Privileged register trap */ if ((regs->iir & 0xffdfffe0) == 0x034008a0) { /* This is a MFCTL cr26/cr27 to gr instruction. * PCXS traps on this, so we need to emulate it. */ if (regs->iir & 0x00200000) regs->gr[regs->iir & 0x1f] = mfctl(27); else regs->gr[regs->iir & 0x1f] = mfctl(26); regs->iaoq[0] = regs->iaoq[1]; regs->iaoq[1] += 4; regs->iasq[0] = regs->iasq[1]; return; } die_if_kernel("Privileged register usage", regs, code); si.si_code = ILL_PRVREG; /* Fall thru */ give_sigill: si.si_signo = SIGILL; si.si_errno = 0; si.si_addr = (void *) regs->iaoq[0]; force_sig_info(SIGILL, &si, current); return; case 12: /* Overflow Trap, let the userland signal handler do the cleanup */ si.si_signo = SIGFPE; si.si_code = FPE_INTOVF; si.si_addr = (void *) regs->iaoq[0]; force_sig_info(SIGFPE, &si, current); return; case 13: /* Conditional Trap The condition succees in an instruction which traps on condition */ si.si_signo = SIGFPE; /* Set to zero, and let the userspace app figure it out from the insn pointed to by si_addr */ si.si_code = 0; si.si_addr = (void *) regs->iaoq[0]; force_sig_info(SIGFPE, &si, current); return; case 14: /* Assist Exception Trap, i.e. floating point exception. */ die_if_kernel("Floating point exception", regs, 0); /* quiet */ handle_fpe(regs); return; case 15: /* Data TLB miss fault/Data page fault */ /* Fall thru */ case 16: /* Non-access instruction TLB miss fault */ /* The instruction TLB entry needed for the target address of the FIC is absent, and hardware can't find it, so we get to cleanup */ /* Fall thru */ case 17: /* Non-access data TLB miss fault/Non-access data page fault */ /* TODO: Still need to add slow path emulation code here */ /* TODO: Understand what is meant by the TODO listed above this one. (Carlos) */ fault_address = regs->ior; fault_space = regs->isr; break; case 18: /* PCXS only -- later cpu's split this into types 26,27 & 28 */ /* Check for unaligned access */ if (check_unaligned(regs)) { handle_unaligned(regs); return; } /* Fall Through */ case 26: /* PCXL: Data memory access rights trap */ fault_address = regs->ior; fault_space = regs->isr; break; case 19: /* Data memory break trap */ regs->gr[0] |= PSW_X; /* So we can single-step over the trap */ /* fall thru */ case 21: /* Page reference trap */ handle_gdb_break(regs, TRAP_HWBKPT); return; case 25: /* Taken branch trap */ regs->gr[0] &= ~PSW_T; if (regs->iasq[0]) handle_gdb_break(regs, TRAP_BRANCH); /* else this must be the start of a syscall - just let it * run. */ return; case 7: /* Instruction access rights */ /* PCXL: Instruction memory protection trap */ /* * This could be caused by either: 1) a process attempting * to execute within a vma that does not have execute * permission, or 2) an access rights violation caused by a * flush only translation set up by ptep_get_and_clear(). * So we check the vma permissions to differentiate the two. * If the vma indicates we have execute permission, then * the cause is the latter one. In this case, we need to * call do_page_fault() to fix the problem. */ if (user_mode(regs)) { struct vm_area_struct *vma; down_read(¤t->mm->mmap_sem); vma = find_vma(current->mm,regs->iaoq[0]); if (vma && (regs->iaoq[0] >= vma->vm_start) && (vma->vm_flags & VM_EXEC)) { fault_address = regs->iaoq[0]; fault_space = regs->iasq[0]; up_read(¤t->mm->mmap_sem); break; /* call do_page_fault() */ } up_read(¤t->mm->mmap_sem); } /* Fall Through */ case 27: /* Data memory protection ID trap */ die_if_kernel("Protection id trap", regs, code); si.si_code = SEGV_MAPERR; si.si_signo = SIGSEGV; si.si_errno = 0; if (code == 7) si.si_addr = (void *) regs->iaoq[0]; else si.si_addr = (void *) regs->ior; force_sig_info(SIGSEGV, &si, current); return; case 28: /* Unaligned data reference trap */ handle_unaligned(regs); return; default: if (user_mode(regs)) { #ifdef PRINT_USER_FAULTS printk(KERN_DEBUG "\nhandle_interruption() pid=%d command='%s'\n", current->pid, current->comm); show_regs(regs); #endif /* SIGBUS, for lack of a better one. */ si.si_signo = SIGBUS; si.si_code = BUS_OBJERR; si.si_errno = 0; si.si_addr = (void *) regs->ior; force_sig_info(SIGBUS, &si, current); return; } pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC); parisc_terminate("Unexpected interruption", regs, code, 0); /* NOT REACHED */ } if (user_mode(regs)) { if (fault_space != regs->sr[7]) { #ifdef PRINT_USER_FAULTS if (fault_space == 0) printk(KERN_DEBUG "User Fault on Kernel Space "); else printk(KERN_DEBUG "User Fault (long pointer) "); printk("pid=%d command='%s'\n", current->pid, current->comm); show_regs(regs); #endif si.si_signo = SIGSEGV; si.si_errno = 0; si.si_code = SEGV_MAPERR; si.si_addr = (void *) regs->ior; force_sig_info(SIGSEGV, &si, current); return; } } else { /* * The kernel should never fault on its own address space. */ if (fault_space == 0) { pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC); parisc_terminate("Kernel Fault", regs, code, fault_address); /** NOT REACHED **/ } } local_irq_enable(); do_page_fault(regs, code, fault_address); }
/* 响应请求 */ void do_response() { Ptr_PageTableItem ptr_pageTabIt; unsigned int pageNum, offAddr; unsigned int actAddr; //hzy end printf("进程ID:%d\n", ptr_memAccReq->ID); /* 检查地址是否越界 */ if (ptr_memAccReq->virAddr < 0 || ptr_memAccReq->virAddr >= VIRTUAL_MEMORY_SIZE) { do_error(ERROR_OVER_BOUNDARY); return; } /* 计算页号和页内偏移值 */ pageNum = ptr_memAccReq->virAddr / PAGE_SIZE; pageNum = outerpageTable[pageNum/16].pageIndex + pageNum%16; //多级页表 offAddr = ptr_memAccReq->virAddr % PAGE_SIZE; printf("页号为:%u\t页内偏移为:%u\n", pageNum, offAddr); /* 获取对应页表项 */ ptr_pageTabIt = &pageTable[pageNum]; if(ptr_pageTabIt->ID != ptr_memAccReq->ID) { printf("进程ID:%d 没有获得任何页表ID为%d的访问权限\n",ptr_memAccReq->ID,ptr_pageTabIt->ID); return ; } /* 根据特征位决定是否产生缺页中断 */ if (!ptr_pageTabIt->filled) { do_page_fault(ptr_pageTabIt); } actAddr = ptr_pageTabIt->blockNum * PAGE_SIZE + offAddr; printf("实地址为:%u\n", actAddr); /* 检查页面访问权限并处理访存请求 */ switch (ptr_memAccReq->reqType) { case REQUEST_READ: //读请求 { // ptr_pageTabIt->count++; update_NLRU(ptr_pageTabIt); if (!(ptr_pageTabIt->proType & READABLE)) //页面不可读 { do_error(ERROR_READ_DENY); return; } /* 读取实存中的内容 */ printf("读操作成功:值为%02X\n", actMem[actAddr]); break; } case REQUEST_WRITE: //写请求 { // ptr_pageTabIt->count++; update_NLRU(ptr_pageTabIt); if (!(ptr_pageTabIt->proType & WRITABLE)) //页面不可写 { do_error(ERROR_WRITE_DENY); return; } /* 向实存中写入请求的内容 */ actMem[actAddr] = ptr_memAccReq->value; ptr_pageTabIt->edited = TRUE; printf("写操作成功\n"); break; } case REQUEST_EXECUTE: //执行请求 { // ptr_pageTabIt->count++; update_NLRU(ptr_pageTabIt); if (!(ptr_pageTabIt->proType & EXECUTABLE)) //页面不可执行 { do_error(ERROR_EXECUTE_DENY); return; } printf("执行成功\n"); break; } default: //非法请求类型 { do_error(ERROR_INVALID_REQUEST); return; } } }
void master_exception_handler (long exception, long error) { switch (exception) { case 0: panic ("Exception: divide error!"); case 1: panic ("Exception: debug!"); case 2: panic ("Exception: NMI!"); case 3: panic ("Exception: breakpoint!"); case 4: panic ("Exception: overflow!"); case 5: panic ("Exception: bounds check!"); case 6: panic ("Exception: invalid opcode!"); case 7: panic ("Exception: coprocessor not availiable!"); case 8: panic ("Exception: double fault!"); case 9: panic ("Exception: 9 (reserved)!"); case 10: panic ("Exception: invalid TSS!"); case 11: panic ("Exception: segment not present!"); case 12: panic ("Exception: stack!"); case 13: panic ("Exception: general protection!"); case 14: // //printf ("PF(pid=%u,", (int) current_proc->pid); // // if (error & PAGE_FAULT_P) // printf ("present,"); //else // printf ("not present,"); // //if (error & PAGE_FAULT_RW) // printf ("write,"); //else // printf ("read,"); // //if (error & PAGE_FAULT_US) // printf ("user,"); //else // printf ("supervisor,"); // //printf ("0x%x) ", (int) get_cr2()); // do_page_fault (current_proc, get_cr2(), error); break; case 16: panic ("Exception: coprocessor error!"); case BAD_INT: warning ("Unallowed int# used!"); } }
/* 响应请求 */ void do_response() { Ptr_PageTableItem ptr_pageTabIt; unsigned int masterPageNum, pageNum, offAddr; unsigned int actAddr; int i; int count; while (TRUE) { if ((count = read(fd, ptr_memAccReq, sizeof(MemoryAccessRequest))) < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) { printf("本次读取结束.\n"); return; } else { printf("read FIFO failed.\n"); exit(1); } } else if (count < sizeof(MemoryAccessRequest)) { printf("本次读取结束.\n"); return; } if (ptr_memAccReq->virAddr >= ptr_memAccReq->id * VIRTUAL_MEMORY_EACH && ptr_memAccReq->virAddr < (ptr_memAccReq->id + 1) * VIRTUAL_MEMORY_EACH) { switch(ptr_memAccReq->reqType) { case 0: //读请求 { printf("产生请求:\nid:%d\t地址:%u\t类型:读取\n",ptr_memAccReq->id, ptr_memAccReq->virAddr); break; } case 1: //写请求 { if (ptr_memAccReq->value >= 0 && ptr_memAccReq->value < 0xFFu) { printf("产生请求:\nid:%d\t地址:%u\t类型:写入\t值:%02X\n", ptr_memAccReq->id, ptr_memAccReq->virAddr, ptr_memAccReq->value); } else { do_error(ERROR_INVALID_REQUEST); } break; } case 2: { printf("产生请求:\nid:%d\t地址:%u\t类型:执行\n", ptr_memAccReq->id, ptr_memAccReq->virAddr); break; } default: do_error(ERROR_INVALID_REQUEST); continue; } } else { do_error(ERROR_OVER_BOUNDARY); continue; } /* 计算页号和页内偏移值 */ masterPageNum = ptr_memAccReq->virAddr / PAGE_SUM; pageNum = ptr_memAccReq->virAddr % PAGE_SUM / PAGE_SIZE; offAddr = ptr_memAccReq->virAddr % PAGE_SUM % PAGE_SIZE; printf("一级页号为:%u\t二级页号为:%u\t页内偏移为:%u\n", masterPageNum, pageNum, offAddr); /* 获取对应页表项 */ ptr_pageTabIt = masterPageTable[masterPageNum].pages + pageNum; /* 根据特征位决定是否产生缺页中断 */ if (!ptr_pageTabIt->filled) { do_page_fault(ptr_pageTabIt); } actAddr = ptr_pageTabIt->blockNum * PAGE_SIZE + offAddr; printf("实地址为:%u\n", actAddr); /* 检查页面访问权限并处理访存请求 */ switch (ptr_memAccReq->reqType) { case REQUEST_READ: //读请求 { if (!(ptr_pageTabIt->proType & READABLE)) //页面不可读 { do_error(ERROR_READ_DENY); continue; } /* 读取实存中的内容 */ for (i = 0; i < PAGE_SUM; i++) { pageTable[i].count /= 2; if (pageTable + i == ptr_pageTabIt) { pageTable[i].count += 128; } } printf("读操作成功:值为%02X\n", actMem[actAddr]); break; } case REQUEST_WRITE: //写请求 { if (!(ptr_pageTabIt->proType & WRITABLE)) //页面不可写 { do_error(ERROR_WRITE_DENY); continue; } /* 向实存中写入请求的内容 */ for (i = 0; i < PAGE_SUM; i++) { pageTable[i].count /= 2; if (pageTable + i == ptr_pageTabIt) { pageTable[i].count += 128; } } actMem[actAddr] = ptr_memAccReq->value; ptr_pageTabIt->edited = TRUE; printf("写操作成功\n"); break; } case REQUEST_EXECUTE: //执行请求 { if (!(ptr_pageTabIt->proType & EXECUTABLE)) //页面不可执行 { do_error(ERROR_EXECUTE_DENY); continue; } for (i = 0; i < PAGE_SUM; i++) { pageTable[i].count /= 2; if (pageTable + i == ptr_pageTabIt) { pageTable[i].count += 128; } } printf("执行成功\n"); break; } default: //非法请求类型 { do_error(ERROR_INVALID_REQUEST); continue; } } } }
/* 响应请求 */ void do_response() { Ptr_PageTableItem ptr_pageTabIt; unsigned int pageNum, offAddr,indexNum,ProcessNum; unsigned int actAddr; Ptr_MemoryAccessRequest aptr_memAccReq; int processCount, k, i, c; if(head==NULL){ printf("hi\n"); return;} aptr_memAccReq = head; head = head->next; ProcessNum = aptr_memAccReq->ProcessNum; /* 检查地址是否越界 */ if (aptr_memAccReq->virAddr < aptr_memAccReq->ProcessNum*256 || aptr_memAccReq->virAddr >= (aptr_memAccReq->ProcessNum+1)*256) { printf("viraddr=%d\t,processnum=%d\n",aptr_memAccReq->virAddr,ProcessNum); do_error(ERROR_OVER_BOUNDARY); return; } /* 计算页号和页内偏移值 */ pageNum = (aptr_memAccReq->virAddr-ProcessNum*256) / PAGE_SIZE % INDEX_PAGE ; indexNum = (aptr_memAccReq->virAddr-ProcessNum*256) / PAGE_SIZE / INDEX_PAGE; offAddr = (aptr_memAccReq->virAddr-ProcessNum*256) % PAGE_SIZE; printf("进程号为:%u\t页目录为:%u\t页号为:%u\t页内偏移为:%u\n",ProcessNum,indexNum, pageNum, offAddr); /* 获取对应页表项 */ ptr_pageTabIt = &pageIndex[ProcessNum][indexNum].index[pageNum]; /* 根据特征位决定是否产生缺页中断 */ if (!ptr_pageTabIt->filled) { do_page_fault(ptr_pageTabIt); } actAddr = ptr_pageTabIt->blockNum * PAGE_SIZE + offAddr; printf("实地址为:%u\n", actAddr); for(processCount=0;processCount<Process_SUM;processCount++) for (k = 0; k < INDEX_SUM; k++) for(i=0;i<INDEX_PAGE;i++) { pageIndex[processCount][k].index[i].visited = 0; } /* 检查页面访问权限并处理访存请求 */ switch (aptr_memAccReq->reqType) { case REQUEST_READ: //读请求 { ptr_pageTabIt->visited = 1; for(processCount=0;processCount<Process_SUM;processCount++) for (k = 0; k < INDEX_SUM; k++) for(i=0;i<INDEX_PAGE;i++) { for(c = 7;c > 0;c--){ pageIndex[processCount][k].index[i].count[c] = pageIndex[processCount][k].index[i].count[c - 1]; } pageIndex[processCount][k].index[i].count[0] = pageIndex[processCount][k].index[i].visited + '0'; } if (!(ptr_pageTabIt->proType & READABLE)) //页面不可读 { do_error(ERROR_READ_DENY); return; } /* 读取实存中的内容 */ printf("读操作成功:值为%02X\n", actMem[actAddr]); break; } case REQUEST_WRITE: //写请求 { ptr_pageTabIt->visited = 1; for(processCount=0;processCount<Process_SUM;processCount++) for (k = 0; k < INDEX_SUM; k++) for(i=0;i<INDEX_PAGE;i++) { for(c = 7;c > 0;c--){ pageIndex[processCount][k].index[i].count[c] = pageIndex[processCount][k].index[i].count[c - 1]; } pageIndex[processCount][k].index[i].count[0] = pageIndex[processCount][k].index[i].visited + '0'; } if (!(ptr_pageTabIt->proType & WRITABLE)) //页面不可写 { do_error(ERROR_WRITE_DENY); return; } /* 向实存中写入请求的内容 */ actMem[actAddr] = aptr_memAccReq->value; ptr_pageTabIt->edited = TRUE; printf("写操作成功\n"); break; } case REQUEST_EXECUTE: //执行请求 { ptr_pageTabIt->visited = 1; for(processCount=0;processCount<Process_SUM;processCount++) for (k = 0; k < INDEX_SUM; k++) for(i=0;i<INDEX_PAGE;i++) { for(c = 7;c > 0;c--){ pageIndex[processCount][k].index[i].count[c] = pageIndex[processCount][k].index[i].count[c - 1]; } pageIndex[processCount][k].index[i].count[0] = pageIndex[processCount][k].index[i].visited + '0'; } if (!(ptr_pageTabIt->proType & EXECUTABLE)) //页面不可执行 { do_error(ERROR_EXECUTE_DENY); return; } printf("执行成功\n"); break; } default: //非法请求类型 { do_error(ERROR_INVALID_REQUEST); return; } } }
void do_response() { Ptr_PageTableItem ptr_pageTabIt; unsigned int pageNum, offAddr; unsigned int actAddr; static int counter=10; if(--counter<=0) { div2(); counter=10; } if(ptr_memAccReq->reqType==REQUEST_SWITCH) { do_switch(); return; } /* 检查地址是否越界 */ if (ptr_memAccReq->virAddr < 0 || ptr_memAccReq->virAddr >= VIRTUAL_MEMORY_SIZE) { printf("error1\n"); do_error(ERROR_OVER_BOUNDARY); return; } /* 计算页号和页内偏移值 */ pageNum = ptr_memAccReq->virAddr / PAGE_SIZE; offAddr = ptr_memAccReq->virAddr % PAGE_SIZE; printf("页号为:%u\t页内偏移为:%u\n", pageNum, offAddr); /* 获取对应页表项 */ ptr_pageTabIt = (*pageTable)[pageNum/8]+pageNum%8;; /* 根据特征位决定是否产生缺页中断 */ if (!ptr_pageTabIt->filled) { do_page_fault(ptr_pageTabIt); } actAddr = ptr_pageTabIt->blockNum * PAGE_SIZE + offAddr; printf("实地址为:%u\n", actAddr); /* 检查页面访问权限并处理访存请求 */ switch (ptr_memAccReq->reqType) { case REQUEST_READ: //读请求 { ptr_pageTabIt->count++; aaaaaaccess(ptr_pageTabIt->blockNum); if (!(ptr_pageTabIt->proType & READABLE)) //页面不可读 { printf("error2\n"); do_error(ERROR_READ_DENY); return; } /* 读取实存中的内容 */ printf("读操作成功:值为%02X\n", actMem[actAddr]); break; } case REQUEST_WRITE: //写请求 { ptr_pageTabIt->count++; aaaaaaccess(ptr_pageTabIt->blockNum); if (!(ptr_pageTabIt->proType & WRITABLE)) //页面不可写 { printf("error3\n"); do_error(ERROR_WRITE_DENY); return; } /* 向实存中写入请求的内容 */ actMem[actAddr] = ptr_memAccReq->value; ptr_pageTabIt->edited = TRUE; printf("写操作成功\n"); break; } case REQUEST_EXECUTE: //执行请求 { ptr_pageTabIt->count++; aaaaaaccess(ptr_pageTabIt->blockNum); if (!(ptr_pageTabIt->proType & EXECUTABLE)) //页面不可执行 { printf("error4\n"); do_error(ERROR_EXECUTE_DENY); return; } printf("执行成功\n"); break; } default: //非法请求类型 { printf("error5\n"); do_error(ERROR_INVALID_REQUEST); return; } } }
void write_protection_fault(struct pt_regs *regs) { unsigned long badvadr = pt_badva(regs); do_page_fault(badvadr, FLT_STORE, regs); }
/* 响应请求 */ void do_response() { Ptr_PageTableItem ptr_pageTabIt; unsigned int pageNum, offAddr; unsigned int actAddr; /* 检查地址是否越界 */ if (ptr_memAccReq->virAddr < 0 || ptr_memAccReq->virAddr >= VIRTUAL_MEMORY_SIZE) { do_error(ERROR_OVER_BOUNDARY); return; } /* 计算页号和页内偏移值 */ pageNum = ptr_memAccReq->virAddr / PAGE_SIZE; offAddr = ptr_memAccReq->virAddr % PAGE_SIZE; printf("页号为:%u\t页内偏移为:%u\n", pageNum, offAddr); /* 获取对应页表项 */ ptr_pageTabIt = &pageTable[pageNum]; /*判断请求与页表项是否属于同一进程*/ if(ptr_memAccReq->processNum != ptr_pageTabIt->processNum) { do_error(ERROR_OVER_PROCESS); return; } /* 根据特征位决定是否产生缺页中断 */ if (!ptr_pageTabIt->filled) { do_page_fault(ptr_pageTabIt); } actAddr = ptr_pageTabIt->blockNum * PAGE_SIZE + offAddr; printf("实地址为:%u\n", actAddr); cpuTime++; /* 检查页面访问权限并处理访存请求 */ switch (ptr_memAccReq->reqType) { case REQUEST_READ: //读请求 { ptr_pageTabIt->count++; ptr_pageTabIt->time = cpuTime; if (!(ptr_pageTabIt->proType & READABLE)) //页面不可读 { do_error(ERROR_READ_DENY); return; } /* 读取实存中的内容 */ printf("读操作成功:值为%02X\n", actMem[actAddr]); break; } case REQUEST_WRITE: //写请求 { ptr_pageTabIt->count++; ptr_pageTabIt->time = cpuTime; if (!(ptr_pageTabIt->proType & WRITABLE)) //页面不可写 { do_error(ERROR_WRITE_DENY); return; } /* 向实存中写入请求的内容 */ actMem[actAddr] = ptr_memAccReq->value; ptr_pageTabIt->edited = TRUE; printf("写操作成功\n"); break; } case REQUEST_EXECUTE: //执行请求 { ptr_pageTabIt->count++; ptr_pageTabIt->time = cpuTime; if (!(ptr_pageTabIt->proType & EXECUTABLE)) //页面不可执行 { do_error(ERROR_EXECUTE_DENY); return; } printf("执行成功\n"); break; } default: //非法请求类型 { do_error(ERROR_INVALID_REQUEST); return; } } }
/* 响应请求 */ void do_response() { Ptr_PageTableItem ptr_pageTabIt; unsigned int pageNum1, pageNum2, offAddr; unsigned int actAddr,i; /* 检查地址是否越界 */ if (ptr_memAccReq->virAddr < 0 || ptr_memAccReq->virAddr >= VIRTUAL_MEMORY_SIZE) { do_error(ERROR_OVER_BOUNDARY); return; } /* 计算页号和页内偏移值 */ pageNum1 = ptr_memAccReq->virAddr / LV1_PAGE_SIZE; offAddr = ptr_memAccReq->virAddr % LV1_PAGE_SIZE; pageNum2 = offAddr / LV2_PAGE_SIZE; offAddr = offAddr % LV2_PAGE_SIZE; printf("页号为:%u\t页内偏移为:%u\n", pageNum1 * LV1_PAGE_SUM + pageNum2, offAddr); /* 获取对应页表项 */ ptr_pageTabIt = &pageTable[ptr_memAccReq->FromProgress][pageNum1][pageNum2]; /* 根据特征位决定是否产生缺页中断 */ //printf("%u\t%u\t%u\n", ptr_memAccReq->FromProgress, pageNum1, pageNum2); if (!ptr_pageTabIt->filled) { //printf("everything ok\n"); for(i=0;i<8;i++) { actmemcount[ptr_memAccReq->FromProgress][pageNum1 * LV1_PAGE_SUM + pageNum2][i]=0; } do_page_fault(ptr_pageTabIt); } // if(ptr_memAccReq->FromProgress != ptr_pageTabIt->progressNum) // { // for(i=0;i<8;i++) // { // actmemcount[pageNum1 * LV1_PAGE_SUM + pageNum2][i]=0; // } // do_page_fault(ptr_pageTabIt); // } actAddr = ptr_pageTabIt->blockNum * PAGE_SIZE + offAddr; printf("实地址为:%u\n", actAddr); switch (ptr_memAccReq->reqType) { case REQUEST_READ: //读请求 { ptr_pageTabIt->count++; actmemcount[ptr_memAccReq->FromProgress][pageNum1 * LV1_PAGE_SUM + pageNum2][0]=1; /* 检查页面访问权限并处理访存请求 */ /*if(ptr_memAccReq->FromProgress != ptr_pageTabIt->progressNum){ printf("%d %d",ptr_memAccReq->FromProgress,ptr_pageTabIt->progressNum); do_error(ERROR_UNMATCHED_PROGRESS); return; }*/ if (!(ptr_pageTabIt->proType & READABLE)) //页面不可读 { do_error(ERROR_READ_DENY); return; } /* 读取实存中的内容 */ printf("读操作成功:值为%02X\n", actMem[actAddr]); break; } case REQUEST_WRITE: //写请求 { ptr_pageTabIt->count++; actmemcount[ptr_memAccReq->FromProgress][pageNum1 * LV1_PAGE_SUM + pageNum2][0]=1; /* 检查页面访问权限并处理访存请求 */ /*if(ptr_memAccReq->FromProgress != ptr_pageTabIt->progressNum){ printf("%d %d",ptr_memAccReq->FromProgress,ptr_pageTabIt->progressNum); do_error(ERROR_UNMATCHED_PROGRESS); return; }*/ if (!(ptr_pageTabIt->proType & WRITABLE)) //页面不可写 { do_error(ERROR_WRITE_DENY); return; } /* 向实存中写入请求的内容 */ actMem[actAddr] = ptr_memAccReq->value; ptr_pageTabIt->edited = TRUE; printf("写操作成功\n"); break; } case REQUEST_EXECUTE: //执行请求 { ptr_pageTabIt->count++; actmemcount[ptr_memAccReq->FromProgress][pageNum1 * LV1_PAGE_SUM + pageNum2][0]=1; /* 检查页面访问权限并处理访存请求 */ /*if(ptr_memAccReq->FromProgress != ptr_pageTabIt->progressNum){ printf("%d %d",ptr_memAccReq->FromProgress,ptr_pageTabIt->progressNum); do_error(ERROR_UNMATCHED_PROGRESS); return; }*/ if (!(ptr_pageTabIt->proType & EXECUTABLE)) //页面不可执行 { do_error(ERROR_EXECUTE_DENY); return; } printf("执行成功\n"); break; } default: //非法请求类型 { do_error(ERROR_INVALID_REQUEST); return; } } }
asmlinkage void do_tlbl(struct pt_regs *regs) { do_page_fault(regs, 0, read_c0_badvaddr()); }