summaryrefslogtreecommitdiff
path: root/debian/patches/err
blob: 983c2c1e378a59c7e9b3b489e7a7d7b8b4b8aad2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
err() prints from errno, not from eval.
Also, better print a backtrace in some cases

---
 pci-userspace/src-gnu/pci_user-gnu.c |   48 +++++++++++++++++++++++++++++------
 1 file changed, 41 insertions(+), 7 deletions(-)

Index: rumpkernel/pci-userspace/src-gnu/pci_user-gnu.c
===================================================================
--- rumpkernel.orig/pci-userspace/src-gnu/pci_user-gnu.c
+++ rumpkernel/pci-userspace/src-gnu/pci_user-gnu.c
@@ -45,7 +45,9 @@
 #include <sys/io.h>
 
 #include <assert.h>
+#include <stdarg.h>
 #include <err.h>
+#include <execinfo.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <inttypes.h>
@@ -96,6 +98,26 @@ static device_t acpi_dev;
 #define PCI_CFG1_START 0xcf8
 #define PCI_CFG1_END   0xcff
 
+static void err_backtrace(int eval, const char *fmt, ...)
+{
+	static const size_t size = 128;
+	static const int skip = 1;
+	void *buffer[size];
+	int nptrs;
+
+	nptrs = backtrace(buffer, size);
+
+	if (nptrs > skip) {
+		backtrace_symbols_fd(&buffer[skip], nptrs - skip, STDERR_FILENO);
+		fflush(stderr);
+	}
+
+	va_list ap;
+	va_start(ap, fmt);
+	verr(eval, fmt, ap);
+	va_end(ap);
+}
+
 int
 rumpcomp_pci_iospace_init(void)
 {
@@ -119,6 +141,7 @@ static struct pci_device *pci_devices[NU
 static void
 pci_userspace_init(void)
 {
+	kern_return_t ret;
 	/* FIXME: add a hook to make rump call this, once and only once */
 	static int is_init = 0;
 	if (is_init)
@@ -126,11 +149,15 @@ pci_userspace_init(void)
 
 	MACH_PRINT("pci_userspace_init\n");
 
-	if (get_privileged_ports (&master_host, &master_device))
+	if ((ret = get_privileged_ports (&master_host, &master_device))) {
+		errno = ret;
 		err(1, "get_privileged_ports");
+	}
 
-	if (device_open (master_device, D_READ, "irq", &irq_dev))
+	if ((ret = device_open (master_device, D_READ, "irq", &irq_dev))) {
+		errno = ret;
 		err(2, "device_open irq");
+	}
 
 	/* Optional */
 	if (device_open (master_device, D_READ, "acpi", &acpi_dev)) {
@@ -522,8 +549,10 @@ rumpcomp_pci_virt_to_mach(void *virt)
 
 	tp = mach_task_self();
 	ret = mach_vm_region_info(tp, vaddr, &region, &object);
-	if (KERN_SUCCESS != ret)
-		err(ret, "mach_vm_region_info");
+	if (KERN_SUCCESS != ret) {
+		errno = ret;
+		err_backtrace(ret, "mach_vm_region_info(%p)", (void*) vaddr);
+	}
 
 	ret = mach_vm_object_pages_phys(object, &pages_phys, &pagesCnt);
 	if (ret == KERN_SUCCESS)
@@ -547,16 +576,20 @@ rumpcomp_pci_virt_to_mach(void *virt)
 		}
 
 		ret = vm_deallocate(tp, (vm_address_t)pages_phys, pagesCnt*sizeof(*pages_phys));
-		if (KERN_SUCCESS != ret)
-			err(ret, "vm_deallocate");
+		if (KERN_SUCCESS != ret) {
+			errno = ret;
+			err_backtrace(ret, "vm_deallocate(%p)", (void*) pages_phys);
+		}
 	}
 	else
 	{
 		/* Fallback to non-PAE RPC, hoping for the best  */
 
 		ret = mach_vm_object_pages(object, &pages, &pagesCnt);
-		if (KERN_SUCCESS != ret)
-			err(ret, "mach_vm_object_pages");
+		if (KERN_SUCCESS != ret) {
+			errno = ret;
+			err_backtrace(ret, "mach_vm_object_pages(%u)", object);
+		}
 
 		mach_port_deallocate(mach_task_self(), object);
 
@@ -577,8 +610,10 @@ rumpcomp_pci_virt_to_mach(void *virt)
 		}
 
 		ret = vm_deallocate(tp, (vm_address_t)pages, pagesCnt*sizeof(*pages));
-		if (KERN_SUCCESS != ret)
-			err(ret, "vm_deallocate");
+		if (KERN_SUCCESS != ret) {
+			errno = ret;
+			err_backtrace(ret, "vm_deallocate(%p)", (void*) pages);
+		}
 	}
 
 	if (paddr == 0){