Commit cf74826d authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] ppc64: Check range of PCI memory and I/O accesses on iSeries, from Stephen Rothwell

From: Anton Blanchard <anton@samba.org>

Check range of PCI memory and I/O accesses on iSeries, from Stephen Rothwell
parent d31decfe
...@@ -654,10 +654,16 @@ static int CheckReturnCode(char *TextHdr, struct iSeries_Device_Node *DevNode, ...@@ -654,10 +654,16 @@ static int CheckReturnCode(char *TextHdr, struct iSeries_Device_Node *DevNode,
static inline struct iSeries_Device_Node *xlateIoMmAddress(void *IoAddress, static inline struct iSeries_Device_Node *xlateIoMmAddress(void *IoAddress,
u64 *dsaptr, u64 *BarOffsetPtr) u64 *dsaptr, u64 *BarOffsetPtr)
{ {
unsigned long BaseIoAddr = unsigned long BaseIoAddr;
(unsigned long)IoAddress - iSeries_Base_Io_Memory; unsigned long TableIndex;
long TableIndex = BaseIoAddr / iSeries_IoMmTable_Entry_Size; struct iSeries_Device_Node *DevNode;
struct iSeries_Device_Node *DevNode = iSeries_IoMmTable[TableIndex];
if (((unsigned long)IoAddress < iSeries_Base_Io_Memory) ||
((unsigned long)IoAddress >= iSeries_Max_Io_Memory))
return NULL;
BaseIoAddr = (unsigned long)IoAddress - iSeries_Base_Io_Memory;
TableIndex = BaseIoAddr / iSeries_IoMmTable_Entry_Size;
DevNode = iSeries_IoMmTable[TableIndex];
if (DevNode != NULL) { if (DevNode != NULL) {
int barnum = iSeries_IoBarTable[TableIndex]; int barnum = iSeries_IoBarTable[TableIndex];
...@@ -685,6 +691,18 @@ u8 iSeries_Read_Byte(void *IoAddress) ...@@ -685,6 +691,18 @@ u8 iSeries_Read_Byte(void *IoAddress)
struct iSeries_Device_Node *DevNode = struct iSeries_Device_Node *DevNode =
xlateIoMmAddress(IoAddress, &dsa, &BarOffset); xlateIoMmAddress(IoAddress, &dsa, &BarOffset);
if (DevNode == NULL) {
static unsigned long last_jiffies;
static int num_printed;
if ((jiffies - last_jiffies) > 60 * HZ) {
last_jiffies = jiffies;
num_printed = 0;
}
if (num_printed++ < 10)
printk(KERN_ERR "iSeries_Read_Byte: invalid access at IO address %p\n", IoAddress);
return 0xff;
}
do { do {
++Pci_Io_Read_Count; ++Pci_Io_Read_Count;
HvCall3Ret16(HvCallPciBarLoad8, &ret, dsa, BarOffset, 0); HvCall3Ret16(HvCallPciBarLoad8, &ret, dsa, BarOffset, 0);
...@@ -701,6 +719,18 @@ u16 iSeries_Read_Word(void *IoAddress) ...@@ -701,6 +719,18 @@ u16 iSeries_Read_Word(void *IoAddress)
struct iSeries_Device_Node *DevNode = struct iSeries_Device_Node *DevNode =
xlateIoMmAddress(IoAddress, &dsa, &BarOffset); xlateIoMmAddress(IoAddress, &dsa, &BarOffset);
if (DevNode == NULL) {
static unsigned long last_jiffies;
static int num_printed;
if ((jiffies - last_jiffies) > 60 * HZ) {
last_jiffies = jiffies;
num_printed = 0;
}
if (num_printed++ < 10)
printk(KERN_ERR "iSeries_Read_Word: invalid access at IO address %p\n", IoAddress);
return 0xffff;
}
do { do {
++Pci_Io_Read_Count; ++Pci_Io_Read_Count;
HvCall3Ret16(HvCallPciBarLoad16, &ret, dsa, HvCall3Ret16(HvCallPciBarLoad16, &ret, dsa,
...@@ -718,6 +748,18 @@ u32 iSeries_Read_Long(void *IoAddress) ...@@ -718,6 +748,18 @@ u32 iSeries_Read_Long(void *IoAddress)
struct iSeries_Device_Node *DevNode = struct iSeries_Device_Node *DevNode =
xlateIoMmAddress(IoAddress, &dsa, &BarOffset); xlateIoMmAddress(IoAddress, &dsa, &BarOffset);
if (DevNode == NULL) {
static unsigned long last_jiffies;
static int num_printed;
if ((jiffies - last_jiffies) > 60 * HZ) {
last_jiffies = jiffies;
num_printed = 0;
}
if (num_printed++ < 10)
printk(KERN_ERR "iSeries_Read_Long: invalid access at IO address %p\n", IoAddress);
return 0xffffffff;
}
do { do {
++Pci_Io_Read_Count; ++Pci_Io_Read_Count;
HvCall3Ret16(HvCallPciBarLoad32, &ret, dsa, HvCall3Ret16(HvCallPciBarLoad32, &ret, dsa,
...@@ -742,6 +784,18 @@ void iSeries_Write_Byte(u8 data, void *IoAddress) ...@@ -742,6 +784,18 @@ void iSeries_Write_Byte(u8 data, void *IoAddress)
struct iSeries_Device_Node *DevNode = struct iSeries_Device_Node *DevNode =
xlateIoMmAddress(IoAddress, &dsa, &BarOffset); xlateIoMmAddress(IoAddress, &dsa, &BarOffset);
if (DevNode == NULL) {
static unsigned long last_jiffies;
static int num_printed;
if ((jiffies - last_jiffies) > 60 * HZ) {
last_jiffies = jiffies;
num_printed = 0;
}
if (num_printed++ < 10)
printk(KERN_ERR "iSeries_Write_Byte: invalid access at IO address %p\n", IoAddress);
return;
}
do { do {
++Pci_Io_Write_Count; ++Pci_Io_Write_Count;
rc = HvCall4(HvCallPciBarStore8, dsa, BarOffset, data, 0); rc = HvCall4(HvCallPciBarStore8, dsa, BarOffset, data, 0);
...@@ -756,6 +810,18 @@ void iSeries_Write_Word(u16 data, void *IoAddress) ...@@ -756,6 +810,18 @@ void iSeries_Write_Word(u16 data, void *IoAddress)
struct iSeries_Device_Node *DevNode = struct iSeries_Device_Node *DevNode =
xlateIoMmAddress(IoAddress, &dsa, &BarOffset); xlateIoMmAddress(IoAddress, &dsa, &BarOffset);
if (DevNode == NULL) {
static unsigned long last_jiffies;
static int num_printed;
if ((jiffies - last_jiffies) > 60 * HZ) {
last_jiffies = jiffies;
num_printed = 0;
}
if (num_printed++ < 10)
printk(KERN_ERR "iSeries_Write_Word: invalid access at IO address %p\n", IoAddress);
return;
}
do { do {
++Pci_Io_Write_Count; ++Pci_Io_Write_Count;
rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, swab16(data), 0); rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, swab16(data), 0);
...@@ -770,6 +836,18 @@ void iSeries_Write_Long(u32 data, void *IoAddress) ...@@ -770,6 +836,18 @@ void iSeries_Write_Long(u32 data, void *IoAddress)
struct iSeries_Device_Node *DevNode = struct iSeries_Device_Node *DevNode =
xlateIoMmAddress(IoAddress, &dsa, &BarOffset); xlateIoMmAddress(IoAddress, &dsa, &BarOffset);
if (DevNode == NULL) {
static unsigned long last_jiffies;
static int num_printed;
if ((jiffies - last_jiffies) > 60 * HZ) {
last_jiffies = jiffies;
num_printed = 0;
}
if (num_printed++ < 10)
printk(KERN_ERR "iSeries_Write_Long: invalid access at IO address %p\n", IoAddress);
return;
}
do { do {
++Pci_Io_Write_Count; ++Pci_Io_Write_Count;
rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, swab32(data), 0); rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, swab32(data), 0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment