This commit is contained in:
emellor@leeni.uk.xensource.com committed 2006-04-10 16:36:03 +01:00
commit 224cab0dfd
27 files changed
+553 -635

No files matched your search

+1
View File
@@ -24,6 +24,7 @@ OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
DISTDIR ?= $(XEN_ROOT)/dist
DESTDIR ?= /
INSTALL = install
INSTALL_DIR = $(INSTALL) -d -m0755
+12 -22
View File
@@ -115,18 +115,6 @@ distclean: clean
# Linux name for GNU distclean
mrproper: distclean
install-logging: LOGGING=logging-0.4.9.2
install-logging:
[ -f $(LOGGING).tar.gz ] || wget http://www.red-dove.com/$(LOGGING).tar.gz
tar -zxf $(LOGGING).tar.gz
cd $(LOGGING) && python setup.py install
# handy target to upgrade iptables (use rpm or apt-get in preference)
install-iptables:
wget http://www.netfilter.org/files/iptables-1.2.11.tar.bz2
tar -jxf iptables-1.2.11.tar.bz2
$(MAKE) -C iptables-1.2.11 PREFIX= KERNEL_DIR=../linux-$(LINUX_VER)-xen0 install
help:
@echo 'Installation targets:'
@echo ' install - build and install everything'
@@ -147,23 +135,25 @@ help:
@echo ' dev-docs - build developer-only documentation'
@echo ''
@echo 'Cleaning targets:'
@echo ' clean - clean the Xen, tools and docs (but not'
@echo ' guest kernel) trees'
@echo ' distclean - clean plus delete kernel tarballs and kernel'
@echo ' build trees'
@echo ' clean - clean the Xen, tools and docs (but not guest kernel trees)'
@echo ' distclean - clean plus delete kernel build trees and'
@echo ' local downloaded files'
@echo ' kdelete - delete guest kernel build trees'
@echo ' kclean - clean guest kernel build trees'
@echo ''
@echo 'Dependency installation targets:'
@echo ' install-logging - install the Python Logging package'
@echo ' install-iptables - install iptables tools'
@echo ''
@echo 'Miscellaneous targets:'
@echo ' prep-kernels - prepares kernel directories, does not build'
@echo ' mkpatches - make patches against vanilla kernels from'
@echo ' sparse trees'
@echo ' uninstall - attempt to remove installed Xen tools (use'
@echo ' with extreme care!)'
@echo ' uninstall - attempt to remove installed Xen tools'
@echo ' (use with extreme care!)'
@echo
@echo 'Environment:'
@echo ' XEN_PYTHON_NATIVE_INSTALL=y'
@echo ' - native python install or dist'
@echo ' install into prefix/lib/python<VERSION>'
@echo ' instead of <PREFIX>/lib/python'
@echo ' true if set to non-empty value, false otherwise'
# Use this target with extreme care!
uninstall: D=$(DESTDIR)
+3 -33
View File
@@ -40,29 +40,6 @@ patch-%.bz2:
@echo "Cannot find $(@F) in path $(LINUX_SRC_PATH)"
wget $(KERNEL_REPO)/pub/linux/kernel/v$(_LINUX_VDIR)/$(_LINUX_XDIR)/$(@F) -O./$@
# Expand NetBSD release to NetBSD version
NETBSD_RELEASE ?= 2.0
NETBSD_VER ?= $(patsubst netbsd-%-xen-sparse,%,$(wildcard netbsd-$(NETBSD_RELEASE)*-xen-sparse))
NETBSD_CVSSNAP ?= 20050309
# Setup NetBSD search path
NETBSD_SRC_PATH ?= .:..
vpath netbsd-%.tar.bz2 $(NETBSD_SRC_PATH)
# download a pristine NetBSD tarball if there isn't one in NETBSD_SRC_PATH
netbsd-%-xen-kernel-$(NETBSD_CVSSNAP).tar.bz2:
@echo "Cannot find $@ in path $(NETBSD_SRC_PATH)"
wget http://www.cl.cam.ac.uk/Research/SRG/netos/xen/downloads/$@ -O./$@
netbsd-%.tar.bz2: netbsd-%-xen-kernel-$(NETBSD_CVSSNAP).tar.bz2
ln -fs $< $@
ifeq ($(OS),linux)
OS_VER = $(LINUX_VER)
else
OS_VER = $(NETBSD_VER)
endif
pristine-%: pristine-%/.valid-pristine
@true
@@ -124,27 +101,20 @@ linux-2.6-xen.patch: ref-linux-$(LINUX_VER)/.valid-ref
rm -rf tmp-$@
cp -al $(<D) tmp-$@
( cd linux-2.6-xen-sparse && ./mkbuildtree ../tmp-$@ )
diff -Nurp $(<D) tmp-$@ > $@ || true
diff -Nurp $(patsubst ref%,pristine%,$(<D)) tmp-$@ > $@ || true
rm -rf tmp-$@
%-xen.patch: ref-%/.valid-ref
rm -rf tmp-$@
cp -al $(<D) tmp-$@
( cd $*-xen-sparse && ./mkbuildtree ../tmp-$@ )
diff -Nurp $(<D) tmp-$@ > $@ || true
diff -Nurp $(patsubst ref%,pristine%,$(<D)) tmp-$@ > $@ || true
rm -rf tmp-$@
%-mrproper: %-mrproper-extra
%-mrproper:
rm -rf pristine-$(*)* ref-$(*)* $*.tar.bz2
rm -rf $*-xen.patch
netbsd-%-mrproper-extra:
rm -rf netbsd-$*-tools netbsd-$*-tools.tar.bz2
rm -f netbsd-$*-xen-kernel-$(NETBSD_CVSSNAP).tar.bz2
%-mrproper-extra:
@: # do nothing
config-update-pae:
ifeq ($(XEN_TARGET_X86_PAE),y)
sed -e 's!^CONFIG_HIGHMEM4G=y$$!\# CONFIG_HIGHMEM4G is not set!;s!^\# CONFIG_HIGHMEM64G is not set$$!CONFIG_HIGHMEM64G=y!' $(CONFIG_FILE) > $(CONFIG_FILE)- && mv $(CONFIG_FILE)- $(CONFIG_FILE)
+16 -10
View File
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.16-rc3-xen0
# Thu Feb 16 22:52:42 2006
# Linux kernel version: 2.6.16-xen0
# Sat Apr 8 11:34:07 2006
#
CONFIG_X86_32=y
CONFIG_SEMAPHORE_SLEEPERS=y
@@ -208,7 +208,6 @@ CONFIG_ACPI_BLACKLIST_YEAR=0
CONFIG_ACPI_EC=y
CONFIG_ACPI_POWER=y
CONFIG_ACPI_SYSTEM=y
# CONFIG_X86_PM_TIMER is not set
# CONFIG_ACPI_CONTAINER is not set
#
@@ -392,7 +391,13 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Plug and Play support
#
# CONFIG_PNP is not set
CONFIG_PNP=y
CONFIG_PNP_DEBUG=y
#
# Protocols
#
CONFIG_PNPACPI=y
#
# Block devices
@@ -440,6 +445,7 @@ CONFIG_BLK_DEV_IDECD=y
#
CONFIG_IDE_GENERIC=y
# CONFIG_BLK_DEV_CMD640 is not set
# CONFIG_BLK_DEV_IDEPNP is not set
CONFIG_BLK_DEV_IDEPCI=y
# CONFIG_IDEPCI_SHARE_IRQ is not set
# CONFIG_BLK_DEV_OFFBOARD is not set
@@ -623,6 +629,7 @@ CONFIG_NETDEVICES=y
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
CONFIG_TUN=y
# CONFIG_NET_SB1000 is not set
#
# ARCnet devices
@@ -1064,11 +1071,7 @@ CONFIG_USB_MON=y
# CONFIG_INFINIBAND is not set
#
# SN Devices
#
#
# EDAC - error detection and reporting (RAS)
# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
#
# CONFIG_EDAC is not set
@@ -1306,7 +1309,7 @@ CONFIG_CRYPTO_CRC32C=m
#
# CONFIG_CRYPTO_DEV_PADLOCK is not set
CONFIG_XEN=y
CONFIG_NO_IDLE_HZ=y
CONFIG_XEN_INTERFACE_VERSION=0x00030101
#
# XEN
@@ -1332,6 +1335,7 @@ CONFIG_XEN_DISABLE_SERIAL=y
CONFIG_XEN_SYSFS=y
CONFIG_HAVE_ARCH_ALLOC_SKB=y
CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y
CONFIG_NO_IDLE_HZ=y
#
# Library routines
@@ -1344,4 +1348,6 @@ CONFIG_ZLIB_INFLATE=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_X86_BIOS_REBOOT=y
CONFIG_X86_NO_TSS=y
CONFIG_X86_NO_IDT=y
CONFIG_KTIME_SCALAR=y
+9 -1
View File
@@ -327,7 +327,13 @@ CONFIG_STANDALONE=y
#
# Plug and Play support
#
# CONFIG_PNP is not set
CONFIG_PNP=y
CONFIG_PNP_DEBUG=y
#
# Protocols
#
CONFIG_PNPACPI=y
#
# Block devices
@@ -375,6 +381,7 @@ CONFIG_BLK_DEV_IDECD=y
#
CONFIG_IDE_GENERIC=y
# CONFIG_BLK_DEV_CMD640 is not set
# CONFIG_BLK_DEV_IDEPNP is not set
CONFIG_BLK_DEV_IDEPCI=y
# CONFIG_IDEPCI_SHARE_IRQ is not set
# CONFIG_BLK_DEV_OFFBOARD is not set
@@ -559,6 +566,7 @@ CONFIG_NETDEVICES=y
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
CONFIG_TUN=y
# CONFIG_NET_SB1000 is not set
#
# ARCnet devices
+2 -2
View File
@@ -912,12 +912,12 @@ CONFIG_PARPORT_1284=y
# Plug and Play support
#
CONFIG_PNP=y
# CONFIG_PNP_DEBUG is not set
CONFIG_PNP_DEBUG=y
#
# Protocols
#
# CONFIG_PNPACPI is not set
CONFIG_PNPACPI=y
#
# Block devices
+9 -1
View File
@@ -776,7 +776,13 @@ CONFIG_PARPORT_1284=y
#
# Plug and Play support
#
# CONFIG_PNP is not set
CONFIG_PNP=y
CONFIG_PNP_DEBUG=y
#
# Protocols
#
CONFIG_PNPACPI=y
#
# Block devices
@@ -857,6 +863,7 @@ CONFIG_BLK_DEV_IDESCSI=m
CONFIG_IDE_GENERIC=y
CONFIG_BLK_DEV_CMD640=y
CONFIG_BLK_DEV_CMD640_ENHANCED=y
CONFIG_BLK_DEV_IDEPNP=y
CONFIG_BLK_DEV_IDEPCI=y
CONFIG_IDEPCI_SHARE_IRQ=y
# CONFIG_BLK_DEV_OFFBOARD is not set
@@ -1088,6 +1095,7 @@ CONFIG_DUMMY=m
CONFIG_BONDING=m
CONFIG_EQUALIZER=m
CONFIG_TUN=m
CONFIG_NET_SB1000=m
#
# ARCnet devices
+3 -6
View File
@@ -1,13 +1,10 @@
OS = linux
LINUX_SERIES = 2.6
LINUX_VER = 2.6.16
LINUX_SRCS = linux-2.6.16.tar.bz2
EXTRAVERSION ?= xen
LINUX_DIR = $(OS)-$(LINUX_VER)-$(EXTRAVERSION)
LINUX_DIR = linux-$(LINUX_VER)-$(EXTRAVERSION)
include buildconfigs/Rules.mk
@@ -22,7 +19,7 @@ build: $(LINUX_DIR)/include/linux/autoconf.h
$(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) INSTALL_PATH=$(DESTDIR) vmlinuz
$(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) INSTALL_PATH=$(DESTDIR) install
$(LINUX_DIR)/include/linux/autoconf.h: ref-$(OS)-$(LINUX_VER)/.valid-ref
$(LINUX_DIR)/include/linux/autoconf.h: ref-linux-$(LINUX_VER)/.valid-ref
rm -rf $(LINUX_DIR)
cp -al $(<D) $(LINUX_DIR)
# Apply arch-xen patches
@@ -52,4 +49,4 @@ clean::
$(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) clean
delete:
rm -rf tmp-$(OS)-$(LINUX_VER) $(LINUX_DIR)
rm -rf tmp-linux-$(LINUX_VER) $(LINUX_DIR)
@@ -69,7 +69,7 @@ dma_map_sg(struct device *hwdev, struct scatterlist *sg, int nents,
} else {
for (i = 0; i < nents; i++ ) {
sg[i].dma_address =
page_to_phys(sg[i].page) + sg[i].offset;
page_to_bus(sg[i].page) + sg[i].offset;
sg[i].dma_length = sg[i].length;
BUG_ON(!sg[i].page);
IOMMU_BUG_ON(address_needs_mapping(
@@ -105,7 +105,7 @@ dma_map_page(struct device *dev, struct page *page, unsigned long offset,
dma_addr = swiotlb_map_page(
dev, page, offset, size, direction);
} else {
dma_addr = page_to_phys(page) + offset;
dma_addr = page_to_bus(page) + offset;
IOMMU_BUG_ON(address_needs_mapping(dev, dma_addr));
}
@@ -1848,10 +1848,6 @@ void __init setup_arch(char **cmdline_p)
get_smp_config();
#endif
/* XXX Disable irqdebug until we have a way to avoid interrupt
* conflicts. */
noirqdebug_setup("");
register_memory();
if (xen_start_info->flags & SIF_INITDOMAIN) {
@@ -32,7 +32,7 @@ EXPORT_SYMBOL(swiotlb);
#define OFFSET(val,align) ((unsigned long)((val) & ( (align) - 1)))
#define SG_ENT_PHYS_ADDRESS(sg) (page_to_phys((sg)->page) + (sg)->offset)
#define SG_ENT_PHYS_ADDRESS(sg) (page_to_bus((sg)->page) + (sg)->offset)
/*
* Maximum allowable number of contiguous slabs to map,
@@ -607,7 +607,7 @@ swiotlb_map_page(struct device *hwdev, struct page *page,
dma_addr_t dev_addr;
char *map;
dev_addr = page_to_phys(page) + offset;
dev_addr = page_to_bus(page) + offset;
if (address_needs_mapping(hwdev, dev_addr)) {
buffer.page = page;
buffer.offset = offset;
@@ -59,6 +59,10 @@ void machine_power_off(void)
{
/* We really want to get pending console data out before we die. */
xencons_force_flush();
#if defined(__i386__) || defined(__x86_64__)
if (pm_power_off)
pm_power_off();
#endif
HYPERVISOR_shutdown(SHUTDOWN_poweroff);
}
@@ -102,6 +102,7 @@ static inline void * phys_to_virt(unsigned long address)
*/
#define page_to_pseudophys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
#define page_to_phys(page) (phys_to_machine(page_to_pseudophys(page)))
#define page_to_bus(page) (phys_to_machine(page_to_pseudophys(page)))
#define bio_to_pseudophys(bio) (page_to_pseudophys(bio_page((bio))) + \
(unsigned long) bio_offset((bio)))
@@ -130,6 +130,7 @@ static inline void * phys_to_virt(unsigned long address)
*/
#define page_to_pseudophys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
#define page_to_phys(page) (phys_to_machine(page_to_pseudophys(page)))
#define page_to_bus(page) (phys_to_machine(page_to_pseudophys(page)))
#define bio_to_pseudophys(bio) (page_to_pseudophys(bio_page((bio))) + \
(unsigned long) bio_offset((bio)))
+2 -2
View File
@@ -1369,10 +1369,10 @@ static inline unsigned int cpuid_edx(unsigned int op)
{
unsigned int eax, edx;
__asm__("cpuid"
__asm__("pushl %%ebx; cpuid; popl %%ebx"
: "=a" (eax), "=d" (edx)
: "0" (op)
: "bx", "cx");
: "cx");
return edx;
}
+33 -5
View File
@@ -110,10 +110,10 @@ static int parse_features(
if ( i == XENFEAT_NR_SUBMAPS*32 )
{
ERROR("Unknown feature \"%.*s\".\n", (int)(p-feats), feats);
ERROR("Unknown feature \"%.*s\".", (int)(p-feats), feats);
if ( req )
{
ERROR("Kernel requires an unknown hypervisor feature.\n");
ERROR("Kernel requires an unknown hypervisor feature.");
return -EINVAL;
}
}
@@ -579,6 +579,31 @@ static int setup_guest(int xc_handle,
return -1;
}
#else /* x86 */
/* Check if the platform supports the guest kernel format */
static int compat_check(int xc_handle, struct domain_setup_info *dsi)
{
xen_capabilities_info_t xen_caps = "";
if (xc_version(xc_handle, XENVER_capabilities, &xen_caps) != 0) {
ERROR("Cannot determine host capabilities.");
return 0;
}
if (strstr(xen_caps, "xen-3.0-x86_32p")) {
if (!dsi->pae_kernel) {
ERROR("Non PAE-kernel on PAE host.");
return 0;
}
} else if (dsi->pae_kernel) {
ERROR("PAE-kernel on non-PAE host.");
return 0;
}
return 1;
}
static int setup_guest(int xc_handle,
uint32_t dom,
const char *image, unsigned long image_size,
@@ -635,10 +660,13 @@ static int setup_guest(int xc_handle,
if ( (dsi.v_start & (PAGE_SIZE-1)) != 0 )
{
PERROR("Guest OS must load to a page boundary.\n");
PERROR("Guest OS must load to a page boundary.");
goto error_out;
}
if (!compat_check(xc_handle, &dsi))
goto error_out;
/* Parse and validate kernel features. */
p = strstr(dsi.xen_guest_string, "FEATURES=");
if ( p != NULL )
@@ -647,7 +675,7 @@ static int setup_guest(int xc_handle,
supported_features,
required_features) )
{
ERROR("Failed to parse guest kernel features.\n");
ERROR("Failed to parse guest kernel features.");
goto error_out;
}
@@ -659,7 +687,7 @@ static int setup_guest(int xc_handle,
{
if ( (supported_features[i]&required_features[i]) != required_features[i] )
{
ERROR("Guest kernel does not support a required feature.\n");
ERROR("Guest kernel does not support a required feature.");
goto error_out;
}
}
+15
View File
@@ -69,6 +69,21 @@ static int parseelfimage(const char *image,
return -EINVAL;
}
if (
#if defined(__i386__)
(ehdr->e_ident[EI_CLASS] != ELFCLASS32) ||
(ehdr->e_machine != EM_386) ||
#elif defined(__x86_64__)
(ehdr->e_ident[EI_CLASS] != ELFCLASS64) ||
(ehdr->e_machine != EM_X86_64) ||
#endif
(ehdr->e_ident[EI_DATA] != ELFDATA2LSB) ||
(ehdr->e_type != ET_EXEC) )
{
ERROR("Kernel not a Xen-compatible Elf image.");
return -EINVAL;
}
if ( (ehdr->e_phoff + (ehdr->e_phnum * ehdr->e_phentsize)) > elfsize )
{
ERROR("ELF program headers extend beyond end of image.");
+4 -4
View File
@@ -115,7 +115,7 @@ class PciController(DevController):
dev = PciDevice(domain, bus, slot, func)
except Exception, e:
raise VmError("pci: failed to locate device and "+
"parse it's resources - %s"+str(e))
"parse it's resources - "+str(e))
if dev.driver!='pciback':
raise VmError(("pci: PCI Backend does not own device "+ \
@@ -131,7 +131,7 @@ class PciController(DevController):
nr_ports = size, allow_access = True)
if rc<0:
raise VmError(('pci: failed to configure I/O ports on device '+
'%s - errno=%d')&(dev.name,rc))
'%s - errno=%d')%(dev.name,rc))
for (start, size) in dev.iomem:
# Convert start/size from bytes to page frame sizes
@@ -147,7 +147,7 @@ class PciController(DevController):
allow_access = True)
if rc<0:
raise VmError(('pci: failed to configure I/O memory on device '+
'%s - errno=%d')&(dev.name,rc))
'%s - errno=%d')%(dev.name,rc))
if dev.irq>0:
log.debug('pci: enabling irq %d'%dev.irq)
@@ -155,7 +155,7 @@ class PciController(DevController):
allow_access = True)
if rc<0:
raise VmError(('pci: failed to configure irq on device '+
'%s - errno=%d')&(dev.name,rc))
'%s - errno=%d')%(dev.name,rc))
def waitForBackend(self,devid):
return (0, "ok - no hotplug")
+1 -1
View File
@@ -74,7 +74,7 @@ subdir-n := $(patsubst %,%/,$(patsubst %/,%,$(subdir-n)))
subdir-y := $(patsubst %,%/,$(patsubst %/,%,$(subdir-y)))
# Add explicitly declared subdirectories to the object list.
obj-y += $(patsubst %,%/built_in.o,$(subdir-y))
obj-y += $(patsubst %/,%/built_in.o,$(subdir-y))
# Add implicitly declared subdirectories (in the object list) to the
# subdirectory list, and rewrite the object-list entry.
+11 -16
View File
@@ -1358,25 +1358,20 @@ static void __do_IRQ_guest(int irq)
int pirq_guest_unmask(struct domain *d)
{
irq_desc_t *desc;
int i, j, pirq;
u32 m;
int pirq;
shared_info_t *s = d->shared_info;
for ( i = 0; i < ARRAY_SIZE(d->pirq_mask); i++ )
for ( pirq = find_first_bit(d->pirq_mask, NR_PIRQS);
pirq < NR_PIRQS;
pirq = find_next_bit(d->pirq_mask, NR_PIRQS, pirq+1) )
{
m = d->pirq_mask[i];
while ( (j = ffs(m)) != 0 )
{
m &= ~(1 << --j);
pirq = (i << 5) + j;
desc = &irq_desc[pirq];
spin_lock_irq(&desc->lock);
if ( !test_bit(d->pirq_to_evtchn[pirq], &s->evtchn_mask[0]) &&
test_and_clear_bit(pirq, &d->pirq_mask) &&
(--((irq_guest_action_t *)desc->action)->in_flight == 0) )
desc->handler->end(pirq);
spin_unlock_irq(&desc->lock);
}
desc = &irq_desc[pirq];
spin_lock_irq(&desc->lock);
if ( !test_bit(d->pirq_to_evtchn[pirq], &s->evtchn_mask[0]) &&
test_and_clear_bit(pirq, &d->pirq_mask) &&
(--((irq_guest_action_t *)desc->action)->in_flight == 0) )
desc->handler->end(pirq);
spin_unlock_irq(&desc->lock);
}
return 0;
+121 -39
View File
@@ -75,6 +75,7 @@ int disable_timer_pin_1 __initdata;
static struct irq_pin_list {
int apic, pin, next;
} irq_2_pin[PIN_MAP_SIZE];
static int irq_2_pin_free_entry = NR_IRQS;
int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1};
@@ -85,22 +86,59 @@ int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1};
*/
static void add_pin_to_irq(unsigned int irq, int apic, int pin)
{
static int first_free_entry = NR_IRQS;
struct irq_pin_list *entry = irq_2_pin + irq;
while (entry->next)
while (entry->next) {
BUG_ON((entry->apic == apic) && (entry->pin == pin));
entry = irq_2_pin + entry->next;
}
BUG_ON((entry->apic == apic) && (entry->pin == pin));
if (entry->pin != -1) {
entry->next = first_free_entry;
entry = irq_2_pin + entry->next;
if (++first_free_entry >= PIN_MAP_SIZE)
if (irq_2_pin_free_entry >= PIN_MAP_SIZE)
panic("io_apic.c: whoops");
entry->next = irq_2_pin_free_entry;
entry = irq_2_pin + entry->next;
irq_2_pin_free_entry = entry->next;
entry->next = 0;
}
entry->apic = apic;
entry->pin = pin;
}
static void remove_pin_at_irq(unsigned int irq, int apic, int pin)
{
struct irq_pin_list *entry, *prev;
for (entry = &irq_2_pin[irq]; ; entry = &irq_2_pin[entry->next]) {
if ((entry->apic == apic) && (entry->pin == pin))
break;
if (!entry->next)
BUG();
}
entry->pin = entry->apic = -1;
if (entry != &irq_2_pin[irq]) {
/* Removed entry is not at head of list. */
prev = &irq_2_pin[irq];
while (&irq_2_pin[prev->next] != entry)
prev = &irq_2_pin[prev->next];
prev->next = entry->next;
entry->next = irq_2_pin_free_entry;
irq_2_pin_free_entry = entry - irq_2_pin;
} else if (entry->next != 0) {
/* Removed entry is at head of multi-item list. */
prev = entry;
entry = &irq_2_pin[entry->next];
*prev = *entry;
entry->pin = entry->apic = -1;
entry->next = irq_2_pin_free_entry;
irq_2_pin_free_entry = entry - irq_2_pin;
}
}
/*
* Reroute an IRQ to a different pin.
*/
@@ -959,6 +997,10 @@ static void __init enable_IO_APIC(void)
irq_2_pin[i].next = 0;
}
/* Initialise dynamic irq_2_pin free list. */
for (i = NR_IRQS; i < PIN_MAP_SIZE; i++)
irq_2_pin[i].next = i + 1;
/*
* The number of IO-APIC IRQ registers (== #pins):
*/
@@ -1854,11 +1896,17 @@ int ioapic_guest_read(unsigned long physbase, unsigned int reg, u32 *pval)
return 0;
}
#define WARN_BOGUS_WRITE(f, a...) \
DPRINTK("\n%s: apic=%d, pin=%d, old_irq=%d, new_irq=%d\n" \
"%s: old_entry=%08x, new_entry=%08x\n" \
"%s: " f, __FUNCTION__, apic, pin, old_irq, new_irq, \
__FUNCTION__, *(u32 *)&old_rte, *(u32 *)&new_rte, \
__FUNCTION__ , ##a )
int ioapic_guest_write(unsigned long physbase, unsigned int reg, u32 val)
{
int apic, pin, irq;
struct IO_APIC_route_entry rte = { 0 };
struct irq_pin_list *entry;
int apic, pin, old_irq = -1, new_irq = -1;
struct IO_APIC_route_entry old_rte = { 0 }, new_rte = { 0 };
unsigned long flags;
if ( (apic = ioapic_physbase_to_id(physbase)) < 0 )
@@ -1870,8 +1918,9 @@ int ioapic_guest_write(unsigned long physbase, unsigned int reg, u32 val)
pin = (reg - 0x10) >> 1;
*(u32 *)&rte = val;
rte.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
/* Write first half from guest; second half is target info. */
*(u32 *)&new_rte = val;
new_rte.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
/*
* What about weird destination types?
@@ -1881,7 +1930,7 @@ int ioapic_guest_write(unsigned long physbase, unsigned int reg, u32 val)
* ExtINT: Ignore? Linux only asserts this at start of day.
* For now, print a message and return an error. We can fix up on demand.
*/
if ( rte.delivery_mode > dest_LowestPrio )
if ( new_rte.delivery_mode > dest_LowestPrio )
{
printk("ERROR: Attempt to write weird IOAPIC destination mode!\n");
printk(" APIC=%d/%d, lo-reg=%x\n", apic, pin, val);
@@ -1892,36 +1941,69 @@ int ioapic_guest_write(unsigned long physbase, unsigned int reg, u32 val)
* The guest does not know physical APIC arrangement (flat vs. cluster).
* Apply genapic conventions for this platform.
*/
rte.delivery_mode = INT_DELIVERY_MODE;
rte.dest_mode = INT_DEST_MODE;
if ( rte.vector >= FIRST_DEVICE_VECTOR )
{
/* Is there a valid irq mapped to this vector? */
irq = vector_irq[rte.vector];
if ( !IO_APIC_IRQ(irq) )
return 0;
/* Set the correct irq-handling type. */
irq_desc[IO_APIC_VECTOR(irq)].handler = rte.trigger ?
&ioapic_level_type: &ioapic_edge_type;
/* Record the pin<->irq mapping. */
for ( entry = &irq_2_pin[irq]; ; entry = &irq_2_pin[entry->next] )
{
if ( (entry->apic == apic) && (entry->pin == pin) )
break;
if ( !entry->next )
{
add_pin_to_irq(irq, apic, pin);
break;
}
}
}
new_rte.delivery_mode = INT_DELIVERY_MODE;
new_rte.dest_mode = INT_DEST_MODE;
spin_lock_irqsave(&ioapic_lock, flags);
io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&rte) + 0));
io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&rte) + 1));
/* Read first (interesting) half of current routing entry. */
*(u32 *)&old_rte = io_apic_read(apic, 0x10 + 2 * pin);
/* No change to the first half of the routing entry? Bail quietly. */
if ( *(u32 *)&old_rte == *(u32 *)&new_rte )
{
spin_unlock_irqrestore(&ioapic_lock, flags);
return 0;
}
if ( old_rte.vector >= FIRST_DEVICE_VECTOR )
old_irq = vector_irq[old_rte.vector];
if ( new_rte.vector >= FIRST_DEVICE_VECTOR )
new_irq = vector_irq[new_rte.vector];
if ( (old_irq != new_irq) && (old_irq != -1) && IO_APIC_IRQ(old_irq) )
{
if ( irq_desc[IO_APIC_VECTOR(old_irq)].action )
{
WARN_BOGUS_WRITE("Attempt to remove IO-APIC pin of in-use IRQ!\n");
spin_unlock_irqrestore(&ioapic_lock, flags);
return 0;
}
remove_pin_at_irq(old_irq, apic, pin);
}
if ( (new_irq != -1) && IO_APIC_IRQ(new_irq) )
{
if ( irq_desc[IO_APIC_VECTOR(new_irq)].action )
{
WARN_BOGUS_WRITE("Attempt to %s IO-APIC pin for in-use IRQ!\n",
(old_irq != new_irq) ? "add" : "modify");
spin_unlock_irqrestore(&ioapic_lock, flags);
return 0;
}
/* Set the correct irq-handling type. */
irq_desc[IO_APIC_VECTOR(new_irq)].handler = new_rte.trigger ?
&ioapic_level_type: &ioapic_edge_type;
if ( old_irq != new_irq )
add_pin_to_irq(new_irq, apic, pin);
/* Mask iff level triggered. */
new_rte.mask = new_rte.trigger;
}
else if ( !new_rte.mask )
{
/* This pin leads nowhere but the guest has not masked it. */
WARN_BOGUS_WRITE("Installing bogus unmasked IO-APIC entry!\n");
new_rte.mask = 1;
}
io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&new_rte) + 0));
io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&new_rte) + 1));
spin_unlock_irqrestore(&ioapic_lock, flags);
return 0;
+11 -17
View File
@@ -171,26 +171,20 @@ static void __do_IRQ_guest(int vector)
int pirq_guest_unmask(struct domain *d)
{
irq_desc_t *desc;
unsigned int i, j, pirq;
u32 m;
unsigned int pirq;
shared_info_t *s = d->shared_info;
for ( i = 0; i < ARRAY_SIZE(d->pirq_mask); i++ )
for ( pirq = find_first_bit(d->pirq_mask, NR_PIRQS);
pirq < NR_PIRQS;
pirq = find_next_bit(d->pirq_mask, NR_PIRQS, pirq+1) )
{
m = d->pirq_mask[i];
while ( m != 0 )
{
j = find_first_set_bit(m);
m &= ~(1 << j);
pirq = (i << 5) + j;
desc = &irq_desc[irq_to_vector(pirq)];
spin_lock_irq(&desc->lock);
if ( !test_bit(d->pirq_to_evtchn[pirq], &s->evtchn_mask[0]) &&
test_and_clear_bit(pirq, &d->pirq_mask) &&
(--((irq_guest_action_t *)desc->action)->in_flight == 0) )
desc->handler->end(irq_to_vector(pirq));
spin_unlock_irq(&desc->lock);
}
desc = &irq_desc[irq_to_vector(pirq)];
spin_lock_irq(&desc->lock);
if ( !test_bit(d->pirq_to_evtchn[pirq], &s->evtchn_mask[0]) &&
test_and_clear_bit(pirq, &d->pirq_mask) &&
(--((irq_guest_action_t *)desc->action)->in_flight == 0) )
desc->handler->end(irq_to_vector(pirq));
spin_unlock_irq(&desc->lock);
}
return 0;
+263 -466
View File
File diff suppressed because it is too large. Load diff
+23
View File
@@ -27,6 +27,8 @@
#include <xen/smp.h>
#include <xen/trace.h>
#include <xen/errno.h>
#include <xen/event.h>
#include <xen/softirq.h>
#include <xen/init.h>
#include <asm/atomic.h>
#include <public/dom0_ops.h>
@@ -40,6 +42,11 @@ static struct t_buf *t_bufs[NR_CPUS];
static struct t_rec *t_recs[NR_CPUS];
static int nr_recs;
/* High water mark for trace buffers; */
/* Send virtual interrupt when buffer level reaches this point */
static int t_buf_highwater;
/* a flag recording whether initialization has been done */
/* or more properly, if the tbuf subsystem is enabled right now */
int tb_init_done;
@@ -50,6 +57,12 @@ static unsigned long tb_cpu_mask = (~0UL);
/* which tracing events are enabled */
static u32 tb_event_mask = TRC_ALL;
static void trace_notify_guest(void)
{
send_guest_global_virq(dom0, VIRQ_TBUF);
}
/**
* alloc_trace_bufs - performs initialization of the per-cpu trace buffers.
*
@@ -93,6 +106,9 @@ static int alloc_trace_bufs(void)
t_recs[i] = (struct t_rec *)(buf + 1);
}
t_buf_highwater = nr_recs >> 1; /* 50% high water */
open_softirq(TRACE_SOFTIRQ, trace_notify_guest);
return 0;
}
@@ -272,6 +288,13 @@ void trace(u32 event, unsigned long d1, unsigned long d2,
buf->prod++;
local_irq_restore(flags);
/*
* Notify trace buffer consumer that we've reached the high water mark.
*
*/
if ( (buf->prod - buf->cons) == t_buf_highwater )
raise_softirq(TRACE_SOFTIRQ);
}
/*
+1
View File
@@ -77,6 +77,7 @@
#define VIRQ_DEBUG 1 /* V. Request guest to dump debug info. */
#define VIRQ_CONSOLE 2 /* G. (DOM0) Bytes received on emergency console. */
#define VIRQ_DOM_EXC 3 /* G. (DOM0) Exceptional event for some domain. */
#define VIRQ_TBUF 4 /* G. (DOM0) Trace buffer has records available. */
#define VIRQ_DEBUGGER 6 /* G. (DOM0) A domain has paused for debugging. */
#define VIRQ_XENOPROF 7 /* V. XenOprofile interrupt: new sample available */
#define NR_VIRQS 8
+1 -1
View File
@@ -134,7 +134,7 @@ struct domain
*/
#define NR_PIRQS 256 /* Put this somewhere sane! */
u16 pirq_to_evtchn[NR_PIRQS];
u32 pirq_mask[NR_PIRQS/32];
DECLARE_BITMAP(pirq_mask, NR_PIRQS);
/* I/O capabilities (access to IRQs and memory-mapped I/O). */
struct rangeset *iomem_caps;
+2 -1
View File
@@ -9,7 +9,8 @@
#define NMI_SOFTIRQ 4
#define PAGE_SCRUB_SOFTIRQ 5
#define DOMAIN_SHUTDOWN_FINALISE_SOFTIRQ 6
#define NR_SOFTIRQS 7
#define TRACE_SOFTIRQ 7
#define NR_SOFTIRQS 8
#ifndef __ASSEMBLY__
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.