ia64/linux-2.6.18-xen.hg

view drivers/pci/access.c @ 882:8dec4aa9b8b9

PCI pass through: PCIe IO space multiplexing

This is required for more than 16 HVM domain to boot from
PCIe pass through device.

Linux as dom0 exclusively assigns IO space to downstream PCI bridges
and the assignment unit of PCI bridge IO space is 4K. So the only up
to 16 PCIe device can be accessed via IO space within 64K IO ports.
PCI expansion ROM BIOS often uses IO port access to boot from the
device, so on virtualized environment, it means only up to 16 guest
domain can boot from pass-through device.

This patch allows PCIe IO space sharing of pass-through device.
- reassign IO space of PCIe devices specified by
"guestiomuldev=[<segment>:]<bus>:<dev>[,[<segment:><bus>:dev]][,...]"
to be shared.
This is implemented as Linux PCI quirk fixup.

The sharing unit is PCIe switch. Ie IO space of the end point
devices under the same switch will be shared. If there are more than
one switches, two areas of IO space will be used.

- And the driver which arbitrates the accesses to the multiplexed PCIe
IO space. Later qemu-dm will use this.

Limitation:
IO port of IO shared devices can't be accessed from dom0 Linux device
driver. But this wouldn't be a big issue because PCIe specification
discourages the use of IO space and recommends that IO space should be
used only for bootable device with ROM code. OS device driver should
work without IO space access.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author Keir Fraser <keir.fraser@citrix.com>
date Thu May 28 09:57:49 2009 +0100 (2009-05-28)
parents 831230e53067
children
line source
1 #include <linux/pci.h>
2 #include <linux/module.h>
3 #include <linux/ioport.h>
5 #include "pci.h"
7 /*
8 * This interrupt-safe spinlock protects all accesses to PCI
9 * configuration space.
10 */
12 static DEFINE_SPINLOCK(pci_lock);
14 /*
15 * Wrappers for all PCI configuration access functions. They just check
16 * alignment, do locking and call the low-level functions pointed to
17 * by pci_dev->ops.
18 */
20 #define PCI_byte_BAD 0
21 #define PCI_word_BAD (pos & 1)
22 #define PCI_dword_BAD (pos & 3)
24 #define PCI_OP_READ(size,type,len) \
25 int pci_bus_read_config_##size \
26 (struct pci_bus *bus, unsigned int devfn, int pos, type *value) \
27 { \
28 int res; \
29 unsigned long flags; \
30 u32 data = 0; \
31 if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \
32 spin_lock_irqsave(&pci_lock, flags); \
33 res = bus->ops->read(bus, devfn, pos, len, &data); \
34 *value = (type)data; \
35 spin_unlock_irqrestore(&pci_lock, flags); \
36 return res; \
37 }
39 #define PCI_OP_WRITE(size,type,len) \
40 int pci_bus_write_config_##size \
41 (struct pci_bus *bus, unsigned int devfn, int pos, type value) \
42 { \
43 int res; \
44 unsigned long flags; \
45 if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \
46 spin_lock_irqsave(&pci_lock, flags); \
47 res = bus->ops->write(bus, devfn, pos, len, value); \
48 spin_unlock_irqrestore(&pci_lock, flags); \
49 return res; \
50 }
52 PCI_OP_READ(byte, u8, 1)
53 PCI_OP_READ(word, u16, 2)
54 PCI_OP_READ(dword, u32, 4)
55 PCI_OP_WRITE(byte, u8, 1)
56 PCI_OP_WRITE(word, u16, 2)
57 PCI_OP_WRITE(dword, u32, 4)
59 EXPORT_SYMBOL(pci_bus_read_config_byte);
60 EXPORT_SYMBOL(pci_bus_read_config_word);
61 EXPORT_SYMBOL(pci_bus_read_config_dword);
62 EXPORT_SYMBOL(pci_bus_write_config_byte);
63 EXPORT_SYMBOL(pci_bus_write_config_word);
64 EXPORT_SYMBOL(pci_bus_write_config_dword);
66 static u32 pci_user_cached_config(struct pci_dev *dev, int pos)
67 {
68 u32 data;
70 data = dev->saved_config_space[pos/sizeof(dev->saved_config_space[0])];
71 data >>= (pos % sizeof(dev->saved_config_space[0])) * 8;
72 return data;
73 }
75 #define PCI_USER_READ_CONFIG(size,type) \
76 int pci_user_read_config_##size \
77 (struct pci_dev *dev, int pos, type *val) \
78 { \
79 unsigned long flags; \
80 int ret = 0; \
81 u32 data = -1; \
82 if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \
83 spin_lock_irqsave(&pci_lock, flags); \
84 if (likely(!dev->block_ucfg_access)) \
85 ret = dev->bus->ops->read(dev->bus, dev->devfn, \
86 pos, sizeof(type), &data); \
87 else if (pos < sizeof(dev->saved_config_space)) \
88 data = pci_user_cached_config(dev, pos); \
89 spin_unlock_irqrestore(&pci_lock, flags); \
90 *val = (type)data; \
91 return ret; \
92 }
94 #define PCI_USER_WRITE_CONFIG(size,type) \
95 int pci_user_write_config_##size \
96 (struct pci_dev *dev, int pos, type val) \
97 { \
98 unsigned long flags; \
99 int ret = -EIO; \
100 if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \
101 spin_lock_irqsave(&pci_lock, flags); \
102 if (likely(!dev->block_ucfg_access)) \
103 ret = dev->bus->ops->write(dev->bus, dev->devfn, \
104 pos, sizeof(type), val); \
105 spin_unlock_irqrestore(&pci_lock, flags); \
106 return ret; \
107 }
109 PCI_USER_READ_CONFIG(byte, u8)
110 PCI_USER_READ_CONFIG(word, u16)
111 PCI_USER_READ_CONFIG(dword, u32)
112 PCI_USER_WRITE_CONFIG(byte, u8)
113 PCI_USER_WRITE_CONFIG(word, u16)
114 PCI_USER_WRITE_CONFIG(dword, u32)
116 /**
117 * pci_block_user_cfg_access - Block userspace PCI config reads/writes
118 * @dev: pci device struct
119 *
120 * This function blocks any userspace PCI config accesses from occurring.
121 * When blocked, any writes will be bit bucketed and reads will return the
122 * data saved using pci_save_state for the first 64 bytes of config
123 * space and return 0xff for all other config reads.
124 **/
125 void pci_block_user_cfg_access(struct pci_dev *dev)
126 {
127 unsigned long flags;
129 pci_save_state(dev);
131 /* spinlock to synchronize with anyone reading config space now */
132 spin_lock_irqsave(&pci_lock, flags);
133 dev->block_ucfg_access = 1;
134 spin_unlock_irqrestore(&pci_lock, flags);
135 }
136 EXPORT_SYMBOL_GPL(pci_block_user_cfg_access);
138 /**
139 * pci_unblock_user_cfg_access - Unblock userspace PCI config reads/writes
140 * @dev: pci device struct
141 *
142 * This function allows userspace PCI config accesses to resume.
143 **/
144 void pci_unblock_user_cfg_access(struct pci_dev *dev)
145 {
146 unsigned long flags;
148 /* spinlock to synchronize with anyone reading saved config space */
149 spin_lock_irqsave(&pci_lock, flags);
150 dev->block_ucfg_access = 0;
151 spin_unlock_irqrestore(&pci_lock, flags);
152 }
153 EXPORT_SYMBOL_GPL(pci_unblock_user_cfg_access);