@@ -1519,6 +1519,64 @@ static const char *dma_remap_fault_reasons[] =
1519
1519
"PCE for translation request specifies blocking" ,
1520
1520
};
1521
1521
1522
+ static const char * const dma_remap_sm_fault_reasons [] = {
1523
+ "SM: Invalid Root Table Address" ,
1524
+ "SM: TTM 0 for request with PASID" ,
1525
+ "SM: TTM 0 for page group request" ,
1526
+ "Unknown" , "Unknown" , "Unknown" , "Unknown" , "Unknown" , /* 0x33-0x37 */
1527
+ "SM: Error attempting to access Root Entry" ,
1528
+ "SM: Present bit in Root Entry is clear" ,
1529
+ "SM: Non-zero reserved field set in Root Entry" ,
1530
+ "Unknown" , "Unknown" , "Unknown" , "Unknown" , "Unknown" , /* 0x3B-0x3F */
1531
+ "SM: Error attempting to access Context Entry" ,
1532
+ "SM: Present bit in Context Entry is clear" ,
1533
+ "SM: Non-zero reserved field set in the Context Entry" ,
1534
+ "SM: Invalid Context Entry" ,
1535
+ "SM: DTE field in Context Entry is clear" ,
1536
+ "SM: PASID Enable field in Context Entry is clear" ,
1537
+ "SM: PASID is larger than the max in Context Entry" ,
1538
+ "SM: PRE field in Context-Entry is clear" ,
1539
+ "SM: RID_PASID field error in Context-Entry" ,
1540
+ "Unknown" , "Unknown" , "Unknown" , "Unknown" , "Unknown" , "Unknown" , "Unknown" , /* 0x49-0x4F */
1541
+ "SM: Error attempting to access the PASID Directory Entry" ,
1542
+ "SM: Present bit in Directory Entry is clear" ,
1543
+ "SM: Non-zero reserved field set in PASID Directory Entry" ,
1544
+ "Unknown" , "Unknown" , "Unknown" , "Unknown" , "Unknown" , /* 0x53-0x57 */
1545
+ "SM: Error attempting to access PASID Table Entry" ,
1546
+ "SM: Present bit in PASID Table Entry is clear" ,
1547
+ "SM: Non-zero reserved field set in PASID Table Entry" ,
1548
+ "SM: Invalid Scalable-Mode PASID Table Entry" ,
1549
+ "SM: ERE field is clear in PASID Table Entry" ,
1550
+ "SM: SRE field is clear in PASID Table Entry" ,
1551
+ "Unknown" , "Unknown" ,/* 0x5E-0x5F */
1552
+ "Unknown" , "Unknown" , "Unknown" , "Unknown" , "Unknown" , "Unknown" , "Unknown" , "Unknown" , /* 0x60-0x67 */
1553
+ "Unknown" , "Unknown" , "Unknown" , "Unknown" , "Unknown" , "Unknown" , "Unknown" , "Unknown" , /* 0x68-0x6F */
1554
+ "SM: Error attempting to access first-level paging entry" ,
1555
+ "SM: Present bit in first-level paging entry is clear" ,
1556
+ "SM: Non-zero reserved field set in first-level paging entry" ,
1557
+ "SM: Error attempting to access FL-PML4 entry" ,
1558
+ "SM: First-level entry address beyond MGAW in Nested translation" ,
1559
+ "SM: Read permission error in FL-PML4 entry in Nested translation" ,
1560
+ "SM: Read permission error in first-level paging entry in Nested translation" ,
1561
+ "SM: Write permission error in first-level paging entry in Nested translation" ,
1562
+ "SM: Error attempting to access second-level paging entry" ,
1563
+ "SM: Read/Write permission error in second-level paging entry" ,
1564
+ "SM: Non-zero reserved field set in second-level paging entry" ,
1565
+ "SM: Invalid second-level page table pointer" ,
1566
+ "SM: A/D bit update needed in second-level entry when set up in no snoop" ,
1567
+ "Unknown" , "Unknown" , "Unknown" , /* 0x7D-0x7F */
1568
+ "SM: Address in first-level translation is not canonical" ,
1569
+ "SM: U/S set 0 for first-level translation with user privilege" ,
1570
+ "SM: No execute permission for request with PASID and ER=1" ,
1571
+ "SM: Address beyond the DMA hardware max" ,
1572
+ "SM: Second-level entry address beyond the max" ,
1573
+ "SM: No write permission for Write/AtomicOp request" ,
1574
+ "SM: No read permission for Read/AtomicOp request" ,
1575
+ "SM: Invalid address-interrupt address" ,
1576
+ "Unknown" , "Unknown" , "Unknown" , "Unknown" , "Unknown" , "Unknown" , "Unknown" , "Unknown" , /* 0x88-0x8F */
1577
+ "SM: A/D bit update needed in first-level entry when set up in no snoop" ,
1578
+ };
1579
+
1522
1580
static const char * irq_remap_fault_reasons [] =
1523
1581
{
1524
1582
"Detected reserved fields in the decoded interrupt-remapped request" ,
@@ -1536,6 +1594,10 @@ static const char *dmar_get_fault_reason(u8 fault_reason, int *fault_type)
1536
1594
ARRAY_SIZE (irq_remap_fault_reasons ))) {
1537
1595
* fault_type = INTR_REMAP ;
1538
1596
return irq_remap_fault_reasons [fault_reason - 0x20 ];
1597
+ } else if (fault_reason >= 0x30 && (fault_reason - 0x30 <
1598
+ ARRAY_SIZE (dma_remap_sm_fault_reasons ))) {
1599
+ * fault_type = DMA_REMAP ;
1600
+ return dma_remap_sm_fault_reasons [fault_reason - 0x30 ];
1539
1601
} else if (fault_reason < ARRAY_SIZE (dma_remap_fault_reasons )) {
1540
1602
* fault_type = DMA_REMAP ;
1541
1603
return dma_remap_fault_reasons [fault_reason ];
@@ -1611,7 +1673,8 @@ void dmar_msi_read(int irq, struct msi_msg *msg)
1611
1673
}
1612
1674
1613
1675
static int dmar_fault_do_one (struct intel_iommu * iommu , int type ,
1614
- u8 fault_reason , u16 source_id , unsigned long long addr )
1676
+ u8 fault_reason , int pasid , u16 source_id ,
1677
+ unsigned long long addr )
1615
1678
{
1616
1679
const char * reason ;
1617
1680
int fault_type ;
@@ -1624,10 +1687,11 @@ static int dmar_fault_do_one(struct intel_iommu *iommu, int type,
1624
1687
PCI_FUNC (source_id & 0xFF ), addr >> 48 ,
1625
1688
fault_reason , reason );
1626
1689
else
1627
- pr_err ("[%s] Request device [%02x:%02x.%d] fault addr %llx [fault reason %02d] %s\n" ,
1690
+ pr_err ("[%s] Request device [%02x:%02x.%d] PASID %x fault addr %llx [fault reason %02d] %s\n" ,
1628
1691
type ? "DMA Read" : "DMA Write" ,
1629
1692
source_id >> 8 , PCI_SLOT (source_id & 0xFF ),
1630
- PCI_FUNC (source_id & 0xFF ), addr , fault_reason , reason );
1693
+ PCI_FUNC (source_id & 0xFF ), pasid , addr ,
1694
+ fault_reason , reason );
1631
1695
return 0 ;
1632
1696
}
1633
1697
@@ -1659,8 +1723,9 @@ irqreturn_t dmar_fault(int irq, void *dev_id)
1659
1723
u8 fault_reason ;
1660
1724
u16 source_id ;
1661
1725
u64 guest_addr ;
1662
- int type ;
1726
+ int type , pasid ;
1663
1727
u32 data ;
1728
+ bool pasid_present ;
1664
1729
1665
1730
/* highest 32 bits */
1666
1731
data = readl (iommu -> reg + reg +
@@ -1672,10 +1737,12 @@ irqreturn_t dmar_fault(int irq, void *dev_id)
1672
1737
fault_reason = dma_frcd_fault_reason (data );
1673
1738
type = dma_frcd_type (data );
1674
1739
1740
+ pasid = dma_frcd_pasid_value (data );
1675
1741
data = readl (iommu -> reg + reg +
1676
1742
fault_index * PRIMARY_FAULT_REG_LEN + 8 );
1677
1743
source_id = dma_frcd_source_id (data );
1678
1744
1745
+ pasid_present = dma_frcd_pasid_present (data );
1679
1746
guest_addr = dmar_readq (iommu -> reg + reg +
1680
1747
fault_index * PRIMARY_FAULT_REG_LEN );
1681
1748
guest_addr = dma_frcd_page_addr (guest_addr );
@@ -1688,7 +1755,9 @@ irqreturn_t dmar_fault(int irq, void *dev_id)
1688
1755
raw_spin_unlock_irqrestore (& iommu -> register_lock , flag );
1689
1756
1690
1757
if (!ratelimited )
1758
+ /* Using pasid -1 if pasid is not present */
1691
1759
dmar_fault_do_one (iommu , type , fault_reason ,
1760
+ pasid_present ? pasid : -1 ,
1692
1761
source_id , guest_addr );
1693
1762
1694
1763
fault_index ++ ;
0 commit comments