tlb.cc (14278:45892d0d3e98) | tlb.cc (14280:9e3f2937f72c) |
---|---|
1/* 2 * Copyright (c) 2010-2013, 2016-2019 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 787 unchanged lines hidden (view full) --- 796 797 Addr vaddr_tainted = req->getVaddr(); 798 Addr vaddr = purifyTaggedAddr(vaddr_tainted, tc, aarch64EL, ttbcr); 799 800 Request::Flags flags = req->getFlags(); 801 bool is_fetch = (mode == Execute); 802 // Cache clean operations require read permissions to the specified VA 803 bool is_write = !req->isCacheClean() && mode == Write; | 1/* 2 * Copyright (c) 2010-2013, 2016-2019 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 787 unchanged lines hidden (view full) --- 796 797 Addr vaddr_tainted = req->getVaddr(); 798 Addr vaddr = purifyTaggedAddr(vaddr_tainted, tc, aarch64EL, ttbcr); 799 800 Request::Flags flags = req->getFlags(); 801 bool is_fetch = (mode == Execute); 802 // Cache clean operations require read permissions to the specified VA 803 bool is_write = !req->isCacheClean() && mode == Write; |
804 bool is_atomic = req->isAtomic(); |
|
804 bool is_priv M5_VAR_USED = isPriv && !(flags & UserMode); 805 806 updateMiscReg(tc, curTranType); 807 808 // If this is the second stage of translation and the request is for a 809 // stage 1 page table walk then we need to check the HCR.PTW bit. This 810 // allows us to generate a fault if the request targets an area marked 811 // as a device or strongly ordered. --- 8 unchanged lines hidden (view full) --- 820 // Generate an alignment fault for unaligned accesses to device or 821 // strongly ordered memory 822 if (!is_fetch) { 823 if (te->mtype != TlbEntry::MemoryType::Normal) { 824 if (vaddr & mask(flags & AlignmentMask)) { 825 alignFaults++; 826 return std::make_shared<DataAbort>( 827 vaddr_tainted, | 805 bool is_priv M5_VAR_USED = isPriv && !(flags & UserMode); 806 807 updateMiscReg(tc, curTranType); 808 809 // If this is the second stage of translation and the request is for a 810 // stage 1 page table walk then we need to check the HCR.PTW bit. This 811 // allows us to generate a fault if the request targets an area marked 812 // as a device or strongly ordered. --- 8 unchanged lines hidden (view full) --- 821 // Generate an alignment fault for unaligned accesses to device or 822 // strongly ordered memory 823 if (!is_fetch) { 824 if (te->mtype != TlbEntry::MemoryType::Normal) { 825 if (vaddr & mask(flags & AlignmentMask)) { 826 alignFaults++; 827 return std::make_shared<DataAbort>( 828 vaddr_tainted, |
828 TlbEntry::DomainType::NoAccess, is_write, | 829 TlbEntry::DomainType::NoAccess, 830 is_atomic ? false : is_write, |
829 ArmFault::AlignmentFault, isStage2, 830 ArmFault::LpaeTran); 831 } 832 } 833 } 834 835 if (te->nonCacheable) { 836 // Prevent prefetching from I/O devices. --- 10 unchanged lines hidden (view full) --- 847 uint8_t ap = 0x3 & (te->ap); // 2-bit access protection field 848 bool grant = false; 849 850 uint8_t xn = te->xn; 851 uint8_t pxn = te->pxn; 852 bool r = !is_write && !is_fetch; 853 bool w = is_write; 854 bool x = is_fetch; | 831 ArmFault::AlignmentFault, isStage2, 832 ArmFault::LpaeTran); 833 } 834 } 835 } 836 837 if (te->nonCacheable) { 838 // Prevent prefetching from I/O devices. --- 10 unchanged lines hidden (view full) --- 849 uint8_t ap = 0x3 & (te->ap); // 2-bit access protection field 850 bool grant = false; 851 852 uint8_t xn = te->xn; 853 uint8_t pxn = te->pxn; 854 bool r = !is_write && !is_fetch; 855 bool w = is_write; 856 bool x = is_fetch; |
857 858 // grant_read is used for faults from an atomic instruction that 859 // both reads and writes from a memory location. From a ISS point 860 // of view they count as read if a read to that address would have 861 // generated the fault; they count as writes otherwise 862 bool grant_read = true; |
|
855 DPRINTF(TLBVerbose, "Checking permissions: ap:%d, xn:%d, pxn:%d, r:%d, " 856 "w:%d, x:%d\n", ap, xn, pxn, r, w, x); 857 858 if (isStage2) { 859 assert(ArmSystem::haveVirtualization(tc) && aarch64EL != EL2); 860 // In stage 2 we use the hypervisor access permission bits. 861 // The following permissions are described in ARM DDI 0487A.f 862 // D4-1802 863 uint8_t hap = 0x3 & te->hap; | 863 DPRINTF(TLBVerbose, "Checking permissions: ap:%d, xn:%d, pxn:%d, r:%d, " 864 "w:%d, x:%d\n", ap, xn, pxn, r, w, x); 865 866 if (isStage2) { 867 assert(ArmSystem::haveVirtualization(tc) && aarch64EL != EL2); 868 // In stage 2 we use the hypervisor access permission bits. 869 // The following permissions are described in ARM DDI 0487A.f 870 // D4-1802 871 uint8_t hap = 0x3 & te->hap; |
872 grant_read = hap & 0x1; |
|
864 if (is_fetch) { 865 // sctlr.wxn overrides the xn bit 866 grant = !sctlr.wxn && !xn; 867 } else if (is_write) { 868 grant = hap & 0x2; 869 } else { // is_read | 873 if (is_fetch) { 874 // sctlr.wxn overrides the xn bit 875 grant = !sctlr.wxn && !xn; 876 } else if (is_write) { 877 grant = hap & 0x2; 878 } else { // is_read |
870 grant = hap & 0x1; | 879 grant = grant_read; |
871 } 872 } else { 873 switch (aarch64EL) { 874 case EL0: 875 { | 880 } 881 } else { 882 switch (aarch64EL) { 883 case EL0: 884 { |
885 grant_read = ap & 0x1; |
|
876 uint8_t perm = (ap << 2) | (xn << 1) | pxn; 877 switch (perm) { 878 case 0: 879 case 1: 880 case 8: 881 case 9: 882 grant = x; 883 break; --- 17 unchanged lines hidden (view full) --- 901 grant = false; 902 } 903 } 904 break; 905 case EL1: 906 { 907 if (checkPAN(tc, ap, req, mode)) { 908 grant = false; | 886 uint8_t perm = (ap << 2) | (xn << 1) | pxn; 887 switch (perm) { 888 case 0: 889 case 1: 890 case 8: 891 case 9: 892 grant = x; 893 break; --- 17 unchanged lines hidden (view full) --- 911 grant = false; 912 } 913 } 914 break; 915 case EL1: 916 { 917 if (checkPAN(tc, ap, req, mode)) { 918 grant = false; |
919 grant_read = false; |
|
909 break; 910 } 911 912 uint8_t perm = (ap << 2) | (xn << 1) | pxn; 913 switch (perm) { 914 case 0: 915 case 2: 916 grant = r || w || (x && !sctlr.wxn); --- 23 unchanged lines hidden (view full) --- 940 default: 941 grant = false; 942 } 943 } 944 break; 945 case EL2: 946 if (hcr.e2h && checkPAN(tc, ap, req, mode)) { 947 grant = false; | 920 break; 921 } 922 923 uint8_t perm = (ap << 2) | (xn << 1) | pxn; 924 switch (perm) { 925 case 0: 926 case 2: 927 grant = r || w || (x && !sctlr.wxn); --- 23 unchanged lines hidden (view full) --- 951 default: 952 grant = false; 953 } 954 } 955 break; 956 case EL2: 957 if (hcr.e2h && checkPAN(tc, ap, req, mode)) { 958 grant = false; |
959 grant_read = false; |
|
948 break; 949 } 950 M5_FALLTHROUGH; 951 case EL3: 952 { 953 uint8_t perm = (ap & 0x2) | xn; 954 switch (perm) { 955 case 0: --- 29 unchanged lines hidden (view full) --- 985 req->getPC(), 986 ArmFault::PermissionLL + te->lookupLevel, 987 isStage2, ArmFault::LpaeTran); 988 } else { 989 permsFaults++; 990 DPRINTF(TLB, "TLB Fault: Data abort on permission check. AP:%d " 991 "priv:%d write:%d\n", ap, is_priv, is_write); 992 return std::make_shared<DataAbort>( | 960 break; 961 } 962 M5_FALLTHROUGH; 963 case EL3: 964 { 965 uint8_t perm = (ap & 0x2) | xn; 966 switch (perm) { 967 case 0: --- 29 unchanged lines hidden (view full) --- 997 req->getPC(), 998 ArmFault::PermissionLL + te->lookupLevel, 999 isStage2, ArmFault::LpaeTran); 1000 } else { 1001 permsFaults++; 1002 DPRINTF(TLB, "TLB Fault: Data abort on permission check. AP:%d " 1003 "priv:%d write:%d\n", ap, is_priv, is_write); 1004 return std::make_shared<DataAbort>( |
993 vaddr_tainted, te->domain, is_write, | 1005 vaddr_tainted, te->domain, 1006 (is_atomic && !grant_read) ? false : is_write, |
994 ArmFault::PermissionLL + te->lookupLevel, 995 isStage2, ArmFault::LpaeTran); 996 } 997 } 998 999 return NoFault; 1000} 1001 --- 617 unchanged lines hidden --- | 1007 ArmFault::PermissionLL + te->lookupLevel, 1008 isStage2, ArmFault::LpaeTran); 1009 } 1010 } 1011 1012 return NoFault; 1013} 1014 --- 617 unchanged lines hidden --- |