Compare commits
508 Commits
j_785cbcb1
...
master
Author | SHA1 | Date | |
---|---|---|---|
6a01ea2eec | |||
![]() |
182c11afc9 | ||
![]() |
805e00bbae | ||
![]() |
e67cae1f74 | ||
![]() |
242976c8f9 | ||
cd32e018f8 | |||
![]() |
ff12fdef02 | ||
![]() |
170b33b42b | ||
![]() |
fbd6843b19 | ||
![]() |
87c107fec0 | ||
![]() |
a7aff93815 | ||
![]() |
125390a34f | ||
![]() |
0173745597 | ||
![]() |
acab7a00f1 | ||
![]() |
c461282cea | ||
![]() |
d606b89e51 | ||
![]() |
19b22dd663 | ||
![]() |
af7128da3d | ||
![]() |
b5170f87d0 | ||
![]() |
1252f79e8d | ||
![]() |
9f28598dd9 | ||
![]() |
1554c07dc3 | ||
![]() |
8ee5779ea8 | ||
![]() |
366e681a9d | ||
![]() |
f841402153 | ||
![]() |
8aca753f93 | ||
![]() |
a5e7326872 | ||
![]() |
5d6894800e | ||
![]() |
1cc6951e1d | ||
![]() |
22b6866243 | ||
![]() |
7b1c020d37 | ||
![]() |
9fc40622cd | ||
![]() |
fb9b485ccf | ||
![]() |
ddf76022e4 | ||
![]() |
18d5d66d02 | ||
![]() |
ea53bfe2df | ||
![]() |
71964cd085 | ||
![]() |
cddf334f05 | ||
![]() |
beccd92b8e | ||
![]() |
17b7186716 | ||
![]() |
24ee349714 | ||
![]() |
87ba67cee5 | ||
![]() |
9cf5108f6e | ||
![]() |
8f82b34cc9 | ||
![]() |
383118a889 | ||
![]() |
9a3ca002fe | ||
![]() |
c7cfdfe8e8 | ||
![]() |
1d50db3f47 | ||
![]() |
9aac829311 | ||
![]() |
4e4cdf6d8a | ||
![]() |
61485da630 | ||
![]() |
c270f522ae | ||
![]() |
8b2aed93d7 | ||
![]() |
d9f5315ada | ||
![]() |
150288eaa4 | ||
![]() |
9ec407116a | ||
![]() |
a40377d949 | ||
![]() |
bd26af6008 | ||
![]() |
11d6f25d1a | ||
![]() |
1574118f81 | ||
![]() |
5adbe65fee | ||
![]() |
4f870c84fa | ||
![]() |
d48c5bae9e | ||
![]() |
e3a342006f | ||
![]() |
d1ad5080b8 | ||
![]() |
7108c83c5e | ||
![]() |
c6e126517e | ||
![]() |
790685154f | ||
![]() |
ef094d559a | ||
![]() |
c4c75cb41c | ||
![]() |
98cd4d1c78 | ||
![]() |
c68ee341b2 | ||
![]() |
732780e31f | ||
![]() |
d08d1bf6b4 | ||
![]() |
598d75d857 | ||
![]() |
a48e051be2 | ||
![]() |
5a1a029434 | ||
![]() |
a5a4ae6735 | ||
![]() |
1ffeed981d | ||
![]() |
62c107b474 | ||
![]() |
b16cc10308 | ||
![]() |
f2ddd7a205 | ||
![]() |
9290c06d72 | ||
![]() |
cfc9a4c3d7 | ||
![]() |
17bbb7d2ac | ||
![]() |
1fe8359f05 | ||
![]() |
047a30a10b | ||
![]() |
50b7baa8be | ||
![]() |
fd14ac930c | ||
![]() |
1bedd1129e | ||
![]() |
0643a07e26 | ||
![]() |
b935b167f8 | ||
![]() |
924b8ab901 | ||
![]() |
fe376beae2 | ||
![]() |
80fa61ed14 | ||
![]() |
00bbcc62b2 | ||
![]() |
c2a2c69375 | ||
![]() |
61b9336d70 | ||
![]() |
a44160b1bb | ||
![]() |
e69b02bec8 | ||
![]() |
af674124d6 | ||
![]() |
c8f70c1dbf | ||
![]() |
9cfa9a92af | ||
![]() |
43235dd862 | ||
![]() |
eb4c9ed392 | ||
![]() |
c2f71093d3 | ||
![]() |
c168934b2f | ||
![]() |
8575a336cb | ||
![]() |
1d6df3590a | ||
![]() |
f1c70a59b1 | ||
![]() |
9364d55427 | ||
![]() |
d60bf26858 | ||
![]() |
0afef3372d | ||
![]() |
63a357e7ce | ||
![]() |
ed2dd02606 | ||
![]() |
66f0bc42f3 | ||
![]() |
64896e89a4 | ||
![]() |
f71aebfe7f | ||
![]() |
502e8891de | ||
![]() |
0ea1c7b71f | ||
![]() |
6abb50ab49 | ||
![]() |
1d4cdc3c6d | ||
![]() |
0b17071769 | ||
![]() |
4a49bd559e | ||
![]() |
f3ef056267 | ||
![]() |
0a7a0dff2f | ||
![]() |
3d3724b017 | ||
![]() |
750c4bdd4c | ||
![]() |
ebb6c6dd49 | ||
![]() |
39e0090145 | ||
![]() |
d029ec5c68 | ||
![]() |
853ff4cc62 | ||
![]() |
3f7383afce | ||
![]() |
d212552731 | ||
![]() |
8401f85ff1 | ||
![]() |
d382499510 | ||
![]() |
ce8314b4e1 | ||
![]() |
b315bdc036 | ||
![]() |
d27a8e5314 | ||
![]() |
06f28bd3c9 | ||
![]() |
c4b2026156 | ||
![]() |
7dd1395812 | ||
![]() |
f754a8905d | ||
![]() |
e4913200f6 | ||
![]() |
67e33e0360 | ||
![]() |
c138013c75 | ||
![]() |
b24683da20 | ||
![]() |
4700f2cff4 | ||
![]() |
8905340413 | ||
![]() |
b70202bead | ||
![]() |
5468bc3f11 | ||
![]() |
d922e28b0b | ||
![]() |
f9db313392 | ||
![]() |
96b8fba876 | ||
![]() |
870bbb45c0 | ||
![]() |
2c4bf83c10 | ||
![]() |
9248d5d924 | ||
![]() |
984ffdc07f | ||
![]() |
b984faa123 | ||
![]() |
0986e54ca5 | ||
![]() |
33931abaa6 | ||
![]() |
848eea8906 | ||
![]() |
90b55c46ad | ||
![]() |
9a50618f32 | ||
![]() |
9ba57e46ee | ||
![]() |
bbeccc01ac | ||
![]() |
c60e1c82c1 | ||
![]() |
537e0d17a8 | ||
![]() |
a00512fb97 | ||
![]() |
8532058b5b | ||
![]() |
ad64b001a0 | ||
![]() |
9491de3313 | ||
![]() |
f9e729c7af | ||
![]() |
3812053b14 | ||
![]() |
9db4cdbb32 | ||
![]() |
c2cd4052d0 | ||
![]() |
8390e28466 | ||
![]() |
0369b52dab | ||
![]() |
52da881318 | ||
![]() |
9d4ada8d75 | ||
![]() |
93de79d77d | ||
![]() |
66c0d0f191 | ||
![]() |
dd2d8d19e2 | ||
![]() |
283cd4891b | ||
![]() |
84c2883bb0 | ||
![]() |
e13d2cdb24 | ||
![]() |
ea92d403f7 | ||
![]() |
054dfdcf9f | ||
![]() |
0f976d972a | ||
![]() |
2571f3c1d4 | ||
![]() |
8857431418 | ||
![]() |
2a992f583f | ||
![]() |
da653b9c09 | ||
![]() |
e8979b9eb3 | ||
![]() |
78bcad94a3 | ||
![]() |
2a3d08c6b1 | ||
![]() |
98cd82b126 | ||
![]() |
33a7122238 | ||
![]() |
4980ea5488 | ||
![]() |
4fd408e530 | ||
![]() |
4cafaec101 | ||
![]() |
98ffaf518e | ||
![]() |
77f8e8ef6d | ||
![]() |
eb818a6b7f | ||
![]() |
70294f9a0b | ||
![]() |
e7ee521891 | ||
![]() |
268a2dd0ec | ||
![]() |
6350c4ac0e | ||
![]() |
c31394bf6f | ||
![]() |
63c7f01f3f | ||
![]() |
326e572a8c | ||
![]() |
b8cbebfa4b | ||
![]() |
8fd64bba2f | ||
![]() |
67dce0cb22 | ||
![]() |
16d2efa7a4 | ||
![]() |
87506818b0 | ||
![]() |
dcb2959536 | ||
![]() |
ead3bc9b66 | ||
![]() |
0923b4093b | ||
![]() |
17c2e78557 | ||
![]() |
7ea43a153f | ||
![]() |
93dd0f6b78 | ||
![]() |
8154e8756d | ||
![]() |
c743468eb3 | ||
![]() |
e1d289b0e5 | ||
![]() |
f37c8d3879 | ||
![]() |
a8f7518fd0 | ||
![]() |
3364558d5f | ||
![]() |
297748affc | ||
![]() |
f2c3265ef1 | ||
![]() |
7212a98324 | ||
![]() |
6004e2da8a | ||
![]() |
4d05e0b93c | ||
![]() |
2fa23495b4 | ||
![]() |
66197e850d | ||
![]() |
5a30ec4901 | ||
![]() |
8aec124e7c | ||
![]() |
e0f8e9ca81 | ||
![]() |
1ea640950e | ||
![]() |
e3ec79a09b | ||
![]() |
e74dcfef26 | ||
![]() |
f44fd8a1b1 | ||
![]() |
3f96f1533c | ||
![]() |
16068482ef | ||
![]() |
6fb198b237 | ||
![]() |
509a614919 | ||
![]() |
bcb154075c | ||
![]() |
765a2387ea | ||
![]() |
e8fffefad2 | ||
![]() |
3b275ec80a | ||
![]() |
d3c09e68ad | ||
![]() |
f536574e9a | ||
![]() |
233a2e9f94 | ||
![]() |
645d59065a | ||
![]() |
64a1f34050 | ||
![]() |
6417b7cfc3 | ||
![]() |
4c485ca762 | ||
![]() |
dfa0f900a5 | ||
![]() |
5f54d53df2 | ||
![]() |
40ed9a9f4c | ||
![]() |
d85405ec30 | ||
![]() |
e795492b99 | ||
![]() |
dfa046e641 | ||
![]() |
ec697d5db0 | ||
![]() |
55fb54a0c2 | ||
![]() |
762d41e99b | ||
![]() |
c6829b97a1 | ||
![]() |
0821e637f6 | ||
![]() |
0ae44af42d | ||
![]() |
67d6645cd8 | ||
![]() |
e5ff4c6c43 | ||
![]() |
0a61e5805b | ||
![]() |
77e136f08d | ||
![]() |
9af39fa59e | ||
![]() |
b213e9ec05 | ||
![]() |
8cefe84167 | ||
![]() |
ef39a52e0f | ||
![]() |
69126ad1cf | ||
![]() |
eaa1f57699 | ||
![]() |
d78c498a97 | ||
![]() |
e2ec0a1398 | ||
![]() |
ab5f5f3013 | ||
![]() |
8f6ab1ea26 | ||
![]() |
9e8eb99e8f | ||
![]() |
ceb3309147 | ||
![]() |
ef7c5950b5 | ||
![]() |
77d6484c99 | ||
![]() |
dab8297835 | ||
![]() |
8cf0449067 | ||
![]() |
c9318689a6 | ||
![]() |
7c016c3b86 | ||
![]() |
f4eb52befd | ||
![]() |
d41292ed74 | ||
![]() |
5b042abd39 | ||
![]() |
f43d14ef34 | ||
![]() |
7f4bcb4fdc | ||
![]() |
5913e1182b | ||
![]() |
99ff49ad41 | ||
![]() |
deb9802308 | ||
![]() |
fdbdf930ba | ||
![]() |
749f352aa0 | ||
![]() |
c109f90a92 | ||
![]() |
d224d378ab | ||
![]() |
708d7daf0d | ||
![]() |
55f83cb85e | ||
![]() |
907d420275 | ||
![]() |
13575bb29c | ||
![]() |
bd3ef3b782 | ||
![]() |
7d9d60eb69 | ||
![]() |
cf57570e61 | ||
![]() |
2afad7e9aa | ||
![]() |
cc897b77ec | ||
![]() |
2977710ede | ||
![]() |
577aef85e7 | ||
![]() |
4a01763f82 | ||
![]() |
dfdf1250eb | ||
![]() |
e161831c76 | ||
![]() |
40bb3ca977 | ||
![]() |
60a7760a8a | ||
![]() |
ae8a30a0aa | ||
![]() |
6af539d77a | ||
![]() |
3d25e69812 | ||
![]() |
0adbe73ad8 | ||
![]() |
ecacb13980 | ||
![]() |
5c4b82e16d | ||
![]() |
cec6ee8777 | ||
![]() |
ef2d6e118a | ||
![]() |
630574c036 | ||
![]() |
e934aedec6 | ||
![]() |
c637c1b8b8 | ||
![]() |
18ac9d8779 | ||
![]() |
7905b0b2ba | ||
![]() |
cb7604e53d | ||
![]() |
c67443f5f9 | ||
![]() |
f8f5cce6a6 | ||
![]() |
bb54078b2d | ||
![]() |
a784eee66f | ||
![]() |
fe3441e052 | ||
![]() |
6fe4b2ac00 | ||
![]() |
7025371279 | ||
![]() |
0f343a09eb | ||
![]() |
011aaf8c54 | ||
![]() |
a2dcf29ea2 | ||
![]() |
590e9b48b8 | ||
![]() |
2270b57f16 | ||
![]() |
295372ea9e | ||
![]() |
0fe484c606 | ||
![]() |
6febee6aaa | ||
![]() |
5adf12494f | ||
![]() |
0942a771c7 | ||
![]() |
60b0da51cb | ||
![]() |
8c7c726111 | ||
![]() |
a0f9bcf6eb | ||
![]() |
49d23df60b | ||
![]() |
87fc9fcc13 | ||
![]() |
b6415da897 | ||
![]() |
6dd4d86113 | ||
![]() |
a2465eb0e3 | ||
![]() |
927942a2c0 | ||
![]() |
32c1177e01 | ||
![]() |
b6f30a4734 | ||
![]() |
599a6f01c8 | ||
![]() |
55e12b2859 | ||
![]() |
4e9aa16f79 | ||
![]() |
3c68dfe400 | ||
![]() |
e44ecd3778 | ||
![]() |
76301e8cc5 | ||
![]() |
96d320d4e0 | ||
![]() |
bd5d0c63a3 | ||
![]() |
52b3981bf2 | ||
![]() |
c0a145a129 | ||
![]() |
7494090db2 | ||
![]() |
55e3aa12aa | ||
![]() |
afc163dbef | ||
![]() |
d509e647c5 | ||
![]() |
3d2838b750 | ||
![]() |
9d42e64ad3 | ||
![]() |
c30781e5da | ||
![]() |
a2acb741b6 | ||
![]() |
d0d5261907 | ||
![]() |
5be073ac26 | ||
![]() |
7d50af9122 | ||
![]() |
9816084ba9 | ||
![]() |
2cb25cd0cd | ||
![]() |
f6ab40c53e | ||
![]() |
b754a6b36e | ||
![]() |
62deb5a445 | ||
![]() |
a955051342 | ||
![]() |
c2dda25031 | ||
![]() |
2bfc20ed9b | ||
![]() |
cb4b5829d4 | ||
![]() |
becd0c1997 | ||
![]() |
98796f66c1 | ||
![]() |
d3ca20fb86 | ||
![]() |
a58e756d9e | ||
![]() |
4aa5df9496 | ||
![]() |
2de47ed975 | ||
![]() |
fd6b55d478 | ||
![]() |
05e659f162 | ||
![]() |
d0df204f77 | ||
![]() |
dba3f1db89 | ||
![]() |
cc0a7ad42d | ||
![]() |
a0e509ba0c | ||
![]() |
25733b422e | ||
![]() |
f9b8bd98ba | ||
![]() |
da625d767d | ||
![]() |
ed9b1d6b30 | ||
![]() |
aa33198b96 | ||
![]() |
c6a898d4f8 | ||
![]() |
bb9fd2fe33 | ||
![]() |
48d0052f66 | ||
![]() |
1871190c14 | ||
![]() |
c2a8293dca | ||
![]() |
dfb2af20bb | ||
![]() |
3e61cc6caa | ||
![]() |
ca3c8f47d4 | ||
![]() |
16520270d4 | ||
![]() |
8a1ac2f7a9 | ||
![]() |
a9b2749df5 | ||
![]() |
2d04cac5e5 | ||
![]() |
da5a960584 | ||
![]() |
f27df0e0bb | ||
![]() |
65d700f5bb | ||
![]() |
ba8e92cb88 | ||
![]() |
bc09cf4cf8 | ||
![]() |
e8d88303bf | ||
![]() |
428d080242 | ||
![]() |
9e9f2e0fbe | ||
![]() |
0e068253ac | ||
![]() |
9ceaf53181 | ||
![]() |
cd7dc1f7dd | ||
![]() |
66dc83ceb2 | ||
![]() |
4f53ec6a3c | ||
![]() |
4e13372d7e | ||
![]() |
fa53c91147 | ||
![]() |
6148e5d1da | ||
![]() |
e9b47b4c21 | ||
![]() |
3374403b13 | ||
![]() |
b3876838fb | ||
![]() |
05531a8448 | ||
![]() |
e241f60e7a | ||
![]() |
e9371ef60d | ||
![]() |
5db5dca21b | ||
![]() |
3deafdf8aa | ||
![]() |
6c09f56df4 | ||
![]() |
9e0b269cff | ||
![]() |
0f63122c15 | ||
![]() |
3b133f71c4 | ||
![]() |
2f51cb4a9b | ||
![]() |
b8f73770c3 | ||
![]() |
f2cbbfdeb9 | ||
![]() |
3cf4f5ea0e | ||
![]() |
4e68eab71a | ||
![]() |
e45b11c773 | ||
![]() |
f245556636 | ||
![]() |
0290dbe191 | ||
![]() |
e47cfefe16 | ||
![]() |
171dcf228b | ||
![]() |
3edb1f3c9d | ||
![]() |
2411f1bba2 | ||
![]() |
cc4d703135 | ||
![]() |
dd4e419e25 | ||
![]() |
394e2aaef1 | ||
![]() |
a026343945 | ||
![]() |
b5606021c9 | ||
![]() |
d3b78a4d48 | ||
![]() |
7d4f1a1f28 | ||
![]() |
d1eb185f1b | ||
![]() |
3cbbd53565 | ||
![]() |
a1eea48862 | ||
![]() |
3541d3d012 | ||
![]() |
f28d37d159 | ||
![]() |
60ec92374a | ||
![]() |
5751db78f9 | ||
![]() |
0737d28707 | ||
![]() |
550b5f7d95 | ||
![]() |
d1dac3e56d | ||
![]() |
02f451a3fc | ||
![]() |
c8d9a64026 | ||
![]() |
ceba3bd561 | ||
![]() |
5b684de6b6 | ||
![]() |
c58f7da4d1 | ||
![]() |
1aab4188cb | ||
![]() |
8c7d56da65 | ||
![]() |
0ebad7661f | ||
![]() |
4ce6980d66 | ||
![]() |
ca2b2ba12a | ||
![]() |
fd47eb680d | ||
![]() |
2b14e535ad | ||
![]() |
3c69343cca | ||
![]() |
041f871514 | ||
![]() |
69f1baf94d | ||
![]() |
dcecd5104c | ||
![]() |
81c2c73ebf | ||
![]() |
dc079b0edd | ||
![]() |
e929164e52 | ||
![]() |
da6296fbd1 | ||
![]() |
c74209a6da | ||
![]() |
770e621fae | ||
![]() |
ef0bef2c30 | ||
![]() |
db05e688bf | ||
![]() |
a3a94130eb | ||
![]() |
493024345c | ||
![]() |
af80793adf | ||
![]() |
4f527c40e3 | ||
![]() |
c06775b2dc | ||
![]() |
a64f8add24 | ||
![]() |
3726e31626 |
9
.gitignore
vendored
9
.gitignore
vendored
@ -1,3 +1,8 @@
|
||||
linux-*.tar.bz2*
|
||||
linux-*.tar.gz
|
||||
linux-*.tar.xz
|
||||
linux-*.sign
|
||||
WireGuard-*.tar.xz
|
||||
WireGuard-*.tar.asc
|
||||
kernel-*/
|
||||
linux*.tar.sign
|
||||
config-base-*
|
||||
macbook12-spi-driver-*.tar.gz
|
||||
|
38
0001-xen-netfront-detach-crash.patch
Normal file
38
0001-xen-netfront-detach-crash.patch
Normal file
@ -0,0 +1,38 @@
|
||||
From a6b3add4337101ef875423c0888b8ac1cde47c2c Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
|
||||
<marmarek@invisiblethingslab.com>
|
||||
Date: Thu, 6 Sep 2018 15:09:44 +0200
|
||||
Subject: [PATCH] xen-netfront-detach-crash
|
||||
|
||||
When it get to free_page(queue->grant_tx_page[i]), the use counter on this page
|
||||
is already 0, which cause a crash. Not sure if this is the proper fix
|
||||
(according to git log this may introduce some memory leak), but at least it
|
||||
prevent the crash.
|
||||
|
||||
Details in this thread:
|
||||
http://xen.markmail.org/thread/pw5edbtqienjx4q5
|
||||
---
|
||||
drivers/net/xen-netfront.c | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
|
||||
index 482c6c8b0fb7..8f0a790ec5e7 100644
|
||||
--- a/drivers/net/xen-netfront.c
|
||||
+++ b/drivers/net/xen-netfront.c
|
||||
@@ -1138,9 +1138,10 @@ static void xennet_release_tx_bufs(struct netfront_queue *queue)
|
||||
|
||||
skb = queue->tx_skbs[i].skb;
|
||||
get_page(queue->grant_tx_page[i]);
|
||||
- gnttab_end_foreign_access(queue->grant_tx_ref[i],
|
||||
- GNTMAP_readonly,
|
||||
- (unsigned long)page_address(queue->grant_tx_page[i]));
|
||||
+ gnttab_end_foreign_access_ref(
|
||||
+ queue->grant_tx_ref[i], GNTMAP_readonly);
|
||||
+ gnttab_release_grant_reference(
|
||||
+ &queue->gref_tx_head, queue->grant_tx_ref[i]);
|
||||
queue->grant_tx_page[i] = NULL;
|
||||
queue->grant_tx_ref[i] = GRANT_INVALID_REF;
|
||||
add_id_to_freelist(&queue->tx_skb_freelist, queue->tx_skbs, i);
|
||||
--
|
||||
2.21.0
|
||||
|
70
0002-mce-hide-EBUSY-initialization-error-on-Xen.patch
Normal file
70
0002-mce-hide-EBUSY-initialization-error-on-Xen.patch
Normal file
@ -0,0 +1,70 @@
|
||||
From a58197258286cf8dce45cf03b3b2b436b3cf8a99 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
|
||||
<marmarek@invisiblethingslab.com>
|
||||
Date: Tue, 5 Jan 2016 02:44:04 +0100
|
||||
Subject: [PATCH] mce: hide EBUSY initialization error on Xen
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
In case of Xen, the device is already registered by xen mcelog (in
|
||||
xen_late_init_mcelog), so fail here is expected. Note that
|
||||
mcheck_init_device call is still expected to initialize mce_device. Comment
|
||||
from threshold_init_device explaining the situation:
|
||||
|
||||
/*
|
||||
* there are 3 funcs which need to be _initcalled in a logic sequence:
|
||||
* 1. xen_late_init_mcelog
|
||||
* 2. mcheck_init_device
|
||||
* 3. threshold_init_device
|
||||
*
|
||||
* xen_late_init_mcelog must register xen_mce_chrdev_device before
|
||||
* native mce_chrdev_device registration if running under xen platform;
|
||||
*
|
||||
* mcheck_init_device should be inited before threshold_init_device to
|
||||
* initialize mce_device, otherwise a NULL ptr dereference will cause panic.
|
||||
*
|
||||
* so we use following _initcalls
|
||||
* 1. device_initcall(xen_late_init_mcelog);
|
||||
* 2. device_initcall_sync(mcheck_init_device);
|
||||
* 3. late_initcall(threshold_init_device);
|
||||
*
|
||||
* when running under xen, the initcall order is 1,2,3;
|
||||
* on baremetal, we skip 1 and we do only 2 and 3.
|
||||
*/
|
||||
|
||||
Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
|
||||
---
|
||||
arch/x86/kernel/cpu/mce/core.c | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c
|
||||
index 743370ee4983..3af7521b2279 100644
|
||||
--- a/arch/x86/kernel/cpu/mce/core.c
|
||||
+++ b/arch/x86/kernel/cpu/mce/core.c
|
||||
@@ -51,6 +51,10 @@
|
||||
#include <asm/msr.h>
|
||||
#include <asm/reboot.h>
|
||||
|
||||
+#ifdef CONFIG_XEN_MCE_LOG
|
||||
+#include <xen/xen.h>
|
||||
+#endif
|
||||
+
|
||||
#include "internal.h"
|
||||
|
||||
static DEFINE_MUTEX(mce_log_mutex);
|
||||
@@ -2464,6 +2468,11 @@ static __init int mcheck_init_device(void)
|
||||
free_cpumask_var(mce_device_initialized);
|
||||
|
||||
err_out:
|
||||
+#ifdef CONFIG_XEN_MCE_LOG
|
||||
+ /* in case of Xen, the character device was already registered, so do not
|
||||
+ * treat this as an error */
|
||||
+ if (!xen_initial_domain() || err != -EBUSY)
|
||||
+#endif
|
||||
pr_err("Unable to init MCE device (rc: %d)\n", err);
|
||||
|
||||
return err;
|
||||
--
|
||||
2.21.0
|
||||
|
27
0003-Log-error-code-of-EVTCHNOP_bind_pirq-failure.patch
Normal file
27
0003-Log-error-code-of-EVTCHNOP_bind_pirq-failure.patch
Normal file
@ -0,0 +1,27 @@
|
||||
From da15c0c3af84be25fdd695dddf61524099f4322e Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
|
||||
<marmarek@invisiblethingslab.com>
|
||||
Date: Sat, 30 Jan 2016 01:53:26 +0100
|
||||
Subject: [PATCH] Log error code of EVTCHNOP_bind_pirq failure
|
||||
|
||||
Ease debugging of PCI passthrough problems.
|
||||
---
|
||||
drivers/xen/events/events_base.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
|
||||
index 6c8843968a52..54d2e30683c4 100644
|
||||
--- a/drivers/xen/events/events_base.c
|
||||
+++ b/drivers/xen/events/events_base.c
|
||||
@@ -522,7 +522,7 @@ static unsigned int __startup_pirq(unsigned int irq)
|
||||
BIND_PIRQ__WILL_SHARE : 0;
|
||||
rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_pirq, &bind_pirq);
|
||||
if (rc != 0) {
|
||||
- pr_warn("Failed to obtain physical IRQ %d\n", irq);
|
||||
+ pr_warn("Failed to obtain physical IRQ %d (error %d)\n", irq, rc);
|
||||
return 0;
|
||||
}
|
||||
evtchn = bind_pirq.port;
|
||||
--
|
||||
2.21.0
|
||||
|
@ -0,0 +1,39 @@
|
||||
From 1b9928a04716a54933dcaff9ec7e68323f58090b Mon Sep 17 00:00:00 2001
|
||||
From: Marek Marczykowski <marmarek@invisiblethingslab.com>
|
||||
Date: Mon, 11 Jun 2012 22:49:31 +0200
|
||||
Subject: [PATCH] pvops: respect 'removable' xenstore flag for block devices
|
||||
|
||||
Especially this is needed by pmount to allow mount qvm-block attached devices
|
||||
by normal user.
|
||||
---
|
||||
drivers/block/xen-blkfront.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
|
||||
index a74d03913822..e76b999fceca 100644
|
||||
--- a/drivers/block/xen-blkfront.c
|
||||
+++ b/drivers/block/xen-blkfront.c
|
||||
@@ -2339,6 +2339,7 @@ static void blkfront_connect(struct blkfront_info *info)
|
||||
unsigned int binfo;
|
||||
char *envp[] = { "RESIZE=1", NULL };
|
||||
int err, i;
|
||||
+ int removable;
|
||||
|
||||
switch (info->connected) {
|
||||
case BLKIF_STATE_CONNECTED:
|
||||
@@ -2406,6 +2407,12 @@ static void blkfront_connect(struct blkfront_info *info)
|
||||
}
|
||||
}
|
||||
|
||||
+ err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
|
||||
+ "removable", "%d", &removable,
|
||||
+ NULL);
|
||||
+ if (!err && removable)
|
||||
+ binfo |= VDISK_REMOVABLE;
|
||||
+
|
||||
err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size,
|
||||
physical_sector_size);
|
||||
if (err) {
|
||||
--
|
||||
2.21.0
|
||||
|
@ -0,0 +1,34 @@
|
||||
From 61d8059c42eaf388b857e0d5c8460ccb76c2f97c Mon Sep 17 00:00:00 2001
|
||||
From: Marek Marczykowski <marmarek@invisiblethingslab.com>
|
||||
Date: Sun, 15 Jul 2012 19:57:47 +0200
|
||||
Subject: [PATCH] pvops/xen-blkfront: handle FDEJECT as detach request (#630)
|
||||
|
||||
---
|
||||
drivers/block/xen-blkfront.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
|
||||
index e76b999fceca..db7d28ac9747 100644
|
||||
--- a/drivers/block/xen-blkfront.c
|
||||
+++ b/drivers/block/xen-blkfront.c
|
||||
@@ -47,6 +47,7 @@
|
||||
#include <linux/bitmap.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/workqueue.h>
|
||||
+#include <linux/fd.h>
|
||||
|
||||
#include <xen/xen.h>
|
||||
#include <xen/xenbus.h>
|
||||
@@ -511,6 +512,9 @@ static int blkif_ioctl(struct block_device *bdev, fmode_t mode,
|
||||
return 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
+ case FDEJECT:
|
||||
+ xenbus_switch_state(info->xbdev, XenbusStateClosing);
|
||||
+ return 0;
|
||||
|
||||
default:
|
||||
/*printk(KERN_ALERT "ioctl %08x not supported by Xen blkdev\n",
|
||||
--
|
||||
2.21.0
|
||||
|
49
0006-block-add-no_part_scan-module-parameter.patch
Normal file
49
0006-block-add-no_part_scan-module-parameter.patch
Normal file
@ -0,0 +1,49 @@
|
||||
From 56ce69a0260413418c2845182aa93165c4a1ce42 Mon Sep 17 00:00:00 2001
|
||||
From: Rusty Bird <rustybird@openmailbox.org>
|
||||
Date: Mon, 11 Jul 2016 13:05:38 +0000
|
||||
Subject: [PATCH] block: add no_part_scan module parameter
|
||||
|
||||
Define a boolean module parameter named "no_part_scan" defaulting to N,
|
||||
which, if set to Y, always causes the GENHD_FL_NO_PART_SCAN flag to be
|
||||
added to subsequently created block devices, thereby disabling the
|
||||
kernel's various partition table parsers for them.
|
||||
|
||||
The parameter's current value can be changed at any time by writing to
|
||||
the /sys/module/block/parameters/no_part_scan file.
|
||||
---
|
||||
block/genhd.c | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
diff --git a/block/genhd.c b/block/genhd.c
|
||||
index 26b31fcae217..75993c12e123 100644
|
||||
--- a/block/genhd.c
|
||||
+++ b/block/genhd.c
|
||||
@@ -676,6 +676,15 @@ static void register_disk(struct device *parent, struct gendisk *disk,
|
||||
}
|
||||
}
|
||||
|
||||
+/* copied (not moved) from far down below, to have fewer patch hunks */
|
||||
+#undef MODULE_PARAM_PREFIX
|
||||
+#define MODULE_PARAM_PREFIX "block."
|
||||
+
|
||||
+/* partition scanning policy */
|
||||
+static bool disk_no_part_scan = 0;
|
||||
+module_param_named(no_part_scan, disk_no_part_scan, bool, S_IRUGO|S_IWUSR);
|
||||
+MODULE_PARM_DESC(no_part_scan, "When adding block devices, always mark them as not to be scanned for partitions");
|
||||
+
|
||||
/**
|
||||
* __device_add_disk - add disk information to kernel list
|
||||
* @parent: parent device for the disk
|
||||
@@ -704,6 +713,9 @@ static void __device_add_disk(struct device *parent, struct gendisk *disk,
|
||||
if (register_queue)
|
||||
elevator_init_mq(disk->queue);
|
||||
|
||||
+ if (disk_no_part_scan)
|
||||
+ disk->flags |= GENHD_FL_NO_PART_SCAN;
|
||||
+
|
||||
/* minors == 0 indicates to use ext devt from part0 and should
|
||||
* be accompanied with EXT_DEVT flag. Make sure all
|
||||
* parameters make sense.
|
||||
--
|
||||
2.21.0
|
||||
|
58
0007-xen-Add-RING_COPY_RESPONSE.patch
Normal file
58
0007-xen-Add-RING_COPY_RESPONSE.patch
Normal file
@ -0,0 +1,58 @@
|
||||
From 76c089d06f5ff8dc7a54c3e5ef7d2f1447ca8ec4 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
|
||||
<marmarek@invisiblethingslab.com>
|
||||
Date: Tue, 15 Dec 2015 21:35:14 +0100
|
||||
Subject: [PATCH] xen: Add RING_COPY_RESPONSE()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Using RING_GET_RESPONSE() on a shared ring is easy to use incorrectly
|
||||
(i.e., by not considering that the other end may alter the data in the
|
||||
shared ring while it is being inspected). Safe usage of a response
|
||||
generally requires taking a local copy.
|
||||
|
||||
Provide a RING_COPY_RESPONSE() macro to use instead of
|
||||
RING_GET_RESPONSE() and an open-coded memcpy(). This takes care of
|
||||
ensuring that the copy is done correctly regardless of any possible
|
||||
compiler optimizations.
|
||||
|
||||
Use a volatile source to prevent the compiler from reordering or
|
||||
omitting the copy.
|
||||
|
||||
This is part of XSA155.
|
||||
|
||||
CC: stable@vger.kernel.org
|
||||
Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
|
||||
---
|
||||
include/xen/interface/io/ring.h | 14 ++++++++++++++
|
||||
1 file changed, 14 insertions(+)
|
||||
|
||||
diff --git a/include/xen/interface/io/ring.h b/include/xen/interface/io/ring.h
|
||||
index 3f40501fc60b..03702f6874df 100644
|
||||
--- a/include/xen/interface/io/ring.h
|
||||
+++ b/include/xen/interface/io/ring.h
|
||||
@@ -201,6 +201,20 @@ struct __name##_back_ring { \
|
||||
#define RING_GET_RESPONSE(_r, _idx) \
|
||||
(&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].rsp))
|
||||
|
||||
+/*
|
||||
+ * Get a local copy of a response.
|
||||
+ *
|
||||
+ * Use this in preference to RING_GET_RESPONSE() so all processing is
|
||||
+ * done on a local copy that cannot be modified by the other end.
|
||||
+ *
|
||||
+ * Note that https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145 may cause this
|
||||
+ * to be ineffective where _rsp is a struct which consists of only bitfields.
|
||||
+ */
|
||||
+#define RING_COPY_RESPONSE(_r, _idx, _rsp) do { \
|
||||
+ /* Use volatile to force the copy into _rsp. */ \
|
||||
+ *(_rsp) = *(volatile typeof(_rsp))RING_GET_RESPONSE(_r, _idx); \
|
||||
+} while (0)
|
||||
+
|
||||
/* Loop termination condition: Would the specified index overflow the ring? */
|
||||
#define RING_REQUEST_CONS_OVERFLOW(_r, _cons) \
|
||||
(((_cons) - (_r)->rsp_prod_pvt) >= RING_SIZE(_r))
|
||||
--
|
||||
2.21.0
|
||||
|
177
0008-xen-netfront-copy-response-out-of-shared-buffer-befo.patch
Normal file
177
0008-xen-netfront-copy-response-out-of-shared-buffer-befo.patch
Normal file
@ -0,0 +1,177 @@
|
||||
From 688769df7c2365ae836eb755ccf5b196b45cbd56 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
|
||||
<marmarek@invisiblethingslab.com>
|
||||
Date: Wed, 16 Dec 2015 05:09:55 +0100
|
||||
Subject: [PATCH] xen-netfront: copy response out of shared buffer before
|
||||
accessing it
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Make local copy of the response, otherwise backend might modify it while
|
||||
frontend is already processing it - leading to time of check / time of
|
||||
use issue.
|
||||
|
||||
Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
|
||||
---
|
||||
drivers/net/xen-netfront.c | 51 +++++++++++++++++++-------------------
|
||||
1 file changed, 25 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
|
||||
index 8f0a790ec5e7..abb9b3cd87b8 100644
|
||||
--- a/drivers/net/xen-netfront.c
|
||||
+++ b/drivers/net/xen-netfront.c
|
||||
@@ -385,13 +385,13 @@ static void xennet_tx_buf_gc(struct netfront_queue *queue)
|
||||
rmb(); /* Ensure we see responses up to 'rp'. */
|
||||
|
||||
for (cons = queue->tx.rsp_cons; cons != prod; cons++) {
|
||||
- struct xen_netif_tx_response *txrsp;
|
||||
+ struct xen_netif_tx_response txrsp;
|
||||
|
||||
- txrsp = RING_GET_RESPONSE(&queue->tx, cons);
|
||||
- if (txrsp->status == XEN_NETIF_RSP_NULL)
|
||||
+ RING_COPY_RESPONSE(&queue->tx, cons, &txrsp);
|
||||
+ if (txrsp.status == XEN_NETIF_RSP_NULL)
|
||||
continue;
|
||||
|
||||
- id = txrsp->id;
|
||||
+ id = txrsp.id;
|
||||
skb = queue->tx_skbs[id].skb;
|
||||
if (unlikely(gnttab_query_foreign_access(
|
||||
queue->grant_tx_ref[id]) != 0)) {
|
||||
@@ -739,7 +739,7 @@ static int xennet_get_extras(struct netfront_queue *queue,
|
||||
RING_IDX rp)
|
||||
|
||||
{
|
||||
- struct xen_netif_extra_info *extra;
|
||||
+ struct xen_netif_extra_info extra;
|
||||
struct device *dev = &queue->info->netdev->dev;
|
||||
RING_IDX cons = queue->rx.rsp_cons;
|
||||
int err = 0;
|
||||
@@ -755,24 +755,23 @@ static int xennet_get_extras(struct netfront_queue *queue,
|
||||
break;
|
||||
}
|
||||
|
||||
- extra = (struct xen_netif_extra_info *)
|
||||
- RING_GET_RESPONSE(&queue->rx, ++cons);
|
||||
+ RING_COPY_RESPONSE(&queue->rx, ++cons, &extra);
|
||||
|
||||
- if (unlikely(!extra->type ||
|
||||
- extra->type >= XEN_NETIF_EXTRA_TYPE_MAX)) {
|
||||
+ if (unlikely(!extra.type ||
|
||||
+ extra.type >= XEN_NETIF_EXTRA_TYPE_MAX)) {
|
||||
if (net_ratelimit())
|
||||
dev_warn(dev, "Invalid extra type: %d\n",
|
||||
- extra->type);
|
||||
+ extra.type);
|
||||
err = -EINVAL;
|
||||
} else {
|
||||
- memcpy(&extras[extra->type - 1], extra,
|
||||
- sizeof(*extra));
|
||||
+ memcpy(&extras[extra.type - 1], &extra,
|
||||
+ sizeof(extra));
|
||||
}
|
||||
|
||||
skb = xennet_get_rx_skb(queue, cons);
|
||||
ref = xennet_get_rx_ref(queue, cons);
|
||||
xennet_move_rx_slot(queue, skb, ref);
|
||||
- } while (extra->flags & XEN_NETIF_EXTRA_FLAG_MORE);
|
||||
+ } while (extra.flags & XEN_NETIF_EXTRA_FLAG_MORE);
|
||||
|
||||
queue->rx.rsp_cons = cons;
|
||||
return err;
|
||||
@@ -782,28 +781,28 @@ static int xennet_get_responses(struct netfront_queue *queue,
|
||||
struct netfront_rx_info *rinfo, RING_IDX rp,
|
||||
struct sk_buff_head *list)
|
||||
{
|
||||
- struct xen_netif_rx_response *rx = &rinfo->rx;
|
||||
+ struct xen_netif_rx_response rx = rinfo->rx;
|
||||
struct xen_netif_extra_info *extras = rinfo->extras;
|
||||
struct device *dev = &queue->info->netdev->dev;
|
||||
RING_IDX cons = queue->rx.rsp_cons;
|
||||
struct sk_buff *skb = xennet_get_rx_skb(queue, cons);
|
||||
grant_ref_t ref = xennet_get_rx_ref(queue, cons);
|
||||
- int max = XEN_NETIF_NR_SLOTS_MIN + (rx->status <= RX_COPY_THRESHOLD);
|
||||
+ int max = XEN_NETIF_NR_SLOTS_MIN + (rx.status <= RX_COPY_THRESHOLD);
|
||||
int slots = 1;
|
||||
int err = 0;
|
||||
unsigned long ret;
|
||||
|
||||
- if (rx->flags & XEN_NETRXF_extra_info) {
|
||||
+ if (rx.flags & XEN_NETRXF_extra_info) {
|
||||
err = xennet_get_extras(queue, extras, rp);
|
||||
cons = queue->rx.rsp_cons;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
- if (unlikely(rx->status < 0 ||
|
||||
- rx->offset + rx->status > XEN_PAGE_SIZE)) {
|
||||
+ if (unlikely(rx.status < 0 ||
|
||||
+ rx.offset + rx.status > XEN_PAGE_SIZE)) {
|
||||
if (net_ratelimit())
|
||||
dev_warn(dev, "rx->offset: %u, size: %d\n",
|
||||
- rx->offset, rx->status);
|
||||
+ rx.offset, rx.status);
|
||||
xennet_move_rx_slot(queue, skb, ref);
|
||||
err = -EINVAL;
|
||||
goto next;
|
||||
@@ -817,7 +816,7 @@ static int xennet_get_responses(struct netfront_queue *queue,
|
||||
if (ref == GRANT_INVALID_REF) {
|
||||
if (net_ratelimit())
|
||||
dev_warn(dev, "Bad rx response id %d.\n",
|
||||
- rx->id);
|
||||
+ rx.id);
|
||||
err = -EINVAL;
|
||||
goto next;
|
||||
}
|
||||
@@ -830,7 +829,7 @@ static int xennet_get_responses(struct netfront_queue *queue,
|
||||
__skb_queue_tail(list, skb);
|
||||
|
||||
next:
|
||||
- if (!(rx->flags & XEN_NETRXF_more_data))
|
||||
+ if (!(rx.flags & XEN_NETRXF_more_data))
|
||||
break;
|
||||
|
||||
if (cons + slots == rp) {
|
||||
@@ -840,7 +839,7 @@ static int xennet_get_responses(struct netfront_queue *queue,
|
||||
break;
|
||||
}
|
||||
|
||||
- rx = RING_GET_RESPONSE(&queue->rx, cons + slots);
|
||||
+ RING_COPY_RESPONSE(&queue->rx, cons + slots, &rx);
|
||||
skb = xennet_get_rx_skb(queue, cons + slots);
|
||||
ref = xennet_get_rx_ref(queue, cons + slots);
|
||||
slots++;
|
||||
@@ -895,9 +894,9 @@ static int xennet_fill_frags(struct netfront_queue *queue,
|
||||
struct sk_buff *nskb;
|
||||
|
||||
while ((nskb = __skb_dequeue(list))) {
|
||||
- struct xen_netif_rx_response *rx =
|
||||
- RING_GET_RESPONSE(&queue->rx, ++cons);
|
||||
+ struct xen_netif_rx_response rx;
|
||||
skb_frag_t *nfrag = &skb_shinfo(nskb)->frags[0];
|
||||
+ RING_COPY_RESPONSE(&queue->rx, ++cons, &rx);
|
||||
|
||||
if (skb_shinfo(skb)->nr_frags == MAX_SKB_FRAGS) {
|
||||
unsigned int pull_to = NETFRONT_SKB_CB(skb)->pull_to;
|
||||
@@ -913,7 +912,7 @@ static int xennet_fill_frags(struct netfront_queue *queue,
|
||||
|
||||
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
|
||||
skb_frag_page(nfrag),
|
||||
- rx->offset, rx->status, PAGE_SIZE);
|
||||
+ rx.offset, rx.status, PAGE_SIZE);
|
||||
|
||||
skb_shinfo(nskb)->nr_frags = 0;
|
||||
kfree_skb(nskb);
|
||||
@@ -1011,7 +1010,7 @@ static int xennet_poll(struct napi_struct *napi, int budget)
|
||||
i = queue->rx.rsp_cons;
|
||||
work_done = 0;
|
||||
while ((i != rp) && (work_done < budget)) {
|
||||
- memcpy(rx, RING_GET_RESPONSE(&queue->rx, i), sizeof(*rx));
|
||||
+ RING_COPY_RESPONSE(&queue->rx, i, rx);
|
||||
memset(extras, 0, sizeof(rinfo.extras));
|
||||
|
||||
err = xennet_get_responses(queue, &rinfo, rp, &tmpq);
|
||||
--
|
||||
2.21.0
|
||||
|
@ -0,0 +1,64 @@
|
||||
From f2452d28602c2de1d69d5ca2e34e6771374414a1 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
|
||||
<marmarek@invisiblethingslab.com>
|
||||
Date: Wed, 16 Dec 2015 05:19:37 +0100
|
||||
Subject: [PATCH] xen-netfront: do not use data already exposed to backend
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Backend may freely modify anything on shared page, so use data which was
|
||||
supposed to be written there, instead of reading it back from the shared
|
||||
page.
|
||||
|
||||
This is part of XSA155.
|
||||
|
||||
CC: stable@vger.kernel.org
|
||||
Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
|
||||
---
|
||||
drivers/net/xen-netfront.c | 9 +++++----
|
||||
1 file changed, 5 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
|
||||
index abb9b3cd87b8..56c8a4a32672 100644
|
||||
--- a/drivers/net/xen-netfront.c
|
||||
+++ b/drivers/net/xen-netfront.c
|
||||
@@ -456,7 +456,7 @@ static void xennet_tx_setup_grant(unsigned long gfn, unsigned int offset,
|
||||
tx->flags = 0;
|
||||
|
||||
info->tx = tx;
|
||||
- info->size += tx->size;
|
||||
+ info->size += len;
|
||||
}
|
||||
|
||||
static struct xen_netif_tx_request *xennet_make_first_txreq(
|
||||
@@ -572,7 +572,7 @@ static netdev_tx_t xennet_start_xmit(struct sk_buff *skb, struct net_device *dev
|
||||
int slots;
|
||||
struct page *page;
|
||||
unsigned int offset;
|
||||
- unsigned int len;
|
||||
+ unsigned int len, this_len;
|
||||
unsigned long flags;
|
||||
struct netfront_queue *queue = NULL;
|
||||
unsigned int num_queues = dev->real_num_tx_queues;
|
||||
@@ -632,14 +632,15 @@ static netdev_tx_t xennet_start_xmit(struct sk_buff *skb, struct net_device *dev
|
||||
}
|
||||
|
||||
/* First request for the linear area. */
|
||||
+ this_len = min_t(unsigned int, XEN_PAGE_SIZE - offset, len);
|
||||
first_tx = tx = xennet_make_first_txreq(queue, skb,
|
||||
page, offset, len);
|
||||
- offset += tx->size;
|
||||
+ offset += this_len;
|
||||
if (offset == PAGE_SIZE) {
|
||||
page++;
|
||||
offset = 0;
|
||||
}
|
||||
- len -= tx->size;
|
||||
+ len -= this_len;
|
||||
|
||||
if (skb->ip_summed == CHECKSUM_PARTIAL)
|
||||
/* local packet? */
|
||||
--
|
||||
2.21.0
|
||||
|
35
0010-xen-netfront-add-range-check-for-Tx-response-id.patch
Normal file
35
0010-xen-netfront-add-range-check-for-Tx-response-id.patch
Normal file
@ -0,0 +1,35 @@
|
||||
From b5bc80763b7bf0f9e32a9a4d4f930ff50d02385d Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
|
||||
<marmarek@invisiblethingslab.com>
|
||||
Date: Wed, 16 Dec 2015 05:22:24 +0100
|
||||
Subject: [PATCH] xen-netfront: add range check for Tx response id
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Tx response ID is fetched from shared page, so make sure it is sane
|
||||
before using it as an array index.
|
||||
|
||||
This is part of XSA155.
|
||||
|
||||
CC: stable@vger.kernel.org
|
||||
Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
|
||||
---
|
||||
drivers/net/xen-netfront.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
|
||||
index 56c8a4a32672..e11df925c0dc 100644
|
||||
--- a/drivers/net/xen-netfront.c
|
||||
+++ b/drivers/net/xen-netfront.c
|
||||
@@ -392,6 +392,7 @@ static void xennet_tx_buf_gc(struct netfront_queue *queue)
|
||||
continue;
|
||||
|
||||
id = txrsp.id;
|
||||
+ BUG_ON(id >= NET_TX_RING_SIZE);
|
||||
skb = queue->tx_skbs[id].skb;
|
||||
if (unlikely(gnttab_query_foreign_access(
|
||||
queue->grant_tx_ref[id]) != 0)) {
|
||||
--
|
||||
2.21.0
|
||||
|
128
0011-xen-blkfront-make-local-copy-of-response-before-usin.patch
Normal file
128
0011-xen-blkfront-make-local-copy-of-response-before-usin.patch
Normal file
@ -0,0 +1,128 @@
|
||||
From def16082c5e64f97d5d138ae638a6cde7a136432 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
|
||||
<marmarek@invisiblethingslab.com>
|
||||
Date: Wed, 16 Dec 2015 05:51:10 +0100
|
||||
Subject: [PATCH] xen-blkfront: make local copy of response before using it
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Data on the shared page can be changed at any time by the backend. Make
|
||||
a local copy, which is no longer controlled by the backend. And only
|
||||
then access it.
|
||||
|
||||
This is part of XSA155.
|
||||
|
||||
CC: stable@vger.kernel.org
|
||||
Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
|
||||
---
|
||||
drivers/block/xen-blkfront.c | 34 +++++++++++++++++-----------------
|
||||
1 file changed, 17 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
|
||||
index db7d28ac9747..3f6dbaf0265b 100644
|
||||
--- a/drivers/block/xen-blkfront.c
|
||||
+++ b/drivers/block/xen-blkfront.c
|
||||
@@ -1551,7 +1551,7 @@ static bool blkif_completion(unsigned long *id,
|
||||
static irqreturn_t blkif_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct request *req;
|
||||
- struct blkif_response *bret;
|
||||
+ struct blkif_response bret;
|
||||
RING_IDX i, rp;
|
||||
unsigned long flags;
|
||||
struct blkfront_ring_info *rinfo = (struct blkfront_ring_info *)dev_id;
|
||||
@@ -1568,8 +1568,8 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
|
||||
for (i = rinfo->ring.rsp_cons; i != rp; i++) {
|
||||
unsigned long id;
|
||||
|
||||
- bret = RING_GET_RESPONSE(&rinfo->ring, i);
|
||||
- id = bret->id;
|
||||
+ RING_COPY_RESPONSE(&rinfo->ring, i, &bret);
|
||||
+ id = bret.id;
|
||||
/*
|
||||
* The backend has messed up and given us an id that we would
|
||||
* never have given to it (we stamp it up to BLK_RING_SIZE -
|
||||
@@ -1577,39 +1577,39 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
|
||||
*/
|
||||
if (id >= BLK_RING_SIZE(info)) {
|
||||
WARN(1, "%s: response to %s has incorrect id (%ld)\n",
|
||||
- info->gd->disk_name, op_name(bret->operation), id);
|
||||
+ info->gd->disk_name, op_name(bret.operation), id);
|
||||
/* We can't safely get the 'struct request' as
|
||||
* the id is busted. */
|
||||
continue;
|
||||
}
|
||||
req = rinfo->shadow[id].request;
|
||||
|
||||
- if (bret->operation != BLKIF_OP_DISCARD) {
|
||||
+ if (bret.operation != BLKIF_OP_DISCARD) {
|
||||
/*
|
||||
* We may need to wait for an extra response if the
|
||||
* I/O request is split in 2
|
||||
*/
|
||||
- if (!blkif_completion(&id, rinfo, bret))
|
||||
+ if (!blkif_completion(&id, rinfo, &bret))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (add_id_to_freelist(rinfo, id)) {
|
||||
WARN(1, "%s: response to %s (id %ld) couldn't be recycled!\n",
|
||||
- info->gd->disk_name, op_name(bret->operation), id);
|
||||
+ info->gd->disk_name, op_name(bret.operation), id);
|
||||
continue;
|
||||
}
|
||||
|
||||
- if (bret->status == BLKIF_RSP_OKAY)
|
||||
+ if (bret.status == BLKIF_RSP_OKAY)
|
||||
blkif_req(req)->error = BLK_STS_OK;
|
||||
else
|
||||
blkif_req(req)->error = BLK_STS_IOERR;
|
||||
|
||||
- switch (bret->operation) {
|
||||
+ switch (bret.operation) {
|
||||
case BLKIF_OP_DISCARD:
|
||||
- if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) {
|
||||
+ if (unlikely(bret.status == BLKIF_RSP_EOPNOTSUPP)) {
|
||||
struct request_queue *rq = info->rq;
|
||||
printk(KERN_WARNING "blkfront: %s: %s op failed\n",
|
||||
- info->gd->disk_name, op_name(bret->operation));
|
||||
+ info->gd->disk_name, op_name(bret.operation));
|
||||
blkif_req(req)->error = BLK_STS_NOTSUPP;
|
||||
info->feature_discard = 0;
|
||||
info->feature_secdiscard = 0;
|
||||
@@ -1619,15 +1619,15 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
|
||||
break;
|
||||
case BLKIF_OP_FLUSH_DISKCACHE:
|
||||
case BLKIF_OP_WRITE_BARRIER:
|
||||
- if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) {
|
||||
+ if (unlikely(bret.status == BLKIF_RSP_EOPNOTSUPP)) {
|
||||
printk(KERN_WARNING "blkfront: %s: %s op failed\n",
|
||||
- info->gd->disk_name, op_name(bret->operation));
|
||||
+ info->gd->disk_name, op_name(bret.operation));
|
||||
blkif_req(req)->error = BLK_STS_NOTSUPP;
|
||||
}
|
||||
- if (unlikely(bret->status == BLKIF_RSP_ERROR &&
|
||||
+ if (unlikely(bret.status == BLKIF_RSP_ERROR &&
|
||||
rinfo->shadow[id].req.u.rw.nr_segments == 0)) {
|
||||
printk(KERN_WARNING "blkfront: %s: empty %s op failed\n",
|
||||
- info->gd->disk_name, op_name(bret->operation));
|
||||
+ info->gd->disk_name, op_name(bret.operation));
|
||||
blkif_req(req)->error = BLK_STS_NOTSUPP;
|
||||
}
|
||||
if (unlikely(blkif_req(req)->error)) {
|
||||
@@ -1640,9 +1640,9 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
|
||||
/* fall through */
|
||||
case BLKIF_OP_READ:
|
||||
case BLKIF_OP_WRITE:
|
||||
- if (unlikely(bret->status != BLKIF_RSP_OKAY))
|
||||
+ if (unlikely(bret.status != BLKIF_RSP_OKAY))
|
||||
dev_dbg(&info->xbdev->dev, "Bad return from blkdev data "
|
||||
- "request: %x\n", bret->status);
|
||||
+ "request: %x\n", bret.status);
|
||||
|
||||
break;
|
||||
default:
|
||||
--
|
||||
2.21.0
|
||||
|
191
0012-xen-blkfront-prepare-request-locally-only-then-put-i.patch
Normal file
191
0012-xen-blkfront-prepare-request-locally-only-then-put-i.patch
Normal file
@ -0,0 +1,191 @@
|
||||
From 115094605c08f2e2790f6110f7fdc002122e0788 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?=
|
||||
<marmarek@invisiblethingslab.com>
|
||||
Date: Wed, 16 Dec 2015 06:07:14 +0100
|
||||
Subject: [PATCH] xen-blkfront: prepare request locally, only then put it on
|
||||
the shared ring
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Do not reuse data which theoretically might be already modified by the
|
||||
backend. This is mostly about private copy of the request
|
||||
(info->shadow[id].req) - make sure the request saved there is really the
|
||||
one just filled.
|
||||
|
||||
This is part of XSA155.
|
||||
|
||||
CC: stable@vger.kernel.org
|
||||
Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
|
||||
---
|
||||
drivers/block/xen-blkfront.c | 76 +++++++++++++++++++++---------------
|
||||
1 file changed, 44 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
|
||||
index 3f6dbaf0265b..37235ab63ca9 100644
|
||||
--- a/drivers/block/xen-blkfront.c
|
||||
+++ b/drivers/block/xen-blkfront.c
|
||||
@@ -527,19 +527,16 @@ static int blkif_ioctl(struct block_device *bdev, fmode_t mode,
|
||||
|
||||
static unsigned long blkif_ring_get_request(struct blkfront_ring_info *rinfo,
|
||||
struct request *req,
|
||||
- struct blkif_request **ring_req)
|
||||
+ struct blkif_request *ring_req)
|
||||
{
|
||||
unsigned long id;
|
||||
|
||||
- *ring_req = RING_GET_REQUEST(&rinfo->ring, rinfo->ring.req_prod_pvt);
|
||||
- rinfo->ring.req_prod_pvt++;
|
||||
-
|
||||
id = get_id_from_freelist(rinfo);
|
||||
rinfo->shadow[id].request = req;
|
||||
rinfo->shadow[id].status = REQ_WAITING;
|
||||
rinfo->shadow[id].associated_id = NO_ASSOCIATED_ID;
|
||||
|
||||
- (*ring_req)->u.rw.id = id;
|
||||
+ ring_req->u.rw.id = id;
|
||||
|
||||
return id;
|
||||
}
|
||||
@@ -547,23 +544,28 @@ static unsigned long blkif_ring_get_request(struct blkfront_ring_info *rinfo,
|
||||
static int blkif_queue_discard_req(struct request *req, struct blkfront_ring_info *rinfo)
|
||||
{
|
||||
struct blkfront_info *info = rinfo->dev_info;
|
||||
- struct blkif_request *ring_req;
|
||||
+ struct blkif_request ring_req = { 0 };
|
||||
unsigned long id;
|
||||
|
||||
/* Fill out a communications ring structure. */
|
||||
id = blkif_ring_get_request(rinfo, req, &ring_req);
|
||||
|
||||
- ring_req->operation = BLKIF_OP_DISCARD;
|
||||
- ring_req->u.discard.nr_sectors = blk_rq_sectors(req);
|
||||
- ring_req->u.discard.id = id;
|
||||
- ring_req->u.discard.sector_number = (blkif_sector_t)blk_rq_pos(req);
|
||||
+ ring_req.operation = BLKIF_OP_DISCARD;
|
||||
+ ring_req.u.discard.nr_sectors = blk_rq_sectors(req);
|
||||
+ ring_req.u.discard.id = id;
|
||||
+ ring_req.u.discard.sector_number = (blkif_sector_t)blk_rq_pos(req);
|
||||
if (req_op(req) == REQ_OP_SECURE_ERASE && info->feature_secdiscard)
|
||||
- ring_req->u.discard.flag = BLKIF_DISCARD_SECURE;
|
||||
+ ring_req.u.discard.flag = BLKIF_DISCARD_SECURE;
|
||||
else
|
||||
- ring_req->u.discard.flag = 0;
|
||||
+ ring_req.u.discard.flag = 0;
|
||||
+
|
||||
+ /* make the request available to the backend */
|
||||
+ *RING_GET_REQUEST(&rinfo->ring, rinfo->ring.req_prod_pvt) = ring_req;
|
||||
+ wmb();
|
||||
+ rinfo->ring.req_prod_pvt++;
|
||||
|
||||
/* Keep a private copy so we can reissue requests when recovering. */
|
||||
- rinfo->shadow[id].req = *ring_req;
|
||||
+ rinfo->shadow[id].req = ring_req;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -695,7 +697,7 @@ static void blkif_setup_extra_req(struct blkif_request *first,
|
||||
static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *rinfo)
|
||||
{
|
||||
struct blkfront_info *info = rinfo->dev_info;
|
||||
- struct blkif_request *ring_req, *extra_ring_req = NULL;
|
||||
+ struct blkif_request ring_req = { 0 }, extra_ring_req = { 0 };
|
||||
unsigned long id, extra_id = NO_ASSOCIATED_ID;
|
||||
bool require_extra_req = false;
|
||||
int i;
|
||||
@@ -760,16 +762,16 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
|
||||
* BLKIF_OP_WRITE
|
||||
*/
|
||||
BUG_ON(req_op(req) == REQ_OP_FLUSH || req->cmd_flags & REQ_FUA);
|
||||
- ring_req->operation = BLKIF_OP_INDIRECT;
|
||||
- ring_req->u.indirect.indirect_op = rq_data_dir(req) ?
|
||||
+ ring_req.operation = BLKIF_OP_INDIRECT;
|
||||
+ ring_req.u.indirect.indirect_op = rq_data_dir(req) ?
|
||||
BLKIF_OP_WRITE : BLKIF_OP_READ;
|
||||
- ring_req->u.indirect.sector_number = (blkif_sector_t)blk_rq_pos(req);
|
||||
- ring_req->u.indirect.handle = info->handle;
|
||||
- ring_req->u.indirect.nr_segments = num_grant;
|
||||
+ ring_req.u.indirect.sector_number = (blkif_sector_t)blk_rq_pos(req);
|
||||
+ ring_req.u.indirect.handle = info->handle;
|
||||
+ ring_req.u.indirect.nr_segments = num_grant;
|
||||
} else {
|
||||
- ring_req->u.rw.sector_number = (blkif_sector_t)blk_rq_pos(req);
|
||||
- ring_req->u.rw.handle = info->handle;
|
||||
- ring_req->operation = rq_data_dir(req) ?
|
||||
+ ring_req.u.rw.sector_number = (blkif_sector_t)blk_rq_pos(req);
|
||||
+ ring_req.u.rw.handle = info->handle;
|
||||
+ ring_req.operation = rq_data_dir(req) ?
|
||||
BLKIF_OP_WRITE : BLKIF_OP_READ;
|
||||
if (req_op(req) == REQ_OP_FLUSH || req->cmd_flags & REQ_FUA) {
|
||||
/*
|
||||
@@ -780,15 +782,15 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
|
||||
* since it is guaranteed ordered WRT previous writes.)
|
||||
*/
|
||||
if (info->feature_flush && info->feature_fua)
|
||||
- ring_req->operation =
|
||||
+ ring_req.operation =
|
||||
BLKIF_OP_WRITE_BARRIER;
|
||||
else if (info->feature_flush)
|
||||
- ring_req->operation =
|
||||
+ ring_req.operation =
|
||||
BLKIF_OP_FLUSH_DISKCACHE;
|
||||
else
|
||||
- ring_req->operation = 0;
|
||||
+ ring_req.operation = 0;
|
||||
}
|
||||
- ring_req->u.rw.nr_segments = num_grant;
|
||||
+ ring_req.u.rw.nr_segments = num_grant;
|
||||
if (unlikely(require_extra_req)) {
|
||||
extra_id = blkif_ring_get_request(rinfo, req,
|
||||
&extra_ring_req);
|
||||
@@ -798,7 +800,7 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
|
||||
*/
|
||||
rinfo->shadow[extra_id].num_sg = 0;
|
||||
|
||||
- blkif_setup_extra_req(ring_req, extra_ring_req);
|
||||
+ blkif_setup_extra_req(&ring_req, &extra_ring_req);
|
||||
|
||||
/* Link the 2 requests together */
|
||||
rinfo->shadow[extra_id].associated_id = id;
|
||||
@@ -806,12 +808,12 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
|
||||
}
|
||||
}
|
||||
|
||||
- setup.ring_req = ring_req;
|
||||
+ setup.ring_req = &ring_req;
|
||||
setup.id = id;
|
||||
|
||||
setup.require_extra_req = require_extra_req;
|
||||
if (unlikely(require_extra_req))
|
||||
- setup.extra_ring_req = extra_ring_req;
|
||||
+ setup.extra_ring_req = &extra_ring_req;
|
||||
|
||||
for_each_sg(rinfo->shadow[id].sg, sg, num_sg, i) {
|
||||
BUG_ON(sg->offset + sg->length > PAGE_SIZE);
|
||||
@@ -833,10 +835,20 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
|
||||
if (setup.segments)
|
||||
kunmap_atomic(setup.segments);
|
||||
|
||||
+ /* make the request available to the backend */
|
||||
+ *RING_GET_REQUEST(&rinfo->ring, rinfo->ring.req_prod_pvt) = ring_req;
|
||||
+ wmb();
|
||||
+ rinfo->ring.req_prod_pvt++;
|
||||
/* Keep a private copy so we can reissue requests when recovering. */
|
||||
- rinfo->shadow[id].req = *ring_req;
|
||||
- if (unlikely(require_extra_req))
|
||||
- rinfo->shadow[extra_id].req = *extra_ring_req;
|
||||
+ rinfo->shadow[id].req = ring_req;
|
||||
+
|
||||
+ if (unlikely(require_extra_req)) {
|
||||
+ *RING_GET_REQUEST(&rinfo->ring, rinfo->ring.req_prod_pvt) = extra_ring_req;
|
||||
+ wmb();
|
||||
+ rinfo->ring.req_prod_pvt++;
|
||||
+ /* Keep a private copy so we can reissue requests when recovering. */
|
||||
+ rinfo->shadow[extra_id].req = extra_ring_req;
|
||||
+ }
|
||||
|
||||
if (new_persistent_gnts)
|
||||
gnttab_free_grant_references(setup.gref_head);
|
||||
--
|
||||
2.21.0
|
||||
|
@ -0,0 +1,75 @@
|
||||
From 6a9f5a2435d3845b41f32b3768bb1c25bba1be2d Mon Sep 17 00:00:00 2001
|
||||
From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||
Date: Wed, 1 Apr 2015 17:01:26 -0400
|
||||
Subject: [PATCH] xen/pcifront/pciback: Update pciif.h with ->err and ->result
|
||||
values.
|
||||
|
||||
The '->err' should contain only the XEN_PCI_ERR_* type values.
|
||||
The '->result' may contain -EXX values or any other value
|
||||
that the XEN_PCI_OP_* deems appropiate.
|
||||
|
||||
As such update the header and also the implementations.
|
||||
|
||||
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||
|
||||
Details in this thread:
|
||||
https://patchwork.kernel.org/patch/8258431/
|
||||
---
|
||||
drivers/pci/xen-pcifront.c | 2 +-
|
||||
drivers/xen/xen-pciback/pciback_ops.c | 2 +-
|
||||
include/xen/interface/io/pciif.h | 6 ++++--
|
||||
3 files changed, 6 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c
|
||||
index d1b16cf3403f..4d6f2513b104 100644
|
||||
--- a/drivers/pci/xen-pcifront.c
|
||||
+++ b/drivers/pci/xen-pcifront.c
|
||||
@@ -297,7 +297,7 @@ static int pci_frontend_enable_msix(struct pci_dev *dev,
|
||||
} else {
|
||||
pci_err(dev, "enable msix get err %x\n", err);
|
||||
}
|
||||
- return err;
|
||||
+ return err ? -EINVAL : 0;
|
||||
}
|
||||
|
||||
static void pci_frontend_disable_msix(struct pci_dev *dev)
|
||||
diff --git a/drivers/xen/xen-pciback/pciback_ops.c b/drivers/xen/xen-pciback/pciback_ops.c
|
||||
index 787966f44589..0574c9121124 100644
|
||||
--- a/drivers/xen/xen-pciback/pciback_ops.c
|
||||
+++ b/drivers/xen/xen-pciback/pciback_ops.c
|
||||
@@ -266,7 +266,7 @@ int xen_pcibk_enable_msix(struct xen_pcibk_device *pdev,
|
||||
if (dev_data)
|
||||
dev_data->ack_intr = 0;
|
||||
|
||||
- return result > 0 ? 0 : result;
|
||||
+ return result >= 0 ? 0 : XEN_PCI_ERR_op_failed;
|
||||
}
|
||||
|
||||
static
|
||||
diff --git a/include/xen/interface/io/pciif.h b/include/xen/interface/io/pciif.h
|
||||
index d9922ae36eb5..c8b674fd2455 100644
|
||||
--- a/include/xen/interface/io/pciif.h
|
||||
+++ b/include/xen/interface/io/pciif.h
|
||||
@@ -70,7 +70,7 @@ struct xen_pci_op {
|
||||
/* IN: what action to perform: XEN_PCI_OP_* */
|
||||
uint32_t cmd;
|
||||
|
||||
- /* OUT: will contain an error number (if any) from errno.h */
|
||||
+ /* OUT: will contain an XEN_PCI_ERR_* number. */
|
||||
int32_t err;
|
||||
|
||||
/* IN: which device to touch */
|
||||
@@ -82,7 +82,9 @@ struct xen_pci_op {
|
||||
int32_t offset;
|
||||
int32_t size;
|
||||
|
||||
- /* IN/OUT: Contains the result after a READ or the value to WRITE */
|
||||
+ /* IN/OUT: Contains the result after a READ or the value to WRITE.
|
||||
+ * If the err does not have XEN_PCI_ERR_success, depending on
|
||||
+ * XEN_PCI_OP_* might have the errno value. */
|
||||
uint32_t value;
|
||||
/* IN: Contains extra infor for this operation */
|
||||
uint32_t info;
|
||||
--
|
||||
2.21.0
|
||||
|
194
0014-xen-pciback-add-attribute-to-allow-MSI-enable-flag-w.patch
Normal file
194
0014-xen-pciback-add-attribute-to-allow-MSI-enable-flag-w.patch
Normal file
@ -0,0 +1,194 @@
|
||||
From 3a7edaa90f1b3d7066ba9c227577039e4285cb3d Mon Sep 17 00:00:00 2001
|
||||
From: HW42 <hw42@ipsumj.de>
|
||||
Date: Tue, 12 Sep 2017 00:49:02 +0200
|
||||
Subject: [PATCH] xen-pciback: add attribute to allow MSI enable flag writes
|
||||
|
||||
QEMU running in a stubdom needs to be able to set the MSI enable flag in
|
||||
the PCI config space. This adds an attribute 'allow_msi_enable' which
|
||||
when set for a PCI device allows writes to this flag. The toolstack will
|
||||
need to set this for stubdoms.
|
||||
|
||||
This should not introduce any new security issues since a malicious
|
||||
guest (or stubdom) can already generate MSIs through other ways, see
|
||||
[1] page 8.
|
||||
|
||||
[1]: https://invisiblethingslab.com/resources/2011/Software%20Attacks%20on%20Intel%20VT-d.pdf
|
||||
---
|
||||
.../xen/xen-pciback/conf_space_capability.c | 39 +++++++++++
|
||||
drivers/xen/xen-pciback/pci_stub.c | 64 +++++++++++++++++++
|
||||
drivers/xen/xen-pciback/pciback.h | 1 +
|
||||
3 files changed, 104 insertions(+)
|
||||
|
||||
diff --git a/drivers/xen/xen-pciback/conf_space_capability.c b/drivers/xen/xen-pciback/conf_space_capability.c
|
||||
index e5694133ebe5..4be817f448c3 100644
|
||||
--- a/drivers/xen/xen-pciback/conf_space_capability.c
|
||||
+++ b/drivers/xen/xen-pciback/conf_space_capability.c
|
||||
@@ -189,6 +189,40 @@ static const struct config_field caplist_pm[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
+#define MSI_OK_BITS (PCI_MSI_FLAGS_ENABLE)
|
||||
+
|
||||
+static int msi_flags_write(struct pci_dev *dev, int offset, u16 new_value,
|
||||
+ void *data)
|
||||
+{
|
||||
+ int err;
|
||||
+ u16 old_value;
|
||||
+ struct xen_pcibk_dev_data *dev_data = pci_get_drvdata(dev);
|
||||
+
|
||||
+ if (xen_pcibk_permissive || dev_data->permissive)
|
||||
+ goto write;
|
||||
+
|
||||
+ err = pci_read_config_word(dev, offset, &old_value);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ if (!dev_data->allow_msi_enable
|
||||
+ || (new_value ^ old_value) & ~MSI_OK_BITS)
|
||||
+ return PCIBIOS_SET_FAILED;
|
||||
+
|
||||
+write:
|
||||
+ return pci_write_config_word(dev, offset, new_value);
|
||||
+}
|
||||
+
|
||||
+static const struct config_field caplist_msi[] = {
|
||||
+ {
|
||||
+ .offset = PCI_MSI_FLAGS,
|
||||
+ .size = 2,
|
||||
+ .u.w.read = xen_pcibk_read_config_word,
|
||||
+ .u.w.write = msi_flags_write,
|
||||
+ },
|
||||
+ {}
|
||||
+};
|
||||
+
|
||||
static struct xen_pcibk_config_capability xen_pcibk_config_capability_pm = {
|
||||
.capability = PCI_CAP_ID_PM,
|
||||
.fields = caplist_pm,
|
||||
@@ -197,11 +231,16 @@ static struct xen_pcibk_config_capability xen_pcibk_config_capability_vpd = {
|
||||
.capability = PCI_CAP_ID_VPD,
|
||||
.fields = caplist_vpd,
|
||||
};
|
||||
+static struct xen_pcibk_config_capability xen_pcibk_config_capability_msi = {
|
||||
+ .capability = PCI_CAP_ID_MSI,
|
||||
+ .fields = caplist_msi,
|
||||
+};
|
||||
|
||||
int xen_pcibk_config_capability_init(void)
|
||||
{
|
||||
register_capability(&xen_pcibk_config_capability_vpd);
|
||||
register_capability(&xen_pcibk_config_capability_pm);
|
||||
+ register_capability(&xen_pcibk_config_capability_msi);
|
||||
|
||||
return 0;
|
||||
}
|
||||
diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c
|
||||
index 097410a7cdb7..fb6a4a43c11d 100644
|
||||
--- a/drivers/xen/xen-pciback/pci_stub.c
|
||||
+++ b/drivers/xen/xen-pciback/pci_stub.c
|
||||
@@ -304,6 +304,8 @@ void pcistub_put_pci_dev(struct pci_dev *dev)
|
||||
xen_pcibk_config_reset_dev(dev);
|
||||
xen_pcibk_config_free_dyn_fields(dev);
|
||||
|
||||
+ dev_data->allow_msi_enable = 0;
|
||||
+
|
||||
xen_unregister_device_domain_owner(dev);
|
||||
|
||||
spin_lock_irqsave(&found_psdev->lock, flags);
|
||||
@@ -1431,6 +1433,63 @@ static ssize_t permissive_show(struct device_driver *drv, char *buf)
|
||||
}
|
||||
static DRIVER_ATTR_RW(permissive);
|
||||
|
||||
+static ssize_t allow_msi_enable_store(struct device_driver *drv, const char *buf,
|
||||
+ size_t count)
|
||||
+{
|
||||
+ int domain, bus, slot, func;
|
||||
+ int err;
|
||||
+ struct pcistub_device *psdev;
|
||||
+ struct xen_pcibk_dev_data *dev_data;
|
||||
+
|
||||
+ err = str_to_slot(buf, &domain, &bus, &slot, &func);
|
||||
+ if (err)
|
||||
+ goto out;
|
||||
+
|
||||
+ psdev = pcistub_device_find(domain, bus, slot, func);
|
||||
+ if (!psdev) {
|
||||
+ err = -ENODEV;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ dev_data = pci_get_drvdata(psdev->dev);
|
||||
+ /* the driver data for a device should never be null at this point */
|
||||
+ if (!dev_data) {
|
||||
+ err = -ENXIO;
|
||||
+ goto release;
|
||||
+ }
|
||||
+ dev_data->allow_msi_enable = 1;
|
||||
+release:
|
||||
+ pcistub_device_put(psdev);
|
||||
+out:
|
||||
+ if (!err)
|
||||
+ err = count;
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static ssize_t allow_msi_enable_show(struct device_driver *drv, char *buf)
|
||||
+{
|
||||
+ struct pcistub_device *psdev;
|
||||
+ struct xen_pcibk_dev_data *dev_data;
|
||||
+ size_t count = 0;
|
||||
+ unsigned long flags;
|
||||
+ spin_lock_irqsave(&pcistub_devices_lock, flags);
|
||||
+ list_for_each_entry(psdev, &pcistub_devices, dev_list) {
|
||||
+ if (count >= PAGE_SIZE)
|
||||
+ break;
|
||||
+ if (!psdev->dev)
|
||||
+ continue;
|
||||
+ dev_data = pci_get_drvdata(psdev->dev);
|
||||
+ if (!dev_data || !dev_data->allow_msi_enable)
|
||||
+ continue;
|
||||
+ count +=
|
||||
+ scnprintf(buf + count, PAGE_SIZE - count, "%s\n",
|
||||
+ pci_name(psdev->dev));
|
||||
+ }
|
||||
+ spin_unlock_irqrestore(&pcistub_devices_lock, flags);
|
||||
+ return count;
|
||||
+}
|
||||
+static DRIVER_ATTR_RW(allow_msi_enable);
|
||||
+
|
||||
static void pcistub_exit(void)
|
||||
{
|
||||
driver_remove_file(&xen_pcibk_pci_driver.driver, &driver_attr_new_slot);
|
||||
@@ -1440,6 +1499,8 @@ static void pcistub_exit(void)
|
||||
driver_remove_file(&xen_pcibk_pci_driver.driver, &driver_attr_quirks);
|
||||
driver_remove_file(&xen_pcibk_pci_driver.driver,
|
||||
&driver_attr_permissive);
|
||||
+ driver_remove_file(&xen_pcibk_pci_driver.driver,
|
||||
+ &driver_attr_allow_msi_enable);
|
||||
driver_remove_file(&xen_pcibk_pci_driver.driver,
|
||||
&driver_attr_irq_handlers);
|
||||
driver_remove_file(&xen_pcibk_pci_driver.driver,
|
||||
@@ -1530,6 +1591,9 @@ static int __init pcistub_init(void)
|
||||
if (!err)
|
||||
err = driver_create_file(&xen_pcibk_pci_driver.driver,
|
||||
&driver_attr_permissive);
|
||||
+ if (!err)
|
||||
+ err = driver_create_file(&xen_pcibk_pci_driver.driver,
|
||||
+ &driver_attr_allow_msi_enable);
|
||||
|
||||
if (!err)
|
||||
err = driver_create_file(&xen_pcibk_pci_driver.driver,
|
||||
diff --git a/drivers/xen/xen-pciback/pciback.h b/drivers/xen/xen-pciback/pciback.h
|
||||
index 263c059bff90..796f949c92be 100644
|
||||
--- a/drivers/xen/xen-pciback/pciback.h
|
||||
+++ b/drivers/xen/xen-pciback/pciback.h
|
||||
@@ -45,6 +45,7 @@ struct xen_pcibk_dev_data {
|
||||
struct list_head config_fields;
|
||||
struct pci_saved_state *pci_saved_state;
|
||||
unsigned int permissive:1;
|
||||
+ unsigned int allow_msi_enable:1;
|
||||
unsigned int warned_on_write:1;
|
||||
unsigned int enable_intx:1;
|
||||
unsigned int isr_on:1; /* Whether the IRQ handler is installed. */
|
||||
--
|
||||
2.21.0
|
||||
|
138
Makefile
138
Makefile
@ -11,71 +11,110 @@ SOURCEDIR := $(WORKDIR)
|
||||
|
||||
NO_OF_CPUS := $(shell grep -c ^processor /proc/cpuinfo)
|
||||
|
||||
ifndef BUILD_FLAVOR
|
||||
$(error "Add BUILD_FLAVOR=pvops or BUILD_FLAVOR=xenlinux to make cmdline")
|
||||
endif
|
||||
|
||||
RPM_DEFINES := --define "_sourcedir $(SOURCEDIR)" \
|
||||
--define "_specdir $(SPECDIR)" \
|
||||
--define "_builddir $(BUILDDIR)" \
|
||||
--define "_srcrpmdir $(SRCRPMDIR)" \
|
||||
--define "_rpmdir $(RPMDIR)" \
|
||||
--define "build_flavor $(BUILD_FLAVOR)" \
|
||||
--define "jobs $(NO_OF_CPUS)"
|
||||
|
||||
VER_REL := $(shell rpm $(RPM_DEFINES) -q --qf "%{VERSION} %{RELEASE}\n" --specfile $(SPECFILE)| head -1)
|
||||
--define "_rpmdir $(RPMDIR)"
|
||||
|
||||
ifndef NAME
|
||||
$(error "You can not run this Makefile without having NAME defined")
|
||||
endif
|
||||
ifndef VERSION
|
||||
VERSION := $(word 1, $(VER_REL))
|
||||
VERSION := $(shell cat version)
|
||||
endif
|
||||
ifndef RELEASE
|
||||
RELEASE := $(word 2, $(VER_REL))
|
||||
RELEASE := $(shell cat rel)
|
||||
endif
|
||||
|
||||
ifneq ($(VERSION),$(subst -rc,,$(VERSION)))
|
||||
DOWNLOAD_FROM_GIT=1
|
||||
VERIFICATION := hash
|
||||
else
|
||||
VERIFICATION := signature
|
||||
endif
|
||||
|
||||
all: help
|
||||
|
||||
MIRROR := ftp.kernel.org
|
||||
SRC_BASEURL := http://${MIRROR}/pub/linux/kernel/v$(shell echo $(VERSION) | sed 's/^\(2\.[0-9]*\).*/\1/;s/^3\..*/3.x/')
|
||||
SRC_FILE := linux-${VERSION}.tar.bz2
|
||||
ifeq ($(BUILD_FLAVOR),pvops)
|
||||
MIRROR := cdn.kernel.org
|
||||
ifeq (,$(DISTFILES_MIRROR))
|
||||
SRC_BASEURL := https://${MIRROR}/pub/linux/kernel/v$(shell echo $(VERSION) | sed 's/^\(2\.[0-9]*\).*/\1/;s/^3\..*/3.x/;s/^4\..*/4.x/;s/^5\..*/5.x/')
|
||||
else
|
||||
SRC_BASEURL := $(DISTFILES_MIRROR)
|
||||
endif
|
||||
|
||||
ifeq ($(VERIFICATION),signature)
|
||||
SRC_FILE := linux-${VERSION}.tar.xz
|
||||
SIGN_FILE := linux-${VERSION}.tar.sign
|
||||
else
|
||||
SIGN_FILE := linux-${VERSION}.tar.bz2.sign
|
||||
SRC_FILE := linux-${VERSION}.tar.gz
|
||||
HASH_FILE := $(SRC_FILE).sha512
|
||||
endif
|
||||
HASH_FILE :=${SRC_FILE}.sha1sum
|
||||
|
||||
WG_BASE_URL := https://git.zx2c4.com/wireguard-linux-compat/snapshot
|
||||
WG_SRC_FILE := wireguard-linux-compat-0.0.20200121.tar.xz
|
||||
|
||||
WG_SRC_URL := $(WG_BASE_URL)/$(WG_SRC_FILE)
|
||||
WG_SIG_FILE := $(WG_SRC_FILE:%.xz=%.asc)
|
||||
WG_SIG_URL := $(WG_BASE_URL)/$(WG_SIG_FILE)
|
||||
|
||||
SPI_BASE_URL := https://github.com/roadrunner2/macbook12-spi-driver/archive
|
||||
SPI_REVISION := ddfbc7733542b8474a0e8f593aba91e06542be4f
|
||||
SPI_SRC_URL := $(SPI_BASE_URL)/$(SPI_REVISION).tar.gz
|
||||
SPI_SRC_FILE := macbook12-spi-driver-$(SPI_REVISION).tar.gz
|
||||
SPI_HASH_SHA256 := 8039f103fbb351ecbbaddd540feeb7b0b1abfa216f0689a611e43d997426470e
|
||||
|
||||
URL := $(SRC_BASEURL)/$(SRC_FILE)
|
||||
URL_SIGN := $(SRC_BASEURL)/$(SIGN_FILE)
|
||||
|
||||
get-sources: $(SRC_FILE)
|
||||
ifeq ($(DOWNLOAD_FROM_GIT),1)
|
||||
URL := https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/snapshot/linux-$(VERSION).tar.gz
|
||||
endif
|
||||
|
||||
get-sources: $(SRC_FILE) $(SIGN_FILE) $(WG_SRC_FILE) $(WG_SIG_FILE) $(SPI_SRC_FILE)
|
||||
|
||||
$(SRC_FILE):
|
||||
@echo -n "Downloading $(URL)... "
|
||||
@wget -q $(URL)
|
||||
@wget -q $(URL_SIGN)
|
||||
@echo "OK."
|
||||
@wget -q -N $(URL)
|
||||
|
||||
$(SIGN_FILE):
|
||||
@wget -q -N $(URL_SIGN)
|
||||
|
||||
$(WG_SRC_FILE):
|
||||
@wget -q -N $(WG_SRC_URL)
|
||||
|
||||
$(WG_SIG_FILE):
|
||||
@wget -q -N $(WG_SIG_URL)
|
||||
|
||||
$(SPI_SRC_FILE):
|
||||
@wget -q -N -O $(SPI_SRC_FILE) $(SPI_SRC_URL)
|
||||
|
||||
import-keys:
|
||||
gpg --import *-key.asc
|
||||
@if [ -n "$$GNUPGHOME" ]; then rm -f "$$GNUPGHOME/linux-kernel-trustedkeys.gpg"; fi
|
||||
@gpg --no-auto-check-trustdb --no-default-keyring --keyring linux-kernel-trustedkeys.gpg -q --import kernel*-key.asc
|
||||
@if [ -n "$$GNUPGHOME" ]; then rm -f "$$GNUPGHOME/wireguard-trustedkeys.gpg"; fi
|
||||
@gpg --no-auto-check-trustdb --no-default-keyring --keyring wireguard-trustedkeys.gpg -q --import wireguard*-key.asc
|
||||
|
||||
verify-sources: import-keys
|
||||
ifeq ($(BUILD_FLAVOR),pvops)
|
||||
@bzcat $(SRC_FILE) | gpg --verify $(SIGN_FILE) -
|
||||
@xzcat $(WG_SRC_FILE) | gpgv --keyring wireguard-trustedkeys.gpg $(WG_SIG_FILE) - 2>/dev/null
|
||||
ifeq ($(VERIFICATION),signature)
|
||||
@xzcat $(SRC_FILE) | gpgv --keyring linux-kernel-trustedkeys.gpg $(SIGN_FILE) - 2>/dev/null
|
||||
else
|
||||
# @gpg --verify $(SIGN_FILE) $(SRC_FILE)
|
||||
# The key has been compromised
|
||||
# and kernel.org decided not to release signature
|
||||
# with a new key... oh, well...
|
||||
# there are no signatures for rc tarballs
|
||||
# verify locally based on a signed git tag and commit hash file
|
||||
sha512sum --quiet -c $(HASH_FILE)
|
||||
endif
|
||||
sha1sum -c ${HASH_FILE}
|
||||
@gunzip -c $(SPI_SRC_FILE) | sha256sum | head -c64 | grep -q "^$(SPI_HASH_SHA256)$$"
|
||||
|
||||
.PHONY: clean-sources
|
||||
clean-sources:
|
||||
ifneq ($(SRC_FILE), None)
|
||||
-rm $(SRC_FILE)
|
||||
-rm $(SRC_FILE) $(SIGN_FILE)
|
||||
endif
|
||||
ifneq ($(WG_SRC_FILE), None)
|
||||
-rm $(WG_SRC_FILE) $(WG_SIG_FILE)
|
||||
endif
|
||||
ifneq ($(SPI_SRC_FILE), None)
|
||||
-rm $(SPI_SRC_FILE)
|
||||
endif
|
||||
|
||||
|
||||
@ -84,7 +123,11 @@ RPM := rpmbuild
|
||||
|
||||
RPM_WITH_DIRS = $(RPM) $(RPM_DEFINES)
|
||||
|
||||
rpms: get-sources $(SPECFILE)
|
||||
rpms: rpms-dom0
|
||||
|
||||
rpms-vm:
|
||||
|
||||
rpms-dom0: get-sources $(SPECFILE)
|
||||
$(RPM_WITH_DIRS) -bb $(SPECFILE)
|
||||
rpm --addsign $(RPMDIR)/x86_64/*$(VERSION)-$(RELEASE)*.rpm
|
||||
|
||||
@ -106,37 +149,6 @@ srpm: get-sources $(SPECFILE)
|
||||
verrel:
|
||||
@echo $(NAME)-$(VERSION)-$(RELEASE)
|
||||
|
||||
|
||||
update-repo-current:
|
||||
ln -f rpm/x86_64/kernel-$(VERSION)-$(RELEASE)*.rpm ../yum/current-release/current/dom0/rpm/
|
||||
ln -f rpm/x86_64/kernel-debuginfo-$(VERSION)-$(RELEASE)*.rpm ../yum/current-release/current/dom0/rpm/
|
||||
ln -f rpm/x86_64/kernel-devel-$(VERSION)-$(RELEASE)*.rpm ../yum/current-release/current/dom0/rpm/
|
||||
for vmrepo in ../yum/current-release/current/vm/* ; do \
|
||||
ln -f rpm/x86_64/kernel-devel-$(VERSION)-$(RELEASE)*.rpm $$vmrepo/rpm/ ;\
|
||||
done
|
||||
|
||||
update-repo-current-testing:
|
||||
ln -f rpm/x86_64/kernel-$(VERSION)-$(RELEASE)*.rpm ../yum/current-release/current-testing/dom0/rpm/
|
||||
ln -f rpm/x86_64/kernel-debuginfo-$(VERSION)-$(RELEASE)*.rpm ../yum/current-release/current-testing/dom0/rpm/
|
||||
ln -f rpm/x86_64/kernel-devel-$(VERSION)-$(RELEASE)*.rpm ../yum/current-release/current-testing/dom0/rpm/
|
||||
for vmrepo in ../yum/current-release/current-testing/vm/* ; do \
|
||||
ln -f rpm/x86_64/kernel-devel-$(VERSION)-$(RELEASE)*.rpm $$vmrepo/rpm/ ;\
|
||||
done
|
||||
|
||||
update-repo-unstable:
|
||||
ln -f rpm/x86_64/kernel-$(VERSION)-$(RELEASE)*.rpm ../yum/current-release/unstable/dom0/rpm/
|
||||
ln -f rpm/x86_64/kernel-debuginfo-$(VERSION)-$(RELEASE)*.rpm ../yum/current-release/unstable/dom0/rpm/
|
||||
ln -f rpm/x86_64/kernel-devel-$(VERSION)-$(RELEASE)*.rpm ../yum/current-release/unstable/dom0/rpm/
|
||||
for vmrepo in ../yum/current-release/unstable/vm/* ; do \
|
||||
ln -f rpm/x86_64/kernel-devel-$(VERSION)-$(RELEASE)*.rpm $$vmrepo/rpm/ ;\
|
||||
done
|
||||
|
||||
update-repo-installer-kernel-dom0:
|
||||
ln -f rpm/x86_64/kernel-$(VERSION)-$(RELEASE)*.rpm ../installer/yum/qubes-dom0/rpm/
|
||||
|
||||
update-repo-installer-kernel-vm:
|
||||
ln -f rpm/x86_64/kernel-qubes-vm-$(VERSION)-$(RELEASE)*.rpm ../installer/yum/qubes-dom0/rpm/
|
||||
|
||||
# mop up, printing out exactly what was mopped.
|
||||
|
||||
.PHONY : clean
|
||||
|
4
Makefile.builder
Normal file
4
Makefile.builder
Normal file
@ -0,0 +1,4 @@
|
||||
ifeq ($(PACKAGE_SET),dom0)
|
||||
RPM_SPEC_FILES := kernel.spec
|
||||
NO_ARCHIVE := 1
|
||||
endif
|
5775
config-3.2.5-pvops
5775
config-3.2.5-pvops
File diff suppressed because it is too large
Load Diff
9049
config-base
Normal file
9049
config-base
Normal file
File diff suppressed because it is too large
Load Diff
5599
config-pvops
5599
config-pvops
File diff suppressed because it is too large
Load Diff
138
config-qubes
Normal file
138
config-qubes
Normal file
@ -0,0 +1,138 @@
|
||||
## Qubes specific config settings.
|
||||
##
|
||||
## Lines starting with ## are comments.
|
||||
|
||||
|
||||
################################################################################
|
||||
## Enable expert options
|
||||
|
||||
CONFIG_EXPERT=y
|
||||
|
||||
|
||||
################################################################################
|
||||
## Use xz to save space on /boot
|
||||
|
||||
# CONFIG_KERNEL_GZIP is not set
|
||||
CONFIG_KERNEL_XZ=y
|
||||
|
||||
|
||||
################################################################################
|
||||
## Enable /proc/config.gz to help debugging etc.
|
||||
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
|
||||
|
||||
################################################################################
|
||||
## Enable some more hardening options
|
||||
|
||||
CONFIG_GCC_PLUGINS=y
|
||||
CONFIG_GCC_PLUGIN_LATENT_ENTROPY=y
|
||||
CONFIG_GCC_PLUGIN_STRUCTLEAK=y
|
||||
CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL=y
|
||||
## XXX: What's about RANDSTRUCT?
|
||||
|
||||
## Those depend on CONFIG_EXPERT
|
||||
CONFIG_ARCH_MMAP_RND_BITS=32
|
||||
CONFIG_ARCH_MMAP_RND_COMPAT_BITS=16
|
||||
|
||||
CONFIG_REFCOUNT_FULL=y
|
||||
|
||||
# CONFIG_KEXEC is not set
|
||||
|
||||
# CONFIG_LEGACY_VSYSCALL_EMULATE is not set
|
||||
CONFIG_LEGACY_VSYSCALL_NONE=y
|
||||
|
||||
# CONFIG_ACPI_CUSTOM_METHOD is not set
|
||||
|
||||
CONFIG_SECURITY_DMESG_RESTRICT=y
|
||||
|
||||
CONFIG_INTEL_IOMMU_DEFAULT_ON=y
|
||||
|
||||
# CONFIG_PROC_KCORE is not set
|
||||
|
||||
CONFIG_PAGE_POISONING=y
|
||||
# CONFIG_PAGE_POISONING_NO_SANITY is not set
|
||||
CONFIG_PAGE_POISONING_ZERO=y
|
||||
|
||||
CONFIG_PANIC_ON_OOPS=y
|
||||
CONFIG_PANIC_ON_OOPS_VALUE=1
|
||||
CONFIG_PANIC_TIMEOUT=-1
|
||||
|
||||
CONFIG_SCHED_STACK_END_CHECK=y
|
||||
CONFIG_DEBUG_TIMEKEEPING=y
|
||||
|
||||
CONFIG_IO_STRICT_DEVMEM=y
|
||||
|
||||
CONFIG_SECURITY_YAMA=y
|
||||
|
||||
# CONFIG_HIBERNATION is not set
|
||||
|
||||
|
||||
################################################################################
|
||||
## Disable PCI hotplug to prevent DMA attacks via ExpressCard or Thunderbolt
|
||||
## ports. QubesOS/qubes-issues#1673
|
||||
|
||||
# CONFIG_HOTPLUG_PCI is not set
|
||||
|
||||
|
||||
################################################################################
|
||||
## Deactivate selinux by default
|
||||
|
||||
# CONFIG_DEFAULT_SECURITY_SELINUX is not set
|
||||
CONFIG_DEFAULT_SECURITY_DAC=y
|
||||
CONFIG_LSM="yama,loadpin,safesetid,integrity"
|
||||
|
||||
|
||||
################################################################################
|
||||
## Enable paravirt spinlocks. This should be more performant.
|
||||
|
||||
CONFIG_PARAVIRT_SPINLOCKS=y
|
||||
|
||||
|
||||
################################################################################
|
||||
## Disable DEBUG_WX. Xen PV guests currently have some WX pages, so suppress
|
||||
## the useless Warning.
|
||||
|
||||
# CONFIG_DEBUG_WX is not set
|
||||
|
||||
|
||||
################################################################################
|
||||
## Set USB drivers to module to allow attaching PCI devices to pciback before
|
||||
## those get loaded.
|
||||
|
||||
CONFIG_USB_UHCI_HCD=m
|
||||
CONFIG_USB_OHCI_HCD=m
|
||||
CONFIG_USB_EHCI_HCD=m
|
||||
CONFIG_USB_XHCI_HCD=m
|
||||
|
||||
|
||||
################################################################################
|
||||
## USB gadget driver support for testing qvm-usb
|
||||
|
||||
CONFIG_USB_GADGET=m
|
||||
CONFIG_USB_CONFIGFS=m
|
||||
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
|
||||
CONFIG_USB_DUMMY_HCD=m
|
||||
|
||||
|
||||
################################################################################
|
||||
## Enable AppArmor
|
||||
## It's optionally used by Whonix (https://www.whonix.org/wiki/AppArmor).
|
||||
|
||||
CONFIG_SECURITY_APPARMOR=y
|
||||
|
||||
|
||||
################################################################################
|
||||
## TODO: from diff to old config
|
||||
|
||||
## CONFIG_X86_AMD_PLATFORM_DEVICE=y
|
||||
##
|
||||
## # CONFIG_X86_MCELOG_LEGACY is not set
|
||||
## # CONFIG_X86_MCE_INJECT is not set
|
||||
##
|
||||
## CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y
|
||||
##
|
||||
## sensors from 0f976d972a1671a303fad30a5e690304b0b82ee0
|
||||
##
|
||||
## Intel ME driver e0f8e9ca81b80d897b190f48a4af80eff3198cb1
|
95
config-qubes-minimal
Normal file
95
config-qubes-minimal
Normal file
@ -0,0 +1,95 @@
|
||||
## Minimal config for a Qubes VM. Intended for easier testing (git bisect, etc.)
|
||||
##
|
||||
## Lines starting with ## are comments.
|
||||
##
|
||||
## Run
|
||||
##
|
||||
## .../linux-kernel/gen-config arch/x86/configs/x86_64_defconfig .../linux-kernel/config-qubes-minimal
|
||||
##
|
||||
## in a linux tree to generate a complete config file.
|
||||
|
||||
################################################################################
|
||||
## linux/kernel/configs/xen.config
|
||||
|
||||
## global stuff - these enable us to allow some
|
||||
## of the not so generic stuff below for xen
|
||||
CONFIG_PARAVIRT=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_NET_CORE=y
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_BLOCK=y
|
||||
CONFIG_WATCHDOG=y
|
||||
CONFIG_TARGET_CORE=y
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_FB=y
|
||||
CONFIG_INPUT_MISC=y
|
||||
CONFIG_MEMORY_HOTPLUG=y
|
||||
CONFIG_TTY=y
|
||||
## Technically not required but otherwise produces
|
||||
## pretty useless systems starting from allnoconfig
|
||||
## You want TCP/IP and ELF binaries right?
|
||||
CONFIG_INET=y
|
||||
CONFIG_BINFMT_ELF=y
|
||||
## generic config
|
||||
CONFIG_XEN=y
|
||||
CONFIG_XEN_DOM0=y
|
||||
## backend drivers
|
||||
CONFIG_XEN_BACKEND=y
|
||||
CONFIG_XEN_BLKDEV_BACKEND=m
|
||||
CONFIG_XEN_NETDEV_BACKEND=m
|
||||
CONFIG_HVC_XEN=y
|
||||
CONFIG_XEN_WDT=m
|
||||
CONFIG_XEN_SCSI_BACKEND=m
|
||||
## frontend drivers
|
||||
CONFIG_XEN_FBDEV_FRONTEND=m
|
||||
CONFIG_HVC_XEN_FRONTEND=y
|
||||
CONFIG_INPUT_XEN_KBDDEV_FRONTEND=m
|
||||
## others
|
||||
CONFIG_XEN_BALLOON=y
|
||||
CONFIG_XEN_SCRUB_PAGES=y
|
||||
CONFIG_XEN_DEV_EVTCHN=m
|
||||
CONFIG_XEN_BLKDEV_FRONTEND=m
|
||||
CONFIG_XEN_NETDEV_FRONTEND=m
|
||||
CONFIG_XENFS=m
|
||||
CONFIG_XEN_COMPAT_XENFS=y
|
||||
CONFIG_XEN_SYS_HYPERVISOR=y
|
||||
CONFIG_XEN_XENBUS_FRONTEND=y
|
||||
CONFIG_XEN_GNTDEV=m
|
||||
CONFIG_XEN_GRANT_DEV_ALLOC=m
|
||||
CONFIG_SWIOTLB_XEN=y
|
||||
CONFIG_XEN_PRIVCMD=m
|
||||
|
||||
################################################################################
|
||||
## linux/arch/x86/configs/xen.config
|
||||
|
||||
## global x86 required specific stuff
|
||||
CONFIG_64BIT=y
|
||||
|
||||
## These enable us to allow some of the
|
||||
## not so generic stuff below
|
||||
CONFIG_HYPERVISOR_GUEST=y
|
||||
CONFIG_PCI=y
|
||||
CONFIG_PCI_MSI=y
|
||||
CONFIG_X86_MCE=y
|
||||
CONFIG_ACPI_PROCESSOR=y
|
||||
CONFIG_CPU_FREQ=y
|
||||
|
||||
## x86 xen specific config options
|
||||
CONFIG_XEN_PVH=y
|
||||
CONFIG_XEN_SAVE_RESTORE=y
|
||||
## CONFIG_XEN_DEBUG_FS is not set
|
||||
CONFIG_XEN_MCE_LOG=y
|
||||
CONFIG_XEN_ACPI_PROCESSOR=m
|
||||
## x86 specific backend drivers
|
||||
CONFIG_XEN_PCIDEV_BACKEND=m
|
||||
## x86 specific frontend drivers
|
||||
CONFIG_XEN_PCIDEV_FRONTEND=m
|
||||
## depends on MEMORY_HOTPLUG, arm64 doesn't enable this yet,
|
||||
## move to generic config if it ever does.
|
||||
CONFIG_XEN_BALLOON_MEMORY_HOTPLUG=y
|
||||
|
||||
|
||||
################################################################################
|
||||
## Some basic stuff required in an Qubes VM
|
||||
|
||||
CONFIG_DM_SNAPSHOT=m
|
5371
config-xenlinux
5371
config-xenlinux
File diff suppressed because it is too large
Load Diff
61
gen-config
Executable file
61
gen-config
Executable file
@ -0,0 +1,61 @@
|
||||
#!/bin/bash
|
||||
|
||||
# The Qubes OS Project, https://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2017 Simon Gaiser <simon@invisiblethingslab.com>
|
||||
# Copyright (c) 2009-2010 Wind River Systems, Inc.
|
||||
# Copyright 2011 Linaro
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License version 2 as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the GNU General Public License for more details.
|
||||
|
||||
set -eu -o pipefail
|
||||
|
||||
linux_merge_config="./scripts/kconfig/merge_config.sh"
|
||||
make_opts=""
|
||||
|
||||
if [ -n "${LINUX_UPSTREAM_VERSION:-}" ]; then
|
||||
linux_merge_config="../linux-$LINUX_UPSTREAM_VERSION/scripts/kconfig/merge_config.sh"
|
||||
make_opts="-C ../linux-$LINUX_UPSTREAM_VERSION O=$PWD"
|
||||
fi
|
||||
|
||||
if [ -z "$linux_merge_config" ]; then
|
||||
printf 'Error: Could not find merge_config.sh from the linux source tree!\n'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sed_config_exp='s/^\(# \)\{0,1\}\(CONFIG_[a-zA-Z0-9_]*\)[= ].*/\2/p'
|
||||
|
||||
if [ $# -ne 2 ]; then
|
||||
printf 'Usage: gen-config base.config local.config\n'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
base_config="$1"
|
||||
local_config="$2"
|
||||
|
||||
grep -v '^##' "$local_config" > "$local_config.gen" || [ $? -le 1 ]
|
||||
|
||||
$linux_merge_config -m "$base_config" "$local_config.gen"
|
||||
|
||||
make $make_opts KCONFIG_ALLCONFIG=.config alldefconfig
|
||||
|
||||
rc=0
|
||||
for cfg in $(sed -n "$sed_config_exp" "$local_config.gen"); do
|
||||
requested="$(grep -w "$cfg" "$local_config.gen" || true)"
|
||||
actual="$(grep -w "$cfg" .config || true)"
|
||||
if [ "$requested" != "$actual" ]; then
|
||||
printf 'Local config setting for %s didn'\''t make it into the final config\n' "$cfg"
|
||||
rc=1
|
||||
fi
|
||||
done
|
||||
|
||||
rm "$local_config.gen"
|
||||
|
||||
exit $rc
|
96
get-fedora-latest-config
Executable file
96
get-fedora-latest-config
Executable file
@ -0,0 +1,96 @@
|
||||
#!/bin/bash
|
||||
# vim: set ts=4 sw=4 sts=4 et :
|
||||
|
||||
set -e
|
||||
if [ "${VERBOSE:-0}" -ge 2 ] || [ "${DEBUG:-0}" -eq 1 ]; then
|
||||
debug=1
|
||||
set -x
|
||||
fi
|
||||
|
||||
localdir="$(dirname "$(readlink -f "$0")")"
|
||||
releasever="$1"
|
||||
# Set to 1 to include rc srpm
|
||||
rc="$2"
|
||||
|
||||
kernelver="$(cat "$localdir/version")"
|
||||
kernelsrc="linux-$kernelver"
|
||||
|
||||
exit_clean() {
|
||||
local exit_code=$?
|
||||
rm -rf "$tmpdir"
|
||||
exit "${exit_code}"
|
||||
}
|
||||
|
||||
errecho() {
|
||||
>&2 echo "$@"
|
||||
}
|
||||
|
||||
# example of releasever: '29' or 'rawhide'
|
||||
if [ "x$releasever" != "x" ]; then
|
||||
if [[ ! "$releasever" =~ ^[1-9][0-9]$ ]] && [ "$releasever" != "rawhide" ]; then
|
||||
errecho "Invalid release format"
|
||||
exit 1
|
||||
fi
|
||||
elif [ "x$releasever" == "x" ]; then
|
||||
listver="$(curl -s -L https://dl.fedoraproject.org/pub/fedora/linux/releases 2> /dev/null)"
|
||||
releasever="$(echo "$listver" | sed -e 's/<[^>]*>//g' | awk '{print $1}' | grep -o "[1-9][0-9]" | tail -1)"
|
||||
if ! [[ "$releasever" =~ ^[1-9][0-9]$ ]]; then
|
||||
errecho "An error occurred while trying to determine latest Fedora version"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# get the latest kernel rpm
|
||||
latestver=$(dnf -q repoquery kernel-core --disablerepo=* --enablerepo=fedora --enablerepo=updates --releasever="$releasever")
|
||||
if [ "$rc" != "1" ]; then
|
||||
latestver=$(echo "$latestver" | grep -v "rc[0-9]*")
|
||||
fi
|
||||
latestver=$(echo "$latestver" | sort -V | tail -1 | cut -d ':' -f2)
|
||||
latestrpm="kernel-core-$latestver.rpm"
|
||||
|
||||
if [ "$releasever" == 'rawhide' ]; then
|
||||
releasever="$(echo "$latestver" | grep -o "fc[1-9][0-9]" | sed 's/fc//')"
|
||||
fi
|
||||
|
||||
if [ "x$latestrpm" != "x" ] && [ "x$releasever" != "x" ]; then
|
||||
key="$localdir/../builder-rpm/keys/RPM-GPG-KEY-fedora-$releasever-primary"
|
||||
|
||||
trap 'exit_clean' 0 1 2 3 6 15
|
||||
tmpdir="$(mktemp -d -p "$localdir")"
|
||||
# download latest kernel rpm
|
||||
dnf -q download kernel-core --disablerepo=* --enablerepo=fedora --enablerepo=updates --releasever="$releasever"
|
||||
mv "$latestrpm" "$tmpdir/$latestrpm.untrusted"
|
||||
|
||||
# check signature
|
||||
mkdir -p "$tmpdir/rpmdb"
|
||||
rpmkeys --dbpath="$tmpdir/rpmdb" --import "$key"
|
||||
{ rpmkeys --dbpath="$tmpdir/rpmdb" --checksig "$tmpdir/$latestrpm.untrusted" | grep -q 'signatures OK' ; } || { errecho "Failed to check signature"; exit 1; }
|
||||
mv "$tmpdir/$latestrpm.untrusted" "$tmpdir/$latestrpm"
|
||||
|
||||
# extract kernel sources in qubes-linux-kernel
|
||||
tar xf "$localdir/$kernelsrc.tar.xz" -C "$tmpdir"
|
||||
|
||||
# get latest config and put it in extracted sources
|
||||
rpm2cpio "$tmpdir/$latestrpm" | cpio --quiet -i --to-stdout "./lib/modules/$latestver/config" > "$tmpdir/$kernelsrc/.config"
|
||||
|
||||
# generate new config with: yes '' | make oldconfig
|
||||
cd "$tmpdir/$kernelsrc/"
|
||||
## drop config settings which depend on Fedora patches and adjust for the small version difference
|
||||
if [ "$debug" == "1" ]; then
|
||||
yes '' | make oldconfig
|
||||
else
|
||||
yes '' | make oldconfig > /dev/null 2>&1
|
||||
fi
|
||||
## remove comments in header
|
||||
sed -i '1,4d' "$tmpdir/$kernelsrc/.config"
|
||||
|
||||
# create final config
|
||||
cat - "$tmpdir/$kernelsrc/.config" > "$localdir/config-base-$(echo "$latestver" | cut -d '-' -f1)" << EOF
|
||||
# Base config based on Fedora's config ($latestrpm)
|
||||
# Only modification is \`yes '' | make oldconfig\` to drop config settings which
|
||||
# depend on Fedora patches and adjust for the small version difference.
|
||||
EOF
|
||||
rm -rf "$tmpdir"
|
||||
else
|
||||
errecho "Unable to find the latest kernel rpm for Fedora $releasever"; exit 1
|
||||
fi
|
45
kernel-devel.spec
Normal file
45
kernel-devel.spec
Normal file
@ -0,0 +1,45 @@
|
||||
|
||||
%if 0%{?qubes_builder}
|
||||
%define _sourcedir %(pwd)
|
||||
%endif
|
||||
|
||||
#%define _unpackaged_files_terminate_build 0
|
||||
%define variant pvops.qubes
|
||||
%define plainrel %(cat rel)
|
||||
%define rel %{plainrel}.%{variant}
|
||||
%define version %(cat version)
|
||||
|
||||
Name: kernel-devel
|
||||
Version: %{version}
|
||||
Release: %{rel}
|
||||
Epoch: 1000
|
||||
Summary: Development files necessary for building kernel modules
|
||||
|
||||
Group: Development/Sources
|
||||
License: GPL v2 only
|
||||
Url: http://www.kernel.org/
|
||||
|
||||
%description
|
||||
This package contains files necessary for building kernel modules (and
|
||||
kernel module packages) against the pvops flavor of the kernel.
|
||||
|
||||
%prep
|
||||
echo "Dummy spec, do not try to build, use kernel.spec instead"
|
||||
exit 1
|
||||
|
||||
|
||||
%build
|
||||
echo "Dummy spec, do not try to build, use kernel.spec instead"
|
||||
exit 1
|
||||
|
||||
%install
|
||||
echo "Dummy spec, do not try to build, use kernel.spec instead"
|
||||
exit 1
|
||||
|
||||
%files
|
||||
%doc
|
||||
|
||||
|
||||
|
||||
%changelog
|
||||
|
37
kernel.org-1-key.asc
Normal file
37
kernel.org-1-key.asc
Normal file
@ -0,0 +1,37 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mQENBE55CJIBCACkn+aOLmsaq1ejUcXCAOXkO3w7eiLqjR/ziTL2KZ30p7bxP8cT
|
||||
UXvfM7fwE7EnqCCkji25x2xsoKXB8AlUswIEYUFCOupj2BOsVmJ/rKZW7fCvKTOK
|
||||
+BguKjebDxNbgmif39bfSnHDWrW832f5HrYmZn7a/VySDQFdul8Gl/R6gs6PHJbg
|
||||
jjt+K7Px6cQVMVNvY/VBWdvA1zckO/4h6gf3kWWZN+Wlq8wv/pxft8QzNFgweH9o
|
||||
5bj4tnQ+wMCLCLiDsgEuVawoOAkg3dRMugIUoiKoBKw7b21q9Vjp4jezRvciC6Ys
|
||||
4kGUSFG1ZjIn3MpY3f3xZ3yuYwrxQ8JcA7KTABEBAAG0JExpbnVzIFRvcnZhbGRz
|
||||
IDx0b3J2YWxkc0BrZXJuZWwub3JnPokBTgQTAQgAOBYhBKuvEcZaKXCxMKvjxHm+
|
||||
PkMAQRiGBQJaHxkTAhsDBQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEHm+PkMA
|
||||
QRiGzMcH/ieyxrsHR0ng3pi+qy1/sLiTT4WEBN53+1FsGWdP6/DCD3sprFdWDkkB
|
||||
Dfh9vPCVzPqX7siZMJxw3+wOfjNnGBRiGj7mTE/1XeXJHDwFRyBEVa/bY8ExLKbv
|
||||
Bf+xpiWOg2Myj5RYaOUBFbOEtfTPob0FtvfZvK3PXkjODTHhDH7QJT2zNPivHG+E
|
||||
R5VyF1yJEpl10rDTM91NhEeV0n4wpfZkgL8a3JSzo9H2AJX3y35+Dk9wtNge440Z
|
||||
SVWAnjwxhBLX2R0LUszRhU925c0vP2l20eFncBmAT0NKpn7v9a670WHv45PluG+S
|
||||
KKktf6b5/BtfqpC3eV58I6FEtSVpM1u0LkxpbnVzIFRvcnZhbGRzIDx0b3J2YWxk
|
||||
c0BsaW51eC1mb3VuZGF0aW9uLm9yZz6JATgEEwECACIFAk55CJICGwMGCwkIBwMC
|
||||
BhUIAgkKCwQWAgMBAh4BAheAAAoJEHm+PkMAQRiGbpwH/2jMNyBq6SjFrltEwt6c
|
||||
wOJak1lkjpP5IfFMemfKPH03jBv98Yb7nnVE/VofRQi0erPvzU9HPitzmq9Hdaz8
|
||||
pTVD1nNiejn6MBHREY5T10U8J9Holn9S1G3CUvEUaBg+YEhHwWA8hhxFCIRcfz6N
|
||||
PRkZH5zi9xdXBnjLrE3CpoZwVguwCT/25DuSqqJnviKiH+BOvJi/BnHSnjV1J71M
|
||||
OpVabaTZKxQ1Qkwiyo7KRa/MrBV4Cw87MjF1jmja91wWNOuAwv1ST+aSaI038zcl
|
||||
VqbFrc9gHkTeP3o5p8DG3Q7A1pE/yVLRUW+3jucKtiojylWaqxX7FD0RZtIuhNsU
|
||||
ig+5AQ0ETnkIkgEIAN+ybgD0IlgKRPJ3eksafd+KORseBWwxUy3GH0yAg/4jZCsf
|
||||
HZ7jpbRKzxNTKW1kE6ClSqehUsuXT5Vc1eh6079erN3y+JNxl6zZPC9v+5GNyc28
|
||||
qSfNejt4wmwa/y86T7oQfgo77o8Gu/aO/xzOjw7jSDDR3u9p/hFVtsqzptxZzvs3
|
||||
hVaiLS+0mar9qYZheaCUqOXOKVo38Vg5gkOhMEwKvZs9x3fINU/t8ckxOHq6KiLa
|
||||
p5Bq87XP0ZJsCaMBwdLYhOFxAiEVtlzwyo3DvMplIahqqNELb71YDhpMq/Hu+42o
|
||||
R3pqASCPLfO/0GUSdAGXJVhv7L7ng02ETSBmVOUAEQEAAYkBHwQYAQIACQUCTnkI
|
||||
kgIbDAAKCRB5vj5DAEEYhuobB/9Fi1GVG5qnPq14S0WKYEW3N891L37LaXmDh977
|
||||
r/j2dyZOoYIiV4rx6a6urhq9UbcgNw/ke01TNM4y7EhW/lFnxJQXSMjdsXGcb9Hw
|
||||
UevDk2FMV1h9gkHLlqRUlTpjVdQwTB9wMd4bWhZsxybTnGh6o8dCwBEaGNsHsSBY
|
||||
O81OXrTE/fcZEgKCeKW2xdKRiazu6Mu5WLU6gBy2nOc6oL2zKJZjACfllQzBx5+6
|
||||
z2N4Sj0JBOobz4RR2JLElMEckMbdqbIS+c+n02ItMmCORgakf74k+TEbaZx3ZTVH
|
||||
nhvqQqanZz1i4I5IwHJxkUsYLddgYrylZH+MwNDlB5u3I138
|
||||
=d8eq
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
@ -1,9 +0,0 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1.4.11 (GNU/Linux)
|
||||
Comment: A revocation certificate should follow
|
||||
|
||||
iIkEIBECAEkFAk7lL6xCHQJLZXkgd2FzIHVzZWQgdG8gYXV0b3NpZ25pbmc7IGF1
|
||||
dG9zaWduaW5nIHNlcnZlciB3YXMgY29tcHJvbWlzZWQuAAoJEMhroGpRfQ8OS7EA
|
||||
nikD5S7mmNM0QRX+H4BDxvdWzXWyAKCTuDGOdLoZs8gnl/G5UKVjX9mVkg==
|
||||
=eL49
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
446
kernel.spec
446
kernel.spec
@ -1,446 +0,0 @@
|
||||
# A spec file for building xenlinux Dom0 kernel for Qubes
|
||||
# Based on the Open SUSE kernel-spec & Fedora kernel-spec.
|
||||
#
|
||||
|
||||
#%define _unpackaged_files_terminate_build 0
|
||||
%define variant %{build_flavor}.qubes
|
||||
%define rel %(cat rel-%{build_flavor}).%{variant}
|
||||
%define version %(cat version-%{build_flavor})
|
||||
|
||||
%define _buildshell /bin/bash
|
||||
%define build_xen 1
|
||||
|
||||
%global cpu_arch x86_64
|
||||
%define cpu_arch_flavor %cpu_arch/%build_flavor
|
||||
|
||||
%define kernelrelease %version-%rel.%cpu_arch
|
||||
%define my_builddir %_builddir/%{name}-%{version}
|
||||
|
||||
%define build_src_dir %my_builddir/linux-%version
|
||||
%define src_install_dir /usr/src/kernels/%kernelrelease
|
||||
%define kernel_build_dir %my_builddir/linux-obj
|
||||
%define vm_install_dir /var/lib/qubes/vm-kernels/%version
|
||||
|
||||
%(chmod +x %_sourcedir/{guards,apply-patches,check-for-config-changes})
|
||||
|
||||
%define install_vdso 1
|
||||
|
||||
Name: kernel
|
||||
Summary: The Xen Kernel
|
||||
Version: %{version}
|
||||
Epoch: 1000
|
||||
Release: %{rel}
|
||||
License: GPL v2 only
|
||||
Group: System/Kernel
|
||||
Url: http://www.kernel.org/
|
||||
AutoReqProv: on
|
||||
BuildRequires: coreutils module-init-tools sparse
|
||||
BuildRequires: qubes-core-vm-devel
|
||||
Provides: multiversion(kernel)
|
||||
Provides: %name = %version-%kernelrelease
|
||||
|
||||
Provides: kernel-xen-dom0
|
||||
Provides: kernel-qubes-dom0
|
||||
Provides: kernel-drm-nouveau = 16
|
||||
|
||||
Requires: xen >= 3.4.3
|
||||
Requires(post): /sbin/new-kernel-pkg
|
||||
Requires(preun):/sbin/new-kernel-pkg
|
||||
|
||||
Requires(pre): coreutils gawk
|
||||
Requires(post): dracut
|
||||
|
||||
Conflicts: sysfsutils < 2.0
|
||||
# root-lvm only works with newer udevs
|
||||
Conflicts: udev < 118
|
||||
Conflicts: lvm2 < 2.02.33
|
||||
Provides: kernel = %kernelrelease
|
||||
Provides: kernel-uname-r = %kernelrelease
|
||||
|
||||
Source0: linux-%version.tar.bz2
|
||||
Source14: series-%{build_flavor}.conf
|
||||
Source16: guards
|
||||
Source17: apply-patches
|
||||
Source33: check-for-config-changes
|
||||
Source100: config-%{build_flavor}
|
||||
# FIXME: Including dirs this way does NOT produce proper src.rpms
|
||||
Source200: patches.arch
|
||||
Source201: patches.drivers
|
||||
Source202: patches.fixes
|
||||
Source203: patches.rpmify
|
||||
Source204: patches.suse
|
||||
Source205: patches.xen
|
||||
Source207: patches.kernel.org
|
||||
Source300: patches.qubes
|
||||
Source301: u2mfn
|
||||
Source302: vm-initramfs-pre-udev
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
ExclusiveArch: x86_64
|
||||
|
||||
%description
|
||||
Qubes Dom0 kernel.
|
||||
|
||||
%prep
|
||||
if ! [ -e %_sourcedir/linux-%version.tar.bz2 ]; then
|
||||
echo "The %name-%version.nosrc.rpm package does not contain the" \
|
||||
"complete sources. Please install kernel-source-%version.src.rpm."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SYMBOLS="xen-dom0 %{build_flavor}"
|
||||
|
||||
# Unpack all sources and patches
|
||||
%setup -q -c -T -a 0
|
||||
|
||||
mkdir -p %kernel_build_dir
|
||||
|
||||
cd linux-%version
|
||||
|
||||
if [ -r %_sourcedir/series-%{version}-%{build_flavor}.conf ]; then
|
||||
%_sourcedir/apply-patches %_sourcedir/series-%{version}-%{build_flavor}.conf %_sourcedir $SYMBOLS
|
||||
else
|
||||
%_sourcedir/apply-patches %_sourcedir/series-%{build_flavor}.conf %_sourcedir $SYMBOLS
|
||||
fi
|
||||
|
||||
cd %kernel_build_dir
|
||||
|
||||
if [ -f %_sourcedir/config-%{version}-%{build_flavor} ]; then
|
||||
cp %_sourcedir/config-%{version}-%{build_flavor} .config
|
||||
else
|
||||
cp %_sourcedir/config-%{build_flavor} .config
|
||||
fi
|
||||
|
||||
%build_src_dir/scripts/config \
|
||||
--set-str CONFIG_LOCALVERSION -%release.%cpu_arch \
|
||||
--disable CONFIG_DEBUG_INFO
|
||||
# --enable CONFIG_DEBUG_INFO
|
||||
# Enabling CONFIG_DEBUG_INFO produces *huge* packages!
|
||||
|
||||
MAKE_ARGS="$MAKE_ARGS -C %build_src_dir O=$PWD"
|
||||
if test -e %_sourcedir/TOLERATE-UNKNOWN-NEW-CONFIG-OPTIONS; then
|
||||
yes '' | make oldconfig $MAKE_ARGS
|
||||
else
|
||||
cp .config .config.orig
|
||||
make silentoldconfig $MAKE_ARGS < /dev/null
|
||||
%_sourcedir/check-for-config-changes .config.orig .config
|
||||
rm .config.orig
|
||||
fi
|
||||
|
||||
make prepare $MAKE_ARGS
|
||||
make scripts $MAKE_ARGS
|
||||
krel=$(make -s kernelrelease $MAKE_ARGS)
|
||||
|
||||
if [ "$krel" != "%kernelrelease" ]; then
|
||||
echo "Kernel release mismatch: $krel != %kernelrelease" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
make clean $MAKE_ARGS
|
||||
|
||||
rm -f source
|
||||
find . ! -type d -printf '%%P\n' > %my_builddir/obj-files
|
||||
|
||||
%build
|
||||
|
||||
cd %kernel_build_dir
|
||||
|
||||
# If the %jobs macro is defined to a number, make will spawn that many jobs.
|
||||
# There are several ways how to define it:
|
||||
# With plain rpmbuild:
|
||||
# rpmbuild -ba --define 'jobs N' kernel-$flavor.spec
|
||||
# To spawn as many jobs as there are cpu cores:
|
||||
# rpmbuild -ba --define "jobs 0$(grep -c ^processor /proc/cpuinfo)" \
|
||||
# kernel-$flavor.spec
|
||||
make %{?jobs:-j%jobs} all $MAKE_ARGS CONFIG_DEBUG_SECTION_MISMATCH=y
|
||||
|
||||
# Build u2mfn module
|
||||
make -C %kernel_build_dir SUBDIRS=%_builddir/u2mfn modules
|
||||
|
||||
%install
|
||||
|
||||
# get rid of /usr/lib/rpm/brp-strip-debug
|
||||
# strip removes too much from the vmlinux ELF binary
|
||||
export NO_BRP_STRIP_DEBUG=true
|
||||
export STRIP_KEEP_SYMTAB='*/vmlinux-*'
|
||||
|
||||
cd %kernel_build_dir
|
||||
|
||||
mkdir -p %buildroot/boot
|
||||
cp -p System.map %buildroot/boot/System.map-%kernelrelease
|
||||
if [ "%{build_flavor}" == "xenlinux" ]; then
|
||||
cp -p arch/x86/boot/vmlinuz %buildroot/boot/vmlinuz-%kernelrelease
|
||||
else
|
||||
cp -p arch/x86/boot/bzImage %buildroot/boot/vmlinuz-%kernelrelease
|
||||
fi
|
||||
cp .config %buildroot/boot/config-%kernelrelease
|
||||
|
||||
%if %install_vdso
|
||||
# Install the unstripped vdso's that are linked in the kernel image
|
||||
make vdso_install $MAKE_ARGS INSTALL_MOD_PATH=%buildroot
|
||||
%endif
|
||||
|
||||
# Create a dummy initramfs with roughly the size the real one will have.
|
||||
# That way, rpm will know that this package requires some additional
|
||||
# space in /boot.
|
||||
dd if=/dev/zero of=%buildroot/boot/initramfs-%kernelrelease.img \
|
||||
bs=1M count=20
|
||||
|
||||
gzip -c9 < Module.symvers > %buildroot/boot/symvers-%kernelrelease.gz
|
||||
|
||||
make modules_install $MAKE_ARGS INSTALL_MOD_PATH=%buildroot
|
||||
make -C %kernel_build_dir SUBDIRS=%_builddir/u2mfn modules_install $MAKE_ARGS INSTALL_MOD_PATH=%buildroot
|
||||
|
||||
mkdir -p %buildroot/%src_install_dir
|
||||
|
||||
rm -f %buildroot/lib/modules/%kernelrelease/build
|
||||
rm -f %buildroot/lib/modules/%kernelrelease/source
|
||||
mkdir -p %buildroot/lib/modules/%kernelrelease/build
|
||||
(cd %buildroot/lib/modules/%kernelrelease ; ln -s build source)
|
||||
# dirs for additional modules per module-init-tools, kbuild/modules.txt
|
||||
mkdir -p %buildroot/lib/modules/%kernelrelease/extra
|
||||
mkdir -p %buildroot/lib/modules/%kernelrelease/updates
|
||||
mkdir -p %buildroot/lib/modules/%kernelrelease/weak-updates
|
||||
|
||||
pushd %build_src_dir
|
||||
cp --parents `find -type f -name "Makefile*" -o -name "Kconfig*"` %buildroot/lib/modules/%kernelrelease/build
|
||||
cp -a scripts %buildroot/lib/modules/%kernelrelease/build
|
||||
cp -a --parents arch/x86/include/asm %buildroot/lib/modules/%kernelrelease/build/
|
||||
if [ "%{build_flavor}" == "xenlinux" ]; then
|
||||
cp -a --parents arch/x86/include/mach-xen %buildroot/lib/modules/%kernelrelease/build/
|
||||
fi
|
||||
cp -a include %buildroot/lib/modules/%kernelrelease/build/include
|
||||
popd
|
||||
|
||||
cp Module.symvers %buildroot/lib/modules/%kernelrelease/build
|
||||
cp System.map %buildroot/lib/modules/%kernelrelease/build
|
||||
if [ -s Module.markers ]; then
|
||||
cp Module.markers %buildroot/lib/modules/%kernelrelease/build
|
||||
fi
|
||||
|
||||
rm -rf %buildroot/lib/modules/%kernelrelease/build/Documentation
|
||||
cp .config %buildroot/lib/modules/%kernelrelease/build
|
||||
|
||||
rm -f %buildroot/lib/modules/%kernelrelease/build/scripts/*.o
|
||||
rm -f %buildroot/lib/modules/%kernelrelease/build/scripts/*/*.o
|
||||
|
||||
cp -a scripts/* %buildroot/lib/modules/%kernelrelease/build/scripts/
|
||||
cp -a include/* %buildroot/lib/modules/%kernelrelease/build/include
|
||||
|
||||
# Make sure the Makefile and version.h have a matching timestamp so that
|
||||
# external modules can be built
|
||||
touch -r %buildroot/lib/modules/%kernelrelease/build/Makefile %buildroot/lib/modules/%kernelrelease/build/include/linux/version.h
|
||||
touch -r %buildroot/lib/modules/%kernelrelease/build/.config %buildroot/lib/modules/%kernelrelease/build/include/linux/autoconf.h
|
||||
# Copy .config to include/config/auto.conf so "make prepare" is unnecessary.
|
||||
cp %buildroot/lib/modules/%kernelrelease/build/.config %buildroot/lib/modules/%kernelrelease/build/include/config/auto.conf
|
||||
|
||||
if test -s vmlinux.id; then
|
||||
cp vmlinux.id %buildroot/lib/modules/%kernelrelease/build/vmlinux.id
|
||||
else
|
||||
echo >&2 "*** WARNING *** no vmlinux build ID! ***"
|
||||
fi
|
||||
|
||||
#
|
||||
# save the vmlinux file for kernel debugging into the kernel-debuginfo rpm
|
||||
#
|
||||
mkdir -p %buildroot%{debuginfodir}/lib/modules/%kernelrelease
|
||||
cp vmlinux %buildroot%{debuginfodir}/lib/modules/%kernelrelease
|
||||
|
||||
find %buildroot/lib/modules/%kernelrelease -name "*.ko" -type f >modnames
|
||||
|
||||
# mark modules executable so that strip-to-file can strip them
|
||||
xargs --no-run-if-empty chmod u+x < modnames
|
||||
|
||||
# Generate a list of modules for block and networking.
|
||||
|
||||
fgrep /drivers/ modnames | xargs --no-run-if-empty nm -upA |
|
||||
sed -n 's,^.*/\([^/]*\.ko\): *U \(.*\)$,\1 \2,p' > drivers.undef
|
||||
|
||||
collect_modules_list()
|
||||
{
|
||||
sed -r -n -e "s/^([^ ]+) \\.?($2)\$/\\1/p" drivers.undef |
|
||||
LC_ALL=C sort -u > %buildroot/lib/modules/%kernelrelease/modules.$1
|
||||
}
|
||||
|
||||
collect_modules_list networking \
|
||||
'register_netdev|ieee80211_register_hw|usbnet_probe'
|
||||
collect_modules_list block \
|
||||
'ata_scsi_ioctl|scsi_add_host|scsi_add_host_with_dma|blk_init_queue|register_mtd_blktrans|scsi_esp_register|scsi_register_device_handler'
|
||||
collect_modules_list drm \
|
||||
'drm_open|drm_init'
|
||||
collect_modules_list modesetting \
|
||||
'drm_crtc_init'
|
||||
|
||||
# detect missing or incorrect license tags
|
||||
rm -f modinfo
|
||||
while read i
|
||||
do
|
||||
echo -n "${i#%buildroot/lib/modules/%kernelrelease/} " >> modinfo
|
||||
/sbin/modinfo -l $i >> modinfo
|
||||
done < modnames
|
||||
|
||||
egrep -v \
|
||||
'GPL( v2)?$|Dual BSD/GPL$|Dual MPL/GPL$|GPL and additional rights$' \
|
||||
modinfo && exit 1
|
||||
|
||||
rm -f modinfo modnames
|
||||
|
||||
# Move the devel headers out of the root file system
|
||||
mkdir -p %buildroot/usr/src/kernels
|
||||
mv %buildroot/lib/modules/%kernelrelease/build/* %buildroot/%src_install_dir/
|
||||
mv %buildroot/lib/modules/%kernelrelease/build/.config %buildroot/%src_install_dir
|
||||
rmdir %buildroot/lib/modules/%kernelrelease/build
|
||||
ln -sf %src_install_dir %buildroot/lib/modules/%kernelrelease/build
|
||||
|
||||
# Abort if there are any undefined symbols
|
||||
msg="$(/sbin/depmod -F %buildroot/boot/System.map-%kernelrelease \
|
||||
-b %buildroot -ae %kernelrelease 2>&1)"
|
||||
|
||||
if [ $? -ne 0 ] || echo "$msg" | grep 'needs unknown symbol'; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "%{build_flavor}" == "pvops" ]; then
|
||||
mv %buildroot/lib/firmware %buildroot/lib/firmware-all
|
||||
mkdir -p %buildroot/lib/firmware
|
||||
mv %buildroot/lib/firmware-all %buildroot/lib/firmware/%kernelrelease
|
||||
fi
|
||||
# Prepare initramfs for Qubes VM
|
||||
mkdir -p %buildroot/%vm_install_dir
|
||||
/sbin/dracut --nomdadmconf --nolvmconf \
|
||||
--kmoddir %buildroot/lib/modules/%kernelrelease \
|
||||
--include %_sourcedir/vm-initramfs / \
|
||||
-d "xenblk xen-blkfront cdrom ext4 jbd2 crc16 dm_snapshot" \
|
||||
%buildroot/%vm_install_dir/initramfs %kernelrelease
|
||||
|
||||
if [ "%{build_flavor}" == "xenlinux" ]; then
|
||||
cp -p arch/x86/boot/vmlinuz %buildroot/%vm_install_dir/vmlinuz
|
||||
else
|
||||
cp -p arch/x86/boot/bzImage %buildroot/%vm_install_dir/vmlinuz
|
||||
fi
|
||||
|
||||
# Modules for Qubes VM
|
||||
mkdir -p %buildroot%vm_install_dir/modules
|
||||
cp -a %buildroot/lib/modules/%kernelrelease %buildroot%vm_install_dir/modules/
|
||||
mkdir -p %buildroot%vm_install_dir/modules/firmware
|
||||
cp -a %buildroot/lib/firmware/%kernelrelease %buildroot%vm_install_dir/modules/firmware/
|
||||
|
||||
# remove files that will be auto generated by depmod at rpm -i time
|
||||
for i in alias alias.bin ccwmap dep dep.bin ieee1394map inputmap isapnpmap ofmap pcimap seriomap symbols symbols.bin usbmap
|
||||
do
|
||||
rm -f %buildroot/lib/modules/%kernelrelease/modules.$i
|
||||
done
|
||||
|
||||
%post
|
||||
|
||||
INITRD_OPT="--mkinitrd --dracut"
|
||||
|
||||
/sbin/new-kernel-pkg --package %{name}-%{kernelrelease}\
|
||||
$INITRD_OPT \
|
||||
--depmod --kernel-args="max_loop=255"\
|
||||
--multiboot=/boot/xen.gz --mbargs="console=com1" \
|
||||
--banner="Qubes"\
|
||||
--make-default --install %{kernelrelease}
|
||||
|
||||
if [ -e /boot/grub/grub.conf ]; then
|
||||
# Make it possible to enter GRUB menu if something goes wrong...
|
||||
sed -i "s/^timeout *=.*/timeout=3/" /boot/grub/grub.conf
|
||||
fi
|
||||
|
||||
%posttrans
|
||||
/sbin/new-kernel-pkg --package %{name}-%{kernelrelease} --rpmposttrans %{kernelrelease}
|
||||
|
||||
%preun
|
||||
/sbin/new-kernel-pkg --rminitrd --rmmoddep --remove %{kernelrelease}
|
||||
|
||||
%files
|
||||
%defattr(-, root, root)
|
||||
%ghost /boot/initramfs-%{kernelrelease}.img
|
||||
/boot/System.map-%{kernelrelease}
|
||||
/boot/config-%{kernelrelease}
|
||||
/boot/symvers-%kernelrelease.gz
|
||||
%attr(0644, root, root) /boot/vmlinuz-%{kernelrelease}
|
||||
/lib/firmware/%{kernelrelease}
|
||||
/lib/modules/%{kernelrelease}
|
||||
|
||||
%package devel
|
||||
Summary: Development files necessary for building kernel modules
|
||||
License: GPL v2 only
|
||||
Group: Development/Sources
|
||||
Provides: multiversion(kernel)
|
||||
Provides: %name-devel = %kernelrelease
|
||||
Provides: kernel-devel-uname-r = %kernelrelease
|
||||
AutoReqProv: on
|
||||
|
||||
%description devel
|
||||
This package contains files necessary for building kernel modules (and
|
||||
kernel module packages) against the %build_flavor flavor of the kernel.
|
||||
|
||||
%post devel
|
||||
if [ -f /etc/sysconfig/kernel ]
|
||||
then
|
||||
. /etc/sysconfig/kernel || exit $?
|
||||
fi
|
||||
if [ "$HARDLINK" != "no" -a -x /usr/sbin/hardlink ]
|
||||
then
|
||||
(cd /usr/src/kernels/%{kernelrelease} &&
|
||||
/usr/bin/find . -type f | while read f; do
|
||||
hardlink -c /usr/src/kernels/*.fc*.*/$f $f
|
||||
done)
|
||||
fi
|
||||
|
||||
|
||||
%files devel
|
||||
%defattr(-,root,root)
|
||||
/usr/src/kernels/%{kernelrelease}
|
||||
|
||||
|
||||
%package qubes-vm
|
||||
Summary: The Xen Kernel
|
||||
Version: %{version}
|
||||
Release: %{rel}
|
||||
License: GPL v2 only
|
||||
Group: System/Kernel
|
||||
Url: http://www.kernel.org/
|
||||
AutoReqProv: on
|
||||
BuildRequires: coreutils module-init-tools sparse
|
||||
Provides: multiversion(kernel-qubes-vm)
|
||||
|
||||
Provides: kernel-xen-domU
|
||||
Provides: kernel-qubes-domU
|
||||
|
||||
Requires(pre): coreutils gawk
|
||||
Requires(post): dracut
|
||||
|
||||
Conflicts: sysfsutils < 2.0
|
||||
# root-lvm only works with newer udevs
|
||||
Conflicts: udev < 118
|
||||
Conflicts: lvm2 < 2.02.33
|
||||
Provides: kernel-qubes-vm = %version-%kernelrelease
|
||||
|
||||
%description qubes-vm
|
||||
Qubes domU kernel.
|
||||
|
||||
%post qubes-vm
|
||||
|
||||
mkdir /tmp/qubes-modules-%kernelrelease
|
||||
truncate -s 200M /tmp/qubes-modules-%kernelrelease.img
|
||||
mkfs -t ext3 -F /tmp/qubes-modules-%kernelrelease.img > /dev/null
|
||||
mount /tmp/qubes-modules-%kernelrelease.img /tmp/qubes-modules-%kernelrelease -o loop
|
||||
cp -a -t /tmp/qubes-modules-%kernelrelease %vm_install_dir/modules/%kernelrelease
|
||||
mkdir /tmp/qubes-modules-%kernelrelease/firmware
|
||||
cp -a -t /tmp/qubes-modules-%kernelrelease/firmware %vm_install_dir/modules/firmware/%kernelrelease
|
||||
umount /tmp/qubes-modules-%kernelrelease
|
||||
rmdir /tmp/qubes-modules-%kernelrelease
|
||||
mv /tmp/qubes-modules-%kernelrelease.img %vm_install_dir/modules.img
|
||||
|
||||
qubes-prefs --set default-kernel %version
|
||||
|
||||
%files qubes-vm
|
||||
%defattr(-, root, root)
|
||||
%ghost %attr(0644, root, root) %vm_install_dir/modules.img
|
||||
%attr(0644, root, root) %vm_install_dir/initramfs
|
||||
%attr(0644, root, root) %vm_install_dir/vmlinuz
|
||||
%vm_install_dir/modules
|
||||
|
||||
|
||||
%changelog
|
679
kernel.spec.in
Normal file
679
kernel.spec.in
Normal file
@ -0,0 +1,679 @@
|
||||
# A spec file for building xenlinux Dom0 kernel for Qubes
|
||||
# Based on the Open SUSE kernel-spec & Fedora kernel-spec.
|
||||
#
|
||||
|
||||
%define variant qubes
|
||||
%define plainrel @REL@
|
||||
%define rel %{plainrel}.%{variant}
|
||||
%define version %(echo '@VERSION@' | sed 's/~rc.*/.0/')
|
||||
%define upstream_version %(echo '@VERSION@' | sed 's/~rc/-rc/')
|
||||
%if "%{version}" != "%{upstream_version}"
|
||||
%define prerelease 1
|
||||
%define rel 0.%(echo '@VERSION@' | sed 's/.*~rc/rc/').%{plainrel}.%{variant}
|
||||
%else
|
||||
%define prerelease 0
|
||||
%define rel %{plainrel}.%{variant}
|
||||
%endif
|
||||
|
||||
%define name_suffix -latest
|
||||
|
||||
%define _buildshell /bin/bash
|
||||
%define build_xen 1
|
||||
|
||||
%global cpu_arch x86_64
|
||||
%define cpu_arch_flavor %cpu_arch
|
||||
|
||||
%define kernelrelease %(echo %{upstream_version} | sed 's/^[0-9]\\.[0-9]\\+$/\\0.0/;s/-rc.*/.0/')-%rel.%cpu_arch
|
||||
%define my_builddir %_builddir/%{name}-%{version}
|
||||
|
||||
%define build_src_dir %my_builddir/linux-%upstream_version
|
||||
%define src_install_dir /usr/src/kernels/%kernelrelease
|
||||
%define kernel_build_dir %my_builddir/linux-obj
|
||||
%define vm_install_dir /var/lib/qubes/vm-kernels/%upstream_version-%{plainrel}
|
||||
|
||||
%define install_vdso 1
|
||||
%define debuginfodir /usr/lib/debug
|
||||
|
||||
# debuginfo build is disabled by default to save disk space (it needs 2-3GB build time)
|
||||
%define with_debuginfo 0
|
||||
|
||||
# Sign all modules
|
||||
%global signmodules 1
|
||||
|
||||
%if !%{with_debuginfo}
|
||||
%global debug_package %{nil}
|
||||
%define setup_config --disable CONFIG_DEBUG_INFO
|
||||
%else
|
||||
%define setup_config --enable CONFIG_DEBUG_INFO --disable CONFIG_DEBUG_INFO_REDUCED
|
||||
%endif
|
||||
|
||||
Name: kernel%{?name_suffix}
|
||||
Summary: The Xen Kernel
|
||||
Version: %{version}
|
||||
Epoch: 1000
|
||||
Release: %{rel}
|
||||
License: GPL v2 only
|
||||
Group: System/Kernel
|
||||
Url: http://www.kernel.org/
|
||||
AutoReqProv: on
|
||||
BuildRequires: coreutils module-init-tools sparse
|
||||
BuildRequires: qubes-kernel-vm-support
|
||||
BuildRequires: dracut
|
||||
BuildRequires: busybox
|
||||
BuildRequires: bc
|
||||
BuildRequires: openssl
|
||||
BuildRequires: openssl-devel
|
||||
BuildRequires: python3-devel
|
||||
BuildRequires: gcc-plugin-devel
|
||||
BuildRequires: elfutils-libelf-devel
|
||||
BuildRequires: bison
|
||||
BuildRequires: flex
|
||||
BuildRequires: e2fsprogs
|
||||
|
||||
# gcc with support for BTI mitigation
|
||||
%if 0%{?fedora} == 23
|
||||
BuildRequires: gcc >= 5.3.1-6.qubes1
|
||||
%else
|
||||
%if 0%{?fedora} == 25
|
||||
BuildRequires: gcc >= 6.4.1-1.qubes1
|
||||
%else
|
||||
BuildRequires: gcc
|
||||
%endif
|
||||
%endif
|
||||
|
||||
# Needed for building GCC hardened plugins
|
||||
BuildRequires: gcc-c++
|
||||
|
||||
Provides: multiversion(kernel)
|
||||
Provides: %name = %kernelrelease
|
||||
|
||||
Provides: kernel-xen-dom0
|
||||
Provides: kernel-qubes-dom0
|
||||
Provides: kernel-qubes-dom0-pvops
|
||||
Provides: kernel-drm = 4.3.0
|
||||
Provides: kernel-drm-nouveau = 16
|
||||
Provides: kernel-modules-extra = %kernelrelease
|
||||
Provides: kernel-modeset = 1
|
||||
|
||||
Requires(pre): coreutils gawk
|
||||
Requires(post): dracut binutils
|
||||
Requires: qubes-core-dom0-linux-kernel-install
|
||||
|
||||
Conflicts: sysfsutils < 2.0
|
||||
# root-lvm only works with newer udevs
|
||||
Conflicts: udev < 118
|
||||
Conflicts: lvm2 < 2.02.33
|
||||
Provides: kernel = %kernelrelease
|
||||
Provides: kernel-uname-r = %kernelrelease
|
||||
|
||||
ExclusiveArch: x86_64
|
||||
|
||||
%if !%{prerelease}
|
||||
Source0: linux-%{upstream_version}.tar.xz
|
||||
%else
|
||||
Source0: linux-%{upstream_version}.tar.gz
|
||||
%endif
|
||||
Source5: wireguard-linux-compat-0.0.20200121.tar.xz
|
||||
Source6: macbook12-spi-driver-ddfbc7733542b8474a0e8f593aba91e06542be4f.tar.gz
|
||||
Source16: guards
|
||||
Source17: apply-patches
|
||||
Source18: mod-sign.sh
|
||||
Source33: check-for-config-changes
|
||||
Source34: gen-config
|
||||
Source100: config-base
|
||||
Source101: config-qubes
|
||||
%define modsign_cmd %{SOURCE18}
|
||||
|
||||
Patch0: 0001-xen-netfront-detach-crash.patch
|
||||
Patch1: 0002-mce-hide-EBUSY-initialization-error-on-Xen.patch
|
||||
Patch2: 0003-Log-error-code-of-EVTCHNOP_bind_pirq-failure.patch
|
||||
Patch3: 0004-pvops-respect-removable-xenstore-flag-for-block-devi.patch
|
||||
Patch4: 0005-pvops-xen-blkfront-handle-FDEJECT-as-detach-request-.patch
|
||||
Patch5: 0006-block-add-no_part_scan-module-parameter.patch
|
||||
Patch6: 0007-xen-Add-RING_COPY_RESPONSE.patch
|
||||
Patch7: 0008-xen-netfront-copy-response-out-of-shared-buffer-befo.patch
|
||||
Patch8: 0009-xen-netfront-do-not-use-data-already-exposed-to-back.patch
|
||||
Patch9: 0010-xen-netfront-add-range-check-for-Tx-response-id.patch
|
||||
Patch10: 0011-xen-blkfront-make-local-copy-of-response-before-usin.patch
|
||||
Patch11: 0012-xen-blkfront-prepare-request-locally-only-then-put-i.patch
|
||||
Patch12: 0013-xen-pcifront-pciback-Update-pciif.h-with-err-and-res.patch
|
||||
Patch13: 0014-xen-pciback-add-attribute-to-allow-MSI-enable-flag-w.patch
|
||||
|
||||
%description
|
||||
Qubes Dom0 kernel.
|
||||
|
||||
%prep
|
||||
SYMBOLS="xen-dom0 pvops"
|
||||
|
||||
# Unpack all sources and patches
|
||||
%autosetup -N -c -T -a 0
|
||||
|
||||
export LINUX_UPSTREAM_VERSION=%{upstream_version}
|
||||
|
||||
mkdir -p %kernel_build_dir
|
||||
|
||||
cd linux-%upstream_version
|
||||
%autopatch -p1
|
||||
|
||||
# drop EXTRAVERSION - possible -rc suffix already included in %release
|
||||
sed -i -e 's/^EXTRAVERSION = -rc.*/EXTRAVERSION =/' Makefile
|
||||
|
||||
%if 0%{?fedora} >= 31
|
||||
# Mangle /usr/bin/python shebangs to /usr/bin/python3
|
||||
# Mangle all Python shebangs to be Python 3 explicitly
|
||||
# -p preserves timestamps
|
||||
# -n prevents creating ~backup files
|
||||
# -i specifies the interpreter for the shebang
|
||||
# This fixes errors such as
|
||||
# *** ERROR: ambiguous python shebang in /usr/bin/kvm_stat: #!/usr/bin/python. Change it to python3 (or python2) explicitly.
|
||||
# We patch all sources below for which we got a report/error.
|
||||
pathfix.py -i "%{__python3} %{py3_shbang_opts}" -p -n \
|
||||
tools/kvm/kvm_stat/kvm_stat \
|
||||
scripts/show_delta \
|
||||
scripts/diffconfig \
|
||||
scripts/bloat-o-meter \
|
||||
tools/perf/tests/attr.py \
|
||||
tools/perf/scripts/python/stat-cpi.py \
|
||||
tools/perf/scripts/python/sched-migration.py \
|
||||
Documentation \
|
||||
scripts/gen_compile_commands.py
|
||||
%endif
|
||||
|
||||
cd %kernel_build_dir
|
||||
|
||||
# Create QubesOS config kernel
|
||||
%{SOURCE34} %{SOURCE100} %{SOURCE101}
|
||||
|
||||
%build_src_dir/scripts/config \
|
||||
--set-str CONFIG_LOCALVERSION -%release.%cpu_arch %{setup_config}
|
||||
|
||||
MAKE_ARGS="$MAKE_ARGS -C %build_src_dir O=$PWD KERNELRELEASE=%{kernelrelease}"
|
||||
|
||||
make prepare $MAKE_ARGS
|
||||
make scripts $MAKE_ARGS
|
||||
make scripts_basic $MAKE_ARGS
|
||||
krel=$(make -s kernelrelease $MAKE_ARGS)
|
||||
|
||||
if [ "$krel" != "%kernelrelease" ]; then
|
||||
echo "Kernel release mismatch: $krel != %kernelrelease" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
make clean $MAKE_ARGS
|
||||
|
||||
rm -f source
|
||||
find . ! -type d -printf '%%P\n' > %my_builddir/obj-files
|
||||
rm -rf %_builddir/u2mfn
|
||||
u2mfn_ver=`dkms status u2mfn|tail -n 1|cut -f 2 -d ' '|tr -d ':,:'`
|
||||
if [ -n "$u2mfn_ver" ]; then
|
||||
cp -r /usr/src/u2mfn-$u2mfn_ver %_builddir/u2mfn
|
||||
fi
|
||||
|
||||
rm -rf %_builddir/wireguard
|
||||
tar x -C %_builddir -Jpf %{SOURCE5}
|
||||
mv %_builddir/$(basename %{SOURCE5} .tar.xz) %_builddir/wireguard
|
||||
|
||||
rm -rf %_builddir/macbook12-spi-driver
|
||||
tar -x -C %_builddir -zf %{SOURCE6}
|
||||
mv %_builddir/$(basename %{SOURCE6} .tar.gz) %_builddir/macbook12-spi-driver
|
||||
|
||||
%build
|
||||
|
||||
cd %kernel_build_dir
|
||||
|
||||
make %{?_smp_mflags} all $MAKE_ARGS CONFIG_DEBUG_SECTION_MISMATCH=y
|
||||
|
||||
# Build u2mfn module
|
||||
if [ -d "%_builddir/u2mfn" ]; then
|
||||
make -C %kernel_build_dir M=%_builddir/u2mfn modules
|
||||
fi
|
||||
|
||||
if [ -d "%_builddir/wireguard" ]; then
|
||||
make -C %kernel_build_dir M=%_builddir/wireguard/src modules
|
||||
fi
|
||||
|
||||
# Build applespi, apple-ibridge, apple-ib-tb, apple-ib-als modules
|
||||
if [ -d "%_builddir/macbook12-spi-driver" ]; then
|
||||
make -C %kernel_build_dir M=%_builddir/macbook12-spi-driver modules
|
||||
fi
|
||||
|
||||
%define __modsign_install_post \
|
||||
if [ "%{signmodules}" -eq "1" ]; then \
|
||||
%{modsign_cmd} certs/signing_key.pem certs/signing_key.x509 $RPM_BUILD_ROOT/lib/modules/%kernelrelease/ \
|
||||
fi \
|
||||
%{nil}
|
||||
|
||||
#
|
||||
# Disgusting hack alert! We need to ensure we sign modules *after* all
|
||||
# invocations of strip occur, which is in __debug_install_post if
|
||||
# find-debuginfo.sh runs, and __os_install_post if not.
|
||||
#
|
||||
|
||||
%define __spec_install_post \
|
||||
%{?__debug_package:%{__debug_install_post}}\
|
||||
%{__arch_install_post}\
|
||||
%{__os_install_post}\
|
||||
%{?__remove_unwanted_dbginfo_install_post}\
|
||||
%{__modsign_install_post}
|
||||
|
||||
|
||||
%install
|
||||
|
||||
# get rid of /usr/lib/rpm/brp-strip-debug
|
||||
# strip removes too much from the vmlinux ELF binary
|
||||
export NO_BRP_STRIP_DEBUG=true
|
||||
export STRIP_KEEP_SYMTAB='*/vmlinux-*'
|
||||
|
||||
# /lib/modules/%kernelrelease-%build_flavor/build will be a stale symlink until the
|
||||
# kernel-devel package is installed. Don't check for stale symlinks
|
||||
# in the brp-symlink check:
|
||||
export NO_BRP_STALE_LINK_ERROR=yes
|
||||
|
||||
cd %kernel_build_dir
|
||||
|
||||
mkdir -p %buildroot/boot
|
||||
cp -p System.map %buildroot/boot/System.map-%kernelrelease
|
||||
cp -p arch/x86/boot/bzImage %buildroot/boot/vmlinuz-%kernelrelease
|
||||
cp .config %buildroot/boot/config-%kernelrelease
|
||||
|
||||
%if %install_vdso
|
||||
# Install the unstripped vdso's that are linked in the kernel image
|
||||
make vdso_install $MAKE_ARGS INSTALL_MOD_PATH=%buildroot
|
||||
%endif
|
||||
|
||||
# Create a dummy initramfs with roughly the size the real one will have.
|
||||
# That way, rpm will know that this package requires some additional
|
||||
# space in /boot.
|
||||
dd if=/dev/zero of=%buildroot/boot/initramfs-%kernelrelease.img \
|
||||
bs=1M count=20
|
||||
|
||||
gzip -c9 < Module.symvers > %buildroot/boot/symvers-%kernelrelease.gz
|
||||
|
||||
make modules_install $MAKE_ARGS INSTALL_MOD_PATH=%buildroot
|
||||
if [ -d "%_builddir/u2mfn" ]; then
|
||||
make modules_install $MAKE_ARGS INSTALL_MOD_PATH=%buildroot M=%_builddir/u2mfn
|
||||
fi
|
||||
if [ -d "%_builddir/wireguard" ]; then
|
||||
make modules_install $MAKE_ARGS INSTALL_MOD_PATH=%buildroot M=%_builddir/wireguard/src
|
||||
fi
|
||||
if [ -d "%_builddir/macbook12-spi-driver" ]; then
|
||||
make modules_install $MAKE_ARGS INSTALL_MOD_PATH=%buildroot M=%_builddir/macbook12-spi-driver
|
||||
fi
|
||||
|
||||
mkdir -p %buildroot/%src_install_dir
|
||||
|
||||
rm -f %buildroot/lib/modules/%kernelrelease/build
|
||||
rm -f %buildroot/lib/modules/%kernelrelease/source
|
||||
mkdir -p %buildroot/lib/modules/%kernelrelease/build
|
||||
(cd %buildroot/lib/modules/%kernelrelease ; ln -s build source)
|
||||
# dirs for additional modules per module-init-tools, kbuild/modules.txt
|
||||
mkdir -p %buildroot/lib/modules/%kernelrelease/extra
|
||||
mkdir -p %buildroot/lib/modules/%kernelrelease/updates
|
||||
mkdir -p %buildroot/lib/modules/%kernelrelease/weak-updates
|
||||
|
||||
pushd %build_src_dir
|
||||
cp --parents `find -type f -name "Makefile*" -o -name "Kconfig*"` %buildroot/lib/modules/%kernelrelease/build
|
||||
cp -a scripts %buildroot/lib/modules/%kernelrelease/build
|
||||
cp -a --parents arch/x86/include %buildroot/lib/modules/%kernelrelease/build/
|
||||
cp -a include %buildroot/lib/modules/%kernelrelease/build/include
|
||||
popd
|
||||
|
||||
cp Module.symvers %buildroot/lib/modules/%kernelrelease/build
|
||||
cp System.map %buildroot/lib/modules/%kernelrelease/build
|
||||
if [ -s Module.markers ]; then
|
||||
cp Module.markers %buildroot/lib/modules/%kernelrelease/build
|
||||
fi
|
||||
|
||||
rm -rf %buildroot/lib/modules/%kernelrelease/build/Documentation
|
||||
|
||||
# Remove useless scripts that creates ERROR with ambiguous shebang
|
||||
# that are removed too in Fedora
|
||||
rm -rf %buildroot/lib/modules/%kernelrelease/build/scripts/tracing
|
||||
rm -f %buildroot/lib/modules/%kernelrelease/build/scripts/spdxcheck.py
|
||||
|
||||
rm -f %buildroot/lib/modules/%kernelrelease/build/scripts/*.o
|
||||
rm -f %buildroot/lib/modules/%kernelrelease/build/scripts/*/*.o
|
||||
|
||||
cp -a scripts/* %buildroot/lib/modules/%kernelrelease/build/scripts/
|
||||
cp -a include/* %buildroot/lib/modules/%kernelrelease/build/include/
|
||||
cp -a --parents arch/x86/include/* %buildroot/lib/modules/%kernelrelease/build/
|
||||
if [ -f tools/objtool/objtool ]; then
|
||||
cp -a --parents tools/objtool %buildroot/lib/modules/%kernelrelease/build/
|
||||
pushd %build_src_dir
|
||||
cp -a --parents tools/objtool %buildroot/lib/modules/%kernelrelease/build/
|
||||
cp -a --parents tools/build/Build.include %buildroot/lib/modules/%kernelrelease/build/
|
||||
cp -a --parents tools/build/Build %buildroot/lib/modules/%kernelrelease/build/
|
||||
cp -a --parents tools/build/fixdep.c %buildroot/lib/modules/%kernelrelease/build/
|
||||
cp -a --parents tools/scripts/utilities.mak %buildroot/lib/modules/%kernelrelease/build/
|
||||
cp -a --parents tools/lib/str_error_r.c %buildroot/lib/modules/%kernelrelease/build/
|
||||
cp -a --parents tools/lib/string.c %buildroot/lib/modules/%kernelrelease/build/
|
||||
cp -a --parents tools/lib/subcmd/* %buildroot/lib/modules/%kernelrelease/build/
|
||||
popd
|
||||
fi
|
||||
|
||||
# disable GCC plugins for external modules build, to not fail if different gcc
|
||||
# version is used
|
||||
sed -e 's/^\(CONFIG_GCC_PLUGIN.*\)=y/# \1 is not set/' .config > \
|
||||
%buildroot/lib/modules/%kernelrelease/build/.config
|
||||
sed -e '/^#define CONFIG_GCC_PLUGIN/d' include/generated/autoconf.h > \
|
||||
%buildroot/lib/modules/%kernelrelease/build/include/generated/autoconf.h
|
||||
|
||||
# Copy .config to include/config/auto.conf so "make prepare" is unnecessary.
|
||||
cp %buildroot/lib/modules/%kernelrelease/build/.config %buildroot/lib/modules/%kernelrelease/build/include/config/auto.conf
|
||||
|
||||
# Make sure the Makefile and version.h have a matching timestamp so that
|
||||
# external modules can be built
|
||||
touch -r %buildroot/lib/modules/%kernelrelease/build/Makefile %buildroot/lib/modules/%kernelrelease/build/include/generated/uapi/linux/version.h
|
||||
touch -r %buildroot/lib/modules/%kernelrelease/build/.config %buildroot/lib/modules/%kernelrelease/build/include/config/auto.conf
|
||||
touch -r %buildroot/lib/modules/%kernelrelease/build/.config %buildroot/lib/modules/%kernelrelease/build/include/generated/autoconf.h
|
||||
|
||||
if test -s vmlinux.id; then
|
||||
cp vmlinux.id %buildroot/lib/modules/%kernelrelease/build/vmlinux.id
|
||||
else
|
||||
echo >&2 "*** WARNING *** no vmlinux build ID! ***"
|
||||
fi
|
||||
|
||||
#
|
||||
# save the vmlinux file for kernel debugging into the kernel-debuginfo rpm
|
||||
#
|
||||
%if %{with_debuginfo}
|
||||
mkdir -p %buildroot%{debuginfodir}/lib/modules/%kernelrelease
|
||||
cp vmlinux %buildroot%{debuginfodir}/lib/modules/%kernelrelease
|
||||
%endif
|
||||
|
||||
find %buildroot/lib/modules/%kernelrelease -name "*.ko" -type f >modnames
|
||||
|
||||
# mark modules executable so that strip-to-file can strip them
|
||||
xargs --no-run-if-empty chmod u+x < modnames
|
||||
|
||||
# Generate a list of modules for block and networking.
|
||||
|
||||
fgrep /drivers/ modnames | xargs --no-run-if-empty nm -upA |
|
||||
sed -n 's,^.*/\([^/]*\.ko\): *U \(.*\)$,\1 \2,p' > drivers.undef
|
||||
|
||||
collect_modules_list()
|
||||
{
|
||||
sed -r -n -e "s/^([^ ]+) \\.?($2)\$/\\1/p" drivers.undef |
|
||||
LC_ALL=C sort -u > %buildroot/lib/modules/%kernelrelease/modules.$1
|
||||
}
|
||||
|
||||
collect_modules_list networking \
|
||||
'register_netdev|ieee80211_register_hw|usbnet_probe'
|
||||
collect_modules_list block \
|
||||
'ata_scsi_ioctl|scsi_add_host|scsi_add_host_with_dma|blk_init_queue|register_mtd_blktrans|scsi_esp_register|scsi_register_device_handler'
|
||||
collect_modules_list drm \
|
||||
'drm_open|drm_init'
|
||||
collect_modules_list modesetting \
|
||||
'drm_crtc_init'
|
||||
|
||||
# detect missing or incorrect license tags
|
||||
rm -f modinfo
|
||||
while read i
|
||||
do
|
||||
echo -n "${i#%buildroot/lib/modules/%kernelrelease/} " >> modinfo
|
||||
/sbin/modinfo -l $i >> modinfo
|
||||
done < modnames
|
||||
|
||||
egrep -v \
|
||||
'GPL( v2)?$|Dual BSD/GPL$|Dual MPL/GPL$|GPL and additional rights$' \
|
||||
modinfo && exit 1
|
||||
|
||||
rm -f modinfo modnames
|
||||
|
||||
# Move the devel headers out of the root file system
|
||||
mkdir -p %buildroot/usr/src/kernels
|
||||
mv %buildroot/lib/modules/%kernelrelease/build/* %buildroot/%src_install_dir/
|
||||
mv %buildroot/lib/modules/%kernelrelease/build/.config %buildroot/%src_install_dir
|
||||
rmdir %buildroot/lib/modules/%kernelrelease/build
|
||||
ln -sf %src_install_dir %buildroot/lib/modules/%kernelrelease/build
|
||||
|
||||
# Abort if there are any undefined symbols
|
||||
msg="$(/sbin/depmod -F %buildroot/boot/System.map-%kernelrelease \
|
||||
-b %buildroot -ae %kernelrelease 2>&1)"
|
||||
|
||||
if [ $? -ne 0 ] || echo "$msg" | grep 'needs unknown symbol'; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# in case of no firmware built - place empty dir
|
||||
mkdir -p %buildroot/lib/firmware
|
||||
mv %buildroot/lib/firmware %buildroot/lib/firmware-all
|
||||
mkdir -p %buildroot/lib/firmware
|
||||
mv %buildroot/lib/firmware-all %buildroot/lib/firmware/%kernelrelease
|
||||
|
||||
# Prepare initramfs for Qubes VM
|
||||
mkdir -p %buildroot/%vm_install_dir
|
||||
PATH="/sbin:$PATH" dracut --nomdadmconf --nolvmconf \
|
||||
--kmoddir %buildroot/lib/modules/%kernelrelease \
|
||||
--modules "kernel-modules qubes-vm-simple" \
|
||||
--conf /dev/null --confdir /var/empty \
|
||||
-d "xenblk xen-blkfront cdrom ext4 jbd2 crc16 dm_snapshot" \
|
||||
%buildroot/%vm_install_dir/initramfs %kernelrelease || exit 1
|
||||
|
||||
# workaround for buggy dracut-044 in Fedora 25
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1431317
|
||||
# https://github.com/dracutdevs/dracut/issues/194
|
||||
modules_dep=$(lsinitrd "%buildroot/%vm_install_dir/initramfs" \
|
||||
"usr/lib/modules/%kernelrelease/modules.dep")
|
||||
if [ -z "$modules_dep" ]; then
|
||||
tmpdir=$(mktemp -d)
|
||||
zcat "%buildroot/%vm_install_dir/initramfs" | cpio -imd -D "$tmpdir" || exit 1
|
||||
mv "$tmpdir"/%buildroot/lib/modules/%kernelrelease/kernel \
|
||||
"$tmpdir"/lib/modules/%kernelrelease/ || exit 1
|
||||
depmod -F %buildroot/boot/System.map-%kernelrelease \
|
||||
-b "$tmpdir" -a %kernelrelease || exit 1
|
||||
pushd "$tmpdir"
|
||||
if [ -n "$SOURCE_DATE_EPOCH" ]; then
|
||||
find . -exec touch --no-dereference --date="@${SOURCE_DATE_EPOCH}" {} +
|
||||
fi
|
||||
find . -print0 | sort -z \
|
||||
| cpio --null -R 0:0 -H newc -o --reproducible --quiet \
|
||||
| gzip -n > %buildroot/%vm_install_dir/initramfs || exit 1
|
||||
popd
|
||||
fi
|
||||
|
||||
cp -p arch/x86/boot/bzImage %buildroot/%vm_install_dir/vmlinuz
|
||||
|
||||
# default kernel options for this kernel
|
||||
def_kernelopts="root=/dev/mapper/dmroot ro nomodeset console=hvc0"
|
||||
def_kernelopts="$def_kernelopts rd_NO_PLYMOUTH rd.plymouth.enable=0 plymouth.enable=0"
|
||||
if [ -e /usr/lib/dracut/modules.d/90qubes-vm-simple/xen-scrub-pages-supported ]; then
|
||||
# set xen_scrub_pages=0 _only_ when included initramfs does support
|
||||
# re-enabling it
|
||||
def_kernelopts="$def_kernelopts xen_scrub_pages=0"
|
||||
fi
|
||||
echo "$def_kernelopts " > %buildroot/%vm_install_dir/default-kernelopts-common.txt
|
||||
|
||||
# Modules for Qubes VM
|
||||
mkdir -p %buildroot%vm_install_dir/modules
|
||||
cp -a %buildroot/lib/modules/%kernelrelease %buildroot%vm_install_dir/modules/
|
||||
mkdir -p %buildroot%vm_install_dir/modules/firmware
|
||||
cp -a %buildroot/lib/firmware/%kernelrelease %buildroot%vm_install_dir/modules/firmware/
|
||||
|
||||
# Include kernel headers for Qubes VM in "/lib/modules" - so kernel-devel
|
||||
# package will be unnecessary there, regardless of distribution
|
||||
rm -f %buildroot%vm_install_dir/modules/%kernelrelease/build
|
||||
cp -a %buildroot/%src_install_dir %buildroot%vm_install_dir/modules/%kernelrelease/build
|
||||
|
||||
%if 0%{?fedora} >= 25
|
||||
# include kernel+initramfs also inside modules.img, for direct kernel boot with
|
||||
# stubdomain
|
||||
cp %buildroot%vm_install_dir/vmlinuz %buildroot%vm_install_dir/modules/
|
||||
cp %buildroot%vm_install_dir/initramfs %buildroot%vm_install_dir/modules/
|
||||
if [ -n "$SOURCE_DATE_EPOCH" ]; then
|
||||
find %buildroot%vm_install_dir/modules \
|
||||
-exec touch --no-dereference --date="@${SOURCE_DATE_EPOCH}" {} +
|
||||
fi
|
||||
PATH="/sbin:$PATH" mkfs.ext3 -d %buildroot%vm_install_dir/modules \
|
||||
-U dcee2318-92bd-47a5-a15d-e79d1412cdce \
|
||||
%buildroot%vm_install_dir/modules.img 1024M
|
||||
rm -rf %buildroot%vm_install_dir/modules
|
||||
%endif
|
||||
|
||||
# remove files that will be auto generated by depmod at rpm -i time
|
||||
for i in alias alias.bin ccwmap dep dep.bin ieee1394map inputmap isapnpmap ofmap pcimap seriomap symbols symbols.bin usbmap
|
||||
do
|
||||
rm -f %buildroot/lib/modules/%kernelrelease/modules.$i
|
||||
done
|
||||
|
||||
%post
|
||||
/sbin/depmod -a %{kernelrelease}
|
||||
|
||||
%posttrans
|
||||
# with kernel-4.14+ plymouth detects hvc0 serial console and forces text boot
|
||||
# we simply make plymouth ignore it to recover the splash screen
|
||||
if [ -f /etc/default/grub ]; then
|
||||
if ! grep -q plymouth.ignore-serial-consoles /etc/default/grub; then
|
||||
echo 'GRUB_CMDLINE_LINUX="$GRUB_CMDLINE_LINUX plymouth.ignore-serial-consoles"' >> /etc/default/grub
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -f /boot/efi/EFI/qubes/xen.cfg ]; then
|
||||
if ! grep -q plymouth.ignore-serial-consoles /boot/efi/EFI/qubes/xen.cfg; then
|
||||
sed -i 's/kernel=.*/& plymouth.ignore-serial-consoles/g' /boot/efi/EFI/qubes/xen.cfg
|
||||
fi
|
||||
fi
|
||||
|
||||
/bin/kernel-install add %{kernelrelease} /boot/vmlinuz-%{kernelrelease} || exit $?
|
||||
|
||||
# grubby (used by new-kernel-pkg) do not understand xen entries in grub2 config
|
||||
if [ -x /sbin/new-kernel-pkg -a -e /boot/grub2/grub.cfg ]; then
|
||||
grub2-mkconfig > /boot/grub2/grub.cfg
|
||||
fi
|
||||
|
||||
%preun
|
||||
/bin/kernel-install remove %{kernelrelease} /boot/vmlinuz-%{kernelrelease} || exit $?
|
||||
|
||||
%files
|
||||
%defattr(-, root, root)
|
||||
%ghost /boot/initramfs-%{kernelrelease}.img
|
||||
/boot/System.map-%{kernelrelease}
|
||||
/boot/config-%{kernelrelease}
|
||||
/boot/symvers-%kernelrelease.gz
|
||||
%attr(0644, root, root) /boot/vmlinuz-%{kernelrelease}
|
||||
/lib/firmware/%{kernelrelease}
|
||||
/lib/modules/%{kernelrelease}
|
||||
|
||||
%package devel
|
||||
Summary: Development files necessary for building kernel modules
|
||||
License: GPL v2 only
|
||||
Group: Development/Sources
|
||||
Provides: multiversion(kernel)
|
||||
Provides: %name-devel = %kernelrelease
|
||||
%if "%{?name_suffix}" != ""
|
||||
Provides: kernel-devel = %kernelrelease
|
||||
%endif
|
||||
Provides: kernel-devel-uname-r = %kernelrelease
|
||||
Requires: elfutils-libelf-devel
|
||||
AutoReqProv: on
|
||||
|
||||
%description devel
|
||||
This package contains files necessary for building kernel modules (and
|
||||
kernel module packages) against the kernel.
|
||||
|
||||
%post devel
|
||||
if [ -f /etc/sysconfig/kernel ]
|
||||
then
|
||||
. /etc/sysconfig/kernel || exit $?
|
||||
fi
|
||||
if [ "$HARDLINK" != "no" -a -x /usr/sbin/hardlink ]
|
||||
then
|
||||
(cd /usr/src/kernels/%{kernelrelease} &&
|
||||
/usr/bin/find . -type f | while read f; do
|
||||
hardlink -c /usr/src/kernels/*.fc*.*/$f $f
|
||||
done)
|
||||
fi
|
||||
|
||||
|
||||
%files devel
|
||||
%defattr(-,root,root)
|
||||
/usr/src/kernels/%{kernelrelease}
|
||||
|
||||
|
||||
%package qubes-vm
|
||||
Summary: The Xen Kernel
|
||||
Version: %{version}
|
||||
Release: %{rel}
|
||||
License: GPL v2 only
|
||||
Group: System/Kernel
|
||||
Url: http://www.kernel.org/
|
||||
AutoReqProv: on
|
||||
BuildRequires: coreutils module-init-tools sparse
|
||||
Provides: multiversion(kernel-qubes-vm)
|
||||
|
||||
Provides: kernel-xen-domU
|
||||
Provides: kernel-qubes-domU
|
||||
|
||||
Requires(pre): coreutils gawk
|
||||
Requires(post): dracut
|
||||
Requires(post): qubes-core-dom0
|
||||
|
||||
Conflicts: sysfsutils < 2.0
|
||||
# root-lvm only works with newer udevs
|
||||
Conflicts: udev < 118
|
||||
Conflicts: lvm2 < 2.02.33
|
||||
Provides: kernel-qubes-vm = %kernelrelease
|
||||
|
||||
%description qubes-vm
|
||||
Qubes domU kernel.
|
||||
|
||||
%post qubes-vm
|
||||
|
||||
%if 0%{?fedora} < 25
|
||||
mkdir /tmp/qubes-modules-%kernelrelease
|
||||
truncate -s 500M /tmp/qubes-modules-%kernelrelease.img
|
||||
mkfs -t ext3 -F /tmp/qubes-modules-%kernelrelease.img > /dev/null
|
||||
mount /tmp/qubes-modules-%kernelrelease.img /tmp/qubes-modules-%kernelrelease -o loop
|
||||
cp -a -t /tmp/qubes-modules-%kernelrelease %vm_install_dir/modules/%kernelrelease
|
||||
mkdir /tmp/qubes-modules-%kernelrelease/firmware
|
||||
cp -a -t /tmp/qubes-modules-%kernelrelease/firmware %vm_install_dir/modules/firmware/%kernelrelease
|
||||
cp %vm_install_dir/vmlinuz /tmp/qubes-modules-%kernelrelease/
|
||||
cp %vm_install_dir/initramfs /tmp/qubes-modules-%kernelrelease/
|
||||
umount /tmp/qubes-modules-%kernelrelease
|
||||
rmdir /tmp/qubes-modules-%kernelrelease
|
||||
mv /tmp/qubes-modules-%kernelrelease.img %vm_install_dir/modules.img
|
||||
%endif
|
||||
|
||||
current_default="$(qubes-prefs default-kernel)"
|
||||
current_default_path="/var/lib/qubes/vm-kernels/$current_default"
|
||||
current_default_package="$(rpm --qf '%{NAME}' -qf "$current_default_path")"
|
||||
if [ "$current_default_package" = "%{name}-qubes-vm" ]; then
|
||||
# Set kernel as default VM kernel if we are the default package.
|
||||
|
||||
# If qubes-prefs isn't installed yet, the default kernel will be set by %post
|
||||
# of qubes-core-dom0
|
||||
type qubes-prefs &>/dev/null && qubes-prefs --set default-kernel %upstream_version-%plainrel
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
%preun qubes-vm
|
||||
|
||||
if [ "`qubes-prefs -g default-kernel`" == "%upstream_version-%plainrel" ]; then
|
||||
echo "This kernel version is set as default VM kernel, cannot remove"
|
||||
exit 1
|
||||
fi
|
||||
if qvm-ls --kernel | grep -qw "%upstream_version-%plainrel"; then
|
||||
echo "This kernel version is used by at least one VM, cannot remove"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
%files qubes-vm
|
||||
%defattr(-, root, root)
|
||||
%dir %vm_install_dir
|
||||
%if 0%{?fedora} < 25
|
||||
%ghost %attr(0644, root, root) %vm_install_dir/modules.img
|
||||
%else
|
||||
%attr(0644, root, root) %vm_install_dir/modules.img
|
||||
%endif
|
||||
%attr(0644, root, root) %vm_install_dir/initramfs
|
||||
%attr(0644, root, root) %vm_install_dir/vmlinuz
|
||||
%if 0%{?fedora} < 25
|
||||
%vm_install_dir/modules
|
||||
%endif
|
||||
%attr(0644, root, root) %vm_install_dir/default-kernelopts-common.txt
|
||||
|
||||
%changelog
|
||||
@CHANGELOG@
|
37
mod-sign.sh
Executable file
37
mod-sign.sh
Executable file
@ -0,0 +1,37 @@
|
||||
#! /bin/bash
|
||||
|
||||
# The modules_sign target checks for corresponding .o files for every .ko that
|
||||
# is signed. This doesn't work for package builds which re-use the same build
|
||||
# directory for every flavour, and the .config may change between flavours.
|
||||
# So instead of using this script to just sign lib/modules/$KernelVer/extra,
|
||||
# sign all .ko in the buildroot.
|
||||
|
||||
# This essentially duplicates the 'modules_sign' Kbuild target and runs the
|
||||
# same commands for those modules.
|
||||
|
||||
MODSECKEY=$1
|
||||
MODPUBKEY=$2
|
||||
moddir=$3
|
||||
|
||||
modules=`find $moddir -type f -name '*.ko'`
|
||||
|
||||
NPROC=`nproc`
|
||||
[ -z "$NPROC" ] && NPROC=1
|
||||
|
||||
# NB: this loop runs 2000+ iterations. Try to be fast.
|
||||
echo "$modules" | xargs -r -n16 -P $NPROC sh -c "
|
||||
for mod; do
|
||||
./scripts/sign-file sha256 $MODSECKEY $MODPUBKEY \$mod
|
||||
rm -f \$mod.sig \$mod.dig
|
||||
done
|
||||
" DUMMYARG0 # xargs appends ARG1 ARG2..., which go into $mod in for loop.
|
||||
|
||||
RANDOMMOD=$(echo "$modules" | sort -R | head -n 1)
|
||||
if [ "~Module signature appended~" != "$(tail -c 28 $RANDOMMOD)" ]; then
|
||||
echo "*****************************"
|
||||
echo "*** Modules are unsigned! ***"
|
||||
echo "*****************************"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
@ -1,64 +0,0 @@
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Tue, 20 Jul 2010 06:57:08 -0700
|
||||
Subject: AppArmor: Allow dfa backward compatibility with broken userspace
|
||||
Patch-mainline: 2.6.37?
|
||||
|
||||
The apparmor_parser when compiling policy could generate invalid dfas
|
||||
that did not have sufficient padding to avoid invalid references, when
|
||||
used by the kernel. The kernels check to verify the next/check table
|
||||
size was broken meaning invalid dfas were being created by userspace
|
||||
and not caught.
|
||||
|
||||
To remain compatible with old tools that are not fixed, pad the loaded
|
||||
dfas next/check table. The dfa's themselves are valid except for the
|
||||
high padding for potentially invalid transitions (high bounds error),
|
||||
which have a maximimum is 256 entries. So just allocate an extra null filled
|
||||
256 entries for the next/check tables. This will guarentee all bounds
|
||||
are good and invalid transitions go to the null (0) state.
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Jeff Mahoney <jeffm@suse.com>
|
||||
---
|
||||
security/apparmor/match.c | 17 +++++++++++++++++
|
||||
1 file changed, 17 insertions(+)
|
||||
|
||||
--- a/security/apparmor/match.c
|
||||
+++ b/security/apparmor/match.c
|
||||
@@ -57,8 +57,17 @@ static struct table_header *unpack_table
|
||||
if (bsize < tsize)
|
||||
goto out;
|
||||
|
||||
+ /* Pad table allocation for next/check by 256 entries to remain
|
||||
+ * backwards compatible with old (buggy) tools and remain safe without
|
||||
+ * run time checks
|
||||
+ */
|
||||
+ if (th.td_id == YYTD_ID_NXT || th.td_id == YYTD_ID_CHK)
|
||||
+ tsize += 256 * th.td_flags;
|
||||
+
|
||||
table = kvmalloc(tsize);
|
||||
if (table) {
|
||||
+ /* ensure the pad is clear, else there will be errors */
|
||||
+ memset(table, 0, tsize);
|
||||
*table = th;
|
||||
if (th.td_flags == YYTD_DATA8)
|
||||
UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
|
||||
@@ -134,11 +143,19 @@ static int verify_dfa(struct aa_dfa *dfa
|
||||
goto out;
|
||||
|
||||
if (flags & DFA_FLAG_VERIFY_STATES) {
|
||||
+ int warning = 0;
|
||||
for (i = 0; i < state_count; i++) {
|
||||
if (DEFAULT_TABLE(dfa)[i] >= state_count)
|
||||
goto out;
|
||||
/* TODO: do check that DEF state recursion terminates */
|
||||
if (BASE_TABLE(dfa)[i] + 255 >= trans_count) {
|
||||
+ if (warning)
|
||||
+ continue;
|
||||
+ printk(KERN_WARNING "AppArmor DFA next/check "
|
||||
+ "upper bounds error fixed, upgrade "
|
||||
+ "user space tools \n");
|
||||
+ warning = 1;
|
||||
+ } else if (BASE_TABLE(dfa)[i] >= trans_count) {
|
||||
printk(KERN_ERR "AppArmor DFA next/check upper "
|
||||
"bounds error\n");
|
||||
goto out;
|
@ -1,379 +0,0 @@
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Thu, 22 Jul 2010 02:32:02 -0700
|
||||
Subject: AppArmor: compatibility patch for v5 interface
|
||||
Patch-mainline: 2.6.37?
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Jeff Mahoney <jeffm@suse.com>
|
||||
---
|
||||
security/apparmor/Kconfig | 9 +
|
||||
security/apparmor/Makefile | 2
|
||||
security/apparmor/apparmorfs-24.c | 287 +++++++++++++++++++++++++++++++++
|
||||
security/apparmor/apparmorfs.c | 18 +-
|
||||
security/apparmor/include/apparmorfs.h | 6
|
||||
5 files changed, 320 insertions(+), 2 deletions(-)
|
||||
create mode 100644 security/apparmor/apparmorfs-24.c
|
||||
|
||||
--- a/security/apparmor/Kconfig
|
||||
+++ b/security/apparmor/Kconfig
|
||||
@@ -29,3 +29,12 @@ config SECURITY_APPARMOR_BOOTPARAM_VALUE
|
||||
boot.
|
||||
|
||||
If you are unsure how to answer this question, answer 1.
|
||||
+
|
||||
+config SECURITY_APPARMOR_COMPAT_24
|
||||
+ bool "Enable AppArmor 2.4 compatability"
|
||||
+ depends on SECURITY_APPARMOR
|
||||
+ default y
|
||||
+ help
|
||||
+ This option enables compatability with AppArmor 2.4. It is
|
||||
+ recommended if compatability with older versions of AppArmor
|
||||
+ is desired.
|
||||
--- a/security/apparmor/Makefile
|
||||
+++ b/security/apparmor/Makefile
|
||||
@@ -6,6 +6,8 @@ apparmor-y := apparmorfs.o audit.o capab
|
||||
path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
|
||||
resource.o sid.o file.o net.o
|
||||
|
||||
+apparmor-$(CONFIG_SECURITY_APPARMOR_COMPAT_24) += apparmorfs-24.o
|
||||
+
|
||||
clean-files: capability_names.h af_names.h
|
||||
|
||||
quiet_cmd_make-caps = GEN $@
|
||||
--- /dev/null
|
||||
+++ b/security/apparmor/apparmorfs-24.c
|
||||
@@ -0,0 +1,287 @@
|
||||
+/*
|
||||
+ * AppArmor security module
|
||||
+ *
|
||||
+ * This file contains AppArmor /sys/kernel/secrutiy/apparmor interface functions
|
||||
+ *
|
||||
+ * Copyright (C) 1998-2008 Novell/SUSE
|
||||
+ * Copyright 2009-2010 Canonical Ltd.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public License as
|
||||
+ * published by the Free Software Foundation, version 2 of the
|
||||
+ * License.
|
||||
+ *
|
||||
+ *
|
||||
+ * This file contain functions providing an interface for <= AppArmor 2.4
|
||||
+ * compatibility. It is dependent on CONFIG_SECURITY_APPARMOR_COMPAT_24
|
||||
+ * being set (see Makefile).
|
||||
+ */
|
||||
+
|
||||
+#include <linux/security.h>
|
||||
+#include <linux/vmalloc.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/seq_file.h>
|
||||
+#include <linux/uaccess.h>
|
||||
+#include <linux/namei.h>
|
||||
+
|
||||
+#include "include/apparmor.h"
|
||||
+#include "include/audit.h"
|
||||
+#include "include/context.h"
|
||||
+#include "include/policy.h"
|
||||
+
|
||||
+
|
||||
+/* apparmor/matching */
|
||||
+static ssize_t aa_matching_read(struct file *file, char __user *buf,
|
||||
+ size_t size, loff_t *ppos)
|
||||
+{
|
||||
+ const char matching[] = "pattern=aadfa audit perms=crwxamlk/ "
|
||||
+ "user::other";
|
||||
+
|
||||
+ return simple_read_from_buffer(buf, size, ppos, matching,
|
||||
+ sizeof(matching) - 1);
|
||||
+}
|
||||
+
|
||||
+const struct file_operations aa_fs_matching_fops = {
|
||||
+ .read = aa_matching_read,
|
||||
+};
|
||||
+
|
||||
+/* apparmor/features */
|
||||
+static ssize_t aa_features_read(struct file *file, char __user *buf,
|
||||
+ size_t size, loff_t *ppos)
|
||||
+{
|
||||
+ const char features[] = "file=3.1 capability=2.0 network=1.0 "
|
||||
+ "change_hat=1.5 change_profile=1.1 " "aanamespaces=1.1 rlimit=1.1";
|
||||
+
|
||||
+ return simple_read_from_buffer(buf, size, ppos, features,
|
||||
+ sizeof(features) - 1);
|
||||
+}
|
||||
+
|
||||
+const struct file_operations aa_fs_features_fops = {
|
||||
+ .read = aa_features_read,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * __next_namespace - find the next namespace to list
|
||||
+ * @root: root namespace to stop search at (NOT NULL)
|
||||
+ * @ns: current ns position (NOT NULL)
|
||||
+ *
|
||||
+ * Find the next namespace from @ns under @root and handle all locking needed
|
||||
+ * while switching current namespace.
|
||||
+ *
|
||||
+ * Returns: next namespace or NULL if at last namespace under @root
|
||||
+ * NOTE: will not unlock root->lock
|
||||
+ */
|
||||
+static struct aa_namespace *__next_namespace(struct aa_namespace *root,
|
||||
+ struct aa_namespace *ns)
|
||||
+{
|
||||
+ struct aa_namespace *parent;
|
||||
+
|
||||
+ /* is next namespace a child */
|
||||
+ if (!list_empty(&ns->sub_ns)) {
|
||||
+ struct aa_namespace *next;
|
||||
+ next = list_first_entry(&ns->sub_ns, typeof(*ns), base.list);
|
||||
+ read_lock(&next->lock);
|
||||
+ return next;
|
||||
+ }
|
||||
+
|
||||
+ /* check if the next ns is a sibling, parent, gp, .. */
|
||||
+ parent = ns->parent;
|
||||
+ while (parent) {
|
||||
+ read_unlock(&ns->lock);
|
||||
+ list_for_each_entry_continue(ns, &parent->sub_ns, base.list) {
|
||||
+ read_lock(&ns->lock);
|
||||
+ return ns;
|
||||
+ }
|
||||
+ if (parent == root)
|
||||
+ return NULL;
|
||||
+ ns = parent;
|
||||
+ parent = parent->parent;
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * __first_profile - find the first profile in a namespace
|
||||
+ * @root: namespace that is root of profiles being displayed (NOT NULL)
|
||||
+ * @ns: namespace to start in (NOT NULL)
|
||||
+ *
|
||||
+ * Returns: unrefcounted profile or NULL if no profile
|
||||
+ */
|
||||
+static struct aa_profile *__first_profile(struct aa_namespace *root,
|
||||
+ struct aa_namespace *ns)
|
||||
+{
|
||||
+ for ( ; ns; ns = __next_namespace(root, ns)) {
|
||||
+ if (!list_empty(&ns->base.profiles))
|
||||
+ return list_first_entry(&ns->base.profiles,
|
||||
+ struct aa_profile, base.list);
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * __next_profile - step to the next profile in a profile tree
|
||||
+ * @profile: current profile in tree (NOT NULL)
|
||||
+ *
|
||||
+ * Perform a depth first taversal on the profile tree in a namespace
|
||||
+ *
|
||||
+ * Returns: next profile or NULL if done
|
||||
+ * Requires: profile->ns.lock to be held
|
||||
+ */
|
||||
+static struct aa_profile *__next_profile(struct aa_profile *p)
|
||||
+{
|
||||
+ struct aa_profile *parent;
|
||||
+ struct aa_namespace *ns = p->ns;
|
||||
+
|
||||
+ /* is next profile a child */
|
||||
+ if (!list_empty(&p->base.profiles))
|
||||
+ return list_first_entry(&p->base.profiles, typeof(*p),
|
||||
+ base.list);
|
||||
+
|
||||
+ /* is next profile a sibling, parent sibling, gp, subling, .. */
|
||||
+ parent = p->parent;
|
||||
+ while (parent) {
|
||||
+ list_for_each_entry_continue(p, &parent->base.profiles,
|
||||
+ base.list)
|
||||
+ return p;
|
||||
+ p = parent;
|
||||
+ parent = parent->parent;
|
||||
+ }
|
||||
+
|
||||
+ /* is next another profile in the namespace */
|
||||
+ list_for_each_entry_continue(p, &ns->base.profiles, base.list)
|
||||
+ return p;
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * next_profile - step to the next profile in where ever it may be
|
||||
+ * @root: root namespace (NOT NULL)
|
||||
+ * @profile: current profile (NOT NULL)
|
||||
+ *
|
||||
+ * Returns: next profile or NULL if there isn't one
|
||||
+ */
|
||||
+static struct aa_profile *next_profile(struct aa_namespace *root,
|
||||
+ struct aa_profile *profile)
|
||||
+{
|
||||
+ struct aa_profile *next = __next_profile(profile);
|
||||
+ if (next)
|
||||
+ return next;
|
||||
+
|
||||
+ /* finished all profiles in namespace move to next namespace */
|
||||
+ return __first_profile(root, __next_namespace(root, profile->ns));
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * p_start - start a depth first traversal of profile tree
|
||||
+ * @f: seq_file to fill
|
||||
+ * @pos: current position
|
||||
+ *
|
||||
+ * Returns: first profile under current namespace or NULL if none found
|
||||
+ *
|
||||
+ * acquires first ns->lock
|
||||
+ */
|
||||
+static void *p_start(struct seq_file *f, loff_t *pos)
|
||||
+ __acquires(root->lock)
|
||||
+{
|
||||
+ struct aa_profile *profile = NULL;
|
||||
+ struct aa_namespace *root = aa_current_profile()->ns;
|
||||
+ loff_t l = *pos;
|
||||
+ f->private = aa_get_namespace(root);
|
||||
+
|
||||
+
|
||||
+ /* find the first profile */
|
||||
+ read_lock(&root->lock);
|
||||
+ profile = __first_profile(root, root);
|
||||
+
|
||||
+ /* skip to position */
|
||||
+ for (; profile && l > 0; l--)
|
||||
+ profile = next_profile(root, profile);
|
||||
+
|
||||
+ return profile;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * p_next - read the next profile entry
|
||||
+ * @f: seq_file to fill
|
||||
+ * @p: profile previously returned
|
||||
+ * @pos: current position
|
||||
+ *
|
||||
+ * Returns: next profile after @p or NULL if none
|
||||
+ *
|
||||
+ * may acquire/release locks in namespace tree as necessary
|
||||
+ */
|
||||
+static void *p_next(struct seq_file *f, void *p, loff_t *pos)
|
||||
+{
|
||||
+ struct aa_profile *profile = p;
|
||||
+ struct aa_namespace *root = f->private;
|
||||
+ (*pos)++;
|
||||
+
|
||||
+ return next_profile(root, profile);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * p_stop - stop depth first traversal
|
||||
+ * @f: seq_file we are filling
|
||||
+ * @p: the last profile writen
|
||||
+ *
|
||||
+ * Release all locking done by p_start/p_next on namespace tree
|
||||
+ */
|
||||
+static void p_stop(struct seq_file *f, void *p)
|
||||
+ __releases(root->lock)
|
||||
+{
|
||||
+ struct aa_profile *profile = p;
|
||||
+ struct aa_namespace *root = f->private, *ns;
|
||||
+
|
||||
+ if (profile) {
|
||||
+ for (ns = profile->ns; ns && ns != root; ns = ns->parent)
|
||||
+ read_unlock(&ns->lock);
|
||||
+ }
|
||||
+ read_unlock(&root->lock);
|
||||
+ aa_put_namespace(root);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * seq_show_profile - show a profile entry
|
||||
+ * @f: seq_file to file
|
||||
+ * @p: current position (profile) (NOT NULL)
|
||||
+ *
|
||||
+ * Returns: error on failure
|
||||
+ */
|
||||
+static int seq_show_profile(struct seq_file *f, void *p)
|
||||
+{
|
||||
+ struct aa_profile *profile = (struct aa_profile *)p;
|
||||
+ struct aa_namespace *root = f->private;
|
||||
+
|
||||
+ if (profile->ns != root)
|
||||
+ seq_printf(f, ":%s://", aa_ns_name(root, profile->ns));
|
||||
+ seq_printf(f, "%s (%s)\n", profile->base.hname,
|
||||
+ COMPLAIN_MODE(profile) ? "complain" : "enforce");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct seq_operations aa_fs_profiles_op = {
|
||||
+ .start = p_start,
|
||||
+ .next = p_next,
|
||||
+ .stop = p_stop,
|
||||
+ .show = seq_show_profile,
|
||||
+};
|
||||
+
|
||||
+static int profiles_open(struct inode *inode, struct file *file)
|
||||
+{
|
||||
+ return seq_open(file, &aa_fs_profiles_op);
|
||||
+}
|
||||
+
|
||||
+static int profiles_release(struct inode *inode, struct file *file)
|
||||
+{
|
||||
+ return seq_release(inode, file);
|
||||
+}
|
||||
+
|
||||
+const struct file_operations aa_fs_profiles_fops = {
|
||||
+ .open = profiles_open,
|
||||
+ .read = seq_read,
|
||||
+ .llseek = seq_lseek,
|
||||
+ .release = profiles_release,
|
||||
+};
|
||||
--- a/security/apparmor/apparmorfs.c
|
||||
+++ b/security/apparmor/apparmorfs.c
|
||||
@@ -182,7 +182,11 @@ void __init aa_destroy_aafs(void)
|
||||
aafs_remove(".remove");
|
||||
aafs_remove(".replace");
|
||||
aafs_remove(".load");
|
||||
-
|
||||
+#ifdef CONFIG_SECURITY_APPARMOR_COMPAT_24
|
||||
+ aafs_remove("profiles");
|
||||
+ aafs_remove("matching");
|
||||
+ aafs_remove("features");
|
||||
+#endif
|
||||
securityfs_remove(aa_fs_dentry);
|
||||
aa_fs_dentry = NULL;
|
||||
}
|
||||
@@ -213,7 +217,17 @@ int __init aa_create_aafs(void)
|
||||
aa_fs_dentry = NULL;
|
||||
goto error;
|
||||
}
|
||||
-
|
||||
+#ifdef CONFIG_SECURITY_APPARMOR_COMPAT_24
|
||||
+ error = aafs_create("matching", 0444, &aa_fs_matching_fops);
|
||||
+ if (error)
|
||||
+ goto error;
|
||||
+ error = aafs_create("features", 0444, &aa_fs_features_fops);
|
||||
+ if (error)
|
||||
+ goto error;
|
||||
+#endif
|
||||
+ error = aafs_create("profiles", 0440, &aa_fs_profiles_fops);
|
||||
+ if (error)
|
||||
+ goto error;
|
||||
error = aafs_create(".load", 0640, &aa_fs_profile_load);
|
||||
if (error)
|
||||
goto error;
|
||||
--- a/security/apparmor/include/apparmorfs.h
|
||||
+++ b/security/apparmor/include/apparmorfs.h
|
||||
@@ -17,4 +17,10 @@
|
||||
|
||||
extern void __init aa_destroy_aafs(void);
|
||||
|
||||
+#ifdef CONFIG_SECURITY_APPARMOR_COMPAT_24
|
||||
+extern const struct file_operations aa_fs_matching_fops;
|
||||
+extern const struct file_operations aa_fs_features_fops;
|
||||
+extern const struct file_operations aa_fs_profiles_fops;
|
||||
+#endif
|
||||
+
|
||||
#endif /* __AA_APPARMORFS_H */
|
@ -1,518 +0,0 @@
|
||||
From: John Johansen <john.johansen@canonical.com>
|
||||
Date: Mon, 4 Oct 2010 15:03:36 -0700
|
||||
Subject: AppArmor: compatibility patch for v5 network control
|
||||
Patch-mainline: 2.6.37?
|
||||
|
||||
Add compatibility for v5 network rules.
|
||||
|
||||
Signed-off-by: John Johansen <john.johansen@canonical.com>
|
||||
Acked-by: Jeff Mahoney <jeffm@suse.com>
|
||||
---
|
||||
include/linux/lsm_audit.h | 4
|
||||
security/apparmor/Makefile | 6 +
|
||||
security/apparmor/include/net.h | 40 ++++++++
|
||||
security/apparmor/include/policy.h | 3
|
||||
security/apparmor/lsm.c | 112 ++++++++++++++++++++++
|
||||
security/apparmor/net.c | 170 ++++++++++++++++++++++++++++++++++
|
||||
security/apparmor/policy.c | 1
|
||||
security/apparmor/policy_unpack.c | 48 +++++++++
|
||||
8 files changed, 381 insertions(+), 2 deletions(-)
|
||||
create mode 100644 security/apparmor/include/net.h
|
||||
create mode 100644 security/apparmor/net.c
|
||||
|
||||
--- a/include/linux/lsm_audit.h
|
||||
+++ b/include/linux/lsm_audit.h
|
||||
@@ -123,6 +123,10 @@ struct common_audit_data {
|
||||
u32 denied;
|
||||
uid_t ouid;
|
||||
} fs;
|
||||
+ struct {
|
||||
+ int type, protocol;
|
||||
+ struct sock *sk;
|
||||
+ } net;
|
||||
};
|
||||
} apparmor_audit_data;
|
||||
#endif
|
||||
--- a/security/apparmor/Makefile
|
||||
+++ b/security/apparmor/Makefile
|
||||
@@ -4,17 +4,21 @@ obj-$(CONFIG_SECURITY_APPARMOR) += appar
|
||||
|
||||
apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
|
||||
path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
|
||||
- resource.o sid.o file.o
|
||||
+ resource.o sid.o file.o net.o
|
||||
|
||||
clean-files: capability_names.h af_names.h
|
||||
|
||||
quiet_cmd_make-caps = GEN $@
|
||||
cmd_make-caps = echo "static const char *capability_names[] = {" > $@ ; sed -n -e "/CAP_FS_MASK/d" -e "s/^\#define[ \\t]\\+CAP_\\([A-Z0-9_]\\+\\)[ \\t]\\+\\([0-9]\\+\\)\$$/[\\2] = \"\\1\",/p" $< | tr A-Z a-z >> $@ ; echo "};" >> $@
|
||||
|
||||
+quiet_cmd_make-af = GEN $@
|
||||
+cmd_make-af = echo "static const char *address_family_names[] = {" > $@ ; sed -n -e "/AF_MAX/d" -e "/AF_LOCAL/d" -e "s/^\#define[ \\t]\\+AF_\\([A-Z0-9_]\\+\\)[ \\t]\\+\\([0-9]\\+\\)\\(.*\\)\$$/[\\2] = \"\\1\",/p" $< | tr A-Z a-z >> $@ ; echo "};" >> $@
|
||||
+
|
||||
quiet_cmd_make-rlim = GEN $@
|
||||
cmd_make-rlim = echo "static const char *rlim_names[] = {" > $@ ; sed -n --e "/AF_MAX/d" -e "s/^\# \\?define[ \\t]\\+RLIMIT_\\([A-Z0-9_]\\+\\)[ \\t]\\+\\([0-9]\\+\\)\\(.*\\)\$$/[\\2] = \"\\1\",/p" $< | tr A-Z a-z >> $@ ; echo "};" >> $@ ; echo "static const int rlim_map[] = {" >> $@ ; sed -n -e "/AF_MAX/d" -e "s/^\# \\?define[ \\t]\\+\\(RLIMIT_[A-Z0-9_]\\+\\)[ \\t]\\+\\([0-9]\\+\\)\\(.*\\)\$$/\\1,/p" $< >> $@ ; echo "};" >> $@
|
||||
|
||||
$(obj)/capability.o : $(obj)/capability_names.h
|
||||
+$(obj)/net.o : $(obj)/af_names.h
|
||||
$(obj)/resource.o : $(obj)/rlim_names.h
|
||||
$(obj)/capability_names.h : $(srctree)/include/linux/capability.h
|
||||
$(call cmd,make-caps)
|
||||
--- /dev/null
|
||||
+++ b/security/apparmor/include/net.h
|
||||
@@ -0,0 +1,40 @@
|
||||
+/*
|
||||
+ * AppArmor security module
|
||||
+ *
|
||||
+ * This file contains AppArmor network mediation definitions.
|
||||
+ *
|
||||
+ * Copyright (C) 1998-2008 Novell/SUSE
|
||||
+ * Copyright 2009-2010 Canonical Ltd.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public License as
|
||||
+ * published by the Free Software Foundation, version 2 of the
|
||||
+ * License.
|
||||
+ */
|
||||
+
|
||||
+#ifndef __AA_NET_H
|
||||
+#define __AA_NET_H
|
||||
+
|
||||
+#include <net/sock.h>
|
||||
+
|
||||
+/* struct aa_net - network confinement data
|
||||
+ * @allowed: basic network families permissions
|
||||
+ * @audit_network: which network permissions to force audit
|
||||
+ * @quiet_network: which network permissions to quiet rejects
|
||||
+ */
|
||||
+struct aa_net {
|
||||
+ u16 allow[AF_MAX];
|
||||
+ u16 audit[AF_MAX];
|
||||
+ u16 quiet[AF_MAX];
|
||||
+};
|
||||
+
|
||||
+extern int aa_net_perm(int op, struct aa_profile *profile, u16 family,
|
||||
+ int type, int protocol, struct sock *sk);
|
||||
+extern int aa_revalidate_sk(int op, struct sock *sk);
|
||||
+
|
||||
+static inline void aa_free_net_rules(struct aa_net *new)
|
||||
+{
|
||||
+ /* NOP */
|
||||
+}
|
||||
+
|
||||
+#endif /* __AA_NET_H */
|
||||
--- a/security/apparmor/include/policy.h
|
||||
+++ b/security/apparmor/include/policy.h
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "capability.h"
|
||||
#include "domain.h"
|
||||
#include "file.h"
|
||||
+#include "net.h"
|
||||
#include "resource.h"
|
||||
|
||||
extern const char *profile_mode_names[];
|
||||
@@ -145,6 +146,7 @@ struct aa_namespace {
|
||||
* @size: the memory consumed by this profiles rules
|
||||
* @file: The set of rules governing basic file access and domain transitions
|
||||
* @caps: capabilities for the profile
|
||||
+ * @net: network controls for the profile
|
||||
* @rlimits: rlimits for the profile
|
||||
*
|
||||
* The AppArmor profile contains the basic confinement data. Each profile
|
||||
@@ -181,6 +183,7 @@ struct aa_profile {
|
||||
|
||||
struct aa_file_rules file;
|
||||
struct aa_caps caps;
|
||||
+ struct aa_net net;
|
||||
struct aa_rlimit rlimits;
|
||||
};
|
||||
|
||||
--- a/security/apparmor/lsm.c
|
||||
+++ b/security/apparmor/lsm.c
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "include/context.h"
|
||||
#include "include/file.h"
|
||||
#include "include/ipc.h"
|
||||
+#include "include/net.h"
|
||||
#include "include/path.h"
|
||||
#include "include/policy.h"
|
||||
#include "include/procattr.h"
|
||||
@@ -619,6 +620,104 @@ static int apparmor_task_setrlimit(struc
|
||||
return error;
|
||||
}
|
||||
|
||||
+static int apparmor_socket_create(int family, int type, int protocol, int kern)
|
||||
+{
|
||||
+ struct aa_profile *profile;
|
||||
+ int error = 0;
|
||||
+
|
||||
+ if (kern)
|
||||
+ return 0;
|
||||
+
|
||||
+ profile = __aa_current_profile();
|
||||
+ if (!unconfined(profile))
|
||||
+ error = aa_net_perm(OP_CREATE, profile, family, type, protocol,
|
||||
+ NULL);
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_bind(struct socket *sock,
|
||||
+ struct sockaddr *address, int addrlen)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_BIND, sk);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_connect(struct socket *sock,
|
||||
+ struct sockaddr *address, int addrlen)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_CONNECT, sk);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_listen(struct socket *sock, int backlog)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_LISTEN, sk);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_accept(struct socket *sock, struct socket *newsock)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_ACCEPT, sk);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_sendmsg(struct socket *sock,
|
||||
+ struct msghdr *msg, int size)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_SENDMSG, sk);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_recvmsg(struct socket *sock,
|
||||
+ struct msghdr *msg, int size, int flags)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_RECVMSG, sk);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_getsockname(struct socket *sock)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_GETSOCKNAME, sk);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_getpeername(struct socket *sock)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_GETPEERNAME, sk);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_getsockopt(struct socket *sock, int level,
|
||||
+ int optname)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_GETSOCKOPT, sk);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_setsockopt(struct socket *sock, int level,
|
||||
+ int optname)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_SETSOCKOPT, sk);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_shutdown(struct socket *sock, int how)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(OP_SOCK_SHUTDOWN, sk);
|
||||
+}
|
||||
+
|
||||
static struct security_operations apparmor_ops = {
|
||||
.name = "apparmor",
|
||||
|
||||
@@ -650,6 +749,19 @@ static struct security_operations apparm
|
||||
.getprocattr = apparmor_getprocattr,
|
||||
.setprocattr = apparmor_setprocattr,
|
||||
|
||||
+ .socket_create = apparmor_socket_create,
|
||||
+ .socket_bind = apparmor_socket_bind,
|
||||
+ .socket_connect = apparmor_socket_connect,
|
||||
+ .socket_listen = apparmor_socket_listen,
|
||||
+ .socket_accept = apparmor_socket_accept,
|
||||
+ .socket_sendmsg = apparmor_socket_sendmsg,
|
||||
+ .socket_recvmsg = apparmor_socket_recvmsg,
|
||||
+ .socket_getsockname = apparmor_socket_getsockname,
|
||||
+ .socket_getpeername = apparmor_socket_getpeername,
|
||||
+ .socket_getsockopt = apparmor_socket_getsockopt,
|
||||
+ .socket_setsockopt = apparmor_socket_setsockopt,
|
||||
+ .socket_shutdown = apparmor_socket_shutdown,
|
||||
+
|
||||
.cred_alloc_blank = apparmor_cred_alloc_blank,
|
||||
.cred_free = apparmor_cred_free,
|
||||
.cred_prepare = apparmor_cred_prepare,
|
||||
--- /dev/null
|
||||
+++ b/security/apparmor/net.c
|
||||
@@ -0,0 +1,170 @@
|
||||
+/*
|
||||
+ * AppArmor security module
|
||||
+ *
|
||||
+ * This file contains AppArmor network mediation
|
||||
+ *
|
||||
+ * Copyright (C) 1998-2008 Novell/SUSE
|
||||
+ * Copyright 2009-2010 Canonical Ltd.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public License as
|
||||
+ * published by the Free Software Foundation, version 2 of the
|
||||
+ * License.
|
||||
+ */
|
||||
+
|
||||
+#include "include/apparmor.h"
|
||||
+#include "include/audit.h"
|
||||
+#include "include/context.h"
|
||||
+#include "include/net.h"
|
||||
+#include "include/policy.h"
|
||||
+
|
||||
+#include "af_names.h"
|
||||
+
|
||||
+static const char *sock_type_names[] = {
|
||||
+ "unknown(0)",
|
||||
+ "stream",
|
||||
+ "dgram",
|
||||
+ "raw",
|
||||
+ "rdm",
|
||||
+ "seqpacket",
|
||||
+ "dccp",
|
||||
+ "unknown(7)",
|
||||
+ "unknown(8)",
|
||||
+ "unknown(9)",
|
||||
+ "packet",
|
||||
+};
|
||||
+
|
||||
+/* audit callback for net specific fields */
|
||||
+static void audit_cb(struct audit_buffer *ab, void *va)
|
||||
+{
|
||||
+ struct common_audit_data *sa = va;
|
||||
+
|
||||
+ audit_log_format(ab, " family=");
|
||||
+ if (address_family_names[sa->u.net.family]) {
|
||||
+ audit_log_string(ab, address_family_names[sa->u.net.family]);
|
||||
+ } else {
|
||||
+ audit_log_format(ab, " \"unknown(%d)\"", sa->u.net.family);
|
||||
+ }
|
||||
+
|
||||
+ audit_log_format(ab, " sock_type=");
|
||||
+ if (sock_type_names[sa->aad.net.type]) {
|
||||
+ audit_log_string(ab, sock_type_names[sa->aad.net.type]);
|
||||
+ } else {
|
||||
+ audit_log_format(ab, "\"unknown(%d)\"", sa->aad.net.type);
|
||||
+ }
|
||||
+
|
||||
+ audit_log_format(ab, " protocol=%d", sa->aad.net.protocol);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * audit_net - audit network access
|
||||
+ * @profile: profile being enforced (NOT NULL)
|
||||
+ * @op: operation being checked
|
||||
+ * @family: network family
|
||||
+ * @type: network type
|
||||
+ * @protocol: network protocol
|
||||
+ * @sk: socket auditing is being applied to
|
||||
+ * @error: error code for failure else 0
|
||||
+ *
|
||||
+ * Returns: %0 or sa->error else other errorcode on failure
|
||||
+ */
|
||||
+static int audit_net(struct aa_profile *profile, int op, u16 family, int type,
|
||||
+ int protocol, struct sock *sk, int error)
|
||||
+{
|
||||
+ int audit_type = AUDIT_APPARMOR_AUTO;
|
||||
+ struct common_audit_data sa;
|
||||
+ if (sk) {
|
||||
+ COMMON_AUDIT_DATA_INIT(&sa, NET);
|
||||
+ } else {
|
||||
+ COMMON_AUDIT_DATA_INIT(&sa, NONE);
|
||||
+ }
|
||||
+ /* todo fill in socket addr info */
|
||||
+
|
||||
+ sa.aad.op = op,
|
||||
+ sa.u.net.family = family;
|
||||
+ sa.u.net.sk = sk;
|
||||
+ sa.aad.net.type = type;
|
||||
+ sa.aad.net.protocol = protocol;
|
||||
+ sa.aad.error = error;
|
||||
+
|
||||
+ if (likely(!sa.aad.error)) {
|
||||
+ u16 audit_mask = profile->net.audit[sa.u.net.family];
|
||||
+ if (likely((AUDIT_MODE(profile) != AUDIT_ALL) &&
|
||||
+ !(1 << sa.aad.net.type & audit_mask)))
|
||||
+ return 0;
|
||||
+ audit_type = AUDIT_APPARMOR_AUDIT;
|
||||
+ } else {
|
||||
+ u16 quiet_mask = profile->net.quiet[sa.u.net.family];
|
||||
+ u16 kill_mask = 0;
|
||||
+ u16 denied = (1 << sa.aad.net.type) & ~quiet_mask;
|
||||
+
|
||||
+ if (denied & kill_mask)
|
||||
+ audit_type = AUDIT_APPARMOR_KILL;
|
||||
+
|
||||
+ if ((denied & quiet_mask) &&
|
||||
+ AUDIT_MODE(profile) != AUDIT_NOQUIET &&
|
||||
+ AUDIT_MODE(profile) != AUDIT_ALL)
|
||||
+ return COMPLAIN_MODE(profile) ? 0 : sa.aad.error;
|
||||
+ }
|
||||
+
|
||||
+ return aa_audit(audit_type, profile, GFP_KERNEL, &sa, audit_cb);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * aa_net_perm - very course network access check
|
||||
+ * @op: operation being checked
|
||||
+ * @profile: profile being enforced (NOT NULL)
|
||||
+ * @family: network family
|
||||
+ * @type: network type
|
||||
+ * @protocol: network protocol
|
||||
+ *
|
||||
+ * Returns: %0 else error if permission denied
|
||||
+ */
|
||||
+int aa_net_perm(int op, struct aa_profile *profile, u16 family, int type,
|
||||
+ int protocol, struct sock *sk)
|
||||
+{
|
||||
+ u16 family_mask;
|
||||
+ int error;
|
||||
+
|
||||
+ if ((family < 0) || (family >= AF_MAX))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if ((type < 0) || (type >= SOCK_MAX))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ /* unix domain and netlink sockets are handled by ipc */
|
||||
+ if (family == AF_UNIX || family == AF_NETLINK)
|
||||
+ return 0;
|
||||
+
|
||||
+ family_mask = profile->net.allow[family];
|
||||
+
|
||||
+ error = (family_mask & (1 << type)) ? 0 : -EACCES;
|
||||
+
|
||||
+ return audit_net(profile, op, family, type, protocol, sk, error);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * aa_revalidate_sk - Revalidate access to a sock
|
||||
+ * @op: operation being checked
|
||||
+ * @sk: sock being revalidated (NOT NULL)
|
||||
+ *
|
||||
+ * Returns: %0 else error if permission denied
|
||||
+ */
|
||||
+int aa_revalidate_sk(int op, struct sock *sk)
|
||||
+{
|
||||
+ struct aa_profile *profile;
|
||||
+ int error = 0;
|
||||
+
|
||||
+ /* aa_revalidate_sk should not be called from interrupt context
|
||||
+ * don't mediate these calls as they are not task related
|
||||
+ */
|
||||
+ if (in_interrupt())
|
||||
+ return 0;
|
||||
+
|
||||
+ profile = __aa_current_profile();
|
||||
+ if (!unconfined(profile))
|
||||
+ error = aa_net_perm(op, profile, sk->sk_family, sk->sk_type,
|
||||
+ sk->sk_protocol, sk);
|
||||
+
|
||||
+ return error;
|
||||
+}
|
||||
--- a/security/apparmor/policy.c
|
||||
+++ b/security/apparmor/policy.c
|
||||
@@ -745,6 +745,7 @@ static void free_profile(struct aa_profi
|
||||
|
||||
aa_free_file_rules(&profile->file);
|
||||
aa_free_cap_rules(&profile->caps);
|
||||
+ aa_free_net_rules(&profile->net);
|
||||
aa_free_rlimit_rules(&profile->rlimits);
|
||||
|
||||
aa_free_sid(profile->sid);
|
||||
--- a/security/apparmor/policy_unpack.c
|
||||
+++ b/security/apparmor/policy_unpack.c
|
||||
@@ -190,6 +190,19 @@ fail:
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static bool unpack_u16(struct aa_ext *e, u16 *data, const char *name)
|
||||
+{
|
||||
+ if (unpack_nameX(e, AA_U16, name)) {
|
||||
+ if (!inbounds(e, sizeof(u16)))
|
||||
+ return 0;
|
||||
+ if (data)
|
||||
+ *data = le16_to_cpu(get_unaligned((u16 *) e->pos));
|
||||
+ e->pos += sizeof(u16);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name)
|
||||
{
|
||||
if (unpack_nameX(e, AA_U32, name)) {
|
||||
@@ -468,7 +481,8 @@ static struct aa_profile *unpack_profile
|
||||
{
|
||||
struct aa_profile *profile = NULL;
|
||||
const char *name = NULL;
|
||||
- int error = -EPROTO;
|
||||
+ size_t size = 0;
|
||||
+ int i, error = -EPROTO;
|
||||
kernel_cap_t tmpcap;
|
||||
u32 tmp;
|
||||
|
||||
@@ -559,6 +573,38 @@ static struct aa_profile *unpack_profile
|
||||
if (!unpack_rlimits(e, profile))
|
||||
goto fail;
|
||||
|
||||
+ size = unpack_array(e, "net_allowed_af");
|
||||
+ if (size) {
|
||||
+
|
||||
+ for (i = 0; i < size; i++) {
|
||||
+ /* discard extraneous rules that this kernel will
|
||||
+ * never request
|
||||
+ */
|
||||
+ if (i > AF_MAX) {
|
||||
+ u16 tmp;
|
||||
+ if (!unpack_u16(e, &tmp, NULL) ||
|
||||
+ !unpack_u16(e, &tmp, NULL) ||
|
||||
+ !unpack_u16(e, &tmp, NULL))
|
||||
+ goto fail;
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (!unpack_u16(e, &profile->net.allow[i], NULL))
|
||||
+ goto fail;
|
||||
+ if (!unpack_u16(e, &profile->net.audit[i], NULL))
|
||||
+ goto fail;
|
||||
+ if (!unpack_u16(e, &profile->net.quiet[i], NULL))
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ if (!unpack_nameX(e, AA_ARRAYEND, NULL))
|
||||
+ goto fail;
|
||||
+ /*
|
||||
+ * allow unix domain and netlink sockets they are handled
|
||||
+ * by IPC
|
||||
+ */
|
||||
+ }
|
||||
+ profile->net.allow[AF_UNIX] = 0xffff;
|
||||
+ profile->net.allow[AF_NETLINK] = 0xffff;
|
||||
+
|
||||
/* get file rules */
|
||||
profile->file.dfa = unpack_dfa(e);
|
||||
if (IS_ERR(profile->file.dfa)) {
|
@ -1,50 +0,0 @@
|
||||
From b134eac05adf33188616bf53ea38dc6c7ee487e8 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel J Blueman <daniel.blueman@gmail.com>
|
||||
Date: Wed, 18 May 2011 16:31:31 -0700
|
||||
Subject: [PATCH] x86, ioapic: Fix potential resume deadlock
|
||||
|
||||
commit b64ce24daffb634b5b3133a2e411bd4de50654e8 upstream.
|
||||
|
||||
Fix a potential deadlock when resuming; here the calling
|
||||
function has disabled interrupts, so we cannot sleep.
|
||||
|
||||
Change the memory allocation flag from GFP_KERNEL to GFP_ATOMIC.
|
||||
|
||||
TODO: We can do away with this memory allocation during resume
|
||||
by reusing the ioapic suspend/resume code that uses boot time
|
||||
allocated buffers, but we want to keep this -stable patch
|
||||
simple.
|
||||
|
||||
Signed-off-by: Daniel J Blueman <daniel.blueman@gmail.com>
|
||||
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
|
||||
Link: http://lkml.kernel.org/r/20110518233157.385970138@sbsiddha-MOBL3.sc.intel.com
|
||||
Signed-off-by: Ingo Molnar <mingo@elte.hu>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
arch/x86/kernel/apic/io_apic.c | 4 ++--
|
||||
1 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
|
||||
index ca9e2a35..e437778 100644
|
||||
--- a/arch/x86/kernel/apic/io_apic.c
|
||||
+++ b/arch/x86/kernel/apic/io_apic.c
|
||||
@@ -615,14 +615,14 @@ struct IO_APIC_route_entry **alloc_ioapic_entries(void)
|
||||
struct IO_APIC_route_entry **ioapic_entries;
|
||||
|
||||
ioapic_entries = kzalloc(sizeof(*ioapic_entries) * nr_ioapics,
|
||||
- GFP_KERNEL);
|
||||
+ GFP_ATOMIC);
|
||||
if (!ioapic_entries)
|
||||
return 0;
|
||||
|
||||
for (apic = 0; apic < nr_ioapics; apic++) {
|
||||
ioapic_entries[apic] =
|
||||
kzalloc(sizeof(struct IO_APIC_route_entry) *
|
||||
- nr_ioapic_registers[apic], GFP_KERNEL);
|
||||
+ nr_ioapic_registers[apic], GFP_ATOMIC);
|
||||
if (!ioapic_entries[apic])
|
||||
goto nomem;
|
||||
}
|
||||
--
|
||||
1.7.6.5
|
||||
|
@ -1,24 +0,0 @@
|
||||
From: Jeff Mahoney <jeffm@suse.com>
|
||||
Subject: acpi: export acpi_os_hotplug_execute
|
||||
Patch-mainline: not yet
|
||||
|
||||
The ACPI dock driver changes require acpi_os_hotplug_execute,
|
||||
which wasn't exported.
|
||||
|
||||
This patch exports it.
|
||||
|
||||
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
|
||||
---
|
||||
drivers/acpi/osl.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/drivers/acpi/osl.c
|
||||
+++ b/drivers/acpi/osl.c
|
||||
@@ -941,6 +941,7 @@ acpi_status acpi_os_hotplug_execute(acpi
|
||||
{
|
||||
return __acpi_os_execute(0, function, context, 1);
|
||||
}
|
||||
+EXPORT_SYMBOL(acpi_os_hotplug_execute);
|
||||
|
||||
void acpi_os_wait_events_complete(void *context)
|
||||
{
|
@ -1,67 +0,0 @@
|
||||
From: Alexey Starikovskiy <astarikovskiy@suse.de>
|
||||
Subject: ACPI: EC: Don't degrade to poll mode at storm automatically.
|
||||
References: bnc#446142
|
||||
Patch-Mainline: no
|
||||
|
||||
Signed-off-by: Thomas Renninger <trenn@suse.de>
|
||||
|
||||
Not all users of semi-broken EC devices want to degrade to poll mode, so
|
||||
give them right to choose.
|
||||
|
||||
Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
|
||||
---
|
||||
|
||||
Documentation/kernel-parameters.txt | 5 +++++
|
||||
drivers/acpi/ec.c | 15 +++++++++++++++
|
||||
2 files changed, 20 insertions(+)
|
||||
|
||||
|
||||
--- a/Documentation/kernel-parameters.txt
|
||||
+++ b/Documentation/kernel-parameters.txt
|
||||
@@ -691,6 +691,11 @@ and is between 256 and 4096 characters.
|
||||
|
||||
eata= [HW,SCSI]
|
||||
|
||||
+ ec_intr= [HW,ACPI] ACPI Embedded Controller interrupt mode
|
||||
+ Format: <int>
|
||||
+ 0: polling mode
|
||||
+ non-0: interrupt mode (default)
|
||||
+
|
||||
edd= [EDD]
|
||||
Format: {"off" | "on" | "skip[mbr]"}
|
||||
|
||||
--- a/drivers/acpi/ec.c
|
||||
+++ b/drivers/acpi/ec.c
|
||||
@@ -118,6 +118,8 @@ static struct acpi_ec {
|
||||
spinlock_t curr_lock;
|
||||
} *boot_ec, *first_ec;
|
||||
|
||||
+int acpi_ec_intr = 1; /* Default is interrupt mode */
|
||||
+
|
||||
static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
@@ -754,6 +756,8 @@ static int ec_install_handlers(struct ac
|
||||
&acpi_ec_gpe_handler, ec);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -ENODEV;
|
||||
+ if (!acpi_ec_intr)
|
||||
+ set_bit(EC_FLAGS_NO_GPE, &ec->flags);
|
||||
acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME);
|
||||
acpi_enable_gpe(NULL, ec->gpe);
|
||||
status = acpi_install_address_space_handler(ec->handle,
|
||||
@@ -1034,3 +1038,14 @@ static void __exit acpi_ec_exit(void)
|
||||
return;
|
||||
}
|
||||
#endif /* 0 */
|
||||
+
|
||||
+static int __init acpi_ec_set_intr_mode(char *str)
|
||||
+{
|
||||
+ if (!get_option(&str, &acpi_ec_intr)) {
|
||||
+ acpi_ec_intr = 0;
|
||||
+ return 0;
|
||||
+ }
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+__setup("ec_intr=", acpi_ec_set_intr_mode);
|
@ -1,30 +0,0 @@
|
||||
From: Thomas Renninger <trenn@suse.de>
|
||||
Subject: Only use 32 bit addresses if they have a valid length
|
||||
References: bug#581644
|
||||
Patch-Mainline: not yet
|
||||
|
||||
Also not sure whether it will help, but it's a fix.
|
||||
|
||||
Please remove this patch again after a while also if it's not
|
||||
mainline.
|
||||
|
||||
---
|
||||
drivers/acpi/acpica/tbfadt.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/acpi/acpica/tbfadt.c
|
||||
+++ b/drivers/acpi/acpica/tbfadt.c
|
||||
@@ -550,11 +550,12 @@ static void acpi_tb_validate_fadt(void)
|
||||
(!address64->address && length)) {
|
||||
ACPI_WARNING((AE_INFO,
|
||||
"Optional field %s has zero address or length: "
|
||||
- "0x%8.8X%8.8X/0x%X",
|
||||
+ "0x%8.8X%8.8X/0x%X - not using it",
|
||||
name,
|
||||
ACPI_FORMAT_UINT64(address64->
|
||||
address),
|
||||
length));
|
||||
+ address64->address = 0;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
From: Kurt Garloff <garloff@suse.de>
|
||||
Subject: Use SRAT table rev to use 8bit or 16/32bit PXM fields (ia64)
|
||||
References: bnc#503038
|
||||
Patch-mainline: not yet
|
||||
|
||||
In SRAT v1, we had 8bit proximity domain (PXM) fields; SRAT v2 provides
|
||||
32bits for these. The new fields were reserved before.
|
||||
According to the ACPI spec, the OS must disregrard reserved fields.
|
||||
|
||||
ia64 did handle the PXM fields almost consistently, but depending on
|
||||
sgi's sn2 platform. This patch leaves the sn2 logic in, but does also
|
||||
use 16/32 bits for PXM if the SRAT has rev 2 or higher.
|
||||
|
||||
The patch also adds __init to the two pxm accessor functions, as they
|
||||
access __initdata now and are called from an __init function only anyway.
|
||||
|
||||
Note that the code only uses 16 bits for the PXM field in the processor
|
||||
proximity field; the patch does not address this as 16 bits are more than
|
||||
enough.
|
||||
|
||||
This is patch 3/3.
|
||||
|
||||
Signed-off-by: Kurt Garloff <garloff@suse.de>
|
||||
|
||||
---
|
||||
arch/ia64/kernel/acpi.c | 10 ++++++----
|
||||
1 file changed, 6 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/arch/ia64/kernel/acpi.c
|
||||
+++ b/arch/ia64/kernel/acpi.c
|
||||
@@ -429,22 +429,24 @@ static u32 __devinitdata pxm_flag[PXM_FL
|
||||
static struct acpi_table_slit __initdata *slit_table;
|
||||
cpumask_t early_cpu_possible_map = CPU_MASK_NONE;
|
||||
|
||||
-static int get_processor_proximity_domain(struct acpi_srat_cpu_affinity *pa)
|
||||
+static int __init
|
||||
+get_processor_proximity_domain(struct acpi_srat_cpu_affinity *pa)
|
||||
{
|
||||
int pxm;
|
||||
|
||||
pxm = pa->proximity_domain_lo;
|
||||
- if (ia64_platform_is("sn2"))
|
||||
+ if (ia64_platform_is("sn2") || acpi_srat_revision >= 2)
|
||||
pxm += pa->proximity_domain_hi[0] << 8;
|
||||
return pxm;
|
||||
}
|
||||
|
||||
-static int get_memory_proximity_domain(struct acpi_srat_mem_affinity *ma)
|
||||
+static int __init
|
||||
+get_memory_proximity_domain(struct acpi_srat_mem_affinity *ma)
|
||||
{
|
||||
int pxm;
|
||||
|
||||
pxm = ma->proximity_domain;
|
||||
- if (!ia64_platform_is("sn2"))
|
||||
+ if (!ia64_platform_is("sn2") && acpi_srat_revision <= 1)
|
||||
pxm &= 0xff;
|
||||
|
||||
return pxm;
|
@ -1,52 +0,0 @@
|
||||
From: Kurt Garloff <garloff@suse.de>
|
||||
Subject: Store SRAT table revision
|
||||
References: bnc#503038
|
||||
Patch-mainline: not yet
|
||||
|
||||
In SRAT v1, we had 8bit proximity domain (PXM) fields; SRAT v2 provides
|
||||
32bits for these. The new fields were reserved before.
|
||||
According to the ACPI spec, the OS must disregrard reserved fields.
|
||||
In order to know whether or not, we must know what version the SRAT
|
||||
table has.
|
||||
|
||||
This patch stores the SRAT table revision for later consumption
|
||||
by arch specific __init functions.
|
||||
|
||||
This is patch 1/3.
|
||||
|
||||
Signed-off-by: Kurt Garloff <garloff@suse.de>
|
||||
|
||||
---
|
||||
drivers/acpi/numa.c | 3 +++
|
||||
include/acpi/acpi_numa.h | 1 +
|
||||
2 files changed, 4 insertions(+)
|
||||
|
||||
--- a/drivers/acpi/numa.c
|
||||
+++ b/drivers/acpi/numa.c
|
||||
@@ -45,6 +45,8 @@ static int pxm_to_node_map[MAX_PXM_DOMAI
|
||||
static int node_to_pxm_map[MAX_NUMNODES]
|
||||
= { [0 ... MAX_NUMNODES - 1] = PXM_INVAL };
|
||||
|
||||
+unsigned char acpi_srat_revision __initdata;
|
||||
+
|
||||
int pxm_to_node(int pxm)
|
||||
{
|
||||
if (pxm < 0)
|
||||
@@ -259,6 +261,7 @@ static int __init acpi_parse_srat(struct
|
||||
return -EINVAL;
|
||||
|
||||
/* Real work done in acpi_table_parse_srat below. */
|
||||
+ acpi_srat_revision = table->revision;
|
||||
|
||||
return 0;
|
||||
}
|
||||
--- a/include/acpi/acpi_numa.h
|
||||
+++ b/include/acpi/acpi_numa.h
|
||||
@@ -15,6 +15,7 @@ extern int pxm_to_node(int);
|
||||
extern int node_to_pxm(int);
|
||||
extern void __acpi_map_pxm_to_node(int, int);
|
||||
extern int acpi_map_pxm_to_node(int);
|
||||
+extern unsigned char acpi_srat_revision;
|
||||
|
||||
#endif /* CONFIG_ACPI_NUMA */
|
||||
#endif /* __ACP_NUMA_H */
|
@ -1,42 +0,0 @@
|
||||
From: Kurt Garloff <garloff@suse.de>
|
||||
Subject: Use SRAT table rev to use 8bit or 32bit PXM fields (x86-64)
|
||||
References: bnc#503038
|
||||
Patch-mainline: not yet
|
||||
|
||||
In SRAT v1, we had 8bit proximity domain (PXM) fields; SRAT v2 provides
|
||||
32bits for these. The new fields were reserved before.
|
||||
According to the ACPI spec, the OS must disregrard reserved fields.
|
||||
|
||||
x86-64 was rather inconsistent prior to this patch; it used 8 bits
|
||||
for the pxm field in cpu_affinity, but 32 bits in mem_affinity.
|
||||
This patch makes it consistent: Either use 8 bits consistently (SRAT
|
||||
rev 1 or lower) or 32 bits (SRAT rev 2 or higher).
|
||||
|
||||
This is patch 2/3.
|
||||
|
||||
Signed-off-by: Kurt Garloff <garloff@suse.de>
|
||||
|
||||
---
|
||||
arch/x86/mm/srat_64.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
--- a/arch/x86/mm/srat_64.c
|
||||
+++ b/arch/x86/mm/srat_64.c
|
||||
@@ -156,6 +156,8 @@ acpi_numa_processor_affinity_init(struct
|
||||
if ((pa->flags & ACPI_SRAT_CPU_ENABLED) == 0)
|
||||
return;
|
||||
pxm = pa->proximity_domain_lo;
|
||||
+ if (acpi_srat_revision >= 2)
|
||||
+ pxm |= *((unsigned int*)pa->proximity_domain_hi) << 8;
|
||||
node = setup_node(pxm);
|
||||
if (node < 0) {
|
||||
printk(KERN_ERR "SRAT: Too many proximity domains %x\n", pxm);
|
||||
@@ -259,6 +261,8 @@ acpi_numa_memory_affinity_init(struct ac
|
||||
start = ma->base_address;
|
||||
end = start + ma->length;
|
||||
pxm = ma->proximity_domain;
|
||||
+ if (acpi_srat_revision <= 1)
|
||||
+ pxm &= 0xff;
|
||||
node = setup_node(pxm);
|
||||
if (node < 0) {
|
||||
printk(KERN_ERR "SRAT: Too many proximity domains.\n");
|
@ -1,125 +0,0 @@
|
||||
From: Thomas Renninger <trenn@suse.de>
|
||||
Subject: Avoid critical temp shutdowns on specific ThinkPad T4x(p) and R40
|
||||
References: https://bugzilla.novell.com/show_bug.cgi?id=333043
|
||||
Patch-mainline: not yet
|
||||
|
||||
---
|
||||
drivers/acpi/thermal.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 93 insertions(+)
|
||||
|
||||
--- a/drivers/acpi/thermal.c
|
||||
+++ b/drivers/acpi/thermal.c
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <linux/kmod.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/device.h>
|
||||
+#include <linux/dmi.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/thermal.h>
|
||||
#include <acpi/acpi_bus.h>
|
||||
@@ -984,6 +985,86 @@ static void acpi_thermal_guess_offset(st
|
||||
tz->kelvin_offset = 2732;
|
||||
}
|
||||
|
||||
+static struct dmi_system_id thermal_psv_dmi_table[] = {
|
||||
+ {
|
||||
+ .ident = "IBM ThinkPad T41",
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
|
||||
+ DMI_MATCH(DMI_PRODUCT_VERSION,"ThinkPad T41"),
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ .ident = "IBM ThinkPad T42",
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
|
||||
+ DMI_MATCH(DMI_PRODUCT_VERSION,"ThinkPad T42"),
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ .ident = "IBM ThinkPad T43",
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
|
||||
+ DMI_MATCH(DMI_PRODUCT_VERSION,"ThinkPad T43"),
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ .ident = "IBM ThinkPad T41p",
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
|
||||
+ DMI_MATCH(DMI_PRODUCT_VERSION,"ThinkPad T41p"),
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ .ident = "IBM ThinkPad T42p",
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
|
||||
+ DMI_MATCH(DMI_PRODUCT_VERSION,"ThinkPad T42p"),
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ .ident = "IBM ThinkPad T43p",
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
|
||||
+ DMI_MATCH(DMI_PRODUCT_VERSION,"ThinkPad T43p"),
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ .ident = "IBM ThinkPad R40",
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
|
||||
+ DMI_MATCH(DMI_PRODUCT_VERSION,"ThinkPad R40"),
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ .ident = "IBM ThinkPad R50p",
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
|
||||
+ DMI_MATCH(DMI_PRODUCT_VERSION,"ThinkPad R50p"),
|
||||
+ },
|
||||
+ },
|
||||
+ {},
|
||||
+};
|
||||
+
|
||||
+static int acpi_thermal_set_polling(struct acpi_thermal *tz, int seconds)
|
||||
+{
|
||||
+ if (!tz)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ /* Convert value to deci-seconds */
|
||||
+ tz->polling_frequency = seconds * 10;
|
||||
+
|
||||
+ tz->thermal_zone->polling_delay = seconds * 1000;
|
||||
+
|
||||
+ if (tz->tz_enabled)
|
||||
+ thermal_zone_device_update(tz->thermal_zone);
|
||||
+
|
||||
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
+ "Polling frequency set to %lu seconds\n",
|
||||
+ tz->polling_frequency/10));
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int acpi_thermal_add(struct acpi_device *device)
|
||||
{
|
||||
int result = 0;
|
||||
@@ -1015,6 +1096,18 @@ static int acpi_thermal_add(struct acpi_
|
||||
if (result)
|
||||
goto free_memory;
|
||||
|
||||
+ if (dmi_check_system(thermal_psv_dmi_table)) {
|
||||
+ if (tz->trips.passive.flags.valid &&
|
||||
+ tz->trips.passive.temperature > CELSIUS_TO_KELVIN(85)) {
|
||||
+ printk (KERN_INFO "Adjust passive trip point from %lu"
|
||||
+ " to %lu\n",
|
||||
+ KELVIN_TO_CELSIUS(tz->trips.passive.temperature),
|
||||
+ KELVIN_TO_CELSIUS(tz->trips.passive.temperature - 150));
|
||||
+ tz->trips.passive.temperature -= 150;
|
||||
+ acpi_thermal_set_polling(tz, 5);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n",
|
||||
acpi_device_name(device), acpi_device_bid(device),
|
||||
KELVIN_TO_CELSIUS(tz->temperature));
|
@ -1,118 +0,0 @@
|
||||
From: Thomas Renninger <trenn@suse.de>
|
||||
Subject: Introduce acpi_root_table=rsdt boot param and dmi list to force rsdt
|
||||
Patch-mainline: not yet
|
||||
References: http://bugzilla.kernel.org/show_bug.cgi?id=8246
|
||||
|
||||
This one is part of a patch series:
|
||||
acpi_thinkpad_introduce_acpi_root_table_boot_param.patch
|
||||
acpi_thinkpad_introduce_acpica_rsdt_global_variable.patch
|
||||
acpi_thinkpad_remove_R40e_c-state_blacklist.patch
|
||||
|
||||
Blacklist R40e, R51e and T40, T40p, T41, T41p, T42, T42p, R50 and R50p
|
||||
ThinkPads to use the RSDT instead of the XSDT.
|
||||
|
||||
Update: Jan 12 2009 jeffm
|
||||
* 2.6.29-rc1 introduced acpi_rsdt_forced. I've updated the patch to issue
|
||||
a warning that acpi=rsdt is the prefered method of forcing.
|
||||
* Moved the dmi table stuff to the main dmi table in x86/kernel/acpi/boot.
|
||||
|
||||
Update: Apr 10 2009 jeffm
|
||||
* Removed documentation, since it's deprecated.
|
||||
|
||||
Signed-off-by: Thomas Renninger <trenn@suse.de>
|
||||
Tested-by: Mark Doughty <me@markdoughty.co.uk>
|
||||
CC: Yakui Zhao <yakui.zhao@intel.com>
|
||||
|
||||
---
|
||||
arch/x86/kernel/acpi/boot.c | 53 ++++++++++++++++++++++++++++++++++++++++++++
|
||||
drivers/acpi/tables.c | 3 ++
|
||||
2 files changed, 56 insertions(+)
|
||||
|
||||
--- a/arch/x86/kernel/acpi/boot.c
|
||||
+++ b/arch/x86/kernel/acpi/boot.c
|
||||
@@ -1350,6 +1350,21 @@ static int __init dmi_ignore_irq0_timer_
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int __init force_acpi_rsdt(const struct dmi_system_id *d)
|
||||
+{
|
||||
+ if (!acpi_force) {
|
||||
+ printk(KERN_NOTICE "%s detected: force use of acpi=rsdt\n",
|
||||
+ d->ident);
|
||||
+ acpi_rsdt_forced = 1;
|
||||
+ } else {
|
||||
+ printk(KERN_NOTICE
|
||||
+ "Warning: acpi=force overrules DMI blacklist: "
|
||||
+ "acpi=rsdt\n");
|
||||
+ }
|
||||
+ return 0;
|
||||
+
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* If your system is blacklisted here, but you find that acpi=force
|
||||
* works for you, please contact linux-acpi@vger.kernel.org
|
||||
@@ -1425,6 +1440,32 @@ static struct dmi_system_id __initdata a
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
|
||||
},
|
||||
},
|
||||
+
|
||||
+ /*
|
||||
+ * Boxes that need RSDT as ACPI root table
|
||||
+ */
|
||||
+ {
|
||||
+ .callback = force_acpi_rsdt,
|
||||
+ .ident = "ThinkPad ", /* R40e, broken C-states */
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_BIOS_VENDOR, "IBM"),
|
||||
+ DMI_MATCH(DMI_BIOS_VERSION, "1SET")},
|
||||
+ },
|
||||
+ {
|
||||
+ .callback = force_acpi_rsdt,
|
||||
+ .ident = "ThinkPad ", /* R50e, slow booting */
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_BIOS_VENDOR, "IBM"),
|
||||
+ DMI_MATCH(DMI_BIOS_VERSION, "1WET")},
|
||||
+ },
|
||||
+ {
|
||||
+ .callback = force_acpi_rsdt,
|
||||
+ .ident = "ThinkPad ", /* T40, T40p, T41, T41p, T42, T42p
|
||||
+ R50, R50p */
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_BIOS_VENDOR, "IBM"),
|
||||
+ DMI_MATCH(DMI_BIOS_VERSION, "1RET")},
|
||||
+ },
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -1612,6 +1653,18 @@ static int __init parse_acpi(char *arg)
|
||||
}
|
||||
early_param("acpi", parse_acpi);
|
||||
|
||||
+/* Alias for acpi=rsdt for compatibility with openSUSE 11.1 and SLE11 */
|
||||
+static int __init parse_acpi_root_table(char *opt)
|
||||
+{
|
||||
+ if (!strcmp(opt, "rsdt")) {
|
||||
+ acpi_rsdt_forced = 1;
|
||||
+ printk(KERN_WARNING "acpi_root_table=rsdt is deprecated. "
|
||||
+ "Please use acpi=rsdt instead.\n");
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+early_param("acpi_root_table", parse_acpi_root_table);
|
||||
+
|
||||
/* FIXME: Using pci= for an ACPI parameter is a travesty. */
|
||||
static int __init parse_pci(char *arg)
|
||||
{
|
||||
--- a/drivers/acpi/tables.c
|
||||
+++ b/drivers/acpi/tables.c
|
||||
@@ -339,6 +339,9 @@ int __init acpi_table_init(void)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
+ if (acpi_rsdt_forced)
|
||||
+ printk(KERN_INFO "Using RSDT as ACPI root table\n");
|
||||
+
|
||||
status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0);
|
||||
if (ACPI_FAILURE(status))
|
||||
return 1;
|
@ -1,15 +0,0 @@
|
||||
From: jbeulich@novell.com
|
||||
Subject: fix unwind annotations
|
||||
Patch-mainline: queued for 2.6.39
|
||||
|
||||
--- head-2011-02-17.orig/arch/x86/lib/semaphore_32.S 2011-03-01 15:03:45.000000000 +0100
|
||||
+++ head-2011-02-17/arch/x86/lib/semaphore_32.S 2011-03-01 15:04:50.000000000 +0100
|
||||
@@ -36,7 +36,7 @@
|
||||
*/
|
||||
#ifdef CONFIG_SMP
|
||||
ENTRY(__write_lock_failed)
|
||||
- CFI_STARTPROC simple
|
||||
+ CFI_STARTPROC
|
||||
FRAME
|
||||
2: LOCK_PREFIX
|
||||
addl $ RW_LOCK_BIAS,(%eax)
|
@ -1,603 +0,0 @@
|
||||
From: Russ Anderson <rja@sgi.com>
|
||||
Subject: ia64: Call migration code on correctable errors v8
|
||||
References: 415829
|
||||
Acked-by: schwab@suse.de
|
||||
Patch-mainline: not yet
|
||||
|
||||
Migrate data off pages with correctable memory errors. This patch is the
|
||||
ia64 specific piece. It connects the CPE handler to the page migration
|
||||
code. It is implemented as a kernel loadable module, similar to the mca
|
||||
recovery code (mca_recovery.ko). This allows the feature to be turned off
|
||||
by uninstalling the module.
|
||||
|
||||
Update Jan 19 2009 jeffm:
|
||||
- isolate_lru_page doesn't put the page on a list anymore
|
||||
|
||||
|
||||
Signed-off-by: Russ Anderson <rja@sgi.com>
|
||||
|
||||
---
|
||||
arch/ia64/Kconfig | 9
|
||||
arch/ia64/include/asm/mca.h | 6
|
||||
arch/ia64/include/asm/page.h | 1
|
||||
arch/ia64/kernel/Makefile | 1
|
||||
arch/ia64/kernel/cpe_migrate.c | 434 +++++++++++++++++++++++++++++++++++++++++
|
||||
arch/ia64/kernel/mca.c | 37 +++
|
||||
6 files changed, 487 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/arch/ia64/Kconfig
|
||||
+++ b/arch/ia64/Kconfig
|
||||
@@ -511,6 +511,15 @@ config ARCH_PROC_KCORE_TEXT
|
||||
config IA64_MCA_RECOVERY
|
||||
tristate "MCA recovery from errors other than TLB."
|
||||
|
||||
+config IA64_CPE_MIGRATE
|
||||
+ tristate "Migrate data off pages with correctable errors"
|
||||
+ default m
|
||||
+ help
|
||||
+ Migrate data off pages with correctable memory errors. Selecting
|
||||
+ Y will build this functionality into the kernel. Selecting M will
|
||||
+ build this functionality as a kernel loadable module. Installing
|
||||
+ the module will turn on the functionality.
|
||||
+
|
||||
config PERFMON
|
||||
bool "Performance monitor support"
|
||||
help
|
||||
--- a/arch/ia64/include/asm/mca.h
|
||||
+++ b/arch/ia64/include/asm/mca.h
|
||||
@@ -142,6 +142,7 @@ extern unsigned long __per_cpu_mca[NR_CP
|
||||
|
||||
extern int cpe_vector;
|
||||
extern int ia64_cpe_irq;
|
||||
+extern int cpe_poll_enabled;
|
||||
extern void ia64_mca_init(void);
|
||||
extern void ia64_mca_cpu_init(void *);
|
||||
extern void ia64_os_mca_dispatch(void);
|
||||
@@ -156,11 +157,16 @@ extern void ia64_slave_init_handler(void
|
||||
extern void ia64_mca_cmc_vector_setup(void);
|
||||
extern int ia64_reg_MCA_extension(int (*fn)(void *, struct ia64_sal_os_state *));
|
||||
extern void ia64_unreg_MCA_extension(void);
|
||||
+extern int ia64_reg_CE_extension(int (*fn)(void *));
|
||||
+extern void ia64_unreg_CE_extension(void);
|
||||
extern unsigned long ia64_get_rnat(unsigned long *);
|
||||
extern void ia64_set_psr_mc(void);
|
||||
extern void ia64_mca_printk(const char * fmt, ...)
|
||||
__attribute__ ((format (printf, 1, 2)));
|
||||
|
||||
+extern struct list_head badpagelist;
|
||||
+extern unsigned int total_badpages;
|
||||
+
|
||||
struct ia64_mca_notify_die {
|
||||
struct ia64_sal_os_state *sos;
|
||||
int *monarch_cpu;
|
||||
--- a/arch/ia64/include/asm/page.h
|
||||
+++ b/arch/ia64/include/asm/page.h
|
||||
@@ -121,6 +121,7 @@ extern unsigned long max_low_pfn;
|
||||
#endif
|
||||
|
||||
#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
|
||||
+#define phys_to_page(kaddr) (pfn_to_page(kaddr >> PAGE_SHIFT))
|
||||
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
|
||||
#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
|
||||
|
||||
--- a/arch/ia64/kernel/Makefile
|
||||
+++ b/arch/ia64/kernel/Makefile
|
||||
@@ -25,6 +25,7 @@ obj-$(CONFIG_PERFMON) += perfmon_defaul
|
||||
obj-$(CONFIG_IA64_CYCLONE) += cyclone.o
|
||||
obj-$(CONFIG_CPU_FREQ) += cpufreq/
|
||||
obj-$(CONFIG_IA64_MCA_RECOVERY) += mca_recovery.o
|
||||
+obj-$(CONFIG_IA64_CPE_MIGRATE) += cpe_migrate.o
|
||||
obj-$(CONFIG_KPROBES) += kprobes.o jprobes.o
|
||||
obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
|
||||
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o crash.o
|
||||
--- /dev/null
|
||||
+++ b/arch/ia64/kernel/cpe_migrate.c
|
||||
@@ -0,0 +1,434 @@
|
||||
+/*
|
||||
+ * File: cpe_migrate.c
|
||||
+ * Purpose: Migrate data from physical pages with excessive correctable
|
||||
+ * errors to new physical pages. Keep the old pages on a discard
|
||||
+ * list.
|
||||
+ *
|
||||
+ * Copyright (C) 2008 SGI - Silicon Graphics Inc.
|
||||
+ * Copyright (C) 2008 Russ Anderson <rja@sgi.com>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/sysdev.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/sched.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/smp.h>
|
||||
+#include <linux/workqueue.h>
|
||||
+#include <linux/mm.h>
|
||||
+#include <linux/swap.h>
|
||||
+#include <linux/vmalloc.h>
|
||||
+#include <linux/migrate.h>
|
||||
+#include <linux/page-isolation.h>
|
||||
+#include <linux/memcontrol.h>
|
||||
+#include <linux/kobject.h>
|
||||
+
|
||||
+#include <asm/page.h>
|
||||
+#include <asm/system.h>
|
||||
+#include <asm/sn/sn_cpuid.h>
|
||||
+#include <asm/mca.h>
|
||||
+
|
||||
+#define BADRAM_BASENAME "badram"
|
||||
+#define CE_HISTORY_LENGTH 30
|
||||
+
|
||||
+struct cpe_info {
|
||||
+ u64 paddr;
|
||||
+ u16 node;
|
||||
+};
|
||||
+static struct cpe_info cpe[CE_HISTORY_LENGTH];
|
||||
+
|
||||
+static int cpe_polling_enabled = 1;
|
||||
+static int cpe_head;
|
||||
+static int cpe_tail;
|
||||
+static int work_scheduled;
|
||||
+static int mstat_cannot_isolate;
|
||||
+static int mstat_failed_to_discard;
|
||||
+static int mstat_already_marked;
|
||||
+static int mstat_already_on_list;
|
||||
+
|
||||
+DEFINE_SPINLOCK(cpe_migrate_lock);
|
||||
+
|
||||
+static void
|
||||
+get_physical_address(void *buffer, u64 *paddr, u16 *node)
|
||||
+{
|
||||
+ sal_log_record_header_t *rh;
|
||||
+ sal_log_mem_dev_err_info_t *mdei;
|
||||
+ ia64_err_rec_t *err_rec;
|
||||
+ sal_log_platform_err_info_t *plat_err;
|
||||
+ efi_guid_t guid;
|
||||
+
|
||||
+ err_rec = buffer;
|
||||
+ rh = &err_rec->sal_elog_header;
|
||||
+ *paddr = 0;
|
||||
+ *node = 0;
|
||||
+
|
||||
+ /*
|
||||
+ * Make sure it is a corrected error.
|
||||
+ */
|
||||
+ if (rh->severity != sal_log_severity_corrected)
|
||||
+ return;
|
||||
+
|
||||
+ plat_err = (sal_log_platform_err_info_t *)&err_rec->proc_err;
|
||||
+
|
||||
+ guid = plat_err->mem_dev_err.header.guid;
|
||||
+ if (efi_guidcmp(guid, SAL_PLAT_MEM_DEV_ERR_SECT_GUID) == 0) {
|
||||
+ /*
|
||||
+ * Memory cpe
|
||||
+ */
|
||||
+ mdei = &plat_err->mem_dev_err;
|
||||
+ if (mdei->valid.oem_data) {
|
||||
+ if (mdei->valid.physical_addr)
|
||||
+ *paddr = mdei->physical_addr;
|
||||
+
|
||||
+ if (mdei->valid.node) {
|
||||
+ if (ia64_platform_is("sn2"))
|
||||
+ *node = nasid_to_cnodeid(mdei->node);
|
||||
+ else
|
||||
+ *node = mdei->node;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static struct page *
|
||||
+alloc_migrate_page(struct page *ignored, unsigned long node, int **x)
|
||||
+{
|
||||
+
|
||||
+ return alloc_pages_node(node, GFP_HIGHUSER_MOVABLE, 0);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+validate_paddr_page(u64 paddr)
|
||||
+{
|
||||
+ struct page *page;
|
||||
+
|
||||
+ if (!paddr)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (!ia64_phys_addr_valid(paddr))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (!pfn_valid(paddr >> PAGE_SHIFT))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ page = phys_to_page(paddr);
|
||||
+ if (PageMemError(page))
|
||||
+ mstat_already_marked++;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+extern int isolate_lru_page(struct page *);
|
||||
+static int
|
||||
+ia64_mca_cpe_move_page(u64 paddr, u32 node)
|
||||
+{
|
||||
+ LIST_HEAD(pagelist);
|
||||
+ struct page *page;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = validate_paddr_page(paddr);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ /*
|
||||
+ * convert physical address to page number
|
||||
+ */
|
||||
+ page = phys_to_page(paddr);
|
||||
+
|
||||
+ migrate_prep();
|
||||
+ ret = isolate_lru_page(page);
|
||||
+ if (ret) {
|
||||
+ mstat_cannot_isolate++;
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ list_add(&page->lru, &pagelist);
|
||||
+ ret = migrate_pages(&pagelist, alloc_migrate_page, node, 0, true);
|
||||
+ if (ret == 0) {
|
||||
+ total_badpages++;
|
||||
+ list_add_tail(&page->lru, &badpagelist);
|
||||
+ } else {
|
||||
+ mstat_failed_to_discard++;
|
||||
+ /*
|
||||
+ * The page failed to migrate and is not on the bad page list.
|
||||
+ * Clearing the error bit will allow another attempt to migrate
|
||||
+ * if it gets another correctable error.
|
||||
+ */
|
||||
+ ClearPageMemError(page);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * ia64_mca_cpe_migrate
|
||||
+ * The worker that does the actual migration. It pulls a
|
||||
+ * physical address off the list and calls the migration code.
|
||||
+ */
|
||||
+static void
|
||||
+ia64_mca_cpe_migrate(struct work_struct *unused)
|
||||
+{
|
||||
+ int ret;
|
||||
+ u64 paddr;
|
||||
+ u16 node;
|
||||
+
|
||||
+ do {
|
||||
+ paddr = cpe[cpe_tail].paddr;
|
||||
+ if (paddr) {
|
||||
+ /*
|
||||
+ * There is a valid entry that needs processing.
|
||||
+ */
|
||||
+ node = cpe[cpe_tail].node;
|
||||
+
|
||||
+ ret = ia64_mca_cpe_move_page(paddr, node);
|
||||
+ if (ret <= 0)
|
||||
+ /*
|
||||
+ * Even though the return status is negative,
|
||||
+ * clear the entry. If the same address has
|
||||
+ * another CPE it will be re-added to the list.
|
||||
+ */
|
||||
+ cpe[cpe_tail].paddr = 0;
|
||||
+
|
||||
+ }
|
||||
+ if (++cpe_tail >= CE_HISTORY_LENGTH)
|
||||
+ cpe_tail = 0;
|
||||
+
|
||||
+ } while (cpe_tail != cpe_head);
|
||||
+ work_scheduled = 0;
|
||||
+}
|
||||
+
|
||||
+static DECLARE_WORK(cpe_enable_work, ia64_mca_cpe_migrate);
|
||||
+DEFINE_SPINLOCK(cpe_list_lock);
|
||||
+
|
||||
+/*
|
||||
+ * cpe_setup_migrate
|
||||
+ * Get the physical address out of the CPE record, add it
|
||||
+ * to the list of addresses to migrate (if not already on),
|
||||
+ * and schedule the back end worker task. This is called
|
||||
+ * in interrupt context so cannot directly call the migration
|
||||
+ * code.
|
||||
+ *
|
||||
+ * Inputs
|
||||
+ * rec The CPE record
|
||||
+ * Outputs
|
||||
+ * 1 on Success, -1 on failure
|
||||
+ */
|
||||
+static int
|
||||
+cpe_setup_migrate(void *rec)
|
||||
+{
|
||||
+ u64 paddr;
|
||||
+ u16 node;
|
||||
+ /* int head, tail; */
|
||||
+ int i, ret;
|
||||
+
|
||||
+ if (!rec)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ get_physical_address(rec, &paddr, &node);
|
||||
+ ret = validate_paddr_page(paddr);
|
||||
+ if (ret < 0)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if ((cpe_head != cpe_tail) || (cpe[cpe_head].paddr != 0))
|
||||
+ /*
|
||||
+ * List not empty
|
||||
+ */
|
||||
+ for (i = 0; i < CE_HISTORY_LENGTH; i++) {
|
||||
+ if (PAGE_ALIGN(cpe[i].paddr) == PAGE_ALIGN(paddr)) {
|
||||
+ mstat_already_on_list++;
|
||||
+ return 1; /* already on the list */
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!spin_trylock(&cpe_list_lock)) {
|
||||
+ /*
|
||||
+ * Someone else has the lock. To avoid spinning in interrupt
|
||||
+ * handler context, bail.
|
||||
+ */
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ if (cpe[cpe_head].paddr == 0) {
|
||||
+ cpe[cpe_head].node = node;
|
||||
+ cpe[cpe_head].paddr = paddr;
|
||||
+
|
||||
+ if (++cpe_head >= CE_HISTORY_LENGTH)
|
||||
+ cpe_head = 0;
|
||||
+ }
|
||||
+ spin_unlock(&cpe_list_lock);
|
||||
+
|
||||
+ if (!work_scheduled) {
|
||||
+ work_scheduled = 1;
|
||||
+ schedule_work(&cpe_enable_work);
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * =============================================================================
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * free_one_bad_page
|
||||
+ * Free one page from the list of bad pages.
|
||||
+ */
|
||||
+static int
|
||||
+free_one_bad_page(unsigned long paddr)
|
||||
+{
|
||||
+ LIST_HEAD(pagelist);
|
||||
+ struct page *page, *page2, *target;
|
||||
+
|
||||
+ /*
|
||||
+ * Verify page address
|
||||
+ */
|
||||
+ target = phys_to_page(paddr);
|
||||
+ list_for_each_entry_safe(page, page2, &badpagelist, lru) {
|
||||
+ if (page != target)
|
||||
+ continue;
|
||||
+
|
||||
+ ClearPageMemError(page); /* Mark the page as good */
|
||||
+ total_badpages--;
|
||||
+ list_move_tail(&page->lru, &pagelist);
|
||||
+ putback_lru_pages(&pagelist);
|
||||
+ break;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * free_all_bad_pages
|
||||
+ * Free all of the pages on the bad pages list.
|
||||
+ */
|
||||
+static int
|
||||
+free_all_bad_pages(void)
|
||||
+{
|
||||
+ struct page *page, *page2;
|
||||
+
|
||||
+ list_for_each_entry_safe(page, page2, &badpagelist, lru) {
|
||||
+ ClearPageMemError(page); /* Mark the page as good */
|
||||
+ total_badpages--;
|
||||
+ }
|
||||
+ putback_lru_pages(&badpagelist);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#define OPT_LEN 16
|
||||
+
|
||||
+static ssize_t
|
||||
+badpage_store(struct kobject *kobj,
|
||||
+ struct kobj_attribute *attr, const char *buf, size_t count)
|
||||
+{
|
||||
+ char optstr[OPT_LEN];
|
||||
+ unsigned long opt;
|
||||
+ int len = OPT_LEN;
|
||||
+ int err;
|
||||
+
|
||||
+ if (count < len)
|
||||
+ len = count;
|
||||
+
|
||||
+ strlcpy(optstr, buf, len);
|
||||
+
|
||||
+ err = strict_strtoul(optstr, 16, &opt);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ if (opt == 0)
|
||||
+ free_all_bad_pages();
|
||||
+ else
|
||||
+ free_one_bad_page(opt);
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * badpage_show
|
||||
+ * Display the number, size, and addresses of all the pages on the
|
||||
+ * bad page list.
|
||||
+ *
|
||||
+ * Note that sysfs provides buf of PAGE_SIZE length. bufend tracks
|
||||
+ * the remaining space in buf to avoid overflowing.
|
||||
+ */
|
||||
+static ssize_t
|
||||
+badpage_show(struct kobject *kobj,
|
||||
+ struct kobj_attribute *attr, char *buf)
|
||||
+
|
||||
+{
|
||||
+ struct page *page, *page2;
|
||||
+ int i = 0, cnt = 0;
|
||||
+ char *bufend = buf + PAGE_SIZE;
|
||||
+
|
||||
+ cnt = snprintf(buf, bufend - (buf + cnt),
|
||||
+ "Memory marked bad: %d kB\n"
|
||||
+ "Pages marked bad: %d\n"
|
||||
+ "Unable to isolate on LRU: %d\n"
|
||||
+ "Unable to migrate: %d\n"
|
||||
+ "Already marked bad: %d\n"
|
||||
+ "Already on list: %d\n"
|
||||
+ "List of bad physical pages\n",
|
||||
+ total_badpages << (PAGE_SHIFT - 10), total_badpages,
|
||||
+ mstat_cannot_isolate, mstat_failed_to_discard,
|
||||
+ mstat_already_marked, mstat_already_on_list
|
||||
+ );
|
||||
+
|
||||
+ list_for_each_entry_safe(page, page2, &badpagelist, lru) {
|
||||
+ if (bufend - (buf + cnt) < 20)
|
||||
+ break; /* Avoid overflowing the buffer */
|
||||
+ cnt += snprintf(buf + cnt, bufend - (buf + cnt),
|
||||
+ " 0x%011lx", page_to_phys(page));
|
||||
+ if (!(++i % 5))
|
||||
+ cnt += snprintf(buf + cnt, bufend - (buf + cnt), "\n");
|
||||
+ }
|
||||
+ cnt += snprintf(buf + cnt, bufend - (buf + cnt), "\n");
|
||||
+
|
||||
+ return cnt;
|
||||
+}
|
||||
+
|
||||
+static struct kobj_attribute badram_attr = {
|
||||
+ .attr = {
|
||||
+ .name = "badram",
|
||||
+ .mode = S_IWUSR | S_IRUGO,
|
||||
+ },
|
||||
+ .show = badpage_show,
|
||||
+ .store = badpage_store,
|
||||
+};
|
||||
+
|
||||
+static int __init
|
||||
+cpe_migrate_external_handler_init(void)
|
||||
+{
|
||||
+ int error;
|
||||
+
|
||||
+ error = sysfs_create_file(kernel_kobj, &badram_attr.attr);
|
||||
+ if (error)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ /*
|
||||
+ * register external ce handler
|
||||
+ */
|
||||
+ if (ia64_reg_CE_extension(cpe_setup_migrate)) {
|
||||
+ printk(KERN_ERR "ia64_reg_CE_extension failed.\n");
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+ cpe_poll_enabled = cpe_polling_enabled;
|
||||
+
|
||||
+ printk(KERN_INFO "Registered badram Driver\n");
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void __exit
|
||||
+cpe_migrate_external_handler_exit(void)
|
||||
+{
|
||||
+ /* unregister external mca handlers */
|
||||
+ ia64_unreg_CE_extension();
|
||||
+
|
||||
+ sysfs_remove_file(kernel_kobj, &badram_attr.attr);
|
||||
+}
|
||||
+
|
||||
+module_init(cpe_migrate_external_handler_init);
|
||||
+module_exit(cpe_migrate_external_handler_exit);
|
||||
+
|
||||
+module_param(cpe_polling_enabled, int, 0644);
|
||||
+MODULE_PARM_DESC(cpe_polling_enabled,
|
||||
+ "Enable polling with migration");
|
||||
+
|
||||
+MODULE_AUTHOR("Russ Anderson <rja@sgi.com>");
|
||||
+MODULE_DESCRIPTION("ia64 Corrected Error page migration driver");
|
||||
--- a/arch/ia64/kernel/mca.c
|
||||
+++ b/arch/ia64/kernel/mca.c
|
||||
@@ -68,6 +68,9 @@
|
||||
*
|
||||
* 2007-04-27 Russ Anderson <rja@sgi.com>
|
||||
* Support multiple cpus going through OS_MCA in the same event.
|
||||
+ *
|
||||
+ * 2008-04-22 Russ Anderson <rja@sgi.com>
|
||||
+ * Migrate data off pages with correctable memory errors.
|
||||
*/
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/types.h>
|
||||
@@ -164,7 +167,14 @@ static int cmc_polling_enabled = 1;
|
||||
* but encounters problems retrieving CPE logs. This should only be
|
||||
* necessary for debugging.
|
||||
*/
|
||||
-static int cpe_poll_enabled = 1;
|
||||
+int cpe_poll_enabled = 1;
|
||||
+EXPORT_SYMBOL(cpe_poll_enabled);
|
||||
+
|
||||
+unsigned int total_badpages;
|
||||
+EXPORT_SYMBOL(total_badpages);
|
||||
+
|
||||
+LIST_HEAD(badpagelist);
|
||||
+EXPORT_SYMBOL(badpagelist);
|
||||
|
||||
extern void salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe);
|
||||
|
||||
@@ -524,6 +534,28 @@ int mca_recover_range(unsigned long addr
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mca_recover_range);
|
||||
|
||||
+/* Function pointer to Corrected Error memory migration driver */
|
||||
+int (*ia64_mca_ce_extension)(void *);
|
||||
+
|
||||
+int
|
||||
+ia64_reg_CE_extension(int (*fn)(void *))
|
||||
+{
|
||||
+ if (ia64_mca_ce_extension)
|
||||
+ return 1;
|
||||
+
|
||||
+ ia64_mca_ce_extension = fn;
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL(ia64_reg_CE_extension);
|
||||
+
|
||||
+void
|
||||
+ia64_unreg_CE_extension(void)
|
||||
+{
|
||||
+ if (ia64_mca_ce_extension)
|
||||
+ ia64_mca_ce_extension = NULL;
|
||||
+}
|
||||
+EXPORT_SYMBOL(ia64_unreg_CE_extension);
|
||||
+
|
||||
#ifdef CONFIG_ACPI
|
||||
|
||||
int cpe_vector = -1;
|
||||
@@ -535,6 +567,7 @@ ia64_mca_cpe_int_handler (int cpe_irq, v
|
||||
static unsigned long cpe_history[CPE_HISTORY_LENGTH];
|
||||
static int index;
|
||||
static DEFINE_SPINLOCK(cpe_history_lock);
|
||||
+ int recover;
|
||||
|
||||
IA64_MCA_DEBUG("%s: received interrupt vector = %#x on CPU %d\n",
|
||||
__func__, cpe_irq, smp_processor_id());
|
||||
@@ -581,6 +614,8 @@ ia64_mca_cpe_int_handler (int cpe_irq, v
|
||||
out:
|
||||
/* Get the CPE error record and log it */
|
||||
ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CPE);
|
||||
+ recover = (ia64_mca_ce_extension && ia64_mca_ce_extension(
|
||||
+ IA64_LOG_CURR_BUFFER(SAL_INFO_TYPE_CPE)));
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
@ -1,159 +0,0 @@
|
||||
From: Russ Anderson <rja@sgi.com>
|
||||
Subject: ia64: cpe_migrate.ko causes deadlock.
|
||||
References: bnc#464676
|
||||
Patch-mainline: not yet, depends on patches.arch/ia64-page-migration
|
||||
|
||||
schedule_on_each_cpu() deadlocks when called from an event thread.
|
||||
Change cpe_migrate to use a kthread to avoid the problem.
|
||||
|
||||
Signed-off-by: Russ Anderson <rja@sgi.com>
|
||||
Acked-by: Raymund Will <rw@suse.de>
|
||||
|
||||
---
|
||||
arch/ia64/kernel/cpe_migrate.c | 72 +++++++++++++++++++++++++++++++----------
|
||||
1 file changed, 56 insertions(+), 16 deletions(-)
|
||||
|
||||
--- a/arch/ia64/kernel/cpe_migrate.c
|
||||
+++ b/arch/ia64/kernel/cpe_migrate.c
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <linux/page-isolation.h>
|
||||
#include <linux/memcontrol.h>
|
||||
#include <linux/kobject.h>
|
||||
+#include <linux/kthread.h>
|
||||
|
||||
#include <asm/page.h>
|
||||
#include <asm/system.h>
|
||||
@@ -40,12 +41,15 @@ static struct cpe_info cpe[CE_HISTORY_LE
|
||||
static int cpe_polling_enabled = 1;
|
||||
static int cpe_head;
|
||||
static int cpe_tail;
|
||||
-static int work_scheduled;
|
||||
static int mstat_cannot_isolate;
|
||||
static int mstat_failed_to_discard;
|
||||
static int mstat_already_marked;
|
||||
static int mstat_already_on_list;
|
||||
|
||||
+/* IRQ handler notifies this wait queue on receipt of an IRQ */
|
||||
+DECLARE_WAIT_QUEUE_HEAD(cpe_activate_IRQ_wq);
|
||||
+static DECLARE_COMPLETION(kthread_cpe_migrated_exited);
|
||||
+int cpe_active;
|
||||
DEFINE_SPINLOCK(cpe_migrate_lock);
|
||||
|
||||
static void
|
||||
@@ -160,12 +164,12 @@ ia64_mca_cpe_move_page(u64 paddr, u32 no
|
||||
}
|
||||
|
||||
/*
|
||||
- * ia64_mca_cpe_migrate
|
||||
- * The worker that does the actual migration. It pulls a
|
||||
- * physical address off the list and calls the migration code.
|
||||
+ * cpe_process_queue
|
||||
+ * Pulls the physical address off the list and calls the migration code.
|
||||
+ * Will process all the addresses on the list.
|
||||
*/
|
||||
-static void
|
||||
-ia64_mca_cpe_migrate(struct work_struct *unused)
|
||||
+void
|
||||
+cpe_process_queue(void)
|
||||
{
|
||||
int ret;
|
||||
u64 paddr;
|
||||
@@ -193,10 +197,36 @@ ia64_mca_cpe_migrate(struct work_struct
|
||||
cpe_tail = 0;
|
||||
|
||||
} while (cpe_tail != cpe_head);
|
||||
- work_scheduled = 0;
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+inline int
|
||||
+cpe_list_empty(void)
|
||||
+{
|
||||
+ return (cpe_head == cpe_tail) && (!cpe[cpe_head].paddr);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * kthread_cpe_migrate
|
||||
+ * kthread_cpe_migrate is created at module load time and lives
|
||||
+ * until the module is removed. When not active, it will sleep.
|
||||
+ */
|
||||
+static int
|
||||
+kthread_cpe_migrate(void *ignore)
|
||||
+{
|
||||
+ while (cpe_active) {
|
||||
+ /*
|
||||
+ * wait for work
|
||||
+ */
|
||||
+ (void)wait_event_interruptible(cpe_activate_IRQ_wq,
|
||||
+ (!cpe_list_empty() ||
|
||||
+ !cpe_active));
|
||||
+ cpe_process_queue(); /* process work */
|
||||
+ }
|
||||
+ complete(&kthread_cpe_migrated_exited);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
-static DECLARE_WORK(cpe_enable_work, ia64_mca_cpe_migrate);
|
||||
DEFINE_SPINLOCK(cpe_list_lock);
|
||||
|
||||
/*
|
||||
@@ -228,10 +258,7 @@ cpe_setup_migrate(void *rec)
|
||||
if (ret < 0)
|
||||
return -EINVAL;
|
||||
|
||||
- if ((cpe_head != cpe_tail) || (cpe[cpe_head].paddr != 0))
|
||||
- /*
|
||||
- * List not empty
|
||||
- */
|
||||
+ if (!cpe_list_empty())
|
||||
for (i = 0; i < CE_HISTORY_LENGTH; i++) {
|
||||
if (PAGE_ALIGN(cpe[i].paddr) == PAGE_ALIGN(paddr)) {
|
||||
mstat_already_on_list++;
|
||||
@@ -256,10 +283,7 @@ cpe_setup_migrate(void *rec)
|
||||
}
|
||||
spin_unlock(&cpe_list_lock);
|
||||
|
||||
- if (!work_scheduled) {
|
||||
- work_scheduled = 1;
|
||||
- schedule_work(&cpe_enable_work);
|
||||
- }
|
||||
+ wake_up_interruptible(&cpe_activate_IRQ_wq);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -396,12 +420,23 @@ static int __init
|
||||
cpe_migrate_external_handler_init(void)
|
||||
{
|
||||
int error;
|
||||
+ struct task_struct *kthread;
|
||||
|
||||
error = sysfs_create_file(kernel_kobj, &badram_attr.attr);
|
||||
if (error)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
+ * set up the kthread
|
||||
+ */
|
||||
+ cpe_active = 1;
|
||||
+ kthread = kthread_run(kthread_cpe_migrate, NULL, "cpe_migrate");
|
||||
+ if (IS_ERR(kthread)) {
|
||||
+ complete(&kthread_cpe_migrated_exited);
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
* register external ce handler
|
||||
*/
|
||||
if (ia64_reg_CE_extension(cpe_setup_migrate)) {
|
||||
@@ -420,6 +455,11 @@ cpe_migrate_external_handler_exit(void)
|
||||
/* unregister external mca handlers */
|
||||
ia64_unreg_CE_extension();
|
||||
|
||||
+ /* Stop kthread */
|
||||
+ cpe_active = 0; /* tell kthread_cpe_migrate to exit */
|
||||
+ wake_up_interruptible(&cpe_activate_IRQ_wq);
|
||||
+ wait_for_completion(&kthread_cpe_migrated_exited);
|
||||
+
|
||||
sysfs_remove_file(kernel_kobj, &badram_attr.attr);
|
||||
}
|
||||
|
@ -1,54 +0,0 @@
|
||||
From: Jeff Mahoney <jeffm@suse.com>
|
||||
Subject: kmsg: Fix parameter limitations
|
||||
Patch-mainline: Whenever kmsg is upstream
|
||||
|
||||
The kmsg infrastructure, currently only employed on s/390, has limitations
|
||||
with the parameters it can handle due to the way it assembles the
|
||||
magic string for parsing with scripts/kmsg-doc.
|
||||
|
||||
cpp expects the result to be a valid expression and exits with an error
|
||||
if it is not.
|
||||
|
||||
The netfilter ipvs code causes this error, though there are more examples:
|
||||
error: pasting "_ARGS_" and "&" does not give a valid preprocessing token
|
||||
|
||||
This stems from an otherwise valid expression:
|
||||
pr_info("Registered protocols (%s)\n", &protocols[2]);
|
||||
|
||||
It tries to concatenate _ARGS_ and &protocols[2] and fails.
|
||||
|
||||
This patch fixes the issue by stringifying the entire parameter list
|
||||
and allowing kmsg-doc to unquote the resultant expression.
|
||||
|
||||
The dev_* expressions that evaluate to __KMSG_DEV are unaffected because
|
||||
the insertion of the "dev, " between _ARGS_ and the parameter list ends
|
||||
up creating a valid expression.
|
||||
|
||||
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
|
||||
---
|
||||
include/linux/printk.h | 2 +-
|
||||
scripts/kmsg-doc | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/include/linux/printk.h
|
||||
+++ b/include/linux/printk.h
|
||||
@@ -416,7 +416,7 @@ extern int hex_to_bin(char ch);
|
||||
|
||||
/* generate magic string for scripts/kmsg-doc to parse */
|
||||
#define pr_printk_hash(level, format, ...) \
|
||||
- __KMSG_PRINT(level _FMT_ format _ARGS_ ##__VA_ARGS__ _END_)
|
||||
+ __KMSG_PRINT(level _FMT_ format _ARGS_ #__VA_ARGS__ _END_)
|
||||
|
||||
#elif defined(CONFIG_KMSG_IDS) && defined(KMSG_COMPONENT)
|
||||
|
||||
--- a/scripts/kmsg-doc
|
||||
+++ b/scripts/kmsg-doc
|
||||
@@ -307,7 +307,7 @@ sub process_cpp_file($$$$)
|
||||
|
||||
while (<FD>) {
|
||||
chomp;
|
||||
- if (/.*__KMSG_PRINT\(\s*(\S*)\s*_FMT_(.*)_ARGS_\s*(.*)?_END_\s*\)/o) {
|
||||
+ if (/.*__KMSG_PRINT\(\s*(\S*)\s*_FMT_(.*)_ARGS_\s*"(.*)"\s*_END_\s*\)/o) {
|
||||
if ($component ne "") {
|
||||
add_kmsg_print($component, $1, $2, $3);
|
||||
} else {
|
@ -1,139 +0,0 @@
|
||||
From: Alexander Graf <agraf@suse.de>
|
||||
Date: Wed, 18 Nov 2009 00:39:12 +0100
|
||||
Subject: Only export selected pv-ops feature structs
|
||||
References: bnc#556135, FATE#306453
|
||||
Patch-Mainline: Submitted to virtualization list
|
||||
|
||||
To really check for sure that we're not using any pv-ops code by accident,
|
||||
we should make sure that we don't even export the structures used to access
|
||||
pv-ops exported functions.
|
||||
|
||||
So let's surround the pv-ops structs by #ifdefs.
|
||||
|
||||
Signed-off-by: Alexander Graf <agraf@suse.de>
|
||||
---
|
||||
arch/x86/kernel/paravirt.c | 35 +++++++++++++++++++++++++++++------
|
||||
1 file changed, 29 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/arch/x86/kernel/paravirt.c
|
||||
+++ b/arch/x86/kernel/paravirt.c
|
||||
@@ -124,11 +124,21 @@ static void *get_call_destination(u8 typ
|
||||
{
|
||||
struct paravirt_patch_template tmpl = {
|
||||
.pv_init_ops = pv_init_ops,
|
||||
+#ifdef CONFIG_PARAVIRT_TIME
|
||||
.pv_time_ops = pv_time_ops,
|
||||
+#endif
|
||||
+#ifdef CONFIG_PARAVIRT_CPU
|
||||
.pv_cpu_ops = pv_cpu_ops,
|
||||
+#endif
|
||||
+#ifdef CONFIG_PARAVIRT_IRQ
|
||||
.pv_irq_ops = pv_irq_ops,
|
||||
+#endif
|
||||
+#ifdef CONFIG_PARAVIRT_APIC
|
||||
.pv_apic_ops = pv_apic_ops,
|
||||
+#endif
|
||||
+#ifdef CONFIG_PARAVIRT_MMU
|
||||
.pv_mmu_ops = pv_mmu_ops,
|
||||
+#endif
|
||||
#ifdef CONFIG_PARAVIRT_SPINLOCKS
|
||||
.pv_lock_ops = pv_lock_ops,
|
||||
#endif
|
||||
@@ -185,6 +195,7 @@ unsigned paravirt_patch_insns(void *insn
|
||||
return insn_len;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_PARAVIRT_MMU
|
||||
static void native_flush_tlb(void)
|
||||
{
|
||||
__native_flush_tlb();
|
||||
@@ -203,6 +214,7 @@ static void native_flush_tlb_single(unsi
|
||||
{
|
||||
__native_flush_tlb_single(addr);
|
||||
}
|
||||
+#endif /* CONFIG_PARAVIRT_MMU */
|
||||
|
||||
/* These are in entry.S */
|
||||
extern void native_iret(void);
|
||||
@@ -284,6 +296,7 @@ enum paravirt_lazy_mode paravirt_get_laz
|
||||
return percpu_read(paravirt_lazy_mode);
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_PARAVIRT_MMU
|
||||
void arch_flush_lazy_mmu_mode(void)
|
||||
{
|
||||
preempt_disable();
|
||||
@@ -295,6 +308,7 @@ void arch_flush_lazy_mmu_mode(void)
|
||||
|
||||
preempt_enable();
|
||||
}
|
||||
+#endif /* CONFIG_PARAVIRT_MMU */
|
||||
|
||||
struct pv_info pv_info = {
|
||||
.name = "bare hardware",
|
||||
@@ -306,11 +320,16 @@ struct pv_info pv_info = {
|
||||
struct pv_init_ops pv_init_ops = {
|
||||
.patch = native_patch,
|
||||
};
|
||||
+EXPORT_SYMBOL_GPL(pv_info);
|
||||
|
||||
+#ifdef CONFIG_PARAVIRT_TIME
|
||||
struct pv_time_ops pv_time_ops = {
|
||||
.sched_clock = native_sched_clock,
|
||||
};
|
||||
+EXPORT_SYMBOL_GPL(pv_time_ops);
|
||||
+#endif
|
||||
|
||||
+#ifdef CONFIG_PARAVIRT_IRQ
|
||||
struct pv_irq_ops pv_irq_ops = {
|
||||
.save_fl = __PV_IS_CALLEE_SAVE(native_save_fl),
|
||||
.restore_fl = __PV_IS_CALLEE_SAVE(native_restore_fl),
|
||||
@@ -322,7 +341,10 @@ struct pv_irq_ops pv_irq_ops = {
|
||||
.adjust_exception_frame = paravirt_nop,
|
||||
#endif
|
||||
};
|
||||
+EXPORT_SYMBOL (pv_irq_ops);
|
||||
+#endif
|
||||
|
||||
+#ifdef CONFIG_PARAVIRT_CPU
|
||||
struct pv_cpu_ops pv_cpu_ops = {
|
||||
.cpuid = native_cpuid,
|
||||
.get_debugreg = native_get_debugreg,
|
||||
@@ -383,12 +405,17 @@ struct pv_cpu_ops pv_cpu_ops = {
|
||||
.start_context_switch = paravirt_nop,
|
||||
.end_context_switch = paravirt_nop,
|
||||
};
|
||||
+EXPORT_SYMBOL (pv_cpu_ops);
|
||||
+#endif
|
||||
|
||||
+#ifdef CONFIG_PARAVIRT_APIC
|
||||
struct pv_apic_ops pv_apic_ops = {
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
.startup_ipi_hook = paravirt_nop,
|
||||
#endif
|
||||
};
|
||||
+EXPORT_SYMBOL_GPL(pv_apic_ops);
|
||||
+#endif
|
||||
|
||||
#if defined(CONFIG_X86_32) && !defined(CONFIG_X86_PAE)
|
||||
/* 32-bit pagetable entries */
|
||||
@@ -398,6 +425,7 @@ struct pv_apic_ops pv_apic_ops = {
|
||||
#define PTE_IDENT __PV_IS_CALLEE_SAVE(_paravirt_ident_64)
|
||||
#endif
|
||||
|
||||
+#ifdef CONFIG_PARAVIRT_MMU
|
||||
struct pv_mmu_ops pv_mmu_ops = {
|
||||
|
||||
.read_cr2 = native_read_cr2,
|
||||
@@ -466,10 +494,5 @@ struct pv_mmu_ops pv_mmu_ops = {
|
||||
|
||||
.set_fixmap = native_set_fixmap,
|
||||
};
|
||||
-
|
||||
-EXPORT_SYMBOL_GPL(pv_time_ops);
|
||||
-EXPORT_SYMBOL (pv_cpu_ops);
|
||||
EXPORT_SYMBOL (pv_mmu_ops);
|
||||
-EXPORT_SYMBOL_GPL(pv_apic_ops);
|
||||
-EXPORT_SYMBOL_GPL(pv_info);
|
||||
-EXPORT_SYMBOL (pv_irq_ops);
|
||||
+#endif
|
@ -1,80 +0,0 @@
|
||||
From: Alexander Graf <agraf@suse.de>
|
||||
Date: Wed, 18 Nov 2009 12:58:00 +0100
|
||||
Subject: Replace kvm io delay pv-ops with linux magic
|
||||
References: bnc#556135, FATE#306453
|
||||
Patch-Mainline: Submitted to virtualization list
|
||||
|
||||
Currently we use pv-ops to tell linux not to do anything on io_delay.
|
||||
|
||||
While the basic idea is good IMHO, I don't see why we would need pv-ops
|
||||
for that. The io delay function already has a switch that can do nothing
|
||||
if you're so inclined.
|
||||
|
||||
So here's a patch (stacked on top of the previous pv-ops series) that
|
||||
removes the io delay pv-ops hook and just sets the native io delay
|
||||
variable instead.
|
||||
|
||||
Signed-off-by: Alexander Graf <agraf@suse.de>
|
||||
---
|
||||
arch/x86/Kconfig | 14 --------------
|
||||
arch/x86/kernel/kvm.c | 16 +++-------------
|
||||
2 files changed, 3 insertions(+), 27 deletions(-)
|
||||
|
||||
--- a/arch/x86/Kconfig
|
||||
+++ b/arch/x86/Kconfig
|
||||
@@ -548,20 +548,6 @@ config KVM_GUEST
|
||||
This option enables various optimizations for running under the KVM
|
||||
hypervisor.
|
||||
|
||||
-config KVM_IODELAY
|
||||
- bool "KVM IO-delay support"
|
||||
- depends on KVM_GUEST
|
||||
- select PARAVIRT_CPU
|
||||
- ---help---
|
||||
- Usually we wait for PIO access to complete. When inside KVM there's
|
||||
- no need to do that, as we know that we're not going through a bus,
|
||||
- but process PIO requests instantly.
|
||||
-
|
||||
- This option disables PIO waits, but drags in CPU-bound pv-ops. Thus
|
||||
- you will probably get more speed loss than speedup using this option.
|
||||
-
|
||||
- If in doubt, say N.
|
||||
-
|
||||
config KVM_MMU
|
||||
bool "KVM PV MMU support"
|
||||
depends on KVM_GUEST
|
||||
--- a/arch/x86/kernel/kvm.c
|
||||
+++ b/arch/x86/kernel/kvm.c
|
||||
@@ -29,15 +29,6 @@
|
||||
#include <asm/desc.h>
|
||||
#include <asm/tlbflush.h>
|
||||
|
||||
-#ifdef CONFIG_KVM_IODELAY
|
||||
-/*
|
||||
- * No need for any "IO delay" on KVM
|
||||
- */
|
||||
-static void kvm_io_delay(void)
|
||||
-{
|
||||
-}
|
||||
-#endif /* CONFIG_KVM_IODELAY */
|
||||
-
|
||||
#ifdef CONFIG_KVM_MMU
|
||||
#define MMU_QUEUE_SIZE 1024
|
||||
|
||||
@@ -201,13 +192,12 @@ static void kvm_leave_lazy_mmu(void)
|
||||
|
||||
static void __init paravirt_ops_setup(void)
|
||||
{
|
||||
+ extern int io_delay_type;
|
||||
pv_info.name = "KVM";
|
||||
pv_info.paravirt_enabled = 1;
|
||||
|
||||
-#ifdef CONFIG_KVM_IODELAY
|
||||
- if (kvm_para_has_feature(KVM_FEATURE_NOP_IO_DELAY))
|
||||
- pv_cpu_ops.io_delay = kvm_io_delay;
|
||||
-#endif
|
||||
+ /* Disable IO delay */
|
||||
+ io_delay_type = CONFIG_IO_DELAY_TYPE_NONE;
|
||||
|
||||
#ifdef CONFIG_KVM_MMU
|
||||
if (kvm_para_has_feature(KVM_FEATURE_MMU_OP)) {
|
@ -1,728 +0,0 @@
|
||||
From: Alexander Graf <agraf@suse.de>
|
||||
Date: Wed, 18 Nov 2009 00:27:59 +0100
|
||||
Subject: Split paravirt ops by functionality
|
||||
References: bnc#556135, FATE#306453
|
||||
Patch-Mainline: Submitted to virtualization list
|
||||
|
||||
Currently when using paravirt ops it's an all-or-nothing option. We can either
|
||||
use pv-ops for CPU, MMU, timing, etc. or not at all.
|
||||
|
||||
Now there are some use cases where we don't need the full feature set, but only
|
||||
a small chunk of it. KVM is a pretty prominent example for this.
|
||||
|
||||
So let's make everything a bit more fine-grained. We already have a splitting
|
||||
by function groups, namely "cpu", "mmu", "time", "irq", "apic" and "spinlock".
|
||||
|
||||
Taking that existing splitting and extending it to only compile in the PV
|
||||
capable bits sounded like a natural fit. That way we don't get performance hits
|
||||
in MMU code from using the KVM PV clock which only needs the TIME parts of
|
||||
pv-ops.
|
||||
|
||||
We define a new CONFIG_PARAVIRT_ALL option that basically does the same thing
|
||||
the CONFIG_PARAVIRT did before this splitting. We move all users of
|
||||
CONFIG_PARAVIRT to CONFIG_PARAVIRT_ALL, so they behave the same way they did
|
||||
before.
|
||||
|
||||
So here it is - the splitting! I would have made the patch smaller, but this
|
||||
was the closest I could get to atomic (for bisect) while staying sane.
|
||||
|
||||
Signed-off-by: Alexander Graf <agraf@suse.de>
|
||||
---
|
||||
arch/x86/Kconfig | 41 +++++++++++++++++++++++---
|
||||
arch/x86/include/asm/apic.h | 2 -
|
||||
arch/x86/include/asm/desc.h | 4 +-
|
||||
arch/x86/include/asm/fixmap.h | 2 -
|
||||
arch/x86/include/asm/io.h | 2 -
|
||||
arch/x86/include/asm/irqflags.h | 21 ++++++++++---
|
||||
arch/x86/include/asm/mmu_context.h | 4 +-
|
||||
arch/x86/include/asm/msr.h | 4 +-
|
||||
arch/x86/include/asm/paravirt.h | 44 ++++++++++++++++++++++++++--
|
||||
arch/x86/include/asm/paravirt_types.h | 12 +++++++
|
||||
arch/x86/include/asm/pgalloc.h | 2 -
|
||||
arch/x86/include/asm/pgtable-3level_types.h | 2 -
|
||||
arch/x86/include/asm/pgtable.h | 2 -
|
||||
arch/x86/include/asm/processor.h | 2 -
|
||||
arch/x86/include/asm/required-features.h | 2 -
|
||||
arch/x86/include/asm/smp.h | 2 -
|
||||
arch/x86/include/asm/system.h | 13 +++++---
|
||||
arch/x86/include/asm/tlbflush.h | 4 +-
|
||||
arch/x86/kernel/head_64.S | 2 -
|
||||
arch/x86/kernel/paravirt.c | 2 +
|
||||
arch/x86/kernel/tsc.c | 2 -
|
||||
arch/x86/kernel/vsmp_64.c | 2 -
|
||||
arch/x86/kernel/x8664_ksyms_64.c | 2 -
|
||||
arch/x86/xen/Kconfig | 2 -
|
||||
24 files changed, 140 insertions(+), 37 deletions(-)
|
||||
|
||||
--- a/arch/x86/Kconfig
|
||||
+++ b/arch/x86/Kconfig
|
||||
@@ -367,7 +367,7 @@ endif
|
||||
config X86_VSMP
|
||||
bool "ScaleMP vSMP"
|
||||
select PARAVIRT_GUEST
|
||||
- select PARAVIRT
|
||||
+ select PARAVIRT_ALL
|
||||
depends on X86_64 && PCI
|
||||
depends on X86_EXTENDED_PLATFORM
|
||||
---help---
|
||||
@@ -533,7 +533,6 @@ config VMI
|
||||
|
||||
config KVM_CLOCK
|
||||
bool "KVM paravirtualized clock"
|
||||
- select PARAVIRT
|
||||
select PARAVIRT_CLOCK
|
||||
---help---
|
||||
Turning on this option will allow you to run a paravirtualized clock
|
||||
@@ -544,7 +543,7 @@ config KVM_CLOCK
|
||||
|
||||
config KVM_GUEST
|
||||
bool "KVM Guest support"
|
||||
- select PARAVIRT
|
||||
+ select PARAVIRT_ALL
|
||||
---help---
|
||||
This option enables various optimizations for running under the KVM
|
||||
hypervisor.
|
||||
@@ -572,8 +571,42 @@ config PARAVIRT_SPINLOCKS
|
||||
|
||||
If you are unsure how to answer this question, answer N.
|
||||
|
||||
+config PARAVIRT_CPU
|
||||
+ bool
|
||||
+ select PARAVIRT
|
||||
+
|
||||
+config PARAVIRT_TIME
|
||||
+ bool
|
||||
+ select PARAVIRT
|
||||
+
|
||||
+config PARAVIRT_IRQ
|
||||
+ bool
|
||||
+ select PARAVIRT
|
||||
+
|
||||
+config PARAVIRT_APIC
|
||||
+ bool
|
||||
+ select PARAVIRT
|
||||
+
|
||||
+config PARAVIRT_MMU
|
||||
+ bool
|
||||
+ select PARAVIRT
|
||||
+
|
||||
+#
|
||||
+# This is a placeholder to activate the old "include all pv-ops functionality"
|
||||
+# behavior. If you're using this I'd recommend looking through your code to see
|
||||
+# if you can be more specific. It probably saves you a few cycles!
|
||||
+#
|
||||
+config PARAVIRT_ALL
|
||||
+ bool
|
||||
+ select PARAVIRT_CPU
|
||||
+ select PARAVIRT_TIME
|
||||
+ select PARAVIRT_IRQ
|
||||
+ select PARAVIRT_APIC
|
||||
+ select PARAVIRT_MMU
|
||||
+
|
||||
config PARAVIRT_CLOCK
|
||||
bool
|
||||
+ select PARAVIRT_TIME
|
||||
|
||||
endif
|
||||
|
||||
--- a/arch/x86/include/asm/apic.h
|
||||
+++ b/arch/x86/include/asm/apic.h
|
||||
@@ -81,7 +81,7 @@ static inline bool apic_from_smp_config(
|
||||
/*
|
||||
* Basic functions accessing APICs.
|
||||
*/
|
||||
-#ifdef CONFIG_PARAVIRT
|
||||
+#ifdef CONFIG_PARAVIRT_APIC
|
||||
#include <asm/paravirt.h>
|
||||
#endif
|
||||
|
||||
--- a/arch/x86/include/asm/desc.h
|
||||
+++ b/arch/x86/include/asm/desc.h
|
||||
@@ -78,7 +78,7 @@ static inline int desc_empty(const void
|
||||
return !(desc[0] | desc[1]);
|
||||
}
|
||||
|
||||
-#ifdef CONFIG_PARAVIRT
|
||||
+#ifdef CONFIG_PARAVIRT_CPU
|
||||
#include <asm/paravirt.h>
|
||||
#else
|
||||
#define load_TR_desc() native_load_tr_desc()
|
||||
@@ -108,7 +108,7 @@ static inline void paravirt_alloc_ldt(st
|
||||
static inline void paravirt_free_ldt(struct desc_struct *ldt, unsigned entries)
|
||||
{
|
||||
}
|
||||
-#endif /* CONFIG_PARAVIRT */
|
||||
+#endif /* CONFIG_PARAVIRT_CPU */
|
||||
|
||||
#define store_ldt(ldt) asm("sldt %0" : "=m"(ldt))
|
||||
|
||||
--- a/arch/x86/include/asm/fixmap.h
|
||||
+++ b/arch/x86/include/asm/fixmap.h
|
||||
@@ -162,7 +162,7 @@ void __native_set_fixmap(enum fixed_addr
|
||||
void native_set_fixmap(enum fixed_addresses idx,
|
||||
phys_addr_t phys, pgprot_t flags);
|
||||
|
||||
-#ifndef CONFIG_PARAVIRT
|
||||
+#ifndef CONFIG_PARAVIRT_MMU
|
||||
static inline void __set_fixmap(enum fixed_addresses idx,
|
||||
phys_addr_t phys, pgprot_t flags)
|
||||
{
|
||||
--- a/arch/x86/include/asm/io.h
|
||||
+++ b/arch/x86/include/asm/io.h
|
||||
@@ -268,7 +268,7 @@ extern void native_io_delay(void);
|
||||
extern int io_delay_type;
|
||||
extern void io_delay_init(void);
|
||||
|
||||
-#if defined(CONFIG_PARAVIRT)
|
||||
+#if defined(CONFIG_PARAVIRT_CPU)
|
||||
#include <asm/paravirt.h>
|
||||
#else
|
||||
|
||||
--- a/arch/x86/include/asm/irqflags.h
|
||||
+++ b/arch/x86/include/asm/irqflags.h
|
||||
@@ -58,9 +58,11 @@ static inline void native_halt(void)
|
||||
|
||||
#ifdef CONFIG_PARAVIRT
|
||||
#include <asm/paravirt.h>
|
||||
-#else
|
||||
+#endif
|
||||
+
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
+#ifndef CONFIG_PARAVIRT_IRQ
|
||||
static inline unsigned long arch_local_save_flags(void)
|
||||
{
|
||||
return native_save_fl();
|
||||
@@ -110,12 +112,17 @@ static inline unsigned long __raw_local_
|
||||
arch_local_irq_disable();
|
||||
return flags;
|
||||
}
|
||||
-#else
|
||||
+#endif /* CONFIG_PARAVIRT_IRQ */
|
||||
+
|
||||
+#else /* __ASSEMBLY__ */
|
||||
|
||||
+#ifndef CONFIG_PARAVIRT_IRQ
|
||||
#define ENABLE_INTERRUPTS(x) sti
|
||||
#define DISABLE_INTERRUPTS(x) cli
|
||||
+#endif /* !CONFIG_PARAVIRT_IRQ */
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
+#ifndef CONFIG_PARAVIRT_CPU
|
||||
#define SWAPGS swapgs
|
||||
/*
|
||||
* Currently paravirt can't handle swapgs nicely when we
|
||||
@@ -128,8 +135,6 @@ static inline unsigned long __raw_local_
|
||||
*/
|
||||
#define SWAPGS_UNSAFE_STACK swapgs
|
||||
|
||||
-#define PARAVIRT_ADJUST_EXCEPTION_FRAME /* */
|
||||
-
|
||||
#define INTERRUPT_RETURN iretq
|
||||
#define USERGS_SYSRET64 \
|
||||
swapgs; \
|
||||
@@ -141,16 +146,22 @@ static inline unsigned long __raw_local_
|
||||
swapgs; \
|
||||
sti; \
|
||||
sysexit
|
||||
+#endif /* !CONFIG_PARAVIRT_CPU */
|
||||
+
|
||||
+#ifndef CONFIG_PARAVIRT_IRQ
|
||||
+#define PARAVIRT_ADJUST_EXCEPTION_FRAME /* */
|
||||
+#endif /* !CONFIG_PARAVIRT_IRQ */
|
||||
|
||||
#else
|
||||
+#ifndef CONFIG_PARAVIRT_CPU
|
||||
#define INTERRUPT_RETURN iret
|
||||
#define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit
|
||||
#define GET_CR0_INTO_EAX movl %cr0, %eax
|
||||
+#endif /* !CONFIG_PARAVIRT_CPU */
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
-#endif /* CONFIG_PARAVIRT */
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
static inline int arch_irqs_disabled_flags(unsigned long flags)
|
||||
--- a/arch/x86/include/asm/mmu_context.h
|
||||
+++ b/arch/x86/include/asm/mmu_context.h
|
||||
@@ -6,14 +6,14 @@
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/tlbflush.h>
|
||||
#include <asm/paravirt.h>
|
||||
-#ifndef CONFIG_PARAVIRT
|
||||
+#ifndef CONFIG_PARAVIRT_MMU
|
||||
#include <asm-generic/mm_hooks.h>
|
||||
|
||||
static inline void paravirt_activate_mm(struct mm_struct *prev,
|
||||
struct mm_struct *next)
|
||||
{
|
||||
}
|
||||
-#endif /* !CONFIG_PARAVIRT */
|
||||
+#endif /* !CONFIG_PARAVIRT_MMU */
|
||||
|
||||
/*
|
||||
* Used for LDT copy/destruction.
|
||||
--- a/arch/x86/include/asm/msr.h
|
||||
+++ b/arch/x86/include/asm/msr.h
|
||||
@@ -135,7 +135,7 @@ static inline unsigned long long native_
|
||||
return EAX_EDX_VAL(val, low, high);
|
||||
}
|
||||
|
||||
-#ifdef CONFIG_PARAVIRT
|
||||
+#ifdef CONFIG_PARAVIRT_CPU
|
||||
#include <asm/paravirt.h>
|
||||
#else
|
||||
#include <linux/errno.h>
|
||||
@@ -246,7 +246,7 @@ do {
|
||||
|
||||
#define rdtscpll(val, aux) (val) = native_read_tscp(&(aux))
|
||||
|
||||
-#endif /* !CONFIG_PARAVIRT */
|
||||
+#endif /* !CONFIG_PARAVIRT_CPU */
|
||||
|
||||
|
||||
#define checking_wrmsrl(msr, val) wrmsr_safe((msr), (u32)(val), \
|
||||
--- a/arch/x86/include/asm/paravirt.h
|
||||
+++ b/arch/x86/include/asm/paravirt.h
|
||||
@@ -18,6 +18,7 @@ static inline int paravirt_enabled(void)
|
||||
return pv_info.paravirt_enabled;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_PARAVIRT_CPU
|
||||
static inline void load_sp0(struct tss_struct *tss,
|
||||
struct thread_struct *thread)
|
||||
{
|
||||
@@ -58,7 +59,9 @@ static inline void write_cr0(unsigned lo
|
||||
{
|
||||
PVOP_VCALL1(pv_cpu_ops.write_cr0, x);
|
||||
}
|
||||
+#endif /* CONFIG_PARAVIRT_CPU */
|
||||
|
||||
+#ifdef CONFIG_PARAVIRT_MMU
|
||||
static inline unsigned long read_cr2(void)
|
||||
{
|
||||
return PVOP_CALL0(unsigned long, pv_mmu_ops.read_cr2);
|
||||
@@ -78,7 +81,9 @@ static inline void write_cr3(unsigned lo
|
||||
{
|
||||
PVOP_VCALL1(pv_mmu_ops.write_cr3, x);
|
||||
}
|
||||
+#endif /* CONFIG_PARAVIRT_MMU */
|
||||
|
||||
+#ifdef CONFIG_PARAVIRT_CPU
|
||||
static inline unsigned long read_cr4(void)
|
||||
{
|
||||
return PVOP_CALL0(unsigned long, pv_cpu_ops.read_cr4);
|
||||
@@ -92,8 +97,9 @@ static inline void write_cr4(unsigned lo
|
||||
{
|
||||
PVOP_VCALL1(pv_cpu_ops.write_cr4, x);
|
||||
}
|
||||
+#endif /* CONFIG_PARAVIRT_CPU */
|
||||
|
||||
-#ifdef CONFIG_X86_64
|
||||
+#if defined(CONFIG_X86_64) && defined(CONFIG_PARAVIRT_CPU)
|
||||
static inline unsigned long read_cr8(void)
|
||||
{
|
||||
return PVOP_CALL0(unsigned long, pv_cpu_ops.read_cr8);
|
||||
@@ -105,6 +111,7 @@ static inline void write_cr8(unsigned lo
|
||||
}
|
||||
#endif
|
||||
|
||||
+#ifdef CONFIG_PARAVIRT_IRQ
|
||||
static inline void arch_safe_halt(void)
|
||||
{
|
||||
PVOP_VCALL0(pv_irq_ops.safe_halt);
|
||||
@@ -114,14 +121,18 @@ static inline void halt(void)
|
||||
{
|
||||
PVOP_VCALL0(pv_irq_ops.halt);
|
||||
}
|
||||
+#endif /* CONFIG_PARAVIRT_IRQ */
|
||||
|
||||
+#ifdef CONFIG_PARAVIRT_CPU
|
||||
static inline void wbinvd(void)
|
||||
{
|
||||
PVOP_VCALL0(pv_cpu_ops.wbinvd);
|
||||
}
|
||||
+#endif
|
||||
|
||||
#define get_kernel_rpl() (pv_info.kernel_rpl)
|
||||
|
||||
+#ifdef CONFIG_PARAVIRT_CPU
|
||||
static inline u64 paravirt_read_msr(unsigned msr, int *err)
|
||||
{
|
||||
return PVOP_CALL2(u64, pv_cpu_ops.read_msr, msr, err);
|
||||
@@ -224,12 +235,16 @@ do { \
|
||||
} while (0)
|
||||
|
||||
#define rdtscll(val) (val = paravirt_read_tsc())
|
||||
+#endif /* CONFIG_PARAVIRT_CPU */
|
||||
|
||||
+#ifdef CONFIG_PARAVIRT_TIME
|
||||
static inline unsigned long long paravirt_sched_clock(void)
|
||||
{
|
||||
return PVOP_CALL0(unsigned long long, pv_time_ops.sched_clock);
|
||||
}
|
||||
+#endif /* CONFIG_PARAVIRT_TIME */
|
||||
|
||||
+#ifdef CONFIG_PARAVIRT_CPU
|
||||
static inline unsigned long long paravirt_read_pmc(int counter)
|
||||
{
|
||||
return PVOP_CALL1(u64, pv_cpu_ops.read_pmc, counter);
|
||||
@@ -345,8 +360,9 @@ static inline void slow_down_io(void)
|
||||
pv_cpu_ops.io_delay();
|
||||
#endif
|
||||
}
|
||||
+#endif /* CONFIG_PARAVIRT_CPU */
|
||||
|
||||
-#ifdef CONFIG_SMP
|
||||
+#if defined(CONFIG_SMP) && defined(CONFIG_PARAVIRT_APIC)
|
||||
static inline void startup_ipi_hook(int phys_apicid, unsigned long start_eip,
|
||||
unsigned long start_esp)
|
||||
{
|
||||
@@ -355,6 +371,7 @@ static inline void startup_ipi_hook(int
|
||||
}
|
||||
#endif
|
||||
|
||||
+#ifdef CONFIG_PARAVIRT_MMU
|
||||
static inline void paravirt_activate_mm(struct mm_struct *prev,
|
||||
struct mm_struct *next)
|
||||
{
|
||||
@@ -689,7 +706,9 @@ static inline void pmd_clear(pmd_t *pmdp
|
||||
set_pmd(pmdp, __pmd(0));
|
||||
}
|
||||
#endif /* CONFIG_X86_PAE */
|
||||
+#endif /* CONFIG_PARAVIRT_MMU */
|
||||
|
||||
+#ifdef CONFIG_PARAVIRT_CPU
|
||||
#define __HAVE_ARCH_START_CONTEXT_SWITCH
|
||||
static inline void arch_start_context_switch(struct task_struct *prev)
|
||||
{
|
||||
@@ -700,7 +719,9 @@ static inline void arch_end_context_swit
|
||||
{
|
||||
PVOP_VCALL1(pv_cpu_ops.end_context_switch, next);
|
||||
}
|
||||
+#endif /* CONFIG_PARAVIRT_CPU */
|
||||
|
||||
+#ifdef CONFIG_PARAVIRT_MMU
|
||||
#define __HAVE_ARCH_ENTER_LAZY_MMU_MODE
|
||||
static inline void arch_enter_lazy_mmu_mode(void)
|
||||
{
|
||||
@@ -719,6 +740,7 @@ static inline void __set_fixmap(unsigned
|
||||
{
|
||||
pv_mmu_ops.set_fixmap(idx, phys, flags);
|
||||
}
|
||||
+#endif /* CONFIG_PARAVIRT_MMU */
|
||||
|
||||
#if defined(CONFIG_SMP) && defined(CONFIG_PARAVIRT_SPINLOCKS)
|
||||
|
||||
@@ -829,6 +851,7 @@ static __always_inline void arch_spin_un
|
||||
#define __PV_IS_CALLEE_SAVE(func) \
|
||||
((struct paravirt_callee_save) { func })
|
||||
|
||||
+#ifdef CONFIG_PARAVIRT_IRQ
|
||||
static inline notrace unsigned long arch_local_save_flags(void)
|
||||
{
|
||||
return PVOP_CALLEE0(unsigned long, pv_irq_ops.save_fl);
|
||||
@@ -857,6 +880,7 @@ static inline unsigned long __raw_local_
|
||||
arch_local_irq_disable();
|
||||
return f;
|
||||
}
|
||||
+#endif /* CONFIG_PARAVIRT_IRQ */
|
||||
|
||||
|
||||
/* Make sure as little as possible of this mess escapes. */
|
||||
@@ -939,10 +963,13 @@ extern void default_banner(void);
|
||||
#define PARA_INDIRECT(addr) *%cs:addr
|
||||
#endif
|
||||
|
||||
+#ifdef CONFIG_PARAVIRT_CPU
|
||||
#define INTERRUPT_RETURN \
|
||||
PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_iret), CLBR_NONE, \
|
||||
jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_iret))
|
||||
+#endif /* CONFIG_PARAVIRT_CPU */
|
||||
|
||||
+#ifdef CONFIG_PARAVIRT_IRQ
|
||||
#define DISABLE_INTERRUPTS(clobbers) \
|
||||
PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_disable), clobbers, \
|
||||
PV_SAVE_REGS(clobbers | CLBR_CALLEE_SAVE); \
|
||||
@@ -954,13 +981,17 @@ extern void default_banner(void);
|
||||
PV_SAVE_REGS(clobbers | CLBR_CALLEE_SAVE); \
|
||||
call PARA_INDIRECT(pv_irq_ops+PV_IRQ_irq_enable); \
|
||||
PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);)
|
||||
+#endif /* CONFIG_PARAVIRT_IRQ */
|
||||
|
||||
+#ifdef CONFIG_PARAVIRT_CPU
|
||||
#define USERGS_SYSRET32 \
|
||||
PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_usergs_sysret32), \
|
||||
CLBR_NONE, \
|
||||
jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_usergs_sysret32))
|
||||
+#endif /* CONFIG_PARAVIRT_CPU */
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
+#ifdef CONFIG_PARAVIRT_CPU
|
||||
#define GET_CR0_INTO_EAX \
|
||||
push %ecx; push %edx; \
|
||||
call PARA_INDIRECT(pv_cpu_ops+PV_CPU_read_cr0); \
|
||||
@@ -970,10 +1001,12 @@ extern void default_banner(void);
|
||||
PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_sysexit), \
|
||||
CLBR_NONE, \
|
||||
jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_irq_enable_sysexit))
|
||||
+#endif /* CONFIG_PARAVIRT_CPU */
|
||||
|
||||
|
||||
#else /* !CONFIG_X86_32 */
|
||||
|
||||
+#ifdef CONFIG_PARAVIRT_CPU
|
||||
/*
|
||||
* If swapgs is used while the userspace stack is still current,
|
||||
* there's no way to call a pvop. The PV replacement *must* be
|
||||
@@ -993,17 +1026,23 @@ extern void default_banner(void);
|
||||
PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_swapgs), CLBR_NONE, \
|
||||
call PARA_INDIRECT(pv_cpu_ops+PV_CPU_swapgs) \
|
||||
)
|
||||
+#endif /* CONFIG_PARAVIRT_CPU */
|
||||
|
||||
+#ifdef CONFIG_PARAVIRT_MMU
|
||||
#define GET_CR2_INTO_RCX \
|
||||
call PARA_INDIRECT(pv_mmu_ops+PV_MMU_read_cr2); \
|
||||
movq %rax, %rcx; \
|
||||
xorq %rax, %rax;
|
||||
+#endif /* CONFIG_PARAVIRT_MMU */
|
||||
|
||||
+#ifdef CONFIG_PARAVIRT_IRQ
|
||||
#define PARAVIRT_ADJUST_EXCEPTION_FRAME \
|
||||
PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_adjust_exception_frame), \
|
||||
CLBR_NONE, \
|
||||
call PARA_INDIRECT(pv_irq_ops+PV_IRQ_adjust_exception_frame))
|
||||
+#endif /* CONFIG_PARAVIRT_IRQ */
|
||||
|
||||
+#ifdef CONFIG_PARAVIRT_CPU
|
||||
#define USERGS_SYSRET64 \
|
||||
PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_usergs_sysret64), \
|
||||
CLBR_NONE, \
|
||||
@@ -1013,6 +1052,7 @@ extern void default_banner(void);
|
||||
PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_sysexit), \
|
||||
CLBR_NONE, \
|
||||
jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_irq_enable_sysexit))
|
||||
+#endif /* CONFIG_PARAVIRT_CPU */
|
||||
#endif /* CONFIG_X86_32 */
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
--- a/arch/x86/include/asm/paravirt_types.h
|
||||
+++ b/arch/x86/include/asm/paravirt_types.h
|
||||
@@ -339,12 +339,24 @@ struct paravirt_patch_template {
|
||||
|
||||
extern struct pv_info pv_info;
|
||||
extern struct pv_init_ops pv_init_ops;
|
||||
+#ifdef CONFIG_PARAVIRT_TIME
|
||||
extern struct pv_time_ops pv_time_ops;
|
||||
+#endif
|
||||
+#ifdef CONFIG_PARAVIRT_CPU
|
||||
extern struct pv_cpu_ops pv_cpu_ops;
|
||||
+#endif
|
||||
+#ifdef CONFIG_PARAVIRT_IRQ
|
||||
extern struct pv_irq_ops pv_irq_ops;
|
||||
+#endif
|
||||
+#ifdef CONFIG_PARAVIRT_APIC
|
||||
extern struct pv_apic_ops pv_apic_ops;
|
||||
+#endif
|
||||
+#ifdef CONFIG_PARAVIRT_MMU
|
||||
extern struct pv_mmu_ops pv_mmu_ops;
|
||||
+#endif
|
||||
+#ifdef CONFIG_PARAVIRT_SPINLOCKS
|
||||
extern struct pv_lock_ops pv_lock_ops;
|
||||
+#endif
|
||||
|
||||
#define PARAVIRT_PATCH(x) \
|
||||
(offsetof(struct paravirt_patch_template, x) / sizeof(void *))
|
||||
--- a/arch/x86/include/asm/pgalloc.h
|
||||
+++ b/arch/x86/include/asm/pgalloc.h
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
static inline int __paravirt_pgd_alloc(struct mm_struct *mm) { return 0; }
|
||||
|
||||
-#ifdef CONFIG_PARAVIRT
|
||||
+#ifdef CONFIG_PARAVIRT_MMU
|
||||
#include <asm/paravirt.h>
|
||||
#else
|
||||
#define paravirt_pgd_alloc(mm) __paravirt_pgd_alloc(mm)
|
||||
--- a/arch/x86/include/asm/pgtable-3level_types.h
|
||||
+++ b/arch/x86/include/asm/pgtable-3level_types.h
|
||||
@@ -18,7 +18,7 @@ typedef union {
|
||||
} pte_t;
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
-#ifdef CONFIG_PARAVIRT
|
||||
+#ifdef CONFIG_PARAVIRT_MMU
|
||||
#define SHARED_KERNEL_PMD (pv_info.shared_kernel_pmd)
|
||||
#else
|
||||
#define SHARED_KERNEL_PMD 1
|
||||
--- a/arch/x86/include/asm/pgtable.h
|
||||
+++ b/arch/x86/include/asm/pgtable.h
|
||||
@@ -28,7 +28,7 @@ extern unsigned long empty_zero_page[PAG
|
||||
|
||||
extern struct mm_struct *pgd_page_get_mm(struct page *page);
|
||||
|
||||
-#ifdef CONFIG_PARAVIRT
|
||||
+#ifdef CONFIG_PARAVIRT_MMU
|
||||
#include <asm/paravirt.h>
|
||||
#else /* !CONFIG_PARAVIRT */
|
||||
#define set_pte(ptep, pte) native_set_pte(ptep, pte)
|
||||
--- a/arch/x86/include/asm/processor.h
|
||||
+++ b/arch/x86/include/asm/processor.h
|
||||
@@ -569,7 +569,7 @@ static inline void native_swapgs(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
-#ifdef CONFIG_PARAVIRT
|
||||
+#ifdef CONFIG_PARAVIRT_CPU
|
||||
#include <asm/paravirt.h>
|
||||
#else
|
||||
#define __cpuid native_cpuid
|
||||
--- a/arch/x86/include/asm/required-features.h
|
||||
+++ b/arch/x86/include/asm/required-features.h
|
||||
@@ -48,7 +48,7 @@
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
-#ifdef CONFIG_PARAVIRT
|
||||
+#ifdef CONFIG_PARAVIRT_MMU
|
||||
/* Paravirtualized systems may not have PSE or PGE available */
|
||||
#define NEED_PSE 0
|
||||
#define NEED_PGE 0
|
||||
--- a/arch/x86/include/asm/smp.h
|
||||
+++ b/arch/x86/include/asm/smp.h
|
||||
@@ -66,7 +66,7 @@ struct smp_ops {
|
||||
extern void set_cpu_sibling_map(int cpu);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
-#ifndef CONFIG_PARAVIRT
|
||||
+#ifndef CONFIG_PARAVIRT_APIC
|
||||
#define startup_ipi_hook(phys_apicid, start_eip, start_esp) do { } while (0)
|
||||
#endif
|
||||
extern struct smp_ops smp_ops;
|
||||
--- a/arch/x86/include/asm/system.h
|
||||
+++ b/arch/x86/include/asm/system.h
|
||||
@@ -304,13 +304,18 @@ static inline void native_wbinvd(void)
|
||||
|
||||
#ifdef CONFIG_PARAVIRT
|
||||
#include <asm/paravirt.h>
|
||||
-#else
|
||||
-#define read_cr0() (native_read_cr0())
|
||||
-#define write_cr0(x) (native_write_cr0(x))
|
||||
+#endif/* CONFIG_PARAVIRT */
|
||||
+
|
||||
+#ifndef CONFIG_PARAVIRT_MMU
|
||||
#define read_cr2() (native_read_cr2())
|
||||
#define write_cr2(x) (native_write_cr2(x))
|
||||
#define read_cr3() (native_read_cr3())
|
||||
#define write_cr3(x) (native_write_cr3(x))
|
||||
+#endif /* CONFIG_PARAVIRT_MMU */
|
||||
+
|
||||
+#ifndef CONFIG_PARAVIRT_CPU
|
||||
+#define read_cr0() (native_read_cr0())
|
||||
+#define write_cr0(x) (native_write_cr0(x))
|
||||
#define read_cr4() (native_read_cr4())
|
||||
#define read_cr4_safe() (native_read_cr4_safe())
|
||||
#define write_cr4(x) (native_write_cr4(x))
|
||||
@@ -324,7 +329,7 @@ static inline void native_wbinvd(void)
|
||||
/* Clear the 'TS' bit */
|
||||
#define clts() (native_clts())
|
||||
|
||||
-#endif/* CONFIG_PARAVIRT */
|
||||
+#endif /* CONFIG_PARAVIRT_CPU */
|
||||
|
||||
#define stts() write_cr0(read_cr0() | X86_CR0_TS)
|
||||
|
||||
--- a/arch/x86/include/asm/tlbflush.h
|
||||
+++ b/arch/x86/include/asm/tlbflush.h
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <asm/processor.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
-#ifdef CONFIG_PARAVIRT
|
||||
+#ifdef CONFIG_PARAVIRT_MMU
|
||||
#include <asm/paravirt.h>
|
||||
#else
|
||||
#define __flush_tlb() __native_flush_tlb()
|
||||
@@ -162,7 +162,7 @@ static inline void reset_lazy_tlbstate(v
|
||||
|
||||
#endif /* SMP */
|
||||
|
||||
-#ifndef CONFIG_PARAVIRT
|
||||
+#ifndef CONFIG_PARAVIRT_MMU
|
||||
#define flush_tlb_others(mask, mm, va) native_flush_tlb_others(mask, mm, va)
|
||||
#endif
|
||||
|
||||
--- a/arch/x86/kernel/head_64.S
|
||||
+++ b/arch/x86/kernel/head_64.S
|
||||
@@ -20,7 +20,7 @@
|
||||
#include <asm/processor-flags.h>
|
||||
#include <asm/percpu.h>
|
||||
|
||||
-#ifdef CONFIG_PARAVIRT
|
||||
+#ifdef CONFIG_PARAVIRT_MMU
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/paravirt.h>
|
||||
#else
|
||||
--- a/arch/x86/kernel/paravirt.c
|
||||
+++ b/arch/x86/kernel/paravirt.c
|
||||
@@ -155,12 +155,14 @@ unsigned paravirt_patch_default(u8 type,
|
||||
else if (opfunc == _paravirt_ident_64)
|
||||
ret = paravirt_patch_ident_64(insnbuf, len);
|
||||
|
||||
+#ifdef CONFIG_PARAVIRT_CPU
|
||||
else if (type == PARAVIRT_PATCH(pv_cpu_ops.iret) ||
|
||||
type == PARAVIRT_PATCH(pv_cpu_ops.irq_enable_sysexit) ||
|
||||
type == PARAVIRT_PATCH(pv_cpu_ops.usergs_sysret32) ||
|
||||
type == PARAVIRT_PATCH(pv_cpu_ops.usergs_sysret64))
|
||||
/* If operation requires a jmp, then jmp */
|
||||
ret = paravirt_patch_jmp(insnbuf, opfunc, addr, len);
|
||||
+#endif
|
||||
else
|
||||
/* Otherwise call the function; assume target could
|
||||
clobber any caller-save reg */
|
||||
--- a/arch/x86/kernel/tsc.c
|
||||
+++ b/arch/x86/kernel/tsc.c
|
||||
@@ -66,7 +66,7 @@ u64 native_sched_clock(void)
|
||||
|
||||
/* We need to define a real function for sched_clock, to override the
|
||||
weak default version */
|
||||
-#ifdef CONFIG_PARAVIRT
|
||||
+#ifdef CONFIG_PARAVIRT_TIME
|
||||
unsigned long long sched_clock(void)
|
||||
{
|
||||
return paravirt_sched_clock();
|
||||
--- a/arch/x86/kernel/vsmp_64.c
|
||||
+++ b/arch/x86/kernel/vsmp_64.c
|
||||
@@ -22,7 +22,7 @@
|
||||
#include <asm/paravirt.h>
|
||||
#include <asm/setup.h>
|
||||
|
||||
-#if defined CONFIG_PCI && defined CONFIG_PARAVIRT
|
||||
+#if defined CONFIG_PCI && defined CONFIG_PARAVIRT_IRQ
|
||||
/*
|
||||
* Interrupt control on vSMPowered systems:
|
||||
* ~AC is a shadow of IF. If IF is 'on' AC should be 'off'
|
||||
--- a/arch/x86/kernel/x8664_ksyms_64.c
|
||||
+++ b/arch/x86/kernel/x8664_ksyms_64.c
|
||||
@@ -54,6 +54,6 @@ EXPORT_SYMBOL(memcpy);
|
||||
EXPORT_SYMBOL(__memcpy);
|
||||
|
||||
EXPORT_SYMBOL(empty_zero_page);
|
||||
-#ifndef CONFIG_PARAVIRT
|
||||
+#ifndef CONFIG_PARAVIRT_CPU
|
||||
EXPORT_SYMBOL(native_load_gs_index);
|
||||
#endif
|
||||
--- a/arch/x86/xen/Kconfig
|
||||
+++ b/arch/x86/xen/Kconfig
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
config XEN
|
||||
bool "Xen guest support"
|
||||
- select PARAVIRT
|
||||
+ select PARAVIRT_ALL
|
||||
select PARAVIRT_CLOCK
|
||||
depends on X86_64 || (X86_32 && X86_PAE && !X86_VISWS)
|
||||
depends on X86_CMPXCHG && X86_TSC
|
@ -1,125 +0,0 @@
|
||||
From: Alexander Graf <agraf@suse.de>
|
||||
Date: Wed, 18 Nov 2009 00:45:10 +0100
|
||||
Subject: Split the KVM pv-ops support by feature
|
||||
References: bnc#556135, FATE#306453
|
||||
Patch-Mainline: Submitted to virtualization list
|
||||
|
||||
Currently selecting KVM guest support enabled multiple features at once that
|
||||
not everyone necessarily wants to have, namely:
|
||||
|
||||
- PV MMU
|
||||
- zero io delay
|
||||
- apic detection workaround
|
||||
|
||||
Let's split them off so we don't drag in the full pv-ops framework just to
|
||||
detect we're running on KVM. That gives us more chances to tweak performance!
|
||||
|
||||
Signed-off-by: Alexander Graf <agraf@suse.de>
|
||||
---
|
||||
arch/x86/Kconfig | 29 ++++++++++++++++++++++++++++-
|
||||
arch/x86/kernel/kvm.c | 22 +++++++++++++++-------
|
||||
2 files changed, 43 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/arch/x86/Kconfig
|
||||
+++ b/arch/x86/Kconfig
|
||||
@@ -543,11 +543,38 @@ config KVM_CLOCK
|
||||
|
||||
config KVM_GUEST
|
||||
bool "KVM Guest support"
|
||||
- select PARAVIRT_ALL
|
||||
+ select PARAVIRT
|
||||
---help---
|
||||
This option enables various optimizations for running under the KVM
|
||||
hypervisor.
|
||||
|
||||
+config KVM_IODELAY
|
||||
+ bool "KVM IO-delay support"
|
||||
+ depends on KVM_GUEST
|
||||
+ select PARAVIRT_CPU
|
||||
+ ---help---
|
||||
+ Usually we wait for PIO access to complete. When inside KVM there's
|
||||
+ no need to do that, as we know that we're not going through a bus,
|
||||
+ but process PIO requests instantly.
|
||||
+
|
||||
+ This option disables PIO waits, but drags in CPU-bound pv-ops. Thus
|
||||
+ you will probably get more speed loss than speedup using this option.
|
||||
+
|
||||
+ If in doubt, say N.
|
||||
+
|
||||
+config KVM_MMU
|
||||
+ bool "KVM PV MMU support"
|
||||
+ depends on KVM_GUEST
|
||||
+ select PARAVIRT_MMU
|
||||
+ ---help---
|
||||
+ This option enables the paravirtualized MMU for KVM. In most cases
|
||||
+ it's pretty useless and shouldn't be used.
|
||||
+
|
||||
+ It will only cost you performance, because it drags in pv-ops for
|
||||
+ memory management.
|
||||
+
|
||||
+ If in doubt, say N.
|
||||
+
|
||||
source "arch/x86/lguest/Kconfig"
|
||||
|
||||
config PARAVIRT
|
||||
--- a/arch/x86/kernel/kvm.c
|
||||
+++ b/arch/x86/kernel/kvm.c
|
||||
@@ -29,6 +29,16 @@
|
||||
#include <asm/desc.h>
|
||||
#include <asm/tlbflush.h>
|
||||
|
||||
+#ifdef CONFIG_KVM_IODELAY
|
||||
+/*
|
||||
+ * No need for any "IO delay" on KVM
|
||||
+ */
|
||||
+static void kvm_io_delay(void)
|
||||
+{
|
||||
+}
|
||||
+#endif /* CONFIG_KVM_IODELAY */
|
||||
+
|
||||
+#ifdef CONFIG_KVM_MMU
|
||||
#define MMU_QUEUE_SIZE 1024
|
||||
|
||||
static int kvmapf = 1;
|
||||
@@ -43,13 +53,6 @@ static struct kvm_para_state *kvm_para_s
|
||||
return &per_cpu(para_state, raw_smp_processor_id());
|
||||
}
|
||||
|
||||
-/*
|
||||
- * No need for any "IO delay" on KVM
|
||||
- */
|
||||
-static void kvm_io_delay(void)
|
||||
-{
|
||||
-}
|
||||
-
|
||||
#define KVM_TASK_SLEEP_HASHBITS 8
|
||||
#define KVM_TASK_SLEEP_HASHSIZE (1<<KVM_TASK_SLEEP_HASHBITS)
|
||||
|
||||
@@ -194,15 +197,19 @@ static void kvm_leave_lazy_mmu(void)
|
||||
mmu_queue_flush(state);
|
||||
paravirt_leave_lazy_mmu();
|
||||
}
|
||||
+#endif /* CONFIG_KVM_MMU */
|
||||
|
||||
static void __init paravirt_ops_setup(void)
|
||||
{
|
||||
pv_info.name = "KVM";
|
||||
pv_info.paravirt_enabled = 1;
|
||||
|
||||
+#ifdef CONFIG_KVM_IODELAY
|
||||
if (kvm_para_has_feature(KVM_FEATURE_NOP_IO_DELAY))
|
||||
pv_cpu_ops.io_delay = kvm_io_delay;
|
||||
+#endif
|
||||
|
||||
+#ifdef CONFIG_KVM_MMU
|
||||
if (kvm_para_has_feature(KVM_FEATURE_MMU_OP)) {
|
||||
pv_mmu_ops.set_pte = kvm_set_pte;
|
||||
pv_mmu_ops.set_pte_at = kvm_set_pte_at;
|
||||
@@ -226,6 +233,7 @@ static void __init paravirt_ops_setup(vo
|
||||
pv_mmu_ops.lazy_mode.enter = kvm_enter_lazy_mmu;
|
||||
pv_mmu_ops.lazy_mode.leave = kvm_leave_lazy_mmu;
|
||||
}
|
||||
+#endif /* CONFIG_KVM_MMU */
|
||||
#ifdef CONFIG_X86_IO_APIC
|
||||
no_timer_check = 1;
|
||||
#endif
|
@ -1,148 +0,0 @@
|
||||
From: Russ Anderson <rja@sgi.com>
|
||||
Subject: mm: Avoid putting a bad page back on the LRU v8
|
||||
References: 415829
|
||||
Acked-by: schwab@suse.de
|
||||
Patch-mainline: not yet
|
||||
|
||||
Prevent a page with a physical memory error from being placed back
|
||||
on the LRU. A new page flag (PG_memerror) is added if
|
||||
CONFIG_PAGEFLAGS_EXTENDED is defined.
|
||||
|
||||
Version 8 change: Removed hot path check for pages with memory
|
||||
errors on the free list.
|
||||
|
||||
Signed-off-by: Russ Anderson <rja@sgi.com>
|
||||
Reviewed-by: Christoph Lameter <cl@linux-foundation.org>
|
||||
|
||||
---
|
||||
include/linux/page-flags.h | 16 +++++++++++++++-
|
||||
mm/migrate.c | 33 +++++++++++++++++++++++++++++++++
|
||||
mm/vmscan.c | 1 +
|
||||
3 files changed, 49 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/include/linux/page-flags.h
|
||||
+++ b/include/linux/page-flags.h
|
||||
@@ -88,6 +88,7 @@ enum pageflags {
|
||||
PG_private_2, /* If pagecache, has fs aux data */
|
||||
PG_writeback, /* Page is under writeback */
|
||||
#ifdef CONFIG_PAGEFLAGS_EXTENDED
|
||||
+ PG_memerror, /* Page has a physical memory error */
|
||||
PG_head, /* A head page */
|
||||
PG_tail, /* A tail page */
|
||||
#else
|
||||
@@ -167,14 +168,21 @@ static inline int TestClearPage##uname(s
|
||||
static inline int __TestClearPage##uname(struct page *page) \
|
||||
{ return __test_and_clear_bit(PG_##lname, &page->flags); }
|
||||
|
||||
+#define PAGEFLAGMASK(uname, lname) \
|
||||
+static inline int PAGEMASK_##uname(void) \
|
||||
+ { return (1 << PG_##lname); }
|
||||
+
|
||||
#define PAGEFLAG(uname, lname) TESTPAGEFLAG(uname, lname) \
|
||||
- SETPAGEFLAG(uname, lname) CLEARPAGEFLAG(uname, lname)
|
||||
+ SETPAGEFLAG(uname, lname) CLEARPAGEFLAG(uname, lname) \
|
||||
+ PAGEFLAGMASK(uname, lname)
|
||||
|
||||
#define __PAGEFLAG(uname, lname) TESTPAGEFLAG(uname, lname) \
|
||||
__SETPAGEFLAG(uname, lname) __CLEARPAGEFLAG(uname, lname)
|
||||
|
||||
#define PAGEFLAG_FALSE(uname) \
|
||||
static inline int Page##uname(struct page *page) \
|
||||
+ { return 0; } \
|
||||
+static inline int PAGEMASK_##uname(void) \
|
||||
{ return 0; }
|
||||
|
||||
#define TESTSCFLAG(uname, lname) \
|
||||
@@ -391,6 +399,12 @@ static inline void __ClearPageTail(struc
|
||||
|
||||
#endif /* !PAGEFLAGS_EXTENDED */
|
||||
|
||||
+#ifdef CONFIG_PAGEFLAGS_EXTENDED
|
||||
+PAGEFLAG(MemError, memerror)
|
||||
+#else
|
||||
+PAGEFLAG_FALSE(MemError)
|
||||
+#endif
|
||||
+
|
||||
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||
/*
|
||||
* PageHuge() only returns true for hugetlbfs pages, but not for
|
||||
--- a/mm/migrate.c
|
||||
+++ b/mm/migrate.c
|
||||
@@ -63,6 +63,7 @@ int migrate_prep_local(void)
|
||||
|
||||
return 0;
|
||||
}
|
||||
+EXPORT_SYMBOL(migrate_prep);
|
||||
|
||||
/*
|
||||
* Add isolated pages on the list back to the LRU under page lock
|
||||
@@ -80,6 +81,7 @@ void putback_lru_pages(struct list_head
|
||||
putback_lru_page(page);
|
||||
}
|
||||
}
|
||||
+EXPORT_SYMBOL(putback_lru_pages);
|
||||
|
||||
/*
|
||||
* Restore a potential migration pte to a working pte entry
|
||||
@@ -701,6 +703,25 @@ unlock:
|
||||
* restored.
|
||||
*/
|
||||
list_del(&page->lru);
|
||||
+ if (PageMemError(page)) {
|
||||
+ if (rc == 0)
|
||||
+ /*
|
||||
+ * A page with a memory error that has
|
||||
+ * been migrated will not be moved to
|
||||
+ * the LRU.
|
||||
+ */
|
||||
+ goto move_newpage;
|
||||
+ else
|
||||
+ /*
|
||||
+ * The page failed to migrate and will not
|
||||
+ * be added to the bad page list. Clearing
|
||||
+ * the error bit will allow another attempt
|
||||
+ * to migrate if it gets another correctable
|
||||
+ * error.
|
||||
+ */
|
||||
+ ClearPageMemError(page);
|
||||
+ }
|
||||
+
|
||||
dec_zone_page_state(page, NR_ISOLATED_ANON +
|
||||
page_is_file_cache(page));
|
||||
putback_lru_page(page);
|
||||
@@ -775,6 +796,17 @@ int migrate_pages(struct list_head *from
|
||||
}
|
||||
}
|
||||
}
|
||||
+
|
||||
+ if (rc != 0)
|
||||
+ list_for_each_entry_safe(page, page2, from, lru)
|
||||
+ if (PageMemError(page))
|
||||
+ /*
|
||||
+ * The page failed to migrate. Clearing
|
||||
+ * the error bit will allow another attempt
|
||||
+ * to migrate if it gets another correctable
|
||||
+ * error.
|
||||
+ */
|
||||
+ ClearPageMemError(page);
|
||||
rc = 0;
|
||||
out:
|
||||
if (!swapwrite)
|
||||
@@ -787,6 +819,7 @@ out:
|
||||
|
||||
return nr_failed + retry;
|
||||
}
|
||||
+EXPORT_SYMBOL(migrate_pages);
|
||||
|
||||
#ifdef CONFIG_NUMA
|
||||
/*
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -1127,6 +1127,7 @@ int isolate_lru_page(struct page *page)
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
+EXPORT_SYMBOL(isolate_lru_page);
|
||||
|
||||
/*
|
||||
* Are there way too many processes in the direct reclaim path already?
|
@ -1,32 +0,0 @@
|
||||
From: Thomas Renninger <trenn@suse.de>
|
||||
Subject: Fix huge and wronge C-state drawings due to uninitialized start/end timestamps
|
||||
Patch-Mainline: not yet
|
||||
References: none
|
||||
|
||||
Signed-off-by: Thomas Renninger <trenn@suse.de>
|
||||
|
||||
---
|
||||
tools/perf/builtin-timechart.c | 9 ++++++++-
|
||||
1 file changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
Index: linux-2.6.37-master/tools/perf/builtin-timechart.c
|
||||
===================================================================
|
||||
--- linux-2.6.37-master.orig/tools/perf/builtin-timechart.c
|
||||
+++ linux-2.6.37-master/tools/perf/builtin-timechart.c
|
||||
@@ -654,8 +654,15 @@ static void draw_c_p_states(void)
|
||||
* two pass drawing so that the P state bars are on top of the C state blocks
|
||||
*/
|
||||
while (pwr) {
|
||||
- if (pwr->type == CSTATE)
|
||||
+ if (pwr->type == CSTATE) {
|
||||
+ /* If the first event is an _end event, start timestamp is zero
|
||||
+ -> ignore these */
|
||||
+ if (pwr->start_time == 0 || pwr->end_time == 0) {
|
||||
+ pwr = pwr->next;
|
||||
+ continue;
|
||||
+ }
|
||||
svg_cstate(pwr->cpu, pwr->start_time, pwr->end_time, pwr->state);
|
||||
+ }
|
||||
pwr = pwr->next;
|
||||
}
|
||||
|
@ -1,33 +0,0 @@
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Subject: [PATCH] Fix build_error without CONFIG_PPC_83xx
|
||||
Patch-mainline:
|
||||
References:
|
||||
|
||||
fsl_deep_sleep() is defined only with CONFIG_PPC_83xx although
|
||||
CONFIG_IPIC is set for CONFIG_PPC_MPC512x, too.
|
||||
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
|
||||
---
|
||||
---
|
||||
arch/powerpc/sysdev/ipic.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/arch/powerpc/sysdev/ipic.c
|
||||
+++ b/arch/powerpc/sysdev/ipic.c
|
||||
@@ -921,6 +921,7 @@ static int ipic_suspend(struct sys_devic
|
||||
ipic_saved_state.sermr = ipic_read(ipic->regs, IPIC_SERMR);
|
||||
ipic_saved_state.sercr = ipic_read(ipic->regs, IPIC_SERCR);
|
||||
|
||||
+#ifdef CONFIG_PPC_83xx
|
||||
if (fsl_deep_sleep()) {
|
||||
/* In deep sleep, make sure there can be no
|
||||
* pending interrupts, as this can cause
|
||||
@@ -931,6 +932,7 @@ static int ipic_suspend(struct sys_devic
|
||||
ipic_write(ipic->regs, IPIC_SEMSR, 0);
|
||||
ipic_write(ipic->regs, IPIC_SERMR, 0);
|
||||
}
|
||||
+#endif
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
From: olh@suse.de
|
||||
Subject: force speed to fix autodetection on pegasos2
|
||||
Patch-mainline: never
|
||||
|
||||
---
|
||||
arch/powerpc/platforms/chrp/setup.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/arch/powerpc/platforms/chrp/setup.c
|
||||
+++ b/arch/powerpc/platforms/chrp/setup.c
|
||||
@@ -293,7 +293,7 @@ static void chrp_init_early(void)
|
||||
if (!property)
|
||||
goto out_put;
|
||||
if (!strcmp(property, "failsafe") || !strcmp(property, "serial"))
|
||||
- add_preferred_console("ttyS", 0, NULL);
|
||||
+ add_preferred_console("ttyS", 0, "115200");
|
||||
out_put:
|
||||
of_node_put(node);
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
From: Olaf Hering <olh@suse.de>
|
||||
Subject: new prom=nodisplay option to avoid crash in firmware on B50
|
||||
Patch-mainline: not yet
|
||||
|
||||
add prom=nodisplay
|
||||
avoid crash in firmware on IBM B50 when OF stdout is on serial.
|
||||
|
||||
0 > boot scsi/sd@4:1,yaboot |
|
||||
yaboot starting: loaded at 00200000 00222530 (0/0/00c1a078; sp: 00efffd0)
|
||||
brokenfirmware did not claim executable memory, fixed it myself
|
||||
Config file 'yaboot.cnf' read, 213 bytes
|
||||
|
||||
Welcome to yaboot version 10.1.22-r945.SuSE
|
||||
booted from '/pci@80000000/scsi@10/sd@4:1,yaboot'
|
||||
Enter "help" to get some basic usage information
|
||||
boot:
|
||||
* linux
|
||||
boot: linux 3
|
||||
Please wait, loading kernel...
|
||||
Allocated 00600000 bytes for executable @ 02000000
|
||||
Elf32 kernel loaded...
|
||||
Loading ramdisk...
|
||||
ramdisk loaded 0030e057 @ 04100000
|
||||
OF stdout device is: /pci@80000000/isa@b/serial@i3f8
|
||||
command line: root=/dev/system/root xmon=on sysrq=1 quiet panic=12 3
|
||||
memory layout at init:
|
||||
memory_limit : 00000000 (16 MB aligned)
|
||||
alloc_bottom : 0440f000
|
||||
alloc_top : 30000000
|
||||
alloc_top_hi : 40000000
|
||||
rmo_top : 30000000
|
||||
ram_top : 40000000
|
||||
Looking for displays
|
||||
found display : /pci@80000000/display@16, opening ...
|
||||
Unexpected Firmware Error:
|
||||
DEFAULT CATCH!, code=fff00300 at %SRR0: 00c18ccc %SRR1: 00003030
|
||||
ok
|
||||
0 > reset-all
|
||||
|
||||
|
||||
---
|
||||
arch/powerpc/kernel/prom_init.c | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
--- a/arch/powerpc/kernel/prom_init.c
|
||||
+++ b/arch/powerpc/kernel/prom_init.c
|
||||
@@ -169,6 +169,7 @@ static unsigned long __initdata dt_strin
|
||||
|
||||
static unsigned long __initdata prom_initrd_start, prom_initrd_end;
|
||||
|
||||
+static int __initdata prom_no_display;
|
||||
#ifdef CONFIG_PPC64
|
||||
static int __initdata prom_iommu_force_on;
|
||||
static int __initdata prom_iommu_off;
|
||||
@@ -596,6 +597,14 @@ static void __init early_cmdline_parse(v
|
||||
#endif /* CONFIG_CMDLINE */
|
||||
prom_printf("command line: %s\n", RELOC(prom_cmd_line));
|
||||
|
||||
+ opt = strstr(RELOC(prom_cmd_line), RELOC("prom="));
|
||||
+ if (opt) {
|
||||
+ opt += 5;
|
||||
+ while (*opt && *opt == ' ')
|
||||
+ opt++;
|
||||
+ if (!strncmp(opt, RELOC("nodisplay"), 9))
|
||||
+ RELOC(prom_no_display) = 1;
|
||||
+ }
|
||||
#ifdef CONFIG_PPC64
|
||||
opt = strstr(RELOC(prom_cmd_line), RELOC("iommu="));
|
||||
if (opt) {
|
||||
@@ -2570,6 +2579,7 @@ unsigned long __init prom_init(unsigned
|
||||
/*
|
||||
* Initialize display devices
|
||||
*/
|
||||
+ if (RELOC(prom_no_display) == 0)
|
||||
prom_check_displays();
|
||||
|
||||
#ifdef CONFIG_PPC64
|
@ -1,119 +0,0 @@
|
||||
Subject: [PATCH] add syslog printing to xmon debugger.
|
||||
From: Linas Vepstas <linas@austin.ibm.com>
|
||||
Patch-mainline: Not yet
|
||||
|
||||
|
||||
This patch 'dmesg'/printk log buffer printing to xmon. I find this
|
||||
useful because crashes are almost always preceeded by interesting
|
||||
printk's. This patch is simple & straightforward, except for one
|
||||
possibly controversial aspect: it embeds a small snippet in
|
||||
kernel/printk.c to return the location of the syslog. This is
|
||||
needed because kallsyms and even CONFIG_KALLSYMS_ALL is not enough
|
||||
to reveal the location of log_buf. This code is about 90%
|
||||
cut-n-paste of earlier code from Keith Owens.
|
||||
|
||||
Signed-off-by: Olaf Hering <olh@suse.de>
|
||||
---
|
||||
|
||||
arch/powerpc/xmon/xmon.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
kernel/printk.c | 2 -
|
||||
2 files changed, 58 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/arch/powerpc/xmon/xmon.c
|
||||
+++ b/arch/powerpc/xmon/xmon.c
|
||||
@@ -138,6 +138,7 @@ static struct bpt *in_breakpoint_table(u
|
||||
static int do_step(struct pt_regs *);
|
||||
static void bpt_cmds(void);
|
||||
static void cacheflush(void);
|
||||
+static void xmon_show_dmesg(void);
|
||||
static int cpu_cmd(void);
|
||||
static void csum(void);
|
||||
static void bootcmds(void);
|
||||
@@ -197,6 +198,7 @@ Commands:\n\
|
||||
#endif
|
||||
"\
|
||||
C checksum\n\
|
||||
+ D show dmesg (printk) buffer\n\
|
||||
d dump bytes\n\
|
||||
di dump instructions\n\
|
||||
df dump float values\n\
|
||||
@@ -831,6 +833,9 @@ cmds(struct pt_regs *excp)
|
||||
case 'd':
|
||||
dump();
|
||||
break;
|
||||
+ case 'D':
|
||||
+ xmon_show_dmesg();
|
||||
+ break;
|
||||
case 'l':
|
||||
symbol_lookup();
|
||||
break;
|
||||
@@ -2607,6 +2612,58 @@ static void xmon_print_symbol(unsigned l
|
||||
printf("%s", after);
|
||||
}
|
||||
|
||||
+extern void kdb_syslog_data(char *syslog_data[]);
|
||||
+#define SYSLOG_WRAP(p) if (p < syslog_data[0]) p = syslog_data[1]-1; \
|
||||
+ else if (p >= syslog_data[1]) p = syslog_data[0];
|
||||
+
|
||||
+static void xmon_show_dmesg(void)
|
||||
+{
|
||||
+ char *syslog_data[4], *start, *end, c;
|
||||
+ int logsize;
|
||||
+
|
||||
+ /* syslog_data[0,1] physical start, end+1.
|
||||
+ * syslog_data[2,3] logical start, end+1.
|
||||
+ */
|
||||
+ kdb_syslog_data(syslog_data);
|
||||
+ if (syslog_data[2] == syslog_data[3])
|
||||
+ return;
|
||||
+ logsize = syslog_data[1] - syslog_data[0];
|
||||
+ start = syslog_data[0] + (syslog_data[2] - syslog_data[0]) % logsize;
|
||||
+ end = syslog_data[0] + (syslog_data[3] - syslog_data[0]) % logsize;
|
||||
+
|
||||
+ /* Do a line at a time (max 200 chars) to reduce overhead */
|
||||
+ c = '\0';
|
||||
+ while(1) {
|
||||
+ char *p;
|
||||
+ int chars = 0;
|
||||
+ if (!*start) {
|
||||
+ while (!*start) {
|
||||
+ ++start;
|
||||
+ SYSLOG_WRAP(start);
|
||||
+ if (start == end)
|
||||
+ break;
|
||||
+ }
|
||||
+ if (start == end)
|
||||
+ break;
|
||||
+ }
|
||||
+ p = start;
|
||||
+ while (*start && chars < 200) {
|
||||
+ c = *start;
|
||||
+ ++chars;
|
||||
+ ++start;
|
||||
+ SYSLOG_WRAP(start);
|
||||
+ if (start == end || c == '\n')
|
||||
+ break;
|
||||
+ }
|
||||
+ if (chars)
|
||||
+ printf("%.*s", chars, p);
|
||||
+ if (start == end)
|
||||
+ break;
|
||||
+ }
|
||||
+ if (c != '\n')
|
||||
+ printf("\n");
|
||||
+}
|
||||
+
|
||||
#ifdef CONFIG_PPC_BOOK3S_64
|
||||
static void dump_slb(void)
|
||||
{
|
||||
--- a/kernel/printk.c
|
||||
+++ b/kernel/printk.c
|
||||
@@ -416,7 +416,7 @@ SYSCALL_DEFINE3(syslog, int, type, char
|
||||
return do_syslog(type, buf, len, SYSLOG_FROM_CALL);
|
||||
}
|
||||
|
||||
-#ifdef CONFIG_KGDB_KDB
|
||||
+#if defined(CONFIG_KGDB_KDB) || defined(CONFIG_DEBUG_KERNEL)
|
||||
/* kdb dmesg command needs access to the syslog buffer. do_syslog()
|
||||
* uses locks so it cannot be used during debugging. Just tell kdb
|
||||
* where the start and end of the physical and logical logs are. This
|
@ -1,43 +0,0 @@
|
||||
From: Jeff Mahoney <jeffm@suse.com>
|
||||
Subject: [PATCH] s390: Define FREE_PTE_NR
|
||||
Patch-mainline: Never, unless FREE_PTE_NR is used in generic code
|
||||
|
||||
Commit ba8a9229ab9e80278c28ad68b15053f65b2b0a7c from
|
||||
Martin Schwidefsky <schwidefsky@de.ibm.com> removed the
|
||||
#include <asm-generic/tlb.h> from asm-s390/tlb.h when he defined the
|
||||
s390-specific TLB operations.
|
||||
|
||||
FREE_PTR_NR is generally an internal-only value, but our unmap_vmas-lat
|
||||
patch uses it to make smarter decisions about dumping PTEs in chunks.
|
||||
|
||||
This patch restores the generic value in asm-s390/tlb.h. Since it's only
|
||||
used for an optimization, this should be safe.
|
||||
|
||||
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
|
||||
|
||||
---
|
||||
arch/s390/include/asm/tlb.h | 13 +++++++++++++
|
||||
1 file changed, 13 insertions(+)
|
||||
|
||||
--- a/arch/s390/include/asm/tlb.h
|
||||
+++ b/arch/s390/include/asm/tlb.h
|
||||
@@ -34,6 +34,19 @@
|
||||
#define TLB_NR_PTRS 508
|
||||
#endif
|
||||
|
||||
+/* Lifted from asm-generic/tlb.h; Is used by patches.suse/unmap_vmas-lat */
|
||||
+/*
|
||||
+ * For UP we don't need to worry about TLB flush
|
||||
+ * and page free order so much..
|
||||
+ */
|
||||
+#ifdef CONFIG_SMP
|
||||
+ #define FREE_PTE_NR 506
|
||||
+ #define tlb_fast_mode(tlb) ((tlb)->nr == ~0U)
|
||||
+#else
|
||||
+ #define FREE_PTE_NR 1
|
||||
+ #define tlb_fast_mode(tlb) 1
|
||||
+#endif
|
||||
+
|
||||
struct mmu_gather {
|
||||
struct mm_struct *mm;
|
||||
unsigned int fullmm;
|
@ -1,23 +0,0 @@
|
||||
From: Jiri Slaby <jslaby@suse.cz>
|
||||
Subject: fix build on s390 as of 2.6.36-rc4
|
||||
Patch-mainline: never
|
||||
|
||||
This fixes patches.arch/s390-message-catalog.diff build.
|
||||
|
||||
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
|
||||
|
||||
---
|
||||
include/linux/device.h | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/include/linux/device.h
|
||||
+++ b/include/linux/device.h
|
||||
@@ -660,6 +660,8 @@ int printk_dev_hash(const char *, const
|
||||
|
||||
#endif
|
||||
|
||||
+#define dev_printk(level, dev, format, arg...) \
|
||||
+ dev_printk_hash(level , dev, format, ## arg)
|
||||
#define dev_emerg(dev, format, arg...) \
|
||||
dev_printk_hash(KERN_EMERG , dev , format , ## arg)
|
||||
#define dev_alert(dev, format, arg...) \
|
File diff suppressed because it is too large
Load Diff
@ -1,87 +0,0 @@
|
||||
From: IBM <lcm@us.ibm.com>
|
||||
Subject: Use apic=bigsmp on specific xseries machines
|
||||
References: bnc#440497
|
||||
Patch-Mainline: not yet
|
||||
|
||||
Signed-off-by: Thomas Renninger <trenn@suse.de>
|
||||
|
||||
|
||||
arch/x86/kernel/apic/bigsmp_32.c | 30 +++++++++++++++++++++++++++---
|
||||
arch/x86/kernel/apic/probe_32.c | 4 ++--
|
||||
2 files changed, 29 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/arch/x86/kernel/apic/bigsmp_32.c
|
||||
+++ b/arch/x86/kernel/apic/bigsmp_32.c
|
||||
@@ -156,7 +156,7 @@ static void bigsmp_send_IPI_all(int vect
|
||||
|
||||
static int dmi_bigsmp; /* can be set by dmi scanners */
|
||||
|
||||
-static int hp_ht_bigsmp(const struct dmi_system_id *d)
|
||||
+static int force_bigsmp_apic(const struct dmi_system_id *d)
|
||||
{
|
||||
printk(KERN_NOTICE "%s detected: force use of apic=bigsmp\n", d->ident);
|
||||
dmi_bigsmp = 1;
|
||||
@@ -166,17 +166,41 @@ static int hp_ht_bigsmp(const struct dmi
|
||||
|
||||
|
||||
static const struct dmi_system_id bigsmp_dmi_table[] = {
|
||||
- { hp_ht_bigsmp, "HP ProLiant DL760 G2",
|
||||
+ { force_bigsmp_apic, "HP ProLiant DL760 G2",
|
||||
{ DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
|
||||
DMI_MATCH(DMI_BIOS_VERSION, "P44-"),
|
||||
}
|
||||
},
|
||||
|
||||
- { hp_ht_bigsmp, "HP ProLiant DL740",
|
||||
+ { force_bigsmp_apic, "HP ProLiant DL740",
|
||||
{ DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
|
||||
DMI_MATCH(DMI_BIOS_VERSION, "P47-"),
|
||||
}
|
||||
},
|
||||
+
|
||||
+ { force_bigsmp_apic, "IBM x260 / x366 / x460",
|
||||
+ { DMI_MATCH(DMI_BIOS_VENDOR, "IBM"),
|
||||
+ DMI_MATCH(DMI_BIOS_VERSION, "-[ZT"),
|
||||
+ }
|
||||
+ },
|
||||
+
|
||||
+ { force_bigsmp_apic, "IBM x3800 / x3850 / x3950",
|
||||
+ { DMI_MATCH(DMI_BIOS_VENDOR, "IBM"),
|
||||
+ DMI_MATCH(DMI_BIOS_VERSION, "-[ZU"),
|
||||
+ }
|
||||
+ },
|
||||
+
|
||||
+ { force_bigsmp_apic, "IBM x3800 / x3850 / x3950",
|
||||
+ { DMI_MATCH(DMI_BIOS_VENDOR, "IBM"),
|
||||
+ DMI_MATCH(DMI_BIOS_VERSION, "-[ZS"),
|
||||
+ }
|
||||
+ },
|
||||
+
|
||||
+ { force_bigsmp_apic, "IBM x3850 M2 / x3950 M2",
|
||||
+ { DMI_MATCH(DMI_BIOS_VENDOR, "IBM"),
|
||||
+ DMI_MATCH(DMI_BIOS_VERSION, "-[A3"),
|
||||
+ }
|
||||
+ },
|
||||
{ } /* NULL entry stops DMI scanning */
|
||||
};
|
||||
|
||||
--- a/arch/x86/kernel/apic/probe_32.c
|
||||
+++ b/arch/x86/kernel/apic/probe_32.c
|
||||
@@ -267,7 +267,7 @@ generic_mps_oem_check(struct mpc_table *
|
||||
if (!apic_probe[i]->mps_oem_check(mpc, oem, productid))
|
||||
continue;
|
||||
|
||||
- if (!cmdline_apic) {
|
||||
+ if (!cmdline_apic && apic == &apic_default) {
|
||||
apic = apic_probe[i];
|
||||
printk(KERN_INFO "Switched to APIC driver `%s'.\n",
|
||||
apic->name);
|
||||
@@ -287,7 +287,7 @@ int __init default_acpi_madt_oem_check(c
|
||||
if (!apic_probe[i]->acpi_madt_oem_check(oem_id, oem_table_id))
|
||||
continue;
|
||||
|
||||
- if (!cmdline_apic) {
|
||||
+ if (!cmdline_apic && apic == &apic_default) {
|
||||
apic = apic_probe[i];
|
||||
printk(KERN_INFO "Switched to APIC driver `%s'.\n",
|
||||
apic->name);
|
@ -1,26 +0,0 @@
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Subject: x86: workaround for mccreary HPET read problem
|
||||
Patch-mainline: not yet
|
||||
References: bnc#433746
|
||||
|
||||
On mccreacy platform, the read of HPET CMP register seems not updated
|
||||
immediately after the write and returns the previous value instead.
|
||||
A workaround is to read the register twice.
|
||||
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
|
||||
---
|
||||
---
|
||||
arch/x86/kernel/hpet.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/arch/x86/kernel/hpet.c
|
||||
+++ b/arch/x86/kernel/hpet.c
|
||||
@@ -386,6 +386,7 @@ static int hpet_next_event(unsigned long
|
||||
cnt += (u32) delta;
|
||||
hpet_writel(cnt, HPET_Tn_CMP(timer));
|
||||
|
||||
+ hpet_readl(HPET_Tn_CMP(timer)); /* pre-read for bnc#433746 */
|
||||
/*
|
||||
* We need to read back the CMP register on certain HPET
|
||||
* implementations (ATI chipsets) which seem to delay the
|
@ -1,38 +0,0 @@
|
||||
From: Tejun Heo <tj@kernel.org>
|
||||
Subject: x86: disallow DAC for MCP51 PCI bridge
|
||||
References: bnc#463829
|
||||
Patch-mainline: not yet
|
||||
|
||||
MCP51 corrupts DAC transfers. Disallow it. Reported by pgnet on
|
||||
bnc#463829.
|
||||
|
||||
https://bugzilla.novell.com/show_bug.cgi?id=463829
|
||||
|
||||
Signed-off-by: Tejun Heo <tj@kernel.org>
|
||||
Reported-by: pgnet <pgnet.trash@gmail.com>
|
||||
Signed-off-by: Tejun Heo <teheo@suse.de>
|
||||
---
|
||||
arch/x86/kernel/pci-dma.c | 14 ++++++++++++++
|
||||
1 file changed, 14 insertions(+)
|
||||
|
||||
--- a/arch/x86/kernel/pci-dma.c
|
||||
+++ b/arch/x86/kernel/pci-dma.c
|
||||
@@ -322,4 +322,18 @@ static __devinit void via_no_dac(struct
|
||||
}
|
||||
}
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_ANY_ID, via_no_dac);
|
||||
+
|
||||
+/*
|
||||
+ * MCP51 PCI bridge corrupts data for DAC. Disable it. Reported in
|
||||
+ * bnc#463829.
|
||||
+ */
|
||||
+static __devinit void mcp51_no_dac(struct pci_dev *dev)
|
||||
+{
|
||||
+ if (forbid_dac == 0) {
|
||||
+ printk(KERN_INFO
|
||||
+ "PCI: MCP51 PCI bridge detected. Disabling DAC.\n");
|
||||
+ forbid_dac = 1;
|
||||
+ }
|
||||
+}
|
||||
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x026f, mcp51_no_dac);
|
||||
#endif
|
@ -1,223 +0,0 @@
|
||||
From: Jiri Bohac <jbohac@suse.cz>
|
||||
Subject: allow 64-bit mode for HPET Timer0
|
||||
References: bnc#456700
|
||||
|
||||
The kernel uses the HPET timers in 32-bit mode for clock-events.
|
||||
While 32 bits, with a wrap-around time of >4 minutes, is probably
|
||||
good enough for the clock-event purposes, on some chipsets this
|
||||
has a negative side-effect on the HPET main counter.
|
||||
|
||||
Unlike the original HPET specification 1.0 from 2004, which does not
|
||||
mention any side-effects of setting TN_32MODE_CNF on the
|
||||
individual timers, the ICH9 documentation, for example, says:
|
||||
|
||||
NOTE: When this bit is set to ‘1’, the hardware counter will
|
||||
do a 32-bit operation on comparator match and rollovers, thus
|
||||
the upper 32-bit of the Timer 0 Comparator Value register is
|
||||
ignored. The upper 32-bit of the main counter is not involved
|
||||
in any rollover from lower 32-bit of the main counter and
|
||||
becomes all zeros.
|
||||
|
||||
(see http://www.intel.com/assets/pdf/datasheet/316972.pdf, page
|
||||
819, section 21.1.5, Bit 8). I've seen this behaviour also on
|
||||
ICH8. I have no idea what other chipsets are affected. But I have
|
||||
seen AMD chipsets that Do The Right Thing.
|
||||
|
||||
This means, that when the kernel configures the Timer 0 to 32-bit
|
||||
mode, on these chipsets it also cripples the 64-bit main counter
|
||||
to 32 bits.
|
||||
|
||||
The HPET may be mmapped in userspace and the main counter
|
||||
accessed directly by applications, expecting a 64-bit main
|
||||
counter.
|
||||
|
||||
This patch allows the Timer0 to be configured in 64-bit mode
|
||||
on x86_64 when a hpet64 command-line option is specified.
|
||||
|
||||
Updated-by: Jeff Mahoney <jeffm@suse.com>
|
||||
Signed-off-by: Jiri Bohac <jbohac@suse.cz>
|
||||
|
||||
---
|
||||
Documentation/kernel-parameters.txt | 2
|
||||
arch/x86/kernel/hpet.c | 88 ++++++++++++++++++++++++++++++++----
|
||||
2 files changed, 81 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/Documentation/kernel-parameters.txt
|
||||
+++ b/Documentation/kernel-parameters.txt
|
||||
@@ -497,6 +497,8 @@ and is between 256 and 4096 characters.
|
||||
Range: 0 - 8192
|
||||
Default: 64
|
||||
|
||||
+ hpet64 [X86-64,HPET] enable 64-bit mode of the HPET timer (bnc#456700)
|
||||
+
|
||||
com20020= [HW,NET] ARCnet - COM20020 chipset
|
||||
Format:
|
||||
<io>[,<irq>[,<nodeID>[,<backplane>[,<ckp>[,<timeout>]]]]]
|
||||
--- a/arch/x86/kernel/hpet.c
|
||||
+++ b/arch/x86/kernel/hpet.c
|
||||
@@ -37,6 +37,7 @@ unsigned long hpet_address;
|
||||
static unsigned long hpet_num_timers;
|
||||
#endif
|
||||
static void __iomem *hpet_virt_address;
|
||||
+static int hpet_legacy_use_64_bits;
|
||||
|
||||
struct hpet_dev {
|
||||
struct clock_event_device evt;
|
||||
@@ -59,6 +60,33 @@ static inline void hpet_writel(unsigned
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
#include <asm/pgtable.h>
|
||||
+static inline unsigned long hpet_read_value(unsigned long a)
|
||||
+{
|
||||
+ if (hpet_legacy_use_64_bits)
|
||||
+ return readq(hpet_virt_address + a);
|
||||
+ else
|
||||
+ return readl(hpet_virt_address + a);
|
||||
+}
|
||||
+
|
||||
+static void hpet_write_value(unsigned long d, unsigned long a)
|
||||
+{
|
||||
+ if (hpet_legacy_use_64_bits)
|
||||
+ writeq(d, hpet_virt_address + a);
|
||||
+ else
|
||||
+ writel(d, hpet_virt_address + a);
|
||||
+}
|
||||
+
|
||||
+#else
|
||||
+
|
||||
+static inline unsigned long hpet_read_value(unsigned long a)
|
||||
+{
|
||||
+ return readl(hpet_virt_address + a);
|
||||
+}
|
||||
+
|
||||
+static void hpet_write_value(unsigned long d, unsigned long a)
|
||||
+{
|
||||
+ writel(d, hpet_virt_address + a);
|
||||
+}
|
||||
#endif
|
||||
|
||||
static inline void hpet_set_mapping(void)
|
||||
@@ -103,6 +131,17 @@ static int __init disable_hpet(char *str
|
||||
}
|
||||
__setup("nohpet", disable_hpet);
|
||||
|
||||
+#ifdef CONFIG_X86_64
|
||||
+static int hpet64 = 0;
|
||||
+static int __init hpet64_setup(char *str)
|
||||
+{
|
||||
+ hpet64 = 1;
|
||||
+ return 1;
|
||||
+}
|
||||
+__setup("hpet64", hpet64_setup);
|
||||
+#endif
|
||||
+
|
||||
+
|
||||
static inline int is_hpet_capable(void)
|
||||
{
|
||||
return !boot_hpet_disable && hpet_address;
|
||||
@@ -212,6 +251,7 @@ static void hpet_reserve_platform_timers
|
||||
* Common hpet info
|
||||
*/
|
||||
static unsigned long hpet_period;
|
||||
+static int hpet_legacy_use_64_bits; /* configure T0 in 64-bit mode? */
|
||||
|
||||
static void hpet_legacy_set_mode(enum clock_event_mode mode,
|
||||
struct clock_event_device *evt);
|
||||
@@ -278,10 +318,38 @@ static void hpet_enable_legacy_int(void)
|
||||
hpet_legacy_int_enabled = 1;
|
||||
}
|
||||
|
||||
+static int timer0_use_64_bits(void)
|
||||
+{
|
||||
+#ifndef CONFIG_X86_64
|
||||
+ /* using the HPET in 64-bit mode without atomic 64-bit
|
||||
+ * accesses is too inefficient
|
||||
+ */
|
||||
+ return 0;
|
||||
+#else
|
||||
+
|
||||
+ if (unlikely(hpet64)) {
|
||||
+ u32 id, t0_cfg;
|
||||
+ id = hpet_readl(HPET_ID);
|
||||
+ t0_cfg = hpet_readl(HPET_Tn_CFG(0));
|
||||
+
|
||||
+ if ((id & HPET_ID_64BIT) && (t0_cfg & HPET_TN_64BIT_CAP)) {
|
||||
+ printk(KERN_DEBUG "hpet timer0 configured in 64-bit mode\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ else {
|
||||
+ printk(KERN_DEBUG "hpet timer0 does not support 64-bit mode\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+ else return 0;
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
static void hpet_legacy_clockevent_register(void)
|
||||
{
|
||||
/* Start HPET legacy interrupts */
|
||||
hpet_enable_legacy_int();
|
||||
+ hpet_legacy_use_64_bits = timer0_use_64_bits();
|
||||
|
||||
/*
|
||||
* The mult factor is defined as (include/linux/clockchips.h)
|
||||
@@ -328,9 +396,10 @@ static void hpet_set_mode(enum clock_eve
|
||||
/* Make sure we use edge triggered interrupts */
|
||||
cfg &= ~HPET_TN_LEVEL;
|
||||
cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC |
|
||||
- HPET_TN_SETVAL | HPET_TN_32BIT;
|
||||
+ HPET_TN_SETVAL |
|
||||
+ (hpet_legacy_use_64_bits ? 0 : HPET_TN_32BIT);
|
||||
hpet_writel(cfg, HPET_Tn_CFG(timer));
|
||||
- hpet_writel(cmp, HPET_Tn_CMP(timer));
|
||||
+ hpet_write_value(cmp, HPET_Tn_CMP(timer));
|
||||
udelay(1);
|
||||
/*
|
||||
* HPET on AMD 81xx needs a second write (with HPET_TN_SETVAL
|
||||
@@ -339,7 +408,7 @@ static void hpet_set_mode(enum clock_eve
|
||||
* (See AMD-8111 HyperTransport I/O Hub Data Sheet,
|
||||
* Publication # 24674)
|
||||
*/
|
||||
- hpet_writel((unsigned long) delta, HPET_Tn_CMP(timer));
|
||||
+ hpet_write_value((unsigned long) delta, HPET_Tn_CMP(timer));
|
||||
hpet_start_counter();
|
||||
hpet_print_config();
|
||||
break;
|
||||
@@ -347,7 +416,8 @@ static void hpet_set_mode(enum clock_eve
|
||||
case CLOCK_EVT_MODE_ONESHOT:
|
||||
cfg = hpet_readl(HPET_Tn_CFG(timer));
|
||||
cfg &= ~HPET_TN_PERIODIC;
|
||||
- cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
|
||||
+ cfg |= HPET_TN_ENABLE |
|
||||
+ (hpet_legacy_use_64_bits ? 0 : HPET_TN_32BIT);
|
||||
hpet_writel(cfg, HPET_Tn_CFG(timer));
|
||||
break;
|
||||
|
||||
@@ -376,11 +446,11 @@ static void hpet_set_mode(enum clock_eve
|
||||
static int hpet_next_event(unsigned long delta,
|
||||
struct clock_event_device *evt, int timer)
|
||||
{
|
||||
- u32 cnt;
|
||||
+ unsigned long cnt;
|
||||
|
||||
- cnt = hpet_readl(HPET_COUNTER);
|
||||
+ cnt = hpet_read_value(HPET_COUNTER);
|
||||
cnt += (u32) delta;
|
||||
- hpet_writel(cnt, HPET_Tn_CMP(timer));
|
||||
+ hpet_write_value(cnt, HPET_Tn_CMP(timer));
|
||||
|
||||
hpet_readl(HPET_Tn_CMP(timer)); /* pre-read for bnc#433746 */
|
||||
/*
|
||||
@@ -388,9 +458,9 @@ static int hpet_next_event(unsigned long
|
||||
* what we wrote hit the chip before we compare it to the
|
||||
* counter.
|
||||
*/
|
||||
- WARN_ON_ONCE((u32)hpet_readl(HPET_Tn_CMP(timer)) != cnt);
|
||||
+ WARN_ON_ONCE((u32)hpet_readl(HPET_Tn_CMP(timer)) != (u32)cnt);
|
||||
|
||||
- return (s32)((u32)hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0;
|
||||
+ return (s32)((u32)hpet_readl(HPET_COUNTER) - (u32)cnt) >= 0 ? -ETIME : 0;
|
||||
}
|
||||
|
||||
static void hpet_legacy_set_mode(enum clock_event_mode mode,
|
@ -1,439 +0,0 @@
|
||||
From: jbeulich@novell.com
|
||||
Subject: fix unwind annotations
|
||||
Patch-mainline: tbd
|
||||
References: bnc#472783, bnc#588458
|
||||
|
||||
---
|
||||
arch/x86/kernel/entry_64.S | 131 +++++++++++++++++++++++----------------------
|
||||
arch/x86/kernel/head_64.S | 13 ++++
|
||||
lib/rwsem_64.S | 56 ++++++++++++++---------
|
||||
3 files changed, 114 insertions(+), 84 deletions(-)
|
||||
|
||||
--- a/arch/x86/kernel/entry_64.S
|
||||
+++ b/arch/x86/kernel/entry_64.S
|
||||
@@ -234,21 +234,21 @@ ENDPROC(native_usergs_sysret64)
|
||||
/*
|
||||
* initial frame state for interrupts (and exceptions without error code)
|
||||
*/
|
||||
- .macro EMPTY_FRAME start=1 offset=0
|
||||
- .if \start
|
||||
+ .macro EMPTY_FRAME offset=0
|
||||
CFI_STARTPROC simple
|
||||
CFI_SIGNAL_FRAME
|
||||
- CFI_DEF_CFA rsp,8+\offset
|
||||
- .else
|
||||
- CFI_DEF_CFA_OFFSET 8+\offset
|
||||
- .endif
|
||||
+ CFI_DEF_CFA rsp,\offset
|
||||
.endm
|
||||
|
||||
/*
|
||||
* initial frame state for interrupts (and exceptions without error code)
|
||||
*/
|
||||
.macro INTR_FRAME start=1 offset=0
|
||||
- EMPTY_FRAME \start, SS+8+\offset-RIP
|
||||
+ .if \start
|
||||
+ EMPTY_FRAME SS+8+\offset-RIP
|
||||
+ .else
|
||||
+ CFI_DEF_CFA_OFFSET SS+8+\offset-RIP
|
||||
+ .endif
|
||||
/*CFI_REL_OFFSET ss, SS+\offset-RIP*/
|
||||
CFI_REL_OFFSET rsp, RSP+\offset-RIP
|
||||
/*CFI_REL_OFFSET rflags, EFLAGS+\offset-RIP*/
|
||||
@@ -262,14 +262,15 @@ ENDPROC(native_usergs_sysret64)
|
||||
*/
|
||||
.macro XCPT_FRAME start=1 offset=0
|
||||
INTR_FRAME \start, RIP+\offset-ORIG_RAX
|
||||
- /*CFI_REL_OFFSET orig_rax, ORIG_RAX-ORIG_RAX*/
|
||||
.endm
|
||||
|
||||
/*
|
||||
* frame that enables calling into C.
|
||||
*/
|
||||
.macro PARTIAL_FRAME start=1 offset=0
|
||||
+ .if \start >= 0
|
||||
XCPT_FRAME \start, ORIG_RAX+\offset-ARGOFFSET
|
||||
+ .endif
|
||||
CFI_REL_OFFSET rdi, RDI+\offset-ARGOFFSET
|
||||
CFI_REL_OFFSET rsi, RSI+\offset-ARGOFFSET
|
||||
CFI_REL_OFFSET rdx, RDX+\offset-ARGOFFSET
|
||||
@@ -285,7 +286,9 @@ ENDPROC(native_usergs_sysret64)
|
||||
* frame that enables passing a complete pt_regs to a C function.
|
||||
*/
|
||||
.macro DEFAULT_FRAME start=1 offset=0
|
||||
+ .if \start >= -1
|
||||
PARTIAL_FRAME \start, R11+\offset-R15
|
||||
+ .endif
|
||||
CFI_REL_OFFSET rbx, RBX+\offset
|
||||
CFI_REL_OFFSET rbp, RBP+\offset
|
||||
CFI_REL_OFFSET r12, R12+\offset
|
||||
@@ -297,25 +300,27 @@ ENDPROC(native_usergs_sysret64)
|
||||
/* save partial stack frame */
|
||||
.pushsection .kprobes.text, "ax"
|
||||
ENTRY(save_args)
|
||||
- XCPT_FRAME
|
||||
+ XCPT_FRAME offset=ORIG_RAX-RBP+8
|
||||
cld
|
||||
/*
|
||||
* start from rbp in pt_regs and jump over
|
||||
* return address.
|
||||
*/
|
||||
movq_cfi rdi, RDI+8-RBP
|
||||
- movq_cfi rsi, RSI+8-RBP
|
||||
- movq_cfi rdx, RDX+8-RBP
|
||||
- movq_cfi rcx, RCX+8-RBP
|
||||
+ movq %rsi, RSI+8-RBP(%rsp)
|
||||
+ movq %rdx, RDX+8-RBP(%rsp)
|
||||
+ movq %rcx, RCX+8-RBP(%rsp)
|
||||
movq_cfi rax, RAX+8-RBP
|
||||
- movq_cfi r8, R8+8-RBP
|
||||
- movq_cfi r9, R9+8-RBP
|
||||
- movq_cfi r10, R10+8-RBP
|
||||
- movq_cfi r11, R11+8-RBP
|
||||
+ movq %r8, R8+8-RBP(%rsp)
|
||||
+ movq %r9, R9+8-RBP(%rsp)
|
||||
+ movq %r10, R10+8-RBP(%rsp)
|
||||
+ movq %r11, R11+8-RBP(%rsp)
|
||||
|
||||
leaq -RBP+8(%rsp),%rdi /* arg1 for handler */
|
||||
movq_cfi rbp, 8 /* push %rbp */
|
||||
leaq 8(%rsp), %rbp /* mov %rsp, %ebp */
|
||||
+ CFI_DEF_CFA_REGISTER rbp
|
||||
+ CFI_ADJUST_CFA_OFFSET -8
|
||||
testl $3, CS(%rdi)
|
||||
je 1f
|
||||
SWAPGS
|
||||
@@ -327,11 +332,10 @@ ENTRY(save_args)
|
||||
*/
|
||||
1: incl PER_CPU_VAR(irq_count)
|
||||
jne 2f
|
||||
- popq_cfi %rax /* move return address... */
|
||||
+ popq %rax /* move return address... */
|
||||
mov PER_CPU_VAR(irq_stack_ptr),%rsp
|
||||
- EMPTY_FRAME 0
|
||||
- pushq_cfi %rbp /* backlink for unwinder */
|
||||
- pushq_cfi %rax /* ... to the new stack */
|
||||
+ pushq %rbp /* backlink for unwinder */
|
||||
+ pushq %rax /* ... to the new stack */
|
||||
/*
|
||||
* We entered an interrupt context - irqs are off:
|
||||
*/
|
||||
@@ -342,14 +346,14 @@ END(save_args)
|
||||
.popsection
|
||||
|
||||
ENTRY(save_rest)
|
||||
- PARTIAL_FRAME 1 REST_SKIP+8
|
||||
+ CFI_STARTPROC
|
||||
movq 5*8+16(%rsp), %r11 /* save return address */
|
||||
- movq_cfi rbx, RBX+16
|
||||
- movq_cfi rbp, RBP+16
|
||||
- movq_cfi r12, R12+16
|
||||
- movq_cfi r13, R13+16
|
||||
- movq_cfi r14, R14+16
|
||||
- movq_cfi r15, R15+16
|
||||
+ movq %rbx, RBX+16(%rsp)
|
||||
+ movq %rbp, RBP+16(%rsp)
|
||||
+ movq %r12, R12+16(%rsp)
|
||||
+ movq %r13, R13+16(%rsp)
|
||||
+ movq %r14, R14+16(%rsp)
|
||||
+ movq %r15, R15+16(%rsp)
|
||||
movq %r11, 8(%rsp) /* return address */
|
||||
FIXUP_TOP_OF_STACK %r11, 16
|
||||
ret
|
||||
@@ -359,23 +363,23 @@ END(save_rest)
|
||||
/* save complete stack frame */
|
||||
.pushsection .kprobes.text, "ax"
|
||||
ENTRY(save_paranoid)
|
||||
- XCPT_FRAME 1 RDI+8
|
||||
+ XCPT_FRAME offset=ORIG_RAX-R15+8
|
||||
cld
|
||||
- movq_cfi rdi, RDI+8
|
||||
- movq_cfi rsi, RSI+8
|
||||
+ movq %rdi, RDI+8(%rsp)
|
||||
+ movq %rsi, RSI+8(%rsp)
|
||||
movq_cfi rdx, RDX+8
|
||||
movq_cfi rcx, RCX+8
|
||||
movq_cfi rax, RAX+8
|
||||
- movq_cfi r8, R8+8
|
||||
- movq_cfi r9, R9+8
|
||||
- movq_cfi r10, R10+8
|
||||
- movq_cfi r11, R11+8
|
||||
+ movq %r8, R8+8(%rsp)
|
||||
+ movq %r9, R9+8(%rsp)
|
||||
+ movq %r10, R10+8(%rsp)
|
||||
+ movq %r11, R11+8(%rsp)
|
||||
movq_cfi rbx, RBX+8
|
||||
- movq_cfi rbp, RBP+8
|
||||
- movq_cfi r12, R12+8
|
||||
- movq_cfi r13, R13+8
|
||||
- movq_cfi r14, R14+8
|
||||
- movq_cfi r15, R15+8
|
||||
+ movq %rbp, RBP+8(%rsp)
|
||||
+ movq %r12, R12+8(%rsp)
|
||||
+ movq %r13, R13+8(%rsp)
|
||||
+ movq %r14, R14+8(%rsp)
|
||||
+ movq %r15, R15+8(%rsp)
|
||||
movl $1,%ebx
|
||||
movl $MSR_GS_BASE,%ecx
|
||||
rdmsr
|
||||
@@ -677,7 +681,7 @@ ENTRY(\label)
|
||||
subq $REST_SKIP, %rsp
|
||||
CFI_ADJUST_CFA_OFFSET REST_SKIP
|
||||
call save_rest
|
||||
- DEFAULT_FRAME 0 8 /* offset 8: return address */
|
||||
+ DEFAULT_FRAME -2 8 /* offset 8: return address */
|
||||
leaq 8(%rsp), \arg /* pt_regs pointer */
|
||||
call \func
|
||||
jmp ptregscall_common
|
||||
@@ -794,7 +798,9 @@ END(interrupt)
|
||||
subq $ORIG_RAX-RBP, %rsp
|
||||
CFI_ADJUST_CFA_OFFSET ORIG_RAX-RBP
|
||||
call save_args
|
||||
- PARTIAL_FRAME 0
|
||||
+ PARTIAL_FRAME -1 ARGOFFSET-RBP
|
||||
+ CFI_REL_OFFSET rbp, 0
|
||||
+ CFI_DEF_CFA_REGISTER rbp
|
||||
call \func
|
||||
.endm
|
||||
|
||||
@@ -813,7 +819,6 @@ ret_from_intr:
|
||||
TRACE_IRQS_OFF
|
||||
decl PER_CPU_VAR(irq_count)
|
||||
leaveq
|
||||
-
|
||||
CFI_RESTORE rbp
|
||||
CFI_DEF_CFA_REGISTER rsp
|
||||
CFI_ADJUST_CFA_OFFSET -8
|
||||
@@ -1021,7 +1026,7 @@ ENTRY(\sym)
|
||||
subq $ORIG_RAX-R15, %rsp
|
||||
CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
|
||||
call error_entry
|
||||
- DEFAULT_FRAME 0
|
||||
+ DEFAULT_FRAME -1
|
||||
movq %rsp,%rdi /* pt_regs pointer */
|
||||
xorl %esi,%esi /* no error code */
|
||||
call \do_sym
|
||||
@@ -1038,6 +1043,7 @@ ENTRY(\sym)
|
||||
subq $ORIG_RAX-R15, %rsp
|
||||
CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
|
||||
call save_paranoid
|
||||
+ DEFAULT_FRAME -1
|
||||
TRACE_IRQS_OFF
|
||||
movq %rsp,%rdi /* pt_regs pointer */
|
||||
xorl %esi,%esi /* no error code */
|
||||
@@ -1056,6 +1062,7 @@ ENTRY(\sym)
|
||||
subq $ORIG_RAX-R15, %rsp
|
||||
CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
|
||||
call save_paranoid
|
||||
+ DEFAULT_FRAME -1
|
||||
TRACE_IRQS_OFF
|
||||
movq %rsp,%rdi /* pt_regs pointer */
|
||||
xorl %esi,%esi /* no error code */
|
||||
@@ -1074,7 +1081,7 @@ ENTRY(\sym)
|
||||
subq $ORIG_RAX-R15, %rsp
|
||||
CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
|
||||
call error_entry
|
||||
- DEFAULT_FRAME 0
|
||||
+ DEFAULT_FRAME -1
|
||||
movq %rsp,%rdi /* pt_regs pointer */
|
||||
movq ORIG_RAX(%rsp),%rsi /* get error code */
|
||||
movq $-1,ORIG_RAX(%rsp) /* no syscall to restart */
|
||||
@@ -1092,7 +1099,7 @@ ENTRY(\sym)
|
||||
subq $ORIG_RAX-R15, %rsp
|
||||
CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
|
||||
call save_paranoid
|
||||
- DEFAULT_FRAME 0
|
||||
+ DEFAULT_FRAME -1
|
||||
TRACE_IRQS_OFF
|
||||
movq %rsp,%rdi /* pt_regs pointer */
|
||||
movq ORIG_RAX(%rsp),%rsi /* get error code */
|
||||
@@ -1435,25 +1442,24 @@ END(paranoid_exit)
|
||||
* returns in "no swapgs flag" in %ebx.
|
||||
*/
|
||||
ENTRY(error_entry)
|
||||
- XCPT_FRAME
|
||||
- CFI_ADJUST_CFA_OFFSET 15*8
|
||||
+ XCPT_FRAME offset=ORIG_RAX-R15+8
|
||||
/* oldrax contains error code */
|
||||
cld
|
||||
- movq_cfi rdi, RDI+8
|
||||
- movq_cfi rsi, RSI+8
|
||||
- movq_cfi rdx, RDX+8
|
||||
- movq_cfi rcx, RCX+8
|
||||
- movq_cfi rax, RAX+8
|
||||
- movq_cfi r8, R8+8
|
||||
- movq_cfi r9, R9+8
|
||||
- movq_cfi r10, R10+8
|
||||
- movq_cfi r11, R11+8
|
||||
+ movq %rdi, RDI+8(%rsp)
|
||||
+ movq %rsi, RSI+8(%rsp)
|
||||
+ movq %rdx, RDX+8(%rsp)
|
||||
+ movq %rcx, RCX+8(%rsp)
|
||||
+ movq %rax, RAX+8(%rsp)
|
||||
+ movq %r8, R8+8(%rsp)
|
||||
+ movq %r9, R9+8(%rsp)
|
||||
+ movq %r10, R10+8(%rsp)
|
||||
+ movq %r11, R11+8(%rsp)
|
||||
movq_cfi rbx, RBX+8
|
||||
- movq_cfi rbp, RBP+8
|
||||
- movq_cfi r12, R12+8
|
||||
- movq_cfi r13, R13+8
|
||||
- movq_cfi r14, R14+8
|
||||
- movq_cfi r15, R15+8
|
||||
+ movq %rbp, RBP+8(%rsp)
|
||||
+ movq %r12, R12+8(%rsp)
|
||||
+ movq %r13, R13+8(%rsp)
|
||||
+ movq %r14, R14+8(%rsp)
|
||||
+ movq %r15, R15+8(%rsp)
|
||||
xorl %ebx,%ebx
|
||||
testl $3,CS+8(%rsp)
|
||||
je error_kernelspace
|
||||
@@ -1471,6 +1477,7 @@ error_sti:
|
||||
* compat mode. Check for these here too.
|
||||
*/
|
||||
error_kernelspace:
|
||||
+ CFI_REL_OFFSET rcx, RCX+8
|
||||
incl %ebx
|
||||
leaq irq_return(%rip),%rcx
|
||||
cmpq %rcx,RIP+8(%rsp)
|
||||
@@ -1518,7 +1523,7 @@ ENTRY(nmi)
|
||||
subq $ORIG_RAX-R15, %rsp
|
||||
CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
|
||||
call save_paranoid
|
||||
- DEFAULT_FRAME 0
|
||||
+ DEFAULT_FRAME -1
|
||||
/* paranoidentry do_nmi, 0; without TRACE_IRQS_OFF */
|
||||
movq %rsp,%rdi
|
||||
movq $-1,%rsi
|
||||
--- a/arch/x86/kernel/head_64.S
|
||||
+++ b/arch/x86/kernel/head_64.S
|
||||
@@ -284,6 +284,8 @@ early_idt_handlers:
|
||||
|
||||
ENTRY(early_idt_handler)
|
||||
#ifdef CONFIG_EARLY_PRINTK
|
||||
+#include <asm/calling.h>
|
||||
+#include <asm/dwarf2.h>
|
||||
cmpl $2,early_recursion_flag(%rip)
|
||||
jz 1f
|
||||
incl early_recursion_flag(%rip)
|
||||
@@ -299,6 +301,16 @@ ENTRY(early_idt_handler)
|
||||
testl $0x27d00,%eax
|
||||
je 0f
|
||||
popq %r8 # get error code
|
||||
+
|
||||
+ CFI_STARTPROC simple
|
||||
+ CFI_SIGNAL_FRAME
|
||||
+ CFI_DEF_CFA rsp, SS+8-RIP
|
||||
+# CFI_REL_OFFSET ss, SS-RIP
|
||||
+ CFI_REL_OFFSET rsp, RSP-RIP
|
||||
+# CFI_REL_OFFSET rflags, EFLAGS-RIP
|
||||
+# CFI_REL_OFFSET cs, CS-RIP
|
||||
+ CFI_REL_OFFSET rip, RIP-RIP
|
||||
+
|
||||
0: movq 0(%rsp),%rcx # get ip
|
||||
movq 8(%rsp),%rdx # get cs
|
||||
xorl %eax,%eax
|
||||
@@ -312,6 +324,7 @@ ENTRY(early_idt_handler)
|
||||
movq 0(%rsp),%rsi # get rip again
|
||||
call __print_symbol
|
||||
#endif
|
||||
+ CFI_ENDPROC
|
||||
#endif /* EARLY_PRINTK */
|
||||
1: hlt
|
||||
jmp 1b
|
||||
--- a/arch/x86/lib/rwsem_64.S
|
||||
+++ b/arch/x86/lib/rwsem_64.S
|
||||
@@ -23,43 +23,50 @@
|
||||
#include <asm/dwarf2.h>
|
||||
|
||||
#define save_common_regs \
|
||||
- pushq %rdi; \
|
||||
- pushq %rsi; \
|
||||
- pushq %rcx; \
|
||||
- pushq %r8; \
|
||||
- pushq %r9; \
|
||||
- pushq %r10; \
|
||||
- pushq %r11
|
||||
+ pushq_cfi %rdi; CFI_REL_OFFSET rdi, 0; \
|
||||
+ pushq_cfi %rsi; CFI_REL_OFFSET rsi, 0; \
|
||||
+ pushq_cfi %rcx; CFI_REL_OFFSET rcx, 0; \
|
||||
+ pushq_cfi %r8; CFI_REL_OFFSET r8, 0; \
|
||||
+ pushq_cfi %r9; CFI_REL_OFFSET r9, 0; \
|
||||
+ pushq_cfi %r10; CFI_REL_OFFSET r10, 0; \
|
||||
+ pushq_cfi %r11; CFI_REL_OFFSET r11, 0
|
||||
|
||||
#define restore_common_regs \
|
||||
- popq %r11; \
|
||||
- popq %r10; \
|
||||
- popq %r9; \
|
||||
- popq %r8; \
|
||||
- popq %rcx; \
|
||||
- popq %rsi; \
|
||||
- popq %rdi
|
||||
+ popq_cfi %r11; CFI_RESTORE r11; \
|
||||
+ popq_cfi %r10; CFI_RESTORE r10; \
|
||||
+ popq_cfi %r9; CFI_RESTORE r9; \
|
||||
+ popq_cfi %r8; CFI_RESTORE r8; \
|
||||
+ popq_cfi %rcx; CFI_RESTORE rcx; \
|
||||
+ popq_cfi %rsi; CFI_RESTORE rsi; \
|
||||
+ popq_cfi %rdi; CFI_RESTORE rdi
|
||||
|
||||
/* Fix up special calling conventions */
|
||||
ENTRY(call_rwsem_down_read_failed)
|
||||
+ CFI_STARTPROC
|
||||
save_common_regs
|
||||
- pushq %rdx
|
||||
+ pushq_cfi %rdx
|
||||
+ CFI_REL_OFFSET rdx, 0
|
||||
movq %rax,%rdi
|
||||
call rwsem_down_read_failed
|
||||
- popq %rdx
|
||||
+ popq_cfi %rdx
|
||||
+ CFI_RESTORE rdx
|
||||
restore_common_regs
|
||||
ret
|
||||
- ENDPROC(call_rwsem_down_read_failed)
|
||||
+ CFI_ENDPROC
|
||||
+ENDPROC(call_rwsem_down_read_failed)
|
||||
|
||||
ENTRY(call_rwsem_down_write_failed)
|
||||
+ CFI_STARTPROC
|
||||
save_common_regs
|
||||
movq %rax,%rdi
|
||||
call rwsem_down_write_failed
|
||||
restore_common_regs
|
||||
ret
|
||||
- ENDPROC(call_rwsem_down_write_failed)
|
||||
+ CFI_ENDPROC
|
||||
+ENDPROC(call_rwsem_down_write_failed)
|
||||
|
||||
ENTRY(call_rwsem_wake)
|
||||
+ CFI_STARTPROC
|
||||
decl %edx /* do nothing if still outstanding active readers */
|
||||
jnz 1f
|
||||
save_common_regs
|
||||
@@ -67,15 +74,20 @@ ENTRY(call_rwsem_wake)
|
||||
call rwsem_wake
|
||||
restore_common_regs
|
||||
1: ret
|
||||
- ENDPROC(call_rwsem_wake)
|
||||
+ CFI_ENDPROC
|
||||
+ENDPROC(call_rwsem_wake)
|
||||
|
||||
/* Fix up special calling conventions */
|
||||
ENTRY(call_rwsem_downgrade_wake)
|
||||
+ CFI_STARTPROC
|
||||
save_common_regs
|
||||
- pushq %rdx
|
||||
+ pushq_cfi %rdx
|
||||
+ CFI_REL_OFFSET rdx, 0
|
||||
movq %rax,%rdi
|
||||
call rwsem_downgrade_wake
|
||||
- popq %rdx
|
||||
+ popq_cfi %rdx
|
||||
+ CFI_RESTORE rdx
|
||||
restore_common_regs
|
||||
ret
|
||||
- ENDPROC(call_rwsem_downgrade_wake)
|
||||
+ CFI_ENDPROC
|
||||
+ENDPROC(call_rwsem_downgrade_wake)
|
@ -1,74 +0,0 @@
|
||||
From: Brandon Philips <bphilips@suse.de>
|
||||
Subject: Avoid oops on G33 in 1MB stolen Mem case
|
||||
References: bnc#391261
|
||||
Patch-Mainline: soon (see bug for ref)
|
||||
|
||||
This is similar to f443675affe3f16dd428e46f0f7fd3f4d703eeab which was
|
||||
reverted because it broke with older XOrg driver. This patch only fixes
|
||||
the 1MB stolen case since it causes an oops due to a calculation
|
||||
problem.
|
||||
|
||||
This will not work with older X drivers without the accompanying patch
|
||||
but I think avoiding an oops and making it possible to work with an
|
||||
up-to-date xorg driver is reasonable.
|
||||
|
||||
Explanation of the oops:
|
||||
|
||||
> static void intel_i830_init_gtt_entries(void)
|
||||
...
|
||||
> } else if (IS_G33) {
|
||||
> /* G33's GTT size defined in gmch_ctrl */
|
||||
> switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) {
|
||||
> case G33_PGETBL_SIZE_1M:
|
||||
> size = 1024;
|
||||
> break;
|
||||
...
|
||||
> size += 4;
|
||||
|
||||
size = 1028
|
||||
|
||||
Then since we have the BIOS setting 1MB for the device in the GMCH
|
||||
control we get to here:
|
||||
|
||||
> } else {
|
||||
> switch (gmch_ctrl & I855_GMCH_GMS_MASK) {
|
||||
> case I855_GMCH_GMS_STOLEN_1M:
|
||||
> gtt_entries = MB(1) - KB(size);
|
||||
> break;
|
||||
|
||||
MB(1) = 1 * 1024 * 1024
|
||||
KB(1028) = 1028 * 1024
|
||||
|
||||
MB(1) - KB(1028) = -4096
|
||||
|
||||
> gtt_entries /= KB(4);
|
||||
> intel_private.gtt_entries = gtt_entries;
|
||||
|
||||
We end up with -1 in gtt_entries.
|
||||
|
||||
This leads to intel_i915_configure reading/writing to areas outside of
|
||||
mapped memory and the oops.
|
||||
|
||||
Signed-off-by: Brandon Philips <bphilips@suse.de>
|
||||
Acked-by: Thomas Renninger <trenn@suse.de>
|
||||
|
||||
---
|
||||
drivers/char/agp/intel-gtt.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
--- a/drivers/char/agp/intel-gtt.c
|
||||
+++ b/drivers/char/agp/intel-gtt.c
|
||||
@@ -648,6 +648,13 @@ static void intel_i830_init_gtt_entries(
|
||||
} else {
|
||||
switch (gmch_ctrl & I855_GMCH_GMS_MASK) {
|
||||
case I855_GMCH_GMS_STOLEN_1M:
|
||||
+ if (IS_G33) {
|
||||
+ size = 0;
|
||||
+ printk(KERN_WARNING PFX
|
||||
+ "Warning: G33 chipset with 1MB"
|
||||
+ " allocated. Older X.org Intel drivers"
|
||||
+ " will not work.\n");
|
||||
+ }
|
||||
gtt_entries = MB(1) - KB(size);
|
||||
break;
|
||||
case I855_GMCH_GMS_STOLEN_4M:
|
@ -1,126 +0,0 @@
|
||||
From 3cd8c73bebbc64ab13173931012ed4a58717b446 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Wilson <chris@chris-wilson.co.uk>
|
||||
Date: Tue, 12 Apr 2011 18:06:51 +0100
|
||||
Subject: [PATCH 1/2] drm/i915: Sanitize the output registers after resume
|
||||
|
||||
commit f6e5b1603b8bb7131b6778d0d4e2e5dda120a379 upstream.
|
||||
|
||||
Similar to booting, we need to inspect the state left by the BIOS and
|
||||
remove any conflicting bits before we take over. The example reported by
|
||||
Seth Forshee is very similar to the bug we encountered with the state left
|
||||
by grub2, that the crtc pipe<->planning mapping was reversed from our
|
||||
expectations and so we failed to turn off the outputs when booting or,
|
||||
in this case, resuming. This may be in fact the same bug, but triggered
|
||||
at resume time.
|
||||
|
||||
This patch rearranges the code we already have to clear up the
|
||||
conflicting state upon init and calls it from reset (which is called
|
||||
after we have lost control of the hardware, i.e. along both the boot and
|
||||
resume paths) instead.
|
||||
|
||||
Reported-and-tested-by: Seth Forshee <seth.forshee@canonical.com>
|
||||
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=35796
|
||||
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
||||
Reviewed-by: Keith Packard <keithp@keithp.com>
|
||||
Signed-off-by: Keith Packard <keithp@keithp.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/gpu/drm/i915/intel_display.c | 68 ++++++++++++++++++----------------
|
||||
1 files changed, 36 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
|
||||
index cef853b..c7403e7 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_display.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_display.c
|
||||
@@ -5764,36 +5764,6 @@ cleanup_work:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static void intel_crtc_reset(struct drm_crtc *crtc)
|
||||
-{
|
||||
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||
-
|
||||
- /* Reset flags back to the 'unknown' status so that they
|
||||
- * will be correctly set on the initial modeset.
|
||||
- */
|
||||
- intel_crtc->dpms_mode = -1;
|
||||
-}
|
||||
-
|
||||
-static struct drm_crtc_helper_funcs intel_helper_funcs = {
|
||||
- .dpms = intel_crtc_dpms,
|
||||
- .mode_fixup = intel_crtc_mode_fixup,
|
||||
- .mode_set = intel_crtc_mode_set,
|
||||
- .mode_set_base = intel_pipe_set_base,
|
||||
- .mode_set_base_atomic = intel_pipe_set_base_atomic,
|
||||
- .load_lut = intel_crtc_load_lut,
|
||||
- .disable = intel_crtc_disable,
|
||||
-};
|
||||
-
|
||||
-static const struct drm_crtc_funcs intel_crtc_funcs = {
|
||||
- .reset = intel_crtc_reset,
|
||||
- .cursor_set = intel_crtc_cursor_set,
|
||||
- .cursor_move = intel_crtc_cursor_move,
|
||||
- .gamma_set = intel_crtc_gamma_set,
|
||||
- .set_config = drm_crtc_helper_set_config,
|
||||
- .destroy = intel_crtc_destroy,
|
||||
- .page_flip = intel_crtc_page_flip,
|
||||
-};
|
||||
-
|
||||
static void intel_sanitize_modesetting(struct drm_device *dev,
|
||||
int pipe, int plane)
|
||||
{
|
||||
@@ -5830,6 +5800,42 @@ static void intel_sanitize_modesetting(struct drm_device *dev,
|
||||
intel_disable_pipe(dev_priv, pipe);
|
||||
}
|
||||
|
||||
+static void intel_crtc_reset(struct drm_crtc *crtc)
|
||||
+{
|
||||
+ struct drm_device *dev = crtc->dev;
|
||||
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||
+
|
||||
+ /* Reset flags back to the 'unknown' status so that they
|
||||
+ * will be correctly set on the initial modeset.
|
||||
+ */
|
||||
+ intel_crtc->dpms_mode = -1;
|
||||
+
|
||||
+ /* We need to fix up any BIOS configuration that conflicts with
|
||||
+ * our expectations.
|
||||
+ */
|
||||
+ intel_sanitize_modesetting(dev, intel_crtc->pipe, intel_crtc->plane);
|
||||
+}
|
||||
+
|
||||
+static struct drm_crtc_helper_funcs intel_helper_funcs = {
|
||||
+ .dpms = intel_crtc_dpms,
|
||||
+ .mode_fixup = intel_crtc_mode_fixup,
|
||||
+ .mode_set = intel_crtc_mode_set,
|
||||
+ .mode_set_base = intel_pipe_set_base,
|
||||
+ .mode_set_base_atomic = intel_pipe_set_base_atomic,
|
||||
+ .load_lut = intel_crtc_load_lut,
|
||||
+ .disable = intel_crtc_disable,
|
||||
+};
|
||||
+
|
||||
+static const struct drm_crtc_funcs intel_crtc_funcs = {
|
||||
+ .reset = intel_crtc_reset,
|
||||
+ .cursor_set = intel_crtc_cursor_set,
|
||||
+ .cursor_move = intel_crtc_cursor_move,
|
||||
+ .gamma_set = intel_crtc_gamma_set,
|
||||
+ .set_config = drm_crtc_helper_set_config,
|
||||
+ .destroy = intel_crtc_destroy,
|
||||
+ .page_flip = intel_crtc_page_flip,
|
||||
+};
|
||||
+
|
||||
static void intel_crtc_init(struct drm_device *dev, int pipe)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
@@ -5879,8 +5885,6 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
|
||||
|
||||
setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer,
|
||||
(unsigned long)intel_crtc);
|
||||
-
|
||||
- intel_sanitize_modesetting(dev, intel_crtc->pipe, intel_crtc->plane);
|
||||
}
|
||||
|
||||
int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
|
||||
--
|
||||
1.7.6.5
|
||||
|
@ -1,64 +0,0 @@
|
||||
From 38c1a19fb78da8c2a617b1d8a3fcafb691c1409f Mon Sep 17 00:00:00 2001
|
||||
From: Chris Wilson <chris@chris-wilson.co.uk>
|
||||
Date: Sun, 16 Jan 2011 19:37:30 +0000
|
||||
Subject: [PATCH 1/3] drm/i915: Use ACPI OpRegion to determine lid status
|
||||
|
||||
Admittedly, trusting ACPI or the BIOS at all to be correct is littered
|
||||
with numerous examples where it is wrong. Maybe, just maybe, we will
|
||||
have better luck using the ACPI OpRegion lid status...
|
||||
|
||||
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
||||
---
|
||||
drivers/gpu/drm/i915/i915_drv.h | 1 +
|
||||
drivers/gpu/drm/i915/intel_lvds.c | 7 +++++++
|
||||
drivers/gpu/drm/i915/intel_opregion.c | 2 ++
|
||||
3 files changed, 10 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
|
||||
index 456f404..a299cc6 100644
|
||||
--- a/drivers/gpu/drm/i915/i915_drv.h
|
||||
+++ b/drivers/gpu/drm/i915/i915_drv.h
|
||||
@@ -111,6 +111,7 @@ struct intel_opregion {
|
||||
struct opregion_swsci *swsci;
|
||||
struct opregion_asle *asle;
|
||||
void *vbt;
|
||||
+ u32 __iomem *lid_state;
|
||||
};
|
||||
#define OPREGION_SIZE (8*1024)
|
||||
|
||||
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
|
||||
index bcdba7b..aa29228 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_lvds.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_lvds.c
|
||||
@@ -472,8 +472,15 @@ static enum drm_connector_status
|
||||
intel_lvds_detect(struct drm_connector *connector, bool force)
|
||||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
+ struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
enum drm_connector_status status = connector_status_connected;
|
||||
|
||||
+ /* Assume that the BIOS does not lie through the OpRegion... */
|
||||
+ if (dev_priv->opregion.lid_state)
|
||||
+ return ioread32(dev_priv->opregion.lid_state) & 0x1 ?
|
||||
+ connector_status_connected :
|
||||
+ connector_status_disconnected;
|
||||
+
|
||||
/* ACPI lid methods were generally unreliable in this generation, so
|
||||
* don't even bother.
|
||||
*/
|
||||
diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c
|
||||
index 64fd644..9efccb9 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_opregion.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_opregion.c
|
||||
@@ -489,6 +489,8 @@ int intel_opregion_setup(struct drm_device *dev)
|
||||
opregion->header = base;
|
||||
opregion->vbt = base + OPREGION_VBT_OFFSET;
|
||||
|
||||
+ opregion->lid_state = base + 0x01ac;
|
||||
+
|
||||
mboxes = opregion->header->mboxes;
|
||||
if (mboxes & MBOX_ACPI) {
|
||||
DRM_DEBUG_DRIVER("Public ACPI methods supported\n");
|
||||
--
|
||||
1.7.6.5
|
||||
|
@ -1,35 +0,0 @@
|
||||
From 9e4eb0947431c5a6b55f442aee3eb505e5a334d5 Mon Sep 17 00:00:00 2001
|
||||
From: Jesse Barnes <jbarnes@virtuousgeek.org>
|
||||
Date: Tue, 4 Jan 2011 15:09:29 -0800
|
||||
Subject: [PATCH 2/3] drm/i915: don't enable plane, pipe and PLL prematurely
|
||||
|
||||
On Ironlake+ we need to enable these in a specific order.
|
||||
|
||||
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
|
||||
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
||||
---
|
||||
drivers/gpu/drm/i915/intel_display.c | 8 +++++---
|
||||
1 files changed, 5 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
|
||||
index 49fb54f..711beca 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_display.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_display.c
|
||||
@@ -4322,9 +4322,11 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
|
||||
pipeconf &= ~PIPECONF_DOUBLE_WIDE;
|
||||
}
|
||||
|
||||
- dspcntr |= DISPLAY_PLANE_ENABLE;
|
||||
- pipeconf |= PIPECONF_ENABLE;
|
||||
- dpll |= DPLL_VCO_ENABLE;
|
||||
+ if (!HAS_PCH_SPLIT(dev)) {
|
||||
+ dspcntr |= DISPLAY_PLANE_ENABLE;
|
||||
+ pipeconf |= PIPECONF_ENABLE;
|
||||
+ dpll |= DPLL_VCO_ENABLE;
|
||||
+ }
|
||||
|
||||
DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
|
||||
drm_mode_debug_printmodeline(mode);
|
||||
--
|
||||
1.7.6.5
|
||||
|
@ -1,429 +0,0 @@
|
||||
From 152d92c3e618d1c17c6a84c66aec00af227c3f0e Mon Sep 17 00:00:00 2001
|
||||
From: Jesse Barnes <jbarnes@virtuousgeek.org>
|
||||
Date: Tue, 4 Jan 2011 15:09:30 -0800
|
||||
Subject: [PATCH 3/3] drm/i915: add pipe/plane enable/disable functions
|
||||
|
||||
Add plane enable/disable functions to prevent duplicated code and allow
|
||||
us to easily check for plane enable/disable requirements (such as pipe
|
||||
enable, plane status, pll status etc).
|
||||
|
||||
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
|
||||
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
||||
---
|
||||
drivers/gpu/drm/i915/i915_reg.h | 5 +-
|
||||
drivers/gpu/drm/i915/intel_display.c | 308 +++++++++++++++++++++++-----------
|
||||
2 files changed, 216 insertions(+), 97 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
|
||||
index 12c547a..b0f1290 100644
|
||||
--- a/drivers/gpu/drm/i915/i915_reg.h
|
||||
+++ b/drivers/gpu/drm/i915/i915_reg.h
|
||||
@@ -2537,9 +2537,10 @@
|
||||
#define DISPPLANE_32BPP_30BIT_NO_ALPHA (0xa<<26)
|
||||
#define DISPPLANE_STEREO_ENABLE (1<<25)
|
||||
#define DISPPLANE_STEREO_DISABLE 0
|
||||
-#define DISPPLANE_SEL_PIPE_MASK (1<<24)
|
||||
+#define DISPPLANE_SEL_PIPE_SHIFT 24
|
||||
+#define DISPPLANE_SEL_PIPE_MASK (3<<DISPPLANE_SEL_PIPE_SHIFT)
|
||||
#define DISPPLANE_SEL_PIPE_A 0
|
||||
-#define DISPPLANE_SEL_PIPE_B (1<<24)
|
||||
+#define DISPPLANE_SEL_PIPE_B (1<<DISPPLANE_SEL_PIPE_SHIFT)
|
||||
#define DISPPLANE_SRC_KEY_ENABLE (1<<22)
|
||||
#define DISPPLANE_SRC_KEY_DISABLE 0
|
||||
#define DISPPLANE_LINE_DOUBLE (1<<20)
|
||||
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
|
||||
index 711beca..cef853b 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_display.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_display.c
|
||||
@@ -1058,6 +1058,203 @@ void intel_wait_for_pipe_off(struct drm_device *dev, int pipe)
|
||||
}
|
||||
}
|
||||
|
||||
+static const char *state_string(bool enabled)
|
||||
+{
|
||||
+ return enabled ? "on" : "off";
|
||||
+}
|
||||
+
|
||||
+/* Only for pre-ILK configs */
|
||||
+static void assert_pll(struct drm_i915_private *dev_priv,
|
||||
+ enum pipe pipe, bool state)
|
||||
+{
|
||||
+ int reg;
|
||||
+ u32 val;
|
||||
+ bool cur_state;
|
||||
+
|
||||
+ reg = DPLL(pipe);
|
||||
+ val = I915_READ(reg);
|
||||
+ cur_state = !!(val & DPLL_VCO_ENABLE);
|
||||
+ WARN(cur_state != state,
|
||||
+ "PLL state assertion failure (expected %s, current %s)\n",
|
||||
+ state_string(state), state_string(cur_state));
|
||||
+}
|
||||
+#define assert_pll_enabled(d, p) assert_pll(d, p, true)
|
||||
+#define assert_pll_disabled(d, p) assert_pll(d, p, false)
|
||||
+
|
||||
+static void assert_pipe_enabled(struct drm_i915_private *dev_priv,
|
||||
+ enum pipe pipe)
|
||||
+{
|
||||
+ int reg;
|
||||
+ u32 val;
|
||||
+
|
||||
+ reg = PIPECONF(pipe);
|
||||
+ val = I915_READ(reg);
|
||||
+ WARN(!(val & PIPECONF_ENABLE),
|
||||
+ "pipe %c assertion failure, should be active but is disabled\n",
|
||||
+ pipe ? 'B' : 'A');
|
||||
+}
|
||||
+
|
||||
+static void assert_plane_enabled(struct drm_i915_private *dev_priv,
|
||||
+ enum plane plane)
|
||||
+{
|
||||
+ int reg;
|
||||
+ u32 val;
|
||||
+
|
||||
+ reg = DSPCNTR(plane);
|
||||
+ val = I915_READ(reg);
|
||||
+ WARN(!(val & DISPLAY_PLANE_ENABLE),
|
||||
+ "plane %c assertion failure, should be active but is disabled\n",
|
||||
+ plane ? 'B' : 'A');
|
||||
+}
|
||||
+
|
||||
+static void assert_planes_disabled(struct drm_i915_private *dev_priv,
|
||||
+ enum pipe pipe)
|
||||
+{
|
||||
+ int reg, i;
|
||||
+ u32 val;
|
||||
+ int cur_pipe;
|
||||
+
|
||||
+ /* Need to check both planes against the pipe */
|
||||
+ for (i = 0; i < 2; i++) {
|
||||
+ reg = DSPCNTR(i);
|
||||
+ val = I915_READ(reg);
|
||||
+ cur_pipe = (val & DISPPLANE_SEL_PIPE_MASK) >>
|
||||
+ DISPPLANE_SEL_PIPE_SHIFT;
|
||||
+ WARN((val & DISPLAY_PLANE_ENABLE) && pipe == cur_pipe,
|
||||
+ "plane %d assertion failure, should be off on pipe %c but is still active\n",
|
||||
+ i, pipe ? 'B' : 'A');
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * intel_enable_pipe - enable a pipe, assertiing requirements
|
||||
+ * @dev_priv: i915 private structure
|
||||
+ * @pipe: pipe to enable
|
||||
+ *
|
||||
+ * Enable @pipe, making sure that various hardware specific requirements
|
||||
+ * are met, if applicable, e.g. PLL enabled, LVDS pairs enabled, etc.
|
||||
+ *
|
||||
+ * @pipe should be %PIPE_A or %PIPE_B.
|
||||
+ *
|
||||
+ * Will wait until the pipe is actually running (i.e. first vblank) before
|
||||
+ * returning.
|
||||
+ */
|
||||
+static void intel_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
|
||||
+{
|
||||
+ int reg;
|
||||
+ u32 val;
|
||||
+
|
||||
+ /*
|
||||
+ * A pipe without a PLL won't actually be able to drive bits from
|
||||
+ * a plane. On ILK+ the pipe PLLs are integrated, so we don't
|
||||
+ * need the check.
|
||||
+ */
|
||||
+ if (!HAS_PCH_SPLIT(dev_priv->dev))
|
||||
+ assert_pll_enabled(dev_priv, pipe);
|
||||
+
|
||||
+ reg = PIPECONF(pipe);
|
||||
+ val = I915_READ(reg);
|
||||
+ val |= PIPECONF_ENABLE;
|
||||
+ I915_WRITE(reg, val);
|
||||
+ POSTING_READ(reg);
|
||||
+ intel_wait_for_vblank(dev_priv->dev, pipe);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * intel_disable_pipe - disable a pipe, assertiing requirements
|
||||
+ * @dev_priv: i915 private structure
|
||||
+ * @pipe: pipe to disable
|
||||
+ *
|
||||
+ * Disable @pipe, making sure that various hardware specific requirements
|
||||
+ * are met, if applicable, e.g. plane disabled, panel fitter off, etc.
|
||||
+ *
|
||||
+ * @pipe should be %PIPE_A or %PIPE_B.
|
||||
+ *
|
||||
+ * Will wait until the pipe has shut down before returning.
|
||||
+ */
|
||||
+static void intel_disable_pipe(struct drm_i915_private *dev_priv,
|
||||
+ enum pipe pipe)
|
||||
+{
|
||||
+ int reg;
|
||||
+ u32 val;
|
||||
+
|
||||
+ /*
|
||||
+ * Make sure planes won't keep trying to pump pixels to us,
|
||||
+ * or we might hang the display.
|
||||
+ */
|
||||
+ assert_planes_disabled(dev_priv, pipe);
|
||||
+
|
||||
+ /* Don't disable pipe A or pipe A PLLs if needed */
|
||||
+ if (pipe == PIPE_A && (dev_priv->quirks & QUIRK_PIPEA_FORCE))
|
||||
+ return;
|
||||
+
|
||||
+ reg = PIPECONF(pipe);
|
||||
+ val = I915_READ(reg);
|
||||
+ val &= ~PIPECONF_ENABLE;
|
||||
+ I915_WRITE(reg, val);
|
||||
+ POSTING_READ(reg);
|
||||
+ intel_wait_for_pipe_off(dev_priv->dev, pipe);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * intel_enable_plane - enable a display plane on a given pipe
|
||||
+ * @dev_priv: i915 private structure
|
||||
+ * @plane: plane to enable
|
||||
+ * @pipe: pipe being fed
|
||||
+ *
|
||||
+ * Enable @plane on @pipe, making sure that @pipe is running first.
|
||||
+ */
|
||||
+static void intel_enable_plane(struct drm_i915_private *dev_priv,
|
||||
+ enum plane plane, enum pipe pipe)
|
||||
+{
|
||||
+ int reg;
|
||||
+ u32 val;
|
||||
+
|
||||
+ /* If the pipe isn't enabled, we can't pump pixels and may hang */
|
||||
+ assert_pipe_enabled(dev_priv, pipe);
|
||||
+
|
||||
+ reg = DSPCNTR(plane);
|
||||
+ val = I915_READ(reg);
|
||||
+ val |= DISPLAY_PLANE_ENABLE;
|
||||
+ I915_WRITE(reg, val);
|
||||
+ POSTING_READ(reg);
|
||||
+ intel_wait_for_vblank(dev_priv->dev, pipe);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Plane regs are double buffered, going from enabled->disabled needs a
|
||||
+ * trigger in order to latch. The display address reg provides this.
|
||||
+ */
|
||||
+static void intel_flush_display_plane(struct drm_i915_private *dev_priv,
|
||||
+ enum plane plane)
|
||||
+{
|
||||
+ u32 reg = DSPADDR(plane);
|
||||
+ I915_WRITE(reg, I915_READ(reg));
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * intel_disable_plane - disable a display plane
|
||||
+ * @dev_priv: i915 private structure
|
||||
+ * @plane: plane to disable
|
||||
+ * @pipe: pipe consuming the data
|
||||
+ *
|
||||
+ * Disable @plane; should be an independent operation.
|
||||
+ */
|
||||
+static void intel_disable_plane(struct drm_i915_private *dev_priv,
|
||||
+ enum plane plane, enum pipe pipe)
|
||||
+{
|
||||
+ int reg;
|
||||
+ u32 val;
|
||||
+
|
||||
+ reg = DSPCNTR(plane);
|
||||
+ val = I915_READ(reg);
|
||||
+ val &= ~DISPLAY_PLANE_ENABLE;
|
||||
+ I915_WRITE(reg, val);
|
||||
+ POSTING_READ(reg);
|
||||
+ intel_flush_display_plane(dev_priv, plane);
|
||||
+ intel_wait_for_vblank(dev_priv->dev, pipe);
|
||||
+}
|
||||
+
|
||||
static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
@@ -2003,14 +2200,6 @@ static void ironlake_fdi_enable(struct drm_crtc *crtc)
|
||||
}
|
||||
}
|
||||
|
||||
-static void intel_flush_display_plane(struct drm_device *dev,
|
||||
- int plane)
|
||||
-{
|
||||
- struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
- u32 reg = DSPADDR(plane);
|
||||
- I915_WRITE(reg, I915_READ(reg));
|
||||
-}
|
||||
-
|
||||
/*
|
||||
* When we disable a pipe, we need to clear any pending scanline wait events
|
||||
* to avoid hanging the ring, which we assume we are waiting on.
|
||||
@@ -2158,22 +2347,8 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
|
||||
dev_priv->pch_pf_size);
|
||||
}
|
||||
|
||||
- /* Enable CPU pipe */
|
||||
- reg = PIPECONF(pipe);
|
||||
- temp = I915_READ(reg);
|
||||
- if ((temp & PIPECONF_ENABLE) == 0) {
|
||||
- I915_WRITE(reg, temp | PIPECONF_ENABLE);
|
||||
- POSTING_READ(reg);
|
||||
- intel_wait_for_vblank(dev, intel_crtc->pipe);
|
||||
- }
|
||||
-
|
||||
- /* configure and enable CPU plane */
|
||||
- reg = DSPCNTR(plane);
|
||||
- temp = I915_READ(reg);
|
||||
- if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
|
||||
- I915_WRITE(reg, temp | DISPLAY_PLANE_ENABLE);
|
||||
- intel_flush_display_plane(dev, plane);
|
||||
- }
|
||||
+ intel_enable_pipe(dev_priv, pipe);
|
||||
+ intel_enable_plane(dev_priv, plane, pipe);
|
||||
|
||||
/* Skip the PCH stuff if possible */
|
||||
if (!is_pch_port)
|
||||
@@ -2285,27 +2460,13 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
|
||||
drm_vblank_off(dev, pipe);
|
||||
intel_crtc_update_cursor(crtc, false);
|
||||
|
||||
- /* Disable display plane */
|
||||
- reg = DSPCNTR(plane);
|
||||
- temp = I915_READ(reg);
|
||||
- if (temp & DISPLAY_PLANE_ENABLE) {
|
||||
- I915_WRITE(reg, temp & ~DISPLAY_PLANE_ENABLE);
|
||||
- intel_flush_display_plane(dev, plane);
|
||||
- }
|
||||
+ intel_disable_plane(dev_priv, plane, pipe);
|
||||
|
||||
if (dev_priv->cfb_plane == plane &&
|
||||
dev_priv->display.disable_fbc)
|
||||
dev_priv->display.disable_fbc(dev);
|
||||
|
||||
- /* disable cpu pipe, disable after all planes disabled */
|
||||
- reg = PIPECONF(pipe);
|
||||
- temp = I915_READ(reg);
|
||||
- if (temp & PIPECONF_ENABLE) {
|
||||
- I915_WRITE(reg, temp & ~PIPECONF_ENABLE);
|
||||
- POSTING_READ(reg);
|
||||
- /* wait for cpu pipe off, pipe state */
|
||||
- intel_wait_for_pipe_off(dev, intel_crtc->pipe);
|
||||
- }
|
||||
+ intel_disable_pipe(dev_priv, pipe);
|
||||
|
||||
/* Disable PF */
|
||||
I915_WRITE(pipe ? PFB_CTL_1 : PFA_CTL_1, 0);
|
||||
@@ -2500,19 +2661,8 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
|
||||
udelay(150);
|
||||
}
|
||||
|
||||
- /* Enable the pipe */
|
||||
- reg = PIPECONF(pipe);
|
||||
- temp = I915_READ(reg);
|
||||
- if ((temp & PIPECONF_ENABLE) == 0)
|
||||
- I915_WRITE(reg, temp | PIPECONF_ENABLE);
|
||||
-
|
||||
- /* Enable the plane */
|
||||
- reg = DSPCNTR(plane);
|
||||
- temp = I915_READ(reg);
|
||||
- if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
|
||||
- I915_WRITE(reg, temp | DISPLAY_PLANE_ENABLE);
|
||||
- intel_flush_display_plane(dev, plane);
|
||||
- }
|
||||
+ intel_enable_pipe(dev_priv, pipe);
|
||||
+ intel_enable_plane(dev_priv, plane, pipe);
|
||||
|
||||
intel_crtc_load_lut(crtc);
|
||||
intel_update_fbc(dev);
|
||||
@@ -2544,33 +2694,13 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
|
||||
dev_priv->display.disable_fbc)
|
||||
dev_priv->display.disable_fbc(dev);
|
||||
|
||||
- /* Disable display plane */
|
||||
- reg = DSPCNTR(plane);
|
||||
- temp = I915_READ(reg);
|
||||
- if (temp & DISPLAY_PLANE_ENABLE) {
|
||||
- I915_WRITE(reg, temp & ~DISPLAY_PLANE_ENABLE);
|
||||
- /* Flush the plane changes */
|
||||
- intel_flush_display_plane(dev, plane);
|
||||
-
|
||||
- /* Wait for vblank for the disable to take effect */
|
||||
- if (IS_GEN2(dev))
|
||||
- intel_wait_for_vblank(dev, pipe);
|
||||
- }
|
||||
+ intel_disable_plane(dev_priv, plane, pipe);
|
||||
|
||||
/* Don't disable pipe A or pipe A PLLs if needed */
|
||||
if (pipe == 0 && (dev_priv->quirks & QUIRK_PIPEA_FORCE))
|
||||
goto done;
|
||||
|
||||
- /* Next, disable display pipes */
|
||||
- reg = PIPECONF(pipe);
|
||||
- temp = I915_READ(reg);
|
||||
- if (temp & PIPECONF_ENABLE) {
|
||||
- I915_WRITE(reg, temp & ~PIPECONF_ENABLE);
|
||||
-
|
||||
- /* Wait for the pipe to turn off */
|
||||
- POSTING_READ(reg);
|
||||
- intel_wait_for_pipe_off(dev, pipe);
|
||||
- }
|
||||
+ intel_disable_pipe(dev_priv, pipe);
|
||||
|
||||
reg = DPLL(pipe);
|
||||
temp = I915_READ(reg);
|
||||
@@ -4322,11 +4452,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
|
||||
pipeconf &= ~PIPECONF_DOUBLE_WIDE;
|
||||
}
|
||||
|
||||
- if (!HAS_PCH_SPLIT(dev)) {
|
||||
- dspcntr |= DISPLAY_PLANE_ENABLE;
|
||||
- pipeconf |= PIPECONF_ENABLE;
|
||||
+ if (!HAS_PCH_SPLIT(dev))
|
||||
dpll |= DPLL_VCO_ENABLE;
|
||||
- }
|
||||
|
||||
DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
|
||||
drm_mode_debug_printmodeline(mode);
|
||||
@@ -4535,6 +4662,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
|
||||
|
||||
I915_WRITE(PIPECONF(pipe), pipeconf);
|
||||
POSTING_READ(PIPECONF(pipe));
|
||||
+ if (!HAS_PCH_SPLIT(dev))
|
||||
+ intel_enable_pipe(dev_priv, pipe);
|
||||
|
||||
intel_wait_for_vblank(dev, pipe);
|
||||
|
||||
@@ -4545,6 +4674,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
|
||||
}
|
||||
|
||||
I915_WRITE(DSPCNTR(plane), dspcntr);
|
||||
+ POSTING_READ(DSPCNTR(plane));
|
||||
+ if (!HAS_PCH_SPLIT(dev))
|
||||
+ intel_enable_plane(dev_priv, plane, pipe);
|
||||
|
||||
ret = intel_pipe_set_base(crtc, x, y, old_fb);
|
||||
|
||||
@@ -5694,22 +5826,8 @@ static void intel_sanitize_modesetting(struct drm_device *dev,
|
||||
pipe = !pipe;
|
||||
|
||||
/* Disable the plane and wait for it to stop reading from the pipe. */
|
||||
- I915_WRITE(reg, val & ~DISPLAY_PLANE_ENABLE);
|
||||
- intel_flush_display_plane(dev, plane);
|
||||
-
|
||||
- if (IS_GEN2(dev))
|
||||
- intel_wait_for_vblank(dev, pipe);
|
||||
-
|
||||
- if (pipe == 0 && (dev_priv->quirks & QUIRK_PIPEA_FORCE))
|
||||
- return;
|
||||
-
|
||||
- /* Switch off the pipe. */
|
||||
- reg = PIPECONF(pipe);
|
||||
- val = I915_READ(reg);
|
||||
- if (val & PIPECONF_ENABLE) {
|
||||
- I915_WRITE(reg, val & ~PIPECONF_ENABLE);
|
||||
- intel_wait_for_pipe_off(dev, pipe);
|
||||
- }
|
||||
+ intel_disable_plane(dev_priv, plane, pipe);
|
||||
+ intel_disable_pipe(dev_priv, pipe);
|
||||
}
|
||||
|
||||
static void intel_crtc_init(struct drm_device *dev, int pipe)
|
||||
--
|
||||
1.7.6.5
|
||||
|
@ -1,35 +0,0 @@
|
||||
From 4a122c10fbfe9020df469f0f669da129c5757671 Mon Sep 17 00:00:00 2001
|
||||
From: Dan Rosenberg <drosenberg@vsecurity.com>
|
||||
Date: Thu, 17 Mar 2011 18:32:24 -0400
|
||||
Subject: [PATCH] ALSA: sound/pci/asihpi: check adapter index in hpi_ioctl
|
||||
Git-commit: 4a122c10fbfe9020df469f0f669da129c5757671
|
||||
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6.git
|
||||
Patch-mainline: 2.6.39-rc1
|
||||
References: bnc#680816
|
||||
|
||||
The user-supplied index into the adapters array needs to be checked, or
|
||||
an out-of-bounds kernel pointer could be accessed and used, leading to
|
||||
potentially exploitable memory corruption.
|
||||
|
||||
Signed-off-by: Dan Rosenberg <drosenberg@vsecurity.com>
|
||||
Cc: <stable@kernel.org>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
|
||||
---
|
||||
sound/pci/asihpi/hpioctl.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
--- a/sound/pci/asihpi/hpioctl.c
|
||||
+++ b/sound/pci/asihpi/hpioctl.c
|
||||
@@ -155,6 +155,11 @@
|
||||
goto out;
|
||||
}
|
||||
|
||||
+ if (hm->h.adapter_index >= HPI_MAX_ADAPTERS) {
|
||||
+ err = -EINVAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
pa = &adapters[hm->h.adapter_index];
|
||||
hr->h.size = 0;
|
||||
if (hm->h.object == HPI_OBJ_SUBSYSTEM) {
|
@ -1,96 +0,0 @@
|
||||
From c6b358748e19ce7e230b0926ac42696bc485a562 Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Mon, 28 Mar 2011 12:05:31 +0200
|
||||
Subject: [PATCH] ALSA: hda - Fix pin-config of Gigabyte mobo
|
||||
Git-commit: c6b358748e19ce7e230b0926ac42696bc485a562
|
||||
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6.git
|
||||
Patch-mainline: (to be) 2.6.39-rc2
|
||||
References: bnc#677256
|
||||
|
||||
Use pin-fix instead of the static quirk for Gigabyte mobos 1458:a002.
|
||||
|
||||
Bugzilla: https://bugzilla.novell.com/show_bug.cgi?id=677256
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
|
||||
---
|
||||
sound/pci/hda/patch_realtek.c | 21 ++++++++++++++++++---
|
||||
1 file changed, 18 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/sound/pci/hda/patch_realtek.c
|
||||
+++ b/sound/pci/hda/patch_realtek.c
|
||||
@@ -9932,7 +9932,6 @@ static struct snd_pci_quirk alc882_cfg_t
|
||||
SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
|
||||
SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
|
||||
SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
|
||||
- SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
|
||||
|
||||
SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
|
||||
SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
|
||||
@@ -10769,6 +10768,7 @@ enum {
|
||||
PINFIX_LENOVO_Y530,
|
||||
PINFIX_PB_M5210,
|
||||
PINFIX_ACER_ASPIRE_7736,
|
||||
+ PINFIX_GIGABYTE_880GM,
|
||||
};
|
||||
|
||||
static const struct alc_fixup alc882_fixups[] = {
|
||||
@@ -10800,6 +10800,13 @@ static const struct alc_fixup alc882_fix
|
||||
.type = ALC_FIXUP_SKU,
|
||||
.v.sku = ALC_FIXUP_SKU_IGNORE,
|
||||
},
|
||||
+ [PINFIX_GIGABYTE_880GM] = {
|
||||
+ .type = ALC_FIXUP_PINS,
|
||||
+ .v.pins = (const struct alc_pincfg[]) {
|
||||
+ { 0x14, 0x1114410 }, /* set as speaker */
|
||||
+ { }
|
||||
+ }
|
||||
+ },
|
||||
};
|
||||
|
||||
static struct snd_pci_quirk alc882_fixup_tbl[] = {
|
||||
@@ -10807,6 +10814,7 @@ static struct snd_pci_quirk alc882_fixup
|
||||
SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),
|
||||
SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
|
||||
SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
|
||||
+ SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte", PINFIX_GIGABYTE_880GM),
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -18851,8 +18859,6 @@ static struct snd_pci_quirk alc662_cfg_t
|
||||
ALC662_3ST_6ch_DIG),
|
||||
SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
|
||||
SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
|
||||
- SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
|
||||
- ALC662_3ST_6ch_DIG),
|
||||
SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
|
||||
SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
|
||||
SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
|
||||
@@ -19526,6 +19532,7 @@ enum {
|
||||
ALC662_FIXUP_IDEAPAD,
|
||||
ALC272_FIXUP_MARIO,
|
||||
ALC662_FIXUP_CZC_P10T,
|
||||
+ ALC662_FIXUP_GIGABYTE,
|
||||
};
|
||||
|
||||
static const struct alc_fixup alc662_fixups[] = {
|
||||
@@ -19554,12 +19561,20 @@ static const struct alc_fixup alc662_fix
|
||||
{}
|
||||
}
|
||||
},
|
||||
+ [ALC662_FIXUP_GIGABYTE] = {
|
||||
+ .type = ALC_FIXUP_PINS,
|
||||
+ .v.pins = (const struct alc_pincfg[]) {
|
||||
+ { 0x14, 0x1114410 }, /* set as speaker */
|
||||
+ { }
|
||||
+ }
|
||||
+ },
|
||||
};
|
||||
|
||||
static struct snd_pci_quirk alc662_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
|
||||
SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
|
||||
SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
|
||||
+ SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte", ALC662_FIXUP_GIGABYTE),
|
||||
SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
|
||||
SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
|
||||
SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
|
@ -1,22 +0,0 @@
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Subject: ALSA: hda - Increase the default buffer size
|
||||
Patch-mainline: Never
|
||||
References: 682725
|
||||
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
|
||||
---
|
||||
sound/pci/hda/hda_intel.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/sound/pci/hda/hda_intel.c
|
||||
+++ b/sound/pci/hda/hda_intel.c
|
||||
@@ -2057,7 +2057,7 @@
|
||||
/* buffer pre-allocation */
|
||||
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
|
||||
snd_dma_pci_data(chip->pci),
|
||||
- 1024 * 64, 32 * 1024 * 1024);
|
||||
+ 1024 * 1024, 32 * 1024 * 1024);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,40 +0,0 @@
|
||||
From: Brandon Philips <bphilips@suse.de>
|
||||
Subject: [PATCH] bnx2: entropy source
|
||||
Patch-mainline: never
|
||||
References: FATE#307517
|
||||
|
||||
Current disk-less systems have no entropy source whatsoever. Therefore, the
|
||||
network drivers tg3, bnx2, e1000, e1000e, igb and ixgbe should be enabled to
|
||||
feed entropy to the kernel via the IRQF_SAMPLE_RANDOM flag when loaded. This
|
||||
option shall not be enabled by default but implemented via a module option to
|
||||
be activated by the administrator.
|
||||
|
||||
Signed-off-by: Brandon Philips <bphilips@suse.de>
|
||||
|
||||
---
|
||||
drivers/net/bnx2.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
--- a/drivers/net/bnx2.c
|
||||
+++ b/drivers/net/bnx2.c
|
||||
@@ -84,6 +84,10 @@ MODULE_FIRMWARE(FW_MIPS_FILE_09);
|
||||
MODULE_FIRMWARE(FW_RV2P_FILE_09);
|
||||
MODULE_FIRMWARE(FW_RV2P_FILE_09_Ax);
|
||||
|
||||
+static int entropy = 0;
|
||||
+module_param(entropy, int, 0);
|
||||
+MODULE_PARM_DESC(entropy, "Allow bnx2 to populate the /dev/random entropy pool");
|
||||
+
|
||||
static int disable_msi = 0;
|
||||
|
||||
module_param(disable_msi, int, 0);
|
||||
@@ -6116,6 +6120,9 @@ bnx2_request_irq(struct bnx2 *bp)
|
||||
else
|
||||
flags = IRQF_SHARED;
|
||||
|
||||
+ if (entropy)
|
||||
+ flags |= IRQF_SAMPLE_RANDOM;
|
||||
+
|
||||
for (i = 0; i < bp->irq_nvecs; i++) {
|
||||
irq = &bp->irq_tbl[i];
|
||||
rc = request_irq(irq->vector, irq->handler, flags, irq->name,
|
@ -1,45 +0,0 @@
|
||||
From: Xiuling Ma <xma@us.ibm.com>
|
||||
Subject: [PATCH] disable catas_reset by default to avoid problems with EEH
|
||||
References: bnc#456389
|
||||
Patch-mainline: not yet
|
||||
|
||||
PPC machines with EEH and Mellanox ib/net cards with catastrophic error
|
||||
recovery that encounter a PCI bus error can crash and become
|
||||
unresponsive.
|
||||
|
||||
Disable the card reset to avoid this.
|
||||
|
||||
NOTE: an upstream fix will come later once IBM can review a couple of
|
||||
approaches I suggested since this fix is brute force. This driver didn't have
|
||||
this reset on error feature in SLES10 so it isn't a feature removal.
|
||||
|
||||
Signed-off-by: Xiuling Ma <xma@us.ibm.com>
|
||||
Acked-by: Brandon Philips <bphilips@suse.de>
|
||||
|
||||
---
|
||||
drivers/infiniband/hw/mthca/mthca_catas.c | 2 +-
|
||||
drivers/net/mlx4/catas.c | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/infiniband/hw/mthca/mthca_catas.c
|
||||
+++ b/drivers/infiniband/hw/mthca/mthca_catas.c
|
||||
@@ -51,7 +51,7 @@ static LIST_HEAD(catas_list);
|
||||
static struct workqueue_struct *catas_wq;
|
||||
static struct work_struct catas_work;
|
||||
|
||||
-static int catas_reset_disable;
|
||||
+static int catas_reset_disable = 1;
|
||||
module_param_named(catas_reset_disable, catas_reset_disable, int, 0644);
|
||||
MODULE_PARM_DESC(catas_reset_disable, "disable reset on catastrophic event if nonzero");
|
||||
|
||||
--- a/drivers/net/mlx4/catas.c
|
||||
+++ b/drivers/net/mlx4/catas.c
|
||||
@@ -44,7 +44,7 @@ static DEFINE_SPINLOCK(catas_lock);
|
||||
static LIST_HEAD(catas_list);
|
||||
static struct work_struct catas_work;
|
||||
|
||||
-static int internal_err_reset = 1;
|
||||
+static int internal_err_reset = 0;
|
||||
module_param(internal_err_reset, int, 0644);
|
||||
MODULE_PARM_DESC(internal_err_reset,
|
||||
"Reset device on internal errors if non-zero (default 1)");
|
@ -1,47 +0,0 @@
|
||||
From: Jiri Benc <jbenc@suse.cz>
|
||||
Subject: Enable e1000 as entropy source (disabled by default)
|
||||
References: FATE#307517
|
||||
Patch-mainline: never
|
||||
|
||||
Based on the patch by Oracle:
|
||||
|
||||
> e1000: Add IRQF_SAMPLE_RANDOM flag to e1000 as a module option
|
||||
>
|
||||
> This patch allows for the bnx2 to add to the /dev/random entropy pool
|
||||
> via a module parameter, entropy.
|
||||
>
|
||||
> 0 - default for EL5 - do not populate the entropy pool
|
||||
> 1 - optional - Uses IRQF_SAMPLE_RANDOM flag on request_irq calls to populate
|
||||
> the /dev/random pool
|
||||
>
|
||||
> Signed-off-by: John Sobecki <john.sobecki@oracle.com>
|
||||
|
||||
Signed-off-by: Brandon Philips <bphilips@suse.de>
|
||||
|
||||
---
|
||||
drivers/net/e1000/e1000_main.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
--- a/drivers/net/e1000/e1000_main.c
|
||||
+++ b/drivers/net/e1000/e1000_main.c
|
||||
@@ -213,6 +213,10 @@ static int debug = NETIF_MSG_DRV | NETIF
|
||||
module_param(debug, int, 0);
|
||||
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
|
||||
|
||||
+static int entropy = 0;
|
||||
+module_param(entropy, int, 0);
|
||||
+MODULE_PARM_DESC(entropy, "Allow e1000 to populate the /dev/random entropy pool");
|
||||
+
|
||||
/**
|
||||
* e1000_get_hw_dev - return device
|
||||
* used by hardware layer to print debugging information
|
||||
@@ -272,6 +276,9 @@ static int e1000_request_irq(struct e100
|
||||
int irq_flags = IRQF_SHARED;
|
||||
int err;
|
||||
|
||||
+ if (entropy)
|
||||
+ irq_flags |= IRQF_SAMPLE_RANDOM;
|
||||
+
|
||||
err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name,
|
||||
netdev);
|
||||
if (err) {
|
@ -1,86 +0,0 @@
|
||||
From: Jiri Benc <jbenc@suse.cz>
|
||||
Subject: Enable e1000e as entropy source (disabled by default)
|
||||
References: FATE#307517
|
||||
Patch-mainline: never
|
||||
|
||||
Current disk-less systems have no entropy source whatsoever. Therefore, the
|
||||
network drivers tg3, bnx2, e1000, e1000e, igb and ixgbe should be enabled to
|
||||
feed entropy to the kernel via the IRQF_SAMPLE_RANDOM flag when loaded. This
|
||||
option shall not be enabled by default but implemented via a module option to
|
||||
be activated by the administrator.
|
||||
|
||||
Signed-off-by: Brandon Philips <bphilips@suse.de>
|
||||
|
||||
---
|
||||
drivers/net/e1000e/e1000.h | 1 +
|
||||
drivers/net/e1000e/netdev.c | 14 +++++++++-----
|
||||
drivers/net/e1000e/param.c | 4 ++++
|
||||
3 files changed, 14 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/net/e1000e/e1000.h
|
||||
+++ b/drivers/net/e1000e/e1000.h
|
||||
@@ -467,6 +467,7 @@ extern void e1000e_reset_interrupt_capab
|
||||
extern void e1000e_disable_aspm(struct pci_dev *pdev, u16 state);
|
||||
|
||||
extern unsigned int copybreak;
|
||||
+extern int entropy;
|
||||
|
||||
extern char *e1000e_get_hw_dev_name(struct e1000_hw *hw);
|
||||
|
||||
--- a/drivers/net/e1000e/netdev.c
|
||||
+++ b/drivers/net/e1000e/netdev.c
|
||||
@@ -1847,8 +1847,8 @@ static int e1000_request_msix(struct e10
|
||||
else
|
||||
memcpy(adapter->rx_ring->name, netdev->name, IFNAMSIZ);
|
||||
err = request_irq(adapter->msix_entries[vector].vector,
|
||||
- e1000_intr_msix_rx, 0, adapter->rx_ring->name,
|
||||
- netdev);
|
||||
+ e1000_intr_msix_rx, entropy ? IRQF_SAMPLE_RANDOM : 0,
|
||||
+ adapter->rx_ring->name, netdev);
|
||||
if (err)
|
||||
goto out;
|
||||
adapter->rx_ring->itr_register = E1000_EITR_82574(vector);
|
||||
@@ -1889,6 +1889,7 @@ static int e1000_request_irq(struct e100
|
||||
{
|
||||
struct net_device *netdev = adapter->netdev;
|
||||
int err;
|
||||
+ int irq_flags = 0;
|
||||
|
||||
if (adapter->msix_entries) {
|
||||
err = e1000_request_msix(adapter);
|
||||
@@ -1900,7 +1901,8 @@ static int e1000_request_irq(struct e100
|
||||
e1000e_set_interrupt_capability(adapter);
|
||||
}
|
||||
if (adapter->flags & FLAG_MSI_ENABLED) {
|
||||
- err = request_irq(adapter->pdev->irq, e1000_intr_msi, 0,
|
||||
+ err = request_irq(adapter->pdev->irq, e1000_intr_msi,
|
||||
+ entropy ? IRQF_SAMPLE_RANDOM : 0,
|
||||
netdev->name, netdev);
|
||||
if (!err)
|
||||
return err;
|
||||
@@ -1910,8 +1912,10 @@ static int e1000_request_irq(struct e100
|
||||
adapter->int_mode = E1000E_INT_MODE_LEGACY;
|
||||
}
|
||||
|
||||
- err = request_irq(adapter->pdev->irq, e1000_intr, IRQF_SHARED,
|
||||
- netdev->name, netdev);
|
||||
+ if (entropy)
|
||||
+ irq_flags |= IRQF_SAMPLE_RANDOM;
|
||||
+ err = request_irq(adapter->pdev->irq, e1000_intr,
|
||||
+ irq_flags | IRQF_SHARED, netdev->name, netdev);
|
||||
if (err)
|
||||
e_err("Unable to allocate interrupt, Error: %d\n", err);
|
||||
|
||||
--- a/drivers/net/e1000e/param.c
|
||||
+++ b/drivers/net/e1000e/param.c
|
||||
@@ -31,6 +31,10 @@
|
||||
|
||||
#include "e1000.h"
|
||||
|
||||
+int entropy = 0;
|
||||
+module_param(entropy, int, 0);
|
||||
+MODULE_PARM_DESC(entropy, "Allow e1000e to populate the /dev/random entropy pool");
|
||||
+
|
||||
/*
|
||||
* This is the only thing that needs to be changed to adjust the
|
||||
* maximum number of ports that the driver can manage.
|
@ -1,43 +0,0 @@
|
||||
Subject: add alias entry for portN properties
|
||||
From: olh@suse.de
|
||||
References: 435215 - LTC48564
|
||||
Patch-mainline: not yet
|
||||
|
||||
Use separate table for alias entries in the ehea module,
|
||||
otherwise the probe() function will operate on the separate ports
|
||||
instead of the lhea-"root" entry of the device-tree
|
||||
|
||||
---
|
||||
drivers/net/ehea/ehea_main.c | 14 +++++++++++++-
|
||||
1 file changed, 13 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/ehea/ehea_main.c
|
||||
+++ b/drivers/net/ehea/ehea_main.c
|
||||
@@ -112,6 +112,19 @@ static int __devinit ehea_probe_adapter(
|
||||
|
||||
static int __devexit ehea_remove(struct platform_device *dev);
|
||||
|
||||
+static struct of_device_id ehea_module_device_table[] = {
|
||||
+ {
|
||||
+ .name = "lhea",
|
||||
+ .compatible = "IBM,lhea",
|
||||
+ },
|
||||
+ {
|
||||
+ .type = "network",
|
||||
+ .compatible = "IBM,lhea-ethernet",
|
||||
+ },
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, ehea_module_device_table);
|
||||
+
|
||||
static struct of_device_id ehea_device_table[] = {
|
||||
{
|
||||
.name = "lhea",
|
||||
@@ -119,7 +132,6 @@ static struct of_device_id ehea_device_t
|
||||
},
|
||||
{},
|
||||
};
|
||||
-MODULE_DEVICE_TABLE(of, ehea_device_table);
|
||||
|
||||
static struct of_platform_driver ehea_driver = {
|
||||
.driver = {
|
@ -1,380 +0,0 @@
|
||||
From: Jiri Kosina <jkosina@suse.cz>
|
||||
Subject: Elo USB touchscreen driver
|
||||
Patch-mainline: will be submitted for 2.6.28
|
||||
References: FATE#304972
|
||||
|
||||
This is a driver for Elo USB touchscreen devices.
|
||||
|
||||
Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>
|
||||
Acked-by: Jiri Kosina <jkosina@suse.cz>
|
||||
|
||||
---
|
||||
drivers/hid/hid-core.c | 2
|
||||
drivers/hid/hid-ids.h | 2
|
||||
drivers/input/touchscreen/Kconfig | 12 +
|
||||
drivers/input/touchscreen/Makefile | 1
|
||||
drivers/input/touchscreen/elousb.c | 305 +++++++++++++++++++++++++++++++++++++
|
||||
5 files changed, 322 insertions(+)
|
||||
|
||||
--- a/drivers/hid/hid-core.c
|
||||
+++ b/drivers/hid/hid-core.c
|
||||
@@ -1643,6 +1643,8 @@ static const struct hid_device_id hid_ig
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY, 0x0004) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_4000U) },
|
||||
+ { HID_USB_DEVICE(USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_4500U) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC5UH) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC4UM) },
|
||||
--- a/drivers/hid/hid-ids.h
|
||||
+++ b/drivers/hid/hid-ids.h
|
||||
@@ -216,7 +216,9 @@
|
||||
#define USB_VENDOR_ID_DREAM_CHEEKY 0x1d34
|
||||
|
||||
#define USB_VENDOR_ID_ELO 0x04E7
|
||||
+#define USB_DEVICE_ID_ELO_4000U 0x0009
|
||||
#define USB_DEVICE_ID_ELO_TS2700 0x0020
|
||||
+#define USB_DEVICE_ID_ELO_4500U 0x0030
|
||||
|
||||
#define USB_VENDOR_ID_EMS 0x2006
|
||||
#define USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II 0x0118
|
||||
--- a/drivers/input/touchscreen/Kconfig
|
||||
+++ b/drivers/input/touchscreen/Kconfig
|
||||
@@ -214,6 +214,18 @@ config TOUCHSCREEN_ELO
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called elo.
|
||||
|
||||
+config TOUCHSCREEN_ELOUSB
|
||||
+ tristate "Elo USB touchscreens"
|
||||
+ select USB
|
||||
+ help
|
||||
+ Say Y here if you have an Elo USB touchscreen connected to
|
||||
+ your system.
|
||||
+
|
||||
+ If unsure, say N.
|
||||
+
|
||||
+ To compile this driver as a module, choose M here: the
|
||||
+ module will be called elousb.
|
||||
+
|
||||
config TOUCHSCREEN_WACOM_W8001
|
||||
tristate "Wacom W8001 penabled serial touchscreen"
|
||||
select SERIO
|
||||
--- a/drivers/input/touchscreen/Makefile
|
||||
+++ b/drivers/input/touchscreen/Makefile
|
||||
@@ -22,6 +22,7 @@ obj-$(CONFIG_TOUCHSCREEN_HAMPSHIRE) += h
|
||||
obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o
|
||||
+obj-$(CONFIG_TOUCHSCREEN_ELOUSB) += elousb.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_INTEL_MID) += intel-mid-touch.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/input/touchscreen/elousb.c
|
||||
@@ -0,0 +1,305 @@
|
||||
+/*
|
||||
+ * Copyright (c) 1999-2001 Vojtech Pavlik
|
||||
+ *
|
||||
+ * Elo USB touchscreen support
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation; either version 2 of the License.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
+ *
|
||||
+ * Should you need to contact me, the author, you can do so either by
|
||||
+ * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
|
||||
+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
|
||||
+ */
|
||||
+
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/usb.h>
|
||||
+#include <linux/usb/input.h>
|
||||
+#include <linux/hid.h>
|
||||
+#include <linux/input.h>
|
||||
+
|
||||
+/*
|
||||
+ * Version Information
|
||||
+ */
|
||||
+#define DRIVER_VERSION "v1.1"
|
||||
+#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@suse.cz>"
|
||||
+#define DRIVER_DESC "Elo USB touchscreen driver"
|
||||
+#define DRIVER_LICENSE "GPL"
|
||||
+
|
||||
+MODULE_AUTHOR(DRIVER_AUTHOR);
|
||||
+MODULE_DESCRIPTION(DRIVER_DESC);
|
||||
+MODULE_LICENSE(DRIVER_LICENSE);
|
||||
+
|
||||
+struct elousb {
|
||||
+ char name[128];
|
||||
+ char phys[64];
|
||||
+ struct usb_device *usbdev;
|
||||
+ struct input_dev *dev;
|
||||
+ struct urb *irq;
|
||||
+
|
||||
+ unsigned char *data;
|
||||
+ dma_addr_t data_dma;
|
||||
+};
|
||||
+
|
||||
+static void elousb_irq(struct urb *urb)
|
||||
+{
|
||||
+ struct elousb *elo = urb->context;
|
||||
+ unsigned char *data = elo->data;
|
||||
+ struct input_dev *dev = elo->dev;
|
||||
+ int status;
|
||||
+
|
||||
+ switch (urb->status) {
|
||||
+ case 0: /* success */
|
||||
+ break;
|
||||
+ case -ECONNRESET: /* unlink */
|
||||
+ case -ENOENT:
|
||||
+ case -ESHUTDOWN:
|
||||
+ return;
|
||||
+ /* -EPIPE: should clear the halt */
|
||||
+ default: /* error */
|
||||
+ goto resubmit;
|
||||
+ }
|
||||
+
|
||||
+ if (data[0] != 'T') /* Mandatory ELO packet marker */
|
||||
+ return;
|
||||
+
|
||||
+
|
||||
+ input_report_abs(dev, ABS_X, ((u32)data[3] << 8) | data[2]);
|
||||
+ input_report_abs(dev, ABS_Y, ((u32)data[5] << 8) | data[4]);
|
||||
+
|
||||
+ input_report_abs(dev, ABS_PRESSURE,
|
||||
+ (data[1] & 0x80) ? (((u32)data[7] << 8) | data[6]): 0);
|
||||
+
|
||||
+ if (data[1] & 0x03) {
|
||||
+ input_report_key(dev, BTN_TOUCH, 1);
|
||||
+ input_sync(dev);
|
||||
+ }
|
||||
+
|
||||
+ if (data[1] & 0x04)
|
||||
+ input_report_key(dev, BTN_TOUCH, 0);
|
||||
+
|
||||
+ input_sync(dev);
|
||||
+
|
||||
+resubmit:
|
||||
+ status = usb_submit_urb (urb, GFP_ATOMIC);
|
||||
+ if (status)
|
||||
+ err ("can't resubmit intr, %s-%s/input0, status %d",
|
||||
+ elo->usbdev->bus->bus_name,
|
||||
+ elo->usbdev->devpath, status);
|
||||
+}
|
||||
+
|
||||
+static int elousb_open(struct input_dev *dev)
|
||||
+{
|
||||
+ struct elousb *elo = input_get_drvdata(dev);
|
||||
+
|
||||
+ elo->irq->dev = elo->usbdev;
|
||||
+ if (usb_submit_urb(elo->irq, GFP_KERNEL))
|
||||
+ return -EIO;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void elousb_close(struct input_dev *dev)
|
||||
+{
|
||||
+ struct elousb *elo = input_get_drvdata(dev);
|
||||
+
|
||||
+ usb_kill_urb(elo->irq);
|
||||
+}
|
||||
+
|
||||
+static int elousb_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
||||
+{
|
||||
+ struct usb_device *dev = interface_to_usbdev(intf);
|
||||
+ struct usb_host_interface *interface;
|
||||
+ struct usb_endpoint_descriptor *endpoint;
|
||||
+ struct hid_descriptor *hdesc;
|
||||
+ struct elousb *elo;
|
||||
+ struct input_dev *input_dev;
|
||||
+ int pipe, i;
|
||||
+ unsigned int rsize = 0;
|
||||
+ int error = -ENOMEM;
|
||||
+ char *rdesc;
|
||||
+
|
||||
+ interface = intf->cur_altsetting;
|
||||
+
|
||||
+ if (interface->desc.bNumEndpoints != 1)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ endpoint = &interface->endpoint[0].desc;
|
||||
+ if (!(endpoint->bEndpointAddress & USB_DIR_IN))
|
||||
+ return -ENODEV;
|
||||
+ if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) &&
|
||||
+ (!interface->desc.bNumEndpoints ||
|
||||
+ usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) {
|
||||
+ err("HID class descriptor not present");
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < hdesc->bNumDescriptors; i++)
|
||||
+ if (hdesc->desc[i].bDescriptorType == HID_DT_REPORT)
|
||||
+ rsize = le16_to_cpu(hdesc->desc[i].wDescriptorLength);
|
||||
+
|
||||
+ if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) {
|
||||
+ err("weird size of report descriptor (%u)", rsize);
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
|
||||
+
|
||||
+ elo = kzalloc(sizeof(struct elousb), GFP_KERNEL);
|
||||
+ input_dev = input_allocate_device();
|
||||
+ if (!elo || !input_dev)
|
||||
+ goto fail1;
|
||||
+
|
||||
+ elo->data = usb_buffer_alloc(dev, 8, GFP_ATOMIC, &elo->data_dma);
|
||||
+ if (!elo->data)
|
||||
+ goto fail1;
|
||||
+
|
||||
+ elo->irq = usb_alloc_urb(0, GFP_KERNEL);
|
||||
+ if (!elo->irq)
|
||||
+ goto fail2;
|
||||
+
|
||||
+ if (!(rdesc = kmalloc(rsize, GFP_KERNEL)))
|
||||
+ goto fail3;
|
||||
+
|
||||
+ elo->usbdev = dev;
|
||||
+ elo->dev = input_dev;
|
||||
+
|
||||
+ if ((error = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
|
||||
+ HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0,
|
||||
+ interface->desc.bInterfaceNumber,
|
||||
+ NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0) {
|
||||
+ err("setting HID idle timeout failed, error %d", error);
|
||||
+ error = -ENODEV;
|
||||
+ goto fail4;
|
||||
+ }
|
||||
+
|
||||
+ if ((error = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
|
||||
+ USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN,
|
||||
+ HID_DT_REPORT << 8, interface->desc.bInterfaceNumber,
|
||||
+ rdesc, rsize, USB_CTRL_GET_TIMEOUT)) < rsize) {
|
||||
+ err("reading HID report descriptor failed, error %d", error);
|
||||
+ error = -ENODEV;
|
||||
+ goto fail4;
|
||||
+ }
|
||||
+
|
||||
+ if (dev->manufacturer)
|
||||
+ strlcpy(elo->name, dev->manufacturer, sizeof(elo->name));
|
||||
+
|
||||
+ if (dev->product) {
|
||||
+ if (dev->manufacturer)
|
||||
+ strlcat(elo->name, " ", sizeof(elo->name));
|
||||
+ strlcat(elo->name, dev->product, sizeof(elo->name));
|
||||
+ }
|
||||
+
|
||||
+ if (!strlen(elo->name))
|
||||
+ snprintf(elo->name, sizeof(elo->name),
|
||||
+ "Elo touchscreen %04x:%04x",
|
||||
+ le16_to_cpu(dev->descriptor.idVendor),
|
||||
+ le16_to_cpu(dev->descriptor.idProduct));
|
||||
+
|
||||
+ usb_make_path(dev, elo->phys, sizeof(elo->phys));
|
||||
+ strlcat(elo->phys, "/input0", sizeof(elo->phys));
|
||||
+
|
||||
+ input_dev->name = elo->name;
|
||||
+ input_dev->phys = elo->phys;
|
||||
+ usb_to_input_id(dev, &input_dev->id);
|
||||
+ input_dev->dev.parent = &intf->dev;
|
||||
+
|
||||
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
|
||||
+ set_bit(BTN_TOUCH, input_dev->keybit);
|
||||
+ input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
|
||||
+ set_bit(ABS_PRESSURE, input_dev->absbit);
|
||||
+
|
||||
+ input_set_abs_params(input_dev, ABS_X, 0, 4000, 0, 0);
|
||||
+ input_set_abs_params(input_dev, ABS_Y, 0, 3840, 0, 0);
|
||||
+ input_set_abs_params(input_dev, ABS_PRESSURE, 0, 256, 0, 0);
|
||||
+
|
||||
+ input_set_drvdata(input_dev, elo);
|
||||
+
|
||||
+ input_dev->open = elousb_open;
|
||||
+ input_dev->close = elousb_close;
|
||||
+
|
||||
+ usb_fill_int_urb(elo->irq, dev, pipe, elo->data, 8,
|
||||
+ elousb_irq, elo, endpoint->bInterval);
|
||||
+ elo->irq->transfer_dma = elo->data_dma;
|
||||
+ elo->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
|
||||
+
|
||||
+ input_register_device(elo->dev);
|
||||
+
|
||||
+ usb_set_intfdata(intf, elo);
|
||||
+ return 0;
|
||||
+
|
||||
+fail4:
|
||||
+ kfree(rdesc);
|
||||
+fail3:
|
||||
+ usb_free_urb(elo->irq);
|
||||
+fail2:
|
||||
+ usb_buffer_free(dev, 8, elo->data, elo->data_dma);
|
||||
+fail1:
|
||||
+ input_free_device(input_dev);
|
||||
+ kfree(elo);
|
||||
+ return -ENOMEM;
|
||||
+}
|
||||
+
|
||||
+static void elousb_disconnect(struct usb_interface *intf)
|
||||
+{
|
||||
+ struct elousb *elo = usb_get_intfdata (intf);
|
||||
+
|
||||
+ usb_set_intfdata(intf, NULL);
|
||||
+ if (elo) {
|
||||
+ usb_kill_urb(elo->irq);
|
||||
+ input_unregister_device(elo->dev);
|
||||
+ usb_free_urb(elo->irq);
|
||||
+ usb_buffer_free(interface_to_usbdev(intf), 8, elo->data, elo->data_dma);
|
||||
+ kfree(elo);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static struct usb_device_id elousb_id_table [] = {
|
||||
+ { USB_DEVICE(0x04e7, 0x0009) }, /* CarrolTouch 4000U */
|
||||
+ { USB_DEVICE(0x04e7, 0x0030) }, /* CarrolTouch 4500U */
|
||||
+ { } /* Terminating entry */
|
||||
+};
|
||||
+
|
||||
+MODULE_DEVICE_TABLE (usb, elousb_id_table);
|
||||
+
|
||||
+static struct usb_driver elousb_driver = {
|
||||
+ .name = "elousb",
|
||||
+ .probe = elousb_probe,
|
||||
+ .disconnect = elousb_disconnect,
|
||||
+ .id_table = elousb_id_table,
|
||||
+};
|
||||
+
|
||||
+static int __init elousb_init(void)
|
||||
+{
|
||||
+ int retval = usb_register(&elousb_driver);
|
||||
+ if (retval == 0)
|
||||
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" DRIVER_DESC);
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
+static void __exit elousb_exit(void)
|
||||
+{
|
||||
+ usb_deregister(&elousb_driver);
|
||||
+}
|
||||
+
|
||||
+module_init(elousb_init);
|
||||
+module_exit(elousb_exit);
|
@ -1,70 +0,0 @@
|
||||
From: Jiri Benc <jbenc@suse.cz>
|
||||
Subject: Enable igb as entropy source (disabled by default)
|
||||
References: FATE#307517
|
||||
Patch-mainline: never
|
||||
|
||||
Current disk-less systems have no entropy source whatsoever. Therefore, the
|
||||
network drivers tg3, bnx2, e1000, e1000e, igb and ixgbe should be enabled to
|
||||
feed entropy to the kernel via the IRQF_SAMPLE_RANDOM flag when loaded. This
|
||||
option shall not be enabled by default but implemented via a module option to
|
||||
be activated by the administrator.
|
||||
|
||||
Signed-off-by: Brandon Philips <bphilips@suse.de>
|
||||
|
||||
---
|
||||
drivers/net/igb/igb_main.c | 16 +++++++++++++---
|
||||
1 file changed, 13 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/igb/igb_main.c
|
||||
+++ b/drivers/net/igb/igb_main.c
|
||||
@@ -61,6 +61,10 @@ static const struct e1000_info *igb_info
|
||||
[board_82575] = &e1000_82575_info,
|
||||
};
|
||||
|
||||
+static int entropy = 0;
|
||||
+module_param(entropy, int, 0);
|
||||
+MODULE_PARM_DESC(entropy, "Allow igb to populate the /dev/random entropy pool");
|
||||
+
|
||||
static DEFINE_PCI_DEVICE_TABLE(igb_pci_tbl) = {
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_I350_COPPER), board_82575 },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_I350_FIBER), board_82575 },
|
||||
@@ -897,7 +901,8 @@ static int igb_request_msix(struct igb_a
|
||||
int i, err = 0, vector = 0;
|
||||
|
||||
err = request_irq(adapter->msix_entries[vector].vector,
|
||||
- igb_msix_other, 0, netdev->name, adapter);
|
||||
+ igb_msix_other, entropy ? IRQF_SAMPLE_RANDOM : 0,
|
||||
+ netdev->name, adapter);
|
||||
if (err)
|
||||
goto out;
|
||||
vector++;
|
||||
@@ -1194,6 +1199,10 @@ static int igb_request_irq(struct igb_ad
|
||||
struct net_device *netdev = adapter->netdev;
|
||||
struct pci_dev *pdev = adapter->pdev;
|
||||
int err = 0;
|
||||
+ int irq_flags = 0;
|
||||
+
|
||||
+ if (entropy)
|
||||
+ irq_flags = IRQF_SAMPLE_RANDOM;
|
||||
|
||||
if (adapter->msix_entries) {
|
||||
err = igb_request_msix(adapter);
|
||||
@@ -1228,7 +1237,7 @@ static int igb_request_irq(struct igb_ad
|
||||
}
|
||||
|
||||
if (adapter->flags & IGB_FLAG_HAS_MSI) {
|
||||
- err = request_irq(adapter->pdev->irq, igb_intr_msi, 0,
|
||||
+ err = request_irq(adapter->pdev->irq, igb_intr_msi, irq_flags,
|
||||
netdev->name, adapter);
|
||||
if (!err)
|
||||
goto request_done;
|
||||
@@ -1238,7 +1247,8 @@ static int igb_request_irq(struct igb_ad
|
||||
adapter->flags &= ~IGB_FLAG_HAS_MSI;
|
||||
}
|
||||
|
||||
- err = request_irq(adapter->pdev->irq, igb_intr, IRQF_SHARED,
|
||||
+ irq_flags |= IRQF_SHARED;
|
||||
+ err = request_irq(adapter->pdev->irq, igb_intr, irq_flags,
|
||||
netdev->name, adapter);
|
||||
|
||||
if (err)
|
@ -1,218 +0,0 @@
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Subject: [PATCH 2/2] input: Add LED support to Synaptics device
|
||||
Patch-mainline: Submitted
|
||||
References: bnc#547370,bnc#582529,bnc#589014
|
||||
|
||||
The new Synaptics devices have an LED on the top-left corner.
|
||||
This patch adds a new LED class device to control it. It's created
|
||||
dynamically upon synaptics device probing.
|
||||
|
||||
The LED is controlled via the command 0x0a with parameters 0x88 or 0x10.
|
||||
This seems only on/off control although other value might be accepted.
|
||||
|
||||
The detection of the LED isn't clear yet. It should have been the new
|
||||
capability bits that indicate the presence, but on real machines, it
|
||||
doesn't fit. So, for the time being, the driver checks the product id
|
||||
in the ext capability bits and assumes that LED exists on the known
|
||||
devices.
|
||||
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
|
||||
---
|
||||
drivers/input/mouse/Kconfig | 9 +++
|
||||
drivers/input/mouse/synaptics.c | 111 ++++++++++++++++++++++++++++++++++++++++
|
||||
drivers/input/mouse/synaptics.h | 3 +
|
||||
3 files changed, 123 insertions(+)
|
||||
|
||||
--- a/drivers/input/mouse/Kconfig
|
||||
+++ b/drivers/input/mouse/Kconfig
|
||||
@@ -19,6 +19,7 @@ config MOUSE_PS2
|
||||
select SERIO_LIBPS2
|
||||
select SERIO_I8042 if X86
|
||||
select SERIO_GSCPS2 if GSC
|
||||
+ select LEDS_CLASS if MOUSE_PS2_SYNAPICS_LED
|
||||
help
|
||||
Say Y here if you have a PS/2 mouse connected to your system. This
|
||||
includes the standard 2 or 3-button PS/2 mouse, as well as PS/2
|
||||
@@ -67,6 +68,14 @@ config MOUSE_PS2_SYNAPTICS
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
+config MOUSE_PS2_SYNAPTICS_LED
|
||||
+ bool "Support embedded LED on Synaptics devices"
|
||||
+ depends on MOUSE_PS2_SYNAPTICS
|
||||
+ select NEW_LEDS
|
||||
+ help
|
||||
+ Say Y here if you have a Synaptics device with an embedded LED.
|
||||
+ This will enable LED class driver to control the LED device.
|
||||
+
|
||||
config MOUSE_PS2_LIFEBOOK
|
||||
bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EXPERT
|
||||
default y
|
||||
--- a/drivers/input/mouse/synaptics.c
|
||||
+++ b/drivers/input/mouse/synaptics.c
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <linux/input/mt.h>
|
||||
#include <linux/serio.h>
|
||||
#include <linux/libps2.h>
|
||||
+#include <linux/leds.h>
|
||||
#include <linux/slab.h>
|
||||
#include "psmouse.h"
|
||||
#include "synaptics.h"
|
||||
@@ -353,6 +354,110 @@ static void synaptics_pt_create(struct p
|
||||
serio_register_port(serio);
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_MOUSE_PS2_SYNAPTICS_LED
|
||||
+/*
|
||||
+ * LED handling:
|
||||
+ * Some Synaptics devices have an embeded LED at the top-left corner.
|
||||
+ */
|
||||
+
|
||||
+struct synaptics_led {
|
||||
+ struct psmouse *psmouse;
|
||||
+ struct work_struct work;
|
||||
+ struct led_classdev cdev;
|
||||
+};
|
||||
+
|
||||
+static void synaptics_set_led(struct psmouse *psmouse, int on)
|
||||
+{
|
||||
+ int i;
|
||||
+ unsigned char cmd = on ? 0x88 : 0x10;
|
||||
+
|
||||
+ ps2_begin_command(&psmouse->ps2dev);
|
||||
+ if (__ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11))
|
||||
+ goto out;
|
||||
+ for (i = 6; i >= 0; i -= 2) {
|
||||
+ unsigned char d = (cmd >> i) & 3;
|
||||
+ if (__ps2_command(&psmouse->ps2dev, &d, PSMOUSE_CMD_SETRES))
|
||||
+ goto out;
|
||||
+ }
|
||||
+ cmd = 0x0a;
|
||||
+ __ps2_command(&psmouse->ps2dev, &cmd, PSMOUSE_CMD_SETRATE);
|
||||
+ out:
|
||||
+ ps2_end_command(&psmouse->ps2dev);
|
||||
+}
|
||||
+
|
||||
+static void synaptics_led_work(struct work_struct *work)
|
||||
+{
|
||||
+ struct synaptics_led *led;
|
||||
+
|
||||
+ led = container_of(work, struct synaptics_led, work);
|
||||
+ synaptics_set_led(led->psmouse, led->cdev.brightness);
|
||||
+}
|
||||
+
|
||||
+static void synaptics_led_cdev_brightness_set(struct led_classdev *cdev,
|
||||
+ enum led_brightness value)
|
||||
+{
|
||||
+ struct synaptics_led *led;
|
||||
+
|
||||
+ led = container_of(cdev, struct synaptics_led, cdev);
|
||||
+ schedule_work(&led->work);
|
||||
+}
|
||||
+
|
||||
+static void synaptics_sync_led(struct psmouse *psmouse)
|
||||
+{
|
||||
+ struct synaptics_data *priv = psmouse->private;
|
||||
+
|
||||
+ if (priv->led)
|
||||
+ synaptics_set_led(psmouse, priv->led->cdev.brightness);
|
||||
+}
|
||||
+
|
||||
+static int synaptics_init_led(struct psmouse *psmouse)
|
||||
+{
|
||||
+ struct synaptics_data *priv = psmouse->private;
|
||||
+ struct synaptics_led *led;
|
||||
+ int err;
|
||||
+
|
||||
+ /* FIXME: LED is supposedly detectable in cap0c[1] 0x20, but it seems
|
||||
+ * not working on real machines.
|
||||
+ * So we check the product id to be sure.
|
||||
+ */
|
||||
+ if (!priv->ext_cap_0c || SYN_CAP_PRODUCT_ID(priv->ext_cap) != 0xe4)
|
||||
+ return 0;
|
||||
+
|
||||
+ printk(KERN_INFO "synaptics: support LED control\n");
|
||||
+ led = kzalloc(sizeof(struct synaptics_led), GFP_KERNEL);
|
||||
+ if (!led)
|
||||
+ return -ENOMEM;
|
||||
+ led->psmouse = psmouse;
|
||||
+ INIT_WORK(&led->work, synaptics_led_work);
|
||||
+ led->cdev.name = "psmouse::synaptics";
|
||||
+ led->cdev.brightness_set = synaptics_led_cdev_brightness_set;
|
||||
+ led->cdev.flags = LED_CORE_SUSPENDRESUME;
|
||||
+ err = led_classdev_register(NULL, &led->cdev);
|
||||
+ if (err < 0) {
|
||||
+ kfree(led);
|
||||
+ return err;
|
||||
+ }
|
||||
+ priv->led = led;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void synaptics_free_led(struct psmouse *psmouse)
|
||||
+{
|
||||
+ struct synaptics_data *priv = psmouse->private;
|
||||
+
|
||||
+ if (!priv->led)
|
||||
+ return;
|
||||
+ cancel_work_sync(&priv->led->work);
|
||||
+ synaptics_set_led(psmouse, 0);
|
||||
+ led_classdev_unregister(&priv->led->cdev);
|
||||
+ kfree(priv->led);
|
||||
+}
|
||||
+#else
|
||||
+#define synaptics_init_led(ps) 0
|
||||
+#define synaptics_free_led(ps) do {} while (0)
|
||||
+#define synaptics_sync_led(ps) do {} while (0)
|
||||
+#endif
|
||||
+
|
||||
/*****************************************************************************
|
||||
* Functions to interpret the absolute mode packets
|
||||
****************************************************************************/
|
||||
@@ -647,6 +752,7 @@ static void set_input_params(struct inpu
|
||||
|
||||
static void synaptics_disconnect(struct psmouse *psmouse)
|
||||
{
|
||||
+ synaptics_free_led(psmouse);
|
||||
synaptics_reset(psmouse);
|
||||
kfree(psmouse->private);
|
||||
psmouse->private = NULL;
|
||||
@@ -678,6 +784,8 @@ static int synaptics_reconnect(struct ps
|
||||
return -1;
|
||||
}
|
||||
|
||||
+ synaptics_sync_led(psmouse);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -752,6 +860,9 @@ int synaptics_init(struct psmouse *psmou
|
||||
SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity),
|
||||
priv->model_id, priv->capabilities, priv->ext_cap, priv->ext_cap_0c);
|
||||
|
||||
+ if (synaptics_init_led(psmouse) < 0)
|
||||
+ goto init_fail;
|
||||
+
|
||||
set_input_params(psmouse->dev, priv);
|
||||
|
||||
/*
|
||||
--- a/drivers/input/mouse/synaptics.h
|
||||
+++ b/drivers/input/mouse/synaptics.h
|
||||
@@ -97,6 +97,8 @@ struct synaptics_hw_state {
|
||||
signed char scroll;
|
||||
};
|
||||
|
||||
+struct synaptics_led;
|
||||
+
|
||||
struct synaptics_data {
|
||||
/* Data read from the touchpad */
|
||||
unsigned long int model_id; /* Model-ID */
|
||||
@@ -110,6 +112,7 @@ struct synaptics_data {
|
||||
struct serio *pt_port; /* Pass-through serio port */
|
||||
|
||||
struct synaptics_hw_state mt; /* current gesture packet */
|
||||
+ struct synaptics_led *led;
|
||||
};
|
||||
|
||||
void synaptics_module_init(void);
|
@ -1,90 +0,0 @@
|
||||
From: Jiri Benc <jbenc@suse.cz>
|
||||
Subject: Enable ixgbe as entropy source (disabled by default)
|
||||
References: FATE#307517
|
||||
Patch-mainline: never
|
||||
|
||||
Current disk-less systems have no entropy source whatsoever. Therefore, the
|
||||
network drivers tg3, bnx2, e1000, e1000e, igb and ixgbe should be enabled to
|
||||
feed entropy to the kernel via the IRQF_SAMPLE_RANDOM flag when loaded. This
|
||||
option shall not be enabled by default but implemented via a module option to
|
||||
be activated by the administrator.
|
||||
|
||||
Signed-off-by: Brandon Philips <bphilips@suse.de>
|
||||
|
||||
---
|
||||
drivers/net/ixgbe/ixgbe_main.c | 22 +++++++++++++++++++---
|
||||
1 file changed, 19 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/ixgbe/ixgbe_main.c
|
||||
+++ b/drivers/net/ixgbe/ixgbe_main.c
|
||||
@@ -56,6 +56,11 @@ static const char ixgbe_driver_string[]
|
||||
const char ixgbe_driver_version[] = DRV_VERSION;
|
||||
static char ixgbe_copyright[] = "Copyright (c) 1999-2010 Intel Corporation.";
|
||||
|
||||
+static int entropy = 0;
|
||||
+module_param(entropy, int, 0);
|
||||
+MODULE_PARM_DESC(entropy, "Allow ixgbe to populate the /dev/random entropy pool");
|
||||
+
|
||||
+
|
||||
static const struct ixgbe_info *ixgbe_info_tbl[] = {
|
||||
[board_82598] = &ixgbe_82598_info,
|
||||
[board_82599] = &ixgbe_82599_info,
|
||||
@@ -2317,6 +2322,7 @@ static int ixgbe_request_msix_irqs(struc
|
||||
irqreturn_t (*handler)(int, void *);
|
||||
int i, vector, q_vectors, err;
|
||||
int ri = 0, ti = 0;
|
||||
+ int irq_flags;
|
||||
|
||||
/* Decrement for Other and TCP Timer vectors */
|
||||
q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
|
||||
@@ -2334,22 +2340,27 @@ static int ixgbe_request_msix_irqs(struc
|
||||
struct ixgbe_q_vector *q_vector = adapter->q_vector[vector];
|
||||
handler = SET_HANDLER(q_vector);
|
||||
|
||||
+ irq_flags = 0;
|
||||
if (handler == &ixgbe_msix_clean_rx) {
|
||||
snprintf(q_vector->name, sizeof(q_vector->name) - 1,
|
||||
"%s-%s-%d", netdev->name, "rx", ri++);
|
||||
+ if (entropy)
|
||||
+ irq_flags = IRQF_SAMPLE_RANDOM;
|
||||
} else if (handler == &ixgbe_msix_clean_tx) {
|
||||
snprintf(q_vector->name, sizeof(q_vector->name) - 1,
|
||||
"%s-%s-%d", netdev->name, "tx", ti++);
|
||||
} else if (handler == &ixgbe_msix_clean_many) {
|
||||
snprintf(q_vector->name, sizeof(q_vector->name) - 1,
|
||||
"%s-%s-%d", netdev->name, "TxRx", ri++);
|
||||
+ if (entropy)
|
||||
+ irq_flags = IRQF_SAMPLE_RANDOM;
|
||||
ti++;
|
||||
} else {
|
||||
/* skip this unused q_vector */
|
||||
continue;
|
||||
}
|
||||
err = request_irq(adapter->msix_entries[vector].vector,
|
||||
- handler, 0, q_vector->name,
|
||||
+ handler, irq_flags, q_vector->name,
|
||||
q_vector);
|
||||
if (err) {
|
||||
e_err(probe, "request_irq failed for MSIX interrupt "
|
||||
@@ -2563,14 +2574,19 @@ static int ixgbe_request_irq(struct ixgb
|
||||
{
|
||||
struct net_device *netdev = adapter->netdev;
|
||||
int err;
|
||||
+ int irq_flags = 0;
|
||||
+
|
||||
+ if (entropy)
|
||||
+ irq_flags = IRQF_SAMPLE_RANDOM;
|
||||
|
||||
if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
|
||||
err = ixgbe_request_msix_irqs(adapter);
|
||||
} else if (adapter->flags & IXGBE_FLAG_MSI_ENABLED) {
|
||||
- err = request_irq(adapter->pdev->irq, ixgbe_intr, 0,
|
||||
+ err = request_irq(adapter->pdev->irq, ixgbe_intr, irq_flags,
|
||||
netdev->name, netdev);
|
||||
} else {
|
||||
- err = request_irq(adapter->pdev->irq, ixgbe_intr, IRQF_SHARED,
|
||||
+ irq_flags |= IRQF_SHARED;
|
||||
+ err = request_irq(adapter->pdev->irq, ixgbe_intr, irq_flags,
|
||||
netdev->name, netdev);
|
||||
}
|
||||
|
@ -1,24 +0,0 @@
|
||||
From: Tejun Heo <teheo@suse.de>
|
||||
Subject: [PATCH] libata: unlock HPA by default
|
||||
References: 299267
|
||||
Patch-mainline: not yet
|
||||
|
||||
Unlock HPA by default. This is to stay compatible with the old IDE
|
||||
drivers.
|
||||
|
||||
Signed-off-by: Tejun Heo <teheo@suse.de>
|
||||
---
|
||||
drivers/ata/libata-core.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/ata/libata-core.c
|
||||
+++ b/drivers/ata/libata-core.c
|
||||
@@ -138,7 +138,7 @@ int libata_fua = 0;
|
||||
module_param_named(fua, libata_fua, int, 0444);
|
||||
MODULE_PARM_DESC(fua, "FUA support (0=off [default], 1=on)");
|
||||
|
||||
-static int ata_ignore_hpa;
|
||||
+static int ata_ignore_hpa = 1;
|
||||
module_param_named(ignore_hpa, ata_ignore_hpa, int, 0644);
|
||||
MODULE_PARM_DESC(ignore_hpa, "Ignore HPA limit (0=keep BIOS limits, 1=ignore limits, using full disk)");
|
||||
|
@ -1,70 +0,0 @@
|
||||
From: Martin Wilck <martin.wilck@fujitsu-siemens.com>
|
||||
Subject: megaraid_mbox: Oops on SG_IO
|
||||
References: bnc#475619
|
||||
Patch-mainline: not yet
|
||||
|
||||
This patch fixes an Oops in megaraid_mbox that happens when a
|
||||
MODE_SENSE command for a logical drive is started viaioctl(SG_IO).
|
||||
|
||||
The problem only occurs if the buffer specified by the user to receive
|
||||
the mode data resides in highmem and if the buffer is aligned for
|
||||
direct dma (no bounce buffer necessary). megaraid_mbox emulates
|
||||
the MODE_SENSE command and writes the data using memset() directly
|
||||
into user buffer. If the buffer is at a currently unmapped highmem
|
||||
page, this leads to an Oops.
|
||||
|
||||
Signed-off-by: Hannes Reinecke <hare@suse.de>
|
||||
|
||||
---
|
||||
drivers/scsi/megaraid/megaraid_mbox.c | 28 +++++++++++++++++++++++-----
|
||||
1 file changed, 23 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/scsi/megaraid/megaraid_mbox.c
|
||||
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
|
||||
@@ -1586,13 +1586,20 @@ megaraid_mbox_build_cmd(adapter_t *adapt
|
||||
case MODE_SENSE:
|
||||
{
|
||||
struct scatterlist *sgl;
|
||||
- caddr_t vaddr;
|
||||
+ struct page *pg;
|
||||
+ unsigned char *vaddr;
|
||||
+ unsigned long flags;
|
||||
|
||||
sgl = scsi_sglist(scp);
|
||||
- if (sg_page(sgl)) {
|
||||
- vaddr = (caddr_t) sg_virt(&sgl[0]);
|
||||
+ pg = sg_page(sgl);
|
||||
+ if (pg) {
|
||||
+ local_irq_save(flags);
|
||||
+ vaddr = kmap_atomic(pg, KM_BIO_SRC_IRQ) + sgl->offset;
|
||||
|
||||
memset(vaddr, 0, scp->cmnd[4]);
|
||||
+
|
||||
+ kunmap_atomic(vaddr, KM_BIO_SRC_IRQ);
|
||||
+ local_irq_restore(flags);
|
||||
}
|
||||
else {
|
||||
con_log(CL_ANN, (KERN_WARNING
|
||||
@@ -2330,9 +2337,20 @@ megaraid_mbox_dpc(unsigned long devp)
|
||||
if (scp->cmnd[0] == INQUIRY && status == 0 && islogical == 0
|
||||
&& IS_RAID_CH(raid_dev, scb->dev_channel)) {
|
||||
|
||||
+ struct page *pg;
|
||||
+ unsigned char *vaddr;
|
||||
+ unsigned long flags;
|
||||
+
|
||||
sgl = scsi_sglist(scp);
|
||||
- if (sg_page(sgl)) {
|
||||
- c = *(unsigned char *) sg_virt(&sgl[0]);
|
||||
+ pg = sg_page(sgl);
|
||||
+ if (pg) {
|
||||
+ local_irq_save(flags);
|
||||
+ vaddr = kmap_atomic(pg, KM_BIO_SRC_IRQ) + sgl->offset;
|
||||
+
|
||||
+ c = *vaddr;
|
||||
+
|
||||
+ kunmap_atomic(vaddr, KM_BIO_SRC_IRQ);
|
||||
+ local_irq_restore(flags);
|
||||
} else {
|
||||
con_log(CL_ANN, (KERN_WARNING
|
||||
"megaraid mailbox: invalid sg:%d\n",
|
File diff suppressed because it is too large
Load Diff
@ -1,53 +0,0 @@
|
||||
From: Olaf Hering <olh@suse.de>
|
||||
Subject: enable mouse button emulation also for G5
|
||||
Patch-mainline: never
|
||||
|
||||
fix compile errors
|
||||
|
||||
drivers/macintosh/Kconfig | 2 +-
|
||||
drivers/macintosh/adb.c | 4 ++++
|
||||
drivers/macintosh/adbhid.c | 6 +++++-
|
||||
3 files changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/macintosh/Kconfig
|
||||
+++ b/drivers/macintosh/Kconfig
|
||||
@@ -13,7 +13,7 @@ if MACINTOSH_DRIVERS
|
||||
|
||||
config ADB
|
||||
bool "Apple Desktop Bus (ADB) support"
|
||||
- depends on MAC || (PPC_PMAC && PPC32)
|
||||
+ depends on MAC || PPC_PMAC
|
||||
help
|
||||
Apple Desktop Bus (ADB) support is for support of devices which
|
||||
are connected to an ADB port. ADB devices tend to have 4 pins.
|
||||
--- a/drivers/macintosh/adb.c
|
||||
+++ b/drivers/macintosh/adb.c
|
||||
@@ -298,6 +298,10 @@ static int __init adb_init(void)
|
||||
if (!machine_is(chrp) && !machine_is(powermac))
|
||||
return 0;
|
||||
#endif
|
||||
+#ifdef CONFIG_PPC64
|
||||
+ if (!machine_is(powermac))
|
||||
+ return 0;
|
||||
+#endif
|
||||
#ifdef CONFIG_MAC
|
||||
if (!MACH_IS_MAC)
|
||||
return 0;
|
||||
--- a/drivers/macintosh/adbhid.c
|
||||
+++ b/drivers/macintosh/adbhid.c
|
||||
@@ -1264,10 +1264,14 @@ init_ms_a3(int id)
|
||||
|
||||
static int __init adbhid_init(void)
|
||||
{
|
||||
-#ifndef CONFIG_MAC
|
||||
+#ifdef CONFIG_PPC32
|
||||
if (!machine_is(chrp) && !machine_is(powermac))
|
||||
return 0;
|
||||
#endif
|
||||
+#ifdef CONFIG_PPC64
|
||||
+ if (!machine_is(powermac))
|
||||
+ return 0;
|
||||
+#endif
|
||||
|
||||
led_request.complete = 1;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,707 +0,0 @@
|
||||
From foo@baz Wed Feb 9 13:35:10 PST 2011
|
||||
Date: Wed, 09 Feb 2011 13:35:10 -0800
|
||||
To: Greg KH <greg@kroah.com>
|
||||
From: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
Subject: Staging: samsung-laptop: add support for lots of laptops
|
||||
References: bnc#661682
|
||||
Patch-mainline: 2.6.39
|
||||
|
||||
This is a backport of the upstream version of the driver that added support for
|
||||
all samsung laptop devices.
|
||||
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
|
||||
diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c
|
||||
index 701e8d5..51ec621 100644
|
||||
--- a/drivers/staging/samsung-laptop/samsung-laptop.c
|
||||
+++ b/drivers/staging/samsung-laptop/samsung-laptop.c
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Samsung N130 Laptop driver
|
||||
+ * Samsung Laptop driver
|
||||
*
|
||||
* Copyright (C) 2009 Greg Kroah-Hartman (gregkh@suse.de)
|
||||
* Copyright (C) 2009 Novell Inc.
|
||||
@@ -33,51 +33,6 @@
|
||||
*/
|
||||
#define MAX_BRIGHT 0x07
|
||||
|
||||
-/* Brightness is 0 - 8, as described above. Value 0 is for the BIOS to use */
|
||||
-#define GET_BRIGHTNESS 0x00
|
||||
-#define SET_BRIGHTNESS 0x01
|
||||
-
|
||||
-/* first byte:
|
||||
- * 0x00 - wireless is off
|
||||
- * 0x01 - wireless is on
|
||||
- * second byte:
|
||||
- * 0x02 - 3G is off
|
||||
- * 0x03 - 3G is on
|
||||
- * TODO, verify 3G is correct, that doesn't seem right...
|
||||
- */
|
||||
-#define GET_WIRELESS_BUTTON 0x02
|
||||
-#define SET_WIRELESS_BUTTON 0x03
|
||||
-
|
||||
-/* 0 is off, 1 is on */
|
||||
-#define GET_BACKLIGHT 0x04
|
||||
-#define SET_BACKLIGHT 0x05
|
||||
-
|
||||
-/*
|
||||
- * 0x80 or 0x00 - no action
|
||||
- * 0x81 - recovery key pressed
|
||||
- */
|
||||
-#define GET_RECOVERY_METHOD 0x06
|
||||
-#define SET_RECOVERY_METHOD 0x07
|
||||
-
|
||||
-/* 0 is low, 1 is high */
|
||||
-#define GET_PERFORMANCE_LEVEL 0x08
|
||||
-#define SET_PERFORMANCE_LEVEL 0x09
|
||||
-
|
||||
-/*
|
||||
- * Tell the BIOS that Linux is running on this machine.
|
||||
- * 81 is on, 80 is off
|
||||
- */
|
||||
-#define SET_LINUX 0x0a
|
||||
-
|
||||
-
|
||||
-#define MAIN_FUNCTION 0x4c49
|
||||
-
|
||||
-#define SABI_HEADER_PORT 0x00
|
||||
-#define SABI_HEADER_RE_MEM 0x02
|
||||
-#define SABI_HEADER_IFACEFUNC 0x03
|
||||
-#define SABI_HEADER_EN_MEM 0x04
|
||||
-#define SABI_HEADER_DATA_OFFSET 0x05
|
||||
-#define SABI_HEADER_DATA_SEGMENT 0x07
|
||||
|
||||
#define SABI_IFACE_MAIN 0x00
|
||||
#define SABI_IFACE_SUB 0x02
|
||||
@@ -89,6 +44,173 @@ struct sabi_retval {
|
||||
u8 retval[20];
|
||||
};
|
||||
|
||||
+struct sabi_header_offsets {
|
||||
+ u8 port;
|
||||
+ u8 re_mem;
|
||||
+ u8 iface_func;
|
||||
+ u8 en_mem;
|
||||
+ u8 data_offset;
|
||||
+ u8 data_segment;
|
||||
+};
|
||||
+
|
||||
+struct sabi_commands {
|
||||
+ /*
|
||||
+ * Brightness is 0 - 8, as described above.
|
||||
+ * Value 0 is for the BIOS to use
|
||||
+ */
|
||||
+ u8 get_brightness;
|
||||
+ u8 set_brightness;
|
||||
+
|
||||
+ /*
|
||||
+ * first byte:
|
||||
+ * 0x00 - wireless is off
|
||||
+ * 0x01 - wireless is on
|
||||
+ * second byte:
|
||||
+ * 0x02 - 3G is off
|
||||
+ * 0x03 - 3G is on
|
||||
+ * TODO, verify 3G is correct, that doesn't seem right...
|
||||
+ */
|
||||
+ u8 get_wireless_button;
|
||||
+ u8 set_wireless_button;
|
||||
+
|
||||
+ /* 0 is off, 1 is on */
|
||||
+ u8 get_backlight;
|
||||
+ u8 set_backlight;
|
||||
+
|
||||
+ /*
|
||||
+ * 0x80 or 0x00 - no action
|
||||
+ * 0x81 - recovery key pressed
|
||||
+ */
|
||||
+ u8 get_recovery_mode;
|
||||
+ u8 set_recovery_mode;
|
||||
+
|
||||
+ /*
|
||||
+ * on seclinux: 0 is low, 1 is high,
|
||||
+ * on swsmi: 0 is normal, 1 is silent, 2 is turbo
|
||||
+ */
|
||||
+ u8 get_performance_level;
|
||||
+ u8 set_performance_level;
|
||||
+
|
||||
+ /*
|
||||
+ * Tell the BIOS that Linux is running on this machine.
|
||||
+ * 81 is on, 80 is off
|
||||
+ */
|
||||
+ u8 set_linux;
|
||||
+};
|
||||
+
|
||||
+struct sabi_performance_level {
|
||||
+ const char *name;
|
||||
+ u8 value;
|
||||
+};
|
||||
+
|
||||
+struct sabi_config {
|
||||
+ const char *test_string;
|
||||
+ u16 main_function;
|
||||
+ struct sabi_header_offsets header_offsets;
|
||||
+ struct sabi_commands commands;
|
||||
+ struct sabi_performance_level performance_levels[4];
|
||||
+};
|
||||
+
|
||||
+static struct sabi_config sabi_configs[] = {
|
||||
+ {
|
||||
+ .test_string = "SECLINUX",
|
||||
+
|
||||
+ .main_function = 0x4c59,
|
||||
+
|
||||
+ .header_offsets = {
|
||||
+ .port = 0x00,
|
||||
+ .re_mem = 0x02,
|
||||
+ .iface_func = 0x03,
|
||||
+ .en_mem = 0x04,
|
||||
+ .data_offset = 0x05,
|
||||
+ .data_segment = 0x07,
|
||||
+ },
|
||||
+
|
||||
+ .commands = {
|
||||
+ .get_brightness = 0x00,
|
||||
+ .set_brightness = 0x01,
|
||||
+
|
||||
+ .get_wireless_button = 0x02,
|
||||
+ .set_wireless_button = 0x03,
|
||||
+
|
||||
+ .get_backlight = 0x04,
|
||||
+ .set_backlight = 0x05,
|
||||
+
|
||||
+ .get_recovery_mode = 0x06,
|
||||
+ .set_recovery_mode = 0x07,
|
||||
+
|
||||
+ .get_performance_level = 0x08,
|
||||
+ .set_performance_level = 0x09,
|
||||
+
|
||||
+ .set_linux = 0x0a,
|
||||
+ },
|
||||
+
|
||||
+ .performance_levels = {
|
||||
+ {
|
||||
+ .name = "silent",
|
||||
+ .value = 0,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "normal",
|
||||
+ .value = 1,
|
||||
+ },
|
||||
+ { },
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ .test_string = "SwSmi@",
|
||||
+
|
||||
+ .main_function = 0x5843,
|
||||
+
|
||||
+ .header_offsets = {
|
||||
+ .port = 0x00,
|
||||
+ .re_mem = 0x04,
|
||||
+ .iface_func = 0x02,
|
||||
+ .en_mem = 0x03,
|
||||
+ .data_offset = 0x05,
|
||||
+ .data_segment = 0x07,
|
||||
+ },
|
||||
+
|
||||
+ .commands = {
|
||||
+ .get_brightness = 0x10,
|
||||
+ .set_brightness = 0x11,
|
||||
+
|
||||
+ .get_wireless_button = 0x12,
|
||||
+ .set_wireless_button = 0x13,
|
||||
+
|
||||
+ .get_backlight = 0x2d,
|
||||
+ .set_backlight = 0x2e,
|
||||
+
|
||||
+ .get_recovery_mode = 0xff,
|
||||
+ .set_recovery_mode = 0xff,
|
||||
+
|
||||
+ .get_performance_level = 0x31,
|
||||
+ .set_performance_level = 0x32,
|
||||
+
|
||||
+ .set_linux = 0xff,
|
||||
+ },
|
||||
+
|
||||
+ .performance_levels = {
|
||||
+ {
|
||||
+ .name = "normal",
|
||||
+ .value = 0,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "silent",
|
||||
+ .value = 1,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "overclock",
|
||||
+ .value = 2,
|
||||
+ },
|
||||
+ { },
|
||||
+ },
|
||||
+ },
|
||||
+ { },
|
||||
+};
|
||||
+
|
||||
+static struct sabi_config *sabi_config;
|
||||
+
|
||||
static void __iomem *sabi;
|
||||
static void __iomem *sabi_iface;
|
||||
static void __iomem *f0000_segment;
|
||||
@@ -109,21 +231,21 @@ MODULE_PARM_DESC(debug, "Debug enabled or not");
|
||||
static int sabi_get_command(u8 command, struct sabi_retval *sretval)
|
||||
{
|
||||
int retval = 0;
|
||||
- u16 port = readw(sabi + SABI_HEADER_PORT);
|
||||
+ u16 port = readw(sabi + sabi_config->header_offsets.port);
|
||||
|
||||
mutex_lock(&sabi_mutex);
|
||||
|
||||
/* enable memory to be able to write to it */
|
||||
- outb(readb(sabi + SABI_HEADER_EN_MEM), port);
|
||||
+ outb(readb(sabi + sabi_config->header_offsets.en_mem), port);
|
||||
|
||||
/* write out the command */
|
||||
- writew(MAIN_FUNCTION, sabi_iface + SABI_IFACE_MAIN);
|
||||
+ writew(sabi_config->main_function, sabi_iface + SABI_IFACE_MAIN);
|
||||
writew(command, sabi_iface + SABI_IFACE_SUB);
|
||||
writeb(0, sabi_iface + SABI_IFACE_COMPLETE);
|
||||
- outb(readb(sabi + SABI_HEADER_IFACEFUNC), port);
|
||||
+ outb(readb(sabi + sabi_config->header_offsets.iface_func), port);
|
||||
|
||||
/* write protect memory to make it safe */
|
||||
- outb(readb(sabi + SABI_HEADER_RE_MEM), port);
|
||||
+ outb(readb(sabi + sabi_config->header_offsets.re_mem), port);
|
||||
|
||||
/* see if the command actually succeeded */
|
||||
if (readb(sabi_iface + SABI_IFACE_COMPLETE) == 0xaa &&
|
||||
@@ -156,22 +278,22 @@ exit:
|
||||
static int sabi_set_command(u8 command, u8 data)
|
||||
{
|
||||
int retval = 0;
|
||||
- u16 port = readw(sabi + SABI_HEADER_PORT);
|
||||
+ u16 port = readw(sabi + sabi_config->header_offsets.port);
|
||||
|
||||
mutex_lock(&sabi_mutex);
|
||||
|
||||
/* enable memory to be able to write to it */
|
||||
- outb(readb(sabi + SABI_HEADER_EN_MEM), port);
|
||||
+ outb(readb(sabi + sabi_config->header_offsets.en_mem), port);
|
||||
|
||||
/* write out the command */
|
||||
- writew(MAIN_FUNCTION, sabi_iface + SABI_IFACE_MAIN);
|
||||
+ writew(sabi_config->main_function, sabi_iface + SABI_IFACE_MAIN);
|
||||
writew(command, sabi_iface + SABI_IFACE_SUB);
|
||||
writeb(0, sabi_iface + SABI_IFACE_COMPLETE);
|
||||
writeb(data, sabi_iface + SABI_IFACE_DATA);
|
||||
- outb(readb(sabi + SABI_HEADER_IFACEFUNC), port);
|
||||
+ outb(readb(sabi + sabi_config->header_offsets.iface_func), port);
|
||||
|
||||
/* write protect memory to make it safe */
|
||||
- outb(readb(sabi + SABI_HEADER_RE_MEM), port);
|
||||
+ outb(readb(sabi + sabi_config->header_offsets.re_mem), port);
|
||||
|
||||
/* see if the command actually succeeded */
|
||||
if (readb(sabi_iface + SABI_IFACE_COMPLETE) == 0xaa &&
|
||||
@@ -194,21 +316,21 @@ static void test_backlight(void)
|
||||
{
|
||||
struct sabi_retval sretval;
|
||||
|
||||
- sabi_get_command(GET_BACKLIGHT, &sretval);
|
||||
+ sabi_get_command(sabi_config->commands.get_backlight, &sretval);
|
||||
printk(KERN_DEBUG "backlight = 0x%02x\n", sretval.retval[0]);
|
||||
|
||||
- sabi_set_command(SET_BACKLIGHT, 0);
|
||||
+ sabi_set_command(sabi_config->commands.set_backlight, 0);
|
||||
printk(KERN_DEBUG "backlight should be off\n");
|
||||
|
||||
- sabi_get_command(GET_BACKLIGHT, &sretval);
|
||||
+ sabi_get_command(sabi_config->commands.get_backlight, &sretval);
|
||||
printk(KERN_DEBUG "backlight = 0x%02x\n", sretval.retval[0]);
|
||||
|
||||
msleep(1000);
|
||||
|
||||
- sabi_set_command(SET_BACKLIGHT, 1);
|
||||
+ sabi_set_command(sabi_config->commands.set_backlight, 1);
|
||||
printk(KERN_DEBUG "backlight should be on\n");
|
||||
|
||||
- sabi_get_command(GET_BACKLIGHT, &sretval);
|
||||
+ sabi_get_command(sabi_config->commands.get_backlight, &sretval);
|
||||
printk(KERN_DEBUG "backlight = 0x%02x\n", sretval.retval[0]);
|
||||
}
|
||||
|
||||
@@ -216,21 +338,21 @@ static void test_wireless(void)
|
||||
{
|
||||
struct sabi_retval sretval;
|
||||
|
||||
- sabi_get_command(GET_WIRELESS_BUTTON, &sretval);
|
||||
+ sabi_get_command(sabi_config->commands.get_wireless_button, &sretval);
|
||||
printk(KERN_DEBUG "wireless led = 0x%02x\n", sretval.retval[0]);
|
||||
|
||||
- sabi_set_command(SET_WIRELESS_BUTTON, 0);
|
||||
+ sabi_set_command(sabi_config->commands.set_wireless_button, 0);
|
||||
printk(KERN_DEBUG "wireless led should be off\n");
|
||||
|
||||
- sabi_get_command(GET_WIRELESS_BUTTON, &sretval);
|
||||
+ sabi_get_command(sabi_config->commands.get_wireless_button, &sretval);
|
||||
printk(KERN_DEBUG "wireless led = 0x%02x\n", sretval.retval[0]);
|
||||
|
||||
msleep(1000);
|
||||
|
||||
- sabi_set_command(SET_WIRELESS_BUTTON, 1);
|
||||
+ sabi_set_command(sabi_config->commands.set_wireless_button, 1);
|
||||
printk(KERN_DEBUG "wireless led should be on\n");
|
||||
|
||||
- sabi_get_command(GET_WIRELESS_BUTTON, &sretval);
|
||||
+ sabi_get_command(sabi_config->commands.get_wireless_button, &sretval);
|
||||
printk(KERN_DEBUG "wireless led = 0x%02x\n", sretval.retval[0]);
|
||||
}
|
||||
|
||||
@@ -240,7 +362,8 @@ static u8 read_brightness(void)
|
||||
int user_brightness = 0;
|
||||
int retval;
|
||||
|
||||
- retval = sabi_get_command(GET_BRIGHTNESS, &sretval);
|
||||
+ retval = sabi_get_command(sabi_config->commands.get_brightness,
|
||||
+ &sretval);
|
||||
if (!retval)
|
||||
user_brightness = sretval.retval[0];
|
||||
if (user_brightness != 0)
|
||||
@@ -250,7 +373,8 @@ static u8 read_brightness(void)
|
||||
|
||||
static void set_brightness(u8 user_brightness)
|
||||
{
|
||||
- sabi_set_command(SET_BRIGHTNESS, user_brightness + 1);
|
||||
+ sabi_set_command(sabi_config->commands.set_brightness,
|
||||
+ user_brightness + 1);
|
||||
}
|
||||
|
||||
static int get_brightness(struct backlight_device *bd)
|
||||
@@ -263,9 +387,9 @@ static int update_status(struct backlight_device *bd)
|
||||
set_brightness(bd->props.brightness);
|
||||
|
||||
if (bd->props.power == FB_BLANK_UNBLANK)
|
||||
- sabi_set_command(SET_BACKLIGHT, 1);
|
||||
+ sabi_set_command(sabi_config->commands.set_backlight, 1);
|
||||
else
|
||||
- sabi_set_command(SET_BACKLIGHT, 0);
|
||||
+ sabi_set_command(sabi_config->commands.set_backlight, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -282,9 +406,9 @@ static int rfkill_set(void *data, bool blocked)
|
||||
* blocked == true is off
|
||||
*/
|
||||
if (blocked)
|
||||
- sabi_set_command(SET_WIRELESS_BUTTON, 0);
|
||||
+ sabi_set_command(sabi_config->commands.set_wireless_button, 0);
|
||||
else
|
||||
- sabi_set_command(SET_WIRELESS_BUTTON, 1);
|
||||
+ sabi_set_command(sabi_config->commands.set_wireless_button, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -317,47 +441,49 @@ static void destroy_wireless(void)
|
||||
rfkill_destroy(rfk);
|
||||
}
|
||||
|
||||
-static ssize_t get_silent_state(struct device *dev,
|
||||
- struct device_attribute *attr, char *buf)
|
||||
+static ssize_t get_performance_level(struct device *dev,
|
||||
+ struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct sabi_retval sretval;
|
||||
int retval;
|
||||
+ int i;
|
||||
|
||||
/* Read the state */
|
||||
- retval = sabi_get_command(GET_PERFORMANCE_LEVEL, &sretval);
|
||||
+ retval = sabi_get_command(sabi_config->commands.get_performance_level,
|
||||
+ &sretval);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
/* The logic is backwards, yeah, lots of fun... */
|
||||
- if (sretval.retval[0] == 0)
|
||||
- retval = 1;
|
||||
- else
|
||||
- retval = 0;
|
||||
- return sprintf(buf, "%d\n", retval);
|
||||
+ for (i = 0; sabi_config->performance_levels[i].name; ++i) {
|
||||
+ if (sretval.retval[0] == sabi_config->performance_levels[i].value)
|
||||
+ return sprintf(buf, "%s\n", sabi_config->performance_levels[i].name);
|
||||
+ }
|
||||
+ return sprintf(buf, "%s\n", "unknown");
|
||||
}
|
||||
|
||||
-static ssize_t set_silent_state(struct device *dev,
|
||||
+static ssize_t set_performance_level(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf,
|
||||
size_t count)
|
||||
{
|
||||
- char value;
|
||||
-
|
||||
if (count >= 1) {
|
||||
- value = buf[0];
|
||||
- if ((value == '0') || (value == 'n') || (value == 'N')) {
|
||||
- /* Turn speed up */
|
||||
- sabi_set_command(SET_PERFORMANCE_LEVEL, 0x01);
|
||||
- } else if ((value == '1') || (value == 'y') || (value == 'Y')) {
|
||||
- /* Turn speed down */
|
||||
- sabi_set_command(SET_PERFORMANCE_LEVEL, 0x00);
|
||||
- } else {
|
||||
- return -EINVAL;
|
||||
+ int i;
|
||||
+ for (i = 0; sabi_config->performance_levels[i].name; ++i) {
|
||||
+ struct sabi_performance_level *level =
|
||||
+ &sabi_config->performance_levels[i];
|
||||
+ if (!strncasecmp(level->name, buf, strlen(level->name))) {
|
||||
+ sabi_set_command(sabi_config->commands.set_performance_level,
|
||||
+ level->value);
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
+ if (!sabi_config->performance_levels[i].name)
|
||||
+ return -EINVAL;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
-static DEVICE_ATTR(silent, S_IWUSR | S_IRUGO,
|
||||
- get_silent_state, set_silent_state);
|
||||
+static DEVICE_ATTR(performance_level, S_IWUSR | S_IRUGO,
|
||||
+ get_performance_level, set_performance_level);
|
||||
|
||||
|
||||
static int __init dmi_check_cb(const struct dmi_system_id *id)
|
||||
@@ -388,18 +514,113 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = {
|
||||
},
|
||||
.callback = dmi_check_cb,
|
||||
},
|
||||
+ {
|
||||
+ .ident = "X125",
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_SYS_VENDOR,
|
||||
+ "SAMSUNG ELECTRONICS CO., LTD."),
|
||||
+ DMI_MATCH(DMI_PRODUCT_NAME, "X125"),
|
||||
+ DMI_MATCH(DMI_BOARD_NAME, "X125"),
|
||||
+ },
|
||||
+ .callback = dmi_check_cb,
|
||||
+ },
|
||||
+ {
|
||||
+ .ident = "NC10",
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_SYS_VENDOR,
|
||||
+ "SAMSUNG ELECTRONICS CO., LTD."),
|
||||
+ DMI_MATCH(DMI_PRODUCT_NAME, "NC10"),
|
||||
+ DMI_MATCH(DMI_BOARD_NAME, "NC10"),
|
||||
+ },
|
||||
+ .callback = dmi_check_cb,
|
||||
+ },
|
||||
+ {
|
||||
+ .ident = "NP-Q45",
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_SYS_VENDOR,
|
||||
+ "SAMSUNG ELECTRONICS CO., LTD."),
|
||||
+ DMI_MATCH(DMI_PRODUCT_NAME, "SQ45S70S"),
|
||||
+ DMI_MATCH(DMI_BOARD_NAME, "SQ45S70S"),
|
||||
+ },
|
||||
+ .callback = dmi_check_cb,
|
||||
+ },
|
||||
+ {
|
||||
+ .ident = "X360",
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_SYS_VENDOR,
|
||||
+ "SAMSUNG ELECTRONICS CO., LTD."),
|
||||
+ DMI_MATCH(DMI_PRODUCT_NAME, "X360"),
|
||||
+ DMI_MATCH(DMI_BOARD_NAME, "X360"),
|
||||
+ },
|
||||
+ .callback = dmi_check_cb,
|
||||
+ },
|
||||
+ {
|
||||
+ .ident = "R518",
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_SYS_VENDOR,
|
||||
+ "SAMSUNG ELECTRONICS CO., LTD."),
|
||||
+ DMI_MATCH(DMI_PRODUCT_NAME, "R518"),
|
||||
+ DMI_MATCH(DMI_BOARD_NAME, "R518"),
|
||||
+ },
|
||||
+ .callback = dmi_check_cb,
|
||||
+ },
|
||||
+ {
|
||||
+ .ident = "N150/N210/N220",
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_SYS_VENDOR,
|
||||
+ "SAMSUNG ELECTRONICS CO., LTD."),
|
||||
+ DMI_MATCH(DMI_PRODUCT_NAME, "N150/N210/N220"),
|
||||
+ DMI_MATCH(DMI_BOARD_NAME, "N150/N210/N220"),
|
||||
+ },
|
||||
+ .callback = dmi_check_cb,
|
||||
+ },
|
||||
+ {
|
||||
+ .ident = "R530/R730",
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
|
||||
+ DMI_MATCH(DMI_PRODUCT_NAME, "R530/R730"),
|
||||
+ DMI_MATCH(DMI_BOARD_NAME, "R530/R730"),
|
||||
+ },
|
||||
+ .callback = dmi_check_cb,
|
||||
+ },
|
||||
+ {
|
||||
+ .ident = "NF110/NF210/NF310",
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
|
||||
+ DMI_MATCH(DMI_PRODUCT_NAME, "NF110/NF210/NF310"),
|
||||
+ DMI_MATCH(DMI_BOARD_NAME, "NF110/NF210/NF310"),
|
||||
+ },
|
||||
+ .callback = dmi_check_cb,
|
||||
+ },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(dmi, samsung_dmi_table);
|
||||
|
||||
+static int find_signature(void __iomem *memcheck, const char *testStr)
|
||||
+{
|
||||
+ int i = 0;
|
||||
+ int loca;
|
||||
+
|
||||
+ for (loca = 0; loca < 0xffff; loca++) {
|
||||
+ char temp = readb(memcheck + loca);
|
||||
+
|
||||
+ if (temp == testStr[i]) {
|
||||
+ if (i == strlen(testStr)-1)
|
||||
+ break;
|
||||
+ ++i;
|
||||
+ } else {
|
||||
+ i = 0;
|
||||
+ }
|
||||
+ }
|
||||
+ return loca;
|
||||
+}
|
||||
+
|
||||
static int __init samsung_init(void)
|
||||
{
|
||||
struct backlight_properties props;
|
||||
struct sabi_retval sretval;
|
||||
- const char *testStr = "SECLINUX";
|
||||
- void __iomem *memcheck;
|
||||
unsigned int ifaceP;
|
||||
- int pStr;
|
||||
+ int i;
|
||||
int loca;
|
||||
int retval;
|
||||
|
||||
@@ -414,50 +635,44 @@ static int __init samsung_init(void)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- /* Try to find the signature "SECLINUX" in memory to find the header */
|
||||
- pStr = 0;
|
||||
- memcheck = f0000_segment;
|
||||
- for (loca = 0; loca < 0xffff; loca++) {
|
||||
- char temp = readb(memcheck + loca);
|
||||
-
|
||||
- if (temp == testStr[pStr]) {
|
||||
- if (pStr == strlen(testStr)-1)
|
||||
- break;
|
||||
- ++pStr;
|
||||
- } else {
|
||||
- pStr = 0;
|
||||
- }
|
||||
+ /* Try to find one of the signatures in memory to find the header */
|
||||
+ for (i = 0; sabi_configs[i].test_string != 0; ++i) {
|
||||
+ sabi_config = &sabi_configs[i];
|
||||
+ loca = find_signature(f0000_segment, sabi_config->test_string);
|
||||
+ if (loca != 0xffff)
|
||||
+ break;
|
||||
}
|
||||
+
|
||||
if (loca == 0xffff) {
|
||||
printk(KERN_ERR "This computer does not support SABI\n");
|
||||
goto error_no_signature;
|
||||
- }
|
||||
+ }
|
||||
|
||||
/* point to the SMI port Number */
|
||||
loca += 1;
|
||||
- sabi = (memcheck + loca);
|
||||
+ sabi = (f0000_segment + loca);
|
||||
|
||||
if (debug) {
|
||||
printk(KERN_DEBUG "This computer supports SABI==%x\n",
|
||||
loca + 0xf0000 - 6);
|
||||
printk(KERN_DEBUG "SABI header:\n");
|
||||
printk(KERN_DEBUG " SMI Port Number = 0x%04x\n",
|
||||
- readw(sabi + SABI_HEADER_PORT));
|
||||
+ readw(sabi + sabi_config->header_offsets.port));
|
||||
printk(KERN_DEBUG " SMI Interface Function = 0x%02x\n",
|
||||
- readb(sabi + SABI_HEADER_IFACEFUNC));
|
||||
+ readb(sabi + sabi_config->header_offsets.iface_func));
|
||||
printk(KERN_DEBUG " SMI enable memory buffer = 0x%02x\n",
|
||||
- readb(sabi + SABI_HEADER_EN_MEM));
|
||||
+ readb(sabi + sabi_config->header_offsets.en_mem));
|
||||
printk(KERN_DEBUG " SMI restore memory buffer = 0x%02x\n",
|
||||
- readb(sabi + SABI_HEADER_RE_MEM));
|
||||
+ readb(sabi + sabi_config->header_offsets.re_mem));
|
||||
printk(KERN_DEBUG " SABI data offset = 0x%04x\n",
|
||||
- readw(sabi + SABI_HEADER_DATA_OFFSET));
|
||||
+ readw(sabi + sabi_config->header_offsets.data_offset));
|
||||
printk(KERN_DEBUG " SABI data segment = 0x%04x\n",
|
||||
- readw(sabi + SABI_HEADER_DATA_SEGMENT));
|
||||
+ readw(sabi + sabi_config->header_offsets.data_segment));
|
||||
}
|
||||
|
||||
/* Get a pointer to the SABI Interface */
|
||||
- ifaceP = (readw(sabi + SABI_HEADER_DATA_SEGMENT) & 0x0ffff) << 4;
|
||||
- ifaceP += readw(sabi + SABI_HEADER_DATA_OFFSET) & 0x0ffff;
|
||||
+ ifaceP = (readw(sabi + sabi_config->header_offsets.data_segment) & 0x0ffff) << 4;
|
||||
+ ifaceP += readw(sabi + sabi_config->header_offsets.data_offset) & 0x0ffff;
|
||||
sabi_iface = ioremap(ifaceP, 16);
|
||||
if (!sabi_iface) {
|
||||
printk(KERN_ERR "Can't remap %x\n", ifaceP);
|
||||
@@ -470,15 +685,19 @@ static int __init samsung_init(void)
|
||||
test_backlight();
|
||||
test_wireless();
|
||||
|
||||
- retval = sabi_get_command(GET_BRIGHTNESS, &sretval);
|
||||
+ retval = sabi_get_command(sabi_config->commands.get_brightness,
|
||||
+ &sretval);
|
||||
printk(KERN_DEBUG "brightness = 0x%02x\n", sretval.retval[0]);
|
||||
}
|
||||
|
||||
/* Turn on "Linux" mode in the BIOS */
|
||||
- retval = sabi_set_command(SET_LINUX, 0x81);
|
||||
- if (retval) {
|
||||
- printk(KERN_ERR KBUILD_MODNAME ": Linux mode was not set!\n");
|
||||
- goto error_no_platform;
|
||||
+ if (sabi_config->commands.set_linux != 0xff) {
|
||||
+ retval = sabi_set_command(sabi_config->commands.set_linux,
|
||||
+ 0x81);
|
||||
+ if (retval) {
|
||||
+ printk(KERN_ERR KBUILD_MODNAME ": Linux mode was not set!\n");
|
||||
+ goto error_no_platform;
|
||||
+ }
|
||||
}
|
||||
|
||||
/* knock up a platform device to hang stuff off of */
|
||||
@@ -503,7 +722,7 @@ static int __init samsung_init(void)
|
||||
if (retval)
|
||||
goto error_no_rfk;
|
||||
|
||||
- retval = device_create_file(&sdev->dev, &dev_attr_silent);
|
||||
+ retval = device_create_file(&sdev->dev, &dev_attr_performance_level);
|
||||
if (retval)
|
||||
goto error_file_create;
|
||||
|
||||
@@ -530,9 +749,10 @@ error_no_signature:
|
||||
static void __exit samsung_exit(void)
|
||||
{
|
||||
/* Turn off "Linux" mode in the BIOS */
|
||||
- sabi_set_command(SET_LINUX, 0x80);
|
||||
+ if (sabi_config->commands.set_linux != 0xff)
|
||||
+ sabi_set_command(sabi_config->commands.set_linux, 0x80);
|
||||
|
||||
- device_remove_file(&sdev->dev, &dev_attr_silent);
|
||||
+ device_remove_file(&sdev->dev, &dev_attr_performance_level);
|
||||
backlight_device_unregister(backlight_device);
|
||||
destroy_wireless();
|
||||
iounmap(sabi_iface);
|
@ -1,193 +0,0 @@
|
||||
From: Matt Carlson <mcarlson@broadcom.com>
|
||||
Subject: tg3: 5785 and 57780 asic revs not working
|
||||
References: bnc#580780
|
||||
Patch-mainline: Never
|
||||
|
||||
There is a known problem with phylib that causes a lot of problems.
|
||||
Phylib does not load phy modules as it detects devices on the MDIO bus.
|
||||
If the phylib module gets loaded as a dependancy of tg3, there will be
|
||||
no opportunity to load the needed broadcom.ko module before tg3 requests
|
||||
phylib to probe the MDIO bus. The result will be that tg3 will fail to
|
||||
attach to 5785 and 57780 devices.
|
||||
|
||||
There are several known solutions to this problem. (None of these
|
||||
should go upstream. The upstream fix should be to get phylib to load
|
||||
modules for devices it encounters.) Only one of them need be applied.
|
||||
|
||||
1) Statically link in the broadcom.ko module into the kernel.
|
||||
|
||||
2) Add the following to /etc/modprobe.d/local.conf or its equivalent:
|
||||
|
||||
install tg3 /sbin/modprobe broadcom; /sbin/modprobe --ignore-install tg3
|
||||
|
||||
3) Apply the following patch:
|
||||
|
||||
Signed-off-by: Brandon Philips <bphilips@suse.de>
|
||||
|
||||
---
|
||||
drivers/net/tg3.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
drivers/net/tg3.h | 9 +++++
|
||||
2 files changed, 92 insertions(+)
|
||||
|
||||
--- a/drivers/net/tg3.c
|
||||
+++ b/drivers/net/tg3.c
|
||||
@@ -1998,6 +1998,58 @@ static int tg3_phy_reset(struct tg3 *tp)
|
||||
tg3_phy_toggle_apd(tp, false);
|
||||
|
||||
out:
|
||||
+ if ((tp->phy_id & TG3_PHY_ID_MASK) == TG3_PHY_ID_BCM50610 ||
|
||||
+ (tp->phy_id & TG3_PHY_ID_MASK) == TG3_PHY_ID_BCM50610M) {
|
||||
+ u32 reg;
|
||||
+
|
||||
+ /* Enable SM_DSP clock and tx 6dB coding. */
|
||||
+ reg = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
|
||||
+ MII_TG3_AUXCTL_ACTL_SMDSP_ENA |
|
||||
+ MII_TG3_AUXCTL_ACTL_TX_6DB;
|
||||
+ tg3_writephy(tp, MII_TG3_AUX_CTRL, reg);
|
||||
+
|
||||
+ reg = MII_TG3_DSP_EXP8_REJ2MHz;
|
||||
+ tg3_phydsp_write(tp, MII_TG3_DSP_EXP8, reg);
|
||||
+
|
||||
+ /* Apply workaround to A0 revision parts only. */
|
||||
+ if (tp->phy_id == TG3_PHY_ID_BCM50610 ||
|
||||
+ tp->phy_id == TG3_PHY_ID_BCM50610M) {
|
||||
+ tg3_phydsp_write(tp, 0x001F, 0x0300);
|
||||
+ tg3_phydsp_write(tp, 0x601F, 0x0002);
|
||||
+ tg3_phydsp_write(tp, 0x0F75, 0x003C);
|
||||
+ tg3_phydsp_write(tp, 0x0F96, 0x0010);
|
||||
+ tg3_phydsp_write(tp, 0x0F97, 0x0C0C);
|
||||
+ }
|
||||
+
|
||||
+ /* Turn off SM_DSP clock. */
|
||||
+ reg = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
|
||||
+ MII_TG3_AUXCTL_ACTL_TX_6DB;
|
||||
+ tg3_writephy(tp, MII_TG3_AUX_CTRL, reg);
|
||||
+
|
||||
+ /* Clear all mode configuration bits. */
|
||||
+ reg = MII_TG3_MISC_SHDW_WREN |
|
||||
+ MII_TG3_MISC_SHDW_RGMII_SEL;
|
||||
+ tg3_writephy(tp, MII_TG3_MISC_SHDW, reg);
|
||||
+ }
|
||||
+ if ((tp->phy_id & TG3_PHY_ID_MASK) == TG3_PHY_ID_BCM57780) {
|
||||
+ u32 reg;
|
||||
+
|
||||
+ /* Enable SM_DSP clock and tx 6dB coding. */
|
||||
+ reg = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
|
||||
+ MII_TG3_AUXCTL_ACTL_SMDSP_ENA |
|
||||
+ MII_TG3_AUXCTL_ACTL_TX_6DB;
|
||||
+ tg3_writephy(tp, MII_TG3_AUX_CTRL, reg);
|
||||
+
|
||||
+ tg3_writephy(tp, MII_TG3_DSP_ADDRESS, MII_TG3_DSP_EXP75);
|
||||
+ tg3_readphy(tp, MII_TG3_DSP_RW_PORT, ®);
|
||||
+ reg |= MII_TG3_DSP_EXP75_SUP_CM_OSC;
|
||||
+ tg3_phydsp_write(tp, MII_TG3_DSP_EXP75, reg);
|
||||
+
|
||||
+ /* Turn off SM_DSP clock. */
|
||||
+ reg = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
|
||||
+ MII_TG3_AUXCTL_ACTL_TX_6DB;
|
||||
+ tg3_writephy(tp, MII_TG3_AUX_CTRL, reg);
|
||||
+ }
|
||||
if (tp->phy_flags & TG3_PHYFLG_ADC_BUG) {
|
||||
tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00);
|
||||
tg3_phydsp_write(tp, 0x201f, 0x2aaa);
|
||||
@@ -2054,6 +2106,22 @@ out:
|
||||
/* adjust output voltage */
|
||||
tg3_writephy(tp, MII_TG3_FET_PTEST, 0x12);
|
||||
}
|
||||
+ else if (tp->phy_flags & TG3_PHYFLG_IS_FET) {
|
||||
+ u32 brcmtest;
|
||||
+ if (!tg3_readphy(tp, MII_TG3_FET_TEST, &brcmtest) &&
|
||||
+ !tg3_writephy(tp, MII_TG3_FET_TEST,
|
||||
+ brcmtest | MII_TG3_FET_SHADOW_EN)) {
|
||||
+ u32 val, reg = MII_TG3_FET_SHDW_AUXMODE4;
|
||||
+
|
||||
+ if (!tg3_readphy(tp, reg, &val)) {
|
||||
+ val &= ~MII_TG3_FET_SHDW_AM4_LED_MASK;
|
||||
+ val |= MII_TG3_FET_SHDW_AM4_LED_MODE1;
|
||||
+ tg3_writephy(tp, reg, val);
|
||||
+ }
|
||||
+
|
||||
+ tg3_writephy(tp, MII_TG3_FET_TEST, brcmtest);
|
||||
+ }
|
||||
+ }
|
||||
|
||||
tg3_phy_toggle_automdix(tp, 1);
|
||||
tg3_phy_set_wirespeed(tp);
|
||||
@@ -3288,6 +3356,15 @@ relink:
|
||||
|
||||
tg3_phy_eee_adjust(tp, current_link_up);
|
||||
|
||||
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) {
|
||||
+ if (tp->link_config.active_speed == SPEED_10)
|
||||
+ tw32(MAC_MI_STAT,
|
||||
+ MAC_MI_STAT_10MBPS_MODE |
|
||||
+ MAC_MI_STAT_LNKSTAT_ATTN_ENAB);
|
||||
+ else
|
||||
+ tw32(MAC_MI_STAT, MAC_MI_STAT_LNKSTAT_ATTN_ENAB);
|
||||
+ }
|
||||
+
|
||||
if (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) {
|
||||
/* Polled via timer. */
|
||||
tw32_f(MAC_EVENT, 0);
|
||||
@@ -13411,9 +13488,11 @@ static int __devinit tg3_get_invariants(
|
||||
GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_BX)
|
||||
tp->coalesce_mode |= HOSTCC_MODE_32BYTE;
|
||||
|
||||
+#if 0
|
||||
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
|
||||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
|
||||
tp->tg3_flags3 |= TG3_FLG3_USE_PHYLIB;
|
||||
+#endif
|
||||
|
||||
err = tg3_mdio_init(tp);
|
||||
if (err)
|
||||
@@ -14203,6 +14282,10 @@ static char * __devinit tg3_phy_string(s
|
||||
case TG3_PHY_ID_BCM5718S: return "5718S";
|
||||
case TG3_PHY_ID_BCM57765: return "57765";
|
||||
case TG3_PHY_ID_BCM5719C: return "5719C";
|
||||
+ case TG3_PHY_ID_BCM50610: return "50610";
|
||||
+ case TG3_PHY_ID_BCM50610M: return "50610M";
|
||||
+ case TG3_PHY_ID_BCMAC131: return "AC131";
|
||||
+ case TG3_PHY_ID_BCM57780: return "57780";
|
||||
case TG3_PHY_ID_BCM8002: return "8002/serdes";
|
||||
case 0: return "serdes";
|
||||
default: return "unknown";
|
||||
--- a/drivers/net/tg3.h
|
||||
+++ b/drivers/net/tg3.h
|
||||
@@ -2072,6 +2072,7 @@
|
||||
#define MII_TG3_DSP_EXP8_REJ2MHz 0x0001
|
||||
#define MII_TG3_DSP_EXP8_AEDW 0x0200
|
||||
#define MII_TG3_DSP_EXP75 0x0f75
|
||||
+#define MII_TG3_DSP_EXP75_SUP_CM_OSC 0x0001
|
||||
#define MII_TG3_DSP_EXP96 0x0f96
|
||||
#define MII_TG3_DSP_EXP97 0x0f97
|
||||
|
||||
@@ -2127,6 +2128,8 @@
|
||||
#define MII_TG3_MISC_SHDW_SCR5_LPED 0x0010
|
||||
#define MII_TG3_MISC_SHDW_SCR5_SEL 0x1400
|
||||
|
||||
+#define MII_TG3_MISC_SHDW_RGMII_SEL 0x2c00
|
||||
+
|
||||
#define MII_TG3_TEST1 0x1e
|
||||
#define MII_TG3_TEST1_TRIM_EN 0x0010
|
||||
#define MII_TG3_TEST1_CRC_EN 0x8000
|
||||
@@ -2144,6 +2147,8 @@
|
||||
#define MII_TG3_FET_SHDW_MISCCTRL_MDIX 0x4000
|
||||
|
||||
#define MII_TG3_FET_SHDW_AUXMODE4 0x1a
|
||||
+#define MII_TG3_FET_SHDW_AM4_LED_MODE1 0x0001
|
||||
+#define MII_TG3_FET_SHDW_AM4_LED_MASK 0x0003
|
||||
#define MII_TG3_FET_SHDW_AUXMODE4_SBPD 0x0008
|
||||
|
||||
#define MII_TG3_FET_SHDW_AUXSTAT2 0x1b
|
||||
@@ -2922,6 +2927,10 @@ struct tg3 {
|
||||
#define TG3_PHY_ID_BCM5719C 0x5c0d8a20
|
||||
#define TG3_PHY_ID_BCM5906 0xdc00ac40
|
||||
#define TG3_PHY_ID_BCM8002 0x60010140
|
||||
+#define TG3_PHY_ID_BCM50610 0xbc050d60
|
||||
+#define TG3_PHY_ID_BCM50610M 0xbc050d70
|
||||
+#define TG3_PHY_ID_BCMAC131 0xbc050c70
|
||||
+#define TG3_PHY_ID_BCM57780 0x5c0d8990
|
||||
#define TG3_PHY_ID_INVALID 0xffffffff
|
||||
|
||||
#define PHY_ID_RTL8211C 0x001cc910
|
@ -1,61 +0,0 @@
|
||||
From: Brandon Philips <bphilips@suse.de>
|
||||
Subject: [PATCH] tg3: entropy source
|
||||
Patch-mainline: never
|
||||
References: FATE#307517
|
||||
|
||||
Signed-off-by: Brandon Philips <bphilips@suse.de>
|
||||
|
||||
---
|
||||
drivers/net/tg3.c | 13 +++++++++----
|
||||
1 file changed, 9 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/tg3.c
|
||||
+++ b/drivers/net/tg3.c
|
||||
@@ -15,7 +15,6 @@
|
||||
* notice is accompanying it.
|
||||
*/
|
||||
|
||||
-
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/stringify.h>
|
||||
@@ -67,6 +66,10 @@
|
||||
|
||||
#include "tg3.h"
|
||||
|
||||
+static int entropy = 0;
|
||||
+module_param(entropy, int, 0);
|
||||
+MODULE_PARM_DESC(entropy, "Allow tg3 to populate the /dev/random entropy pool");
|
||||
+
|
||||
#define DRV_MODULE_NAME "tg3"
|
||||
#define TG3_MAJ_NUM 3
|
||||
#define TG3_MIN_NUM 116
|
||||
@@ -8590,10 +8593,13 @@ restart_timer:
|
||||
static int tg3_request_irq(struct tg3 *tp, int irq_num)
|
||||
{
|
||||
irq_handler_t fn;
|
||||
- unsigned long flags;
|
||||
+ unsigned long flags = 0;
|
||||
char *name;
|
||||
struct tg3_napi *tnapi = &tp->napi[irq_num];
|
||||
|
||||
+ if (entropy)
|
||||
+ flags = IRQF_SAMPLE_RANDOM;
|
||||
+
|
||||
if (tp->irq_cnt == 1)
|
||||
name = tp->dev->name;
|
||||
else {
|
||||
@@ -8606,12 +8612,11 @@ static int tg3_request_irq(struct tg3 *t
|
||||
fn = tg3_msi;
|
||||
if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI)
|
||||
fn = tg3_msi_1shot;
|
||||
- flags = IRQF_SAMPLE_RANDOM;
|
||||
} else {
|
||||
fn = tg3_interrupt;
|
||||
if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)
|
||||
fn = tg3_interrupt_tagged;
|
||||
- flags = IRQF_SHARED | IRQF_SAMPLE_RANDOM;
|
||||
+ flags |= IRQF_SHARED;
|
||||
}
|
||||
|
||||
return request_irq(tnapi->irq_vec, fn, flags, name, tnapi);
|
@ -1,78 +0,0 @@
|
||||
From: Vasiliy Kulikov <segooon@gmail.com>
|
||||
Subject: acpi: ec_sys: access user space with get_user()/put_user()
|
||||
Patch-Mainline: hopefully still 2.6.36
|
||||
References: none
|
||||
|
||||
User space pointer may not be dereferenced. Use get_user()/put_user()
|
||||
instead and check their return codes.
|
||||
|
||||
Signed-off-by: Vasiliy Kulikov <segooon@gmail.com>
|
||||
Signed-off-by: Thomas Renninger <trenn@suse.de>
|
||||
---
|
||||
Compile tested.
|
||||
|
||||
drivers/acpi/ec_sys.c | 18 ++++++++++++++----
|
||||
1 files changed, 14 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/acpi/ec_sys.c b/drivers/acpi/ec_sys.c
|
||||
index 0e869b3..cc007d8 100644
|
||||
--- a/drivers/acpi/ec_sys.c
|
||||
+++ b/drivers/acpi/ec_sys.c
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/debugfs.h>
|
||||
+#include <linux/uaccess.h>
|
||||
#include "internal.h"
|
||||
|
||||
MODULE_AUTHOR("Thomas Renninger <trenn@suse.de>");
|
||||
@@ -43,7 +44,6 @@ static ssize_t acpi_ec_read_io(struct file *f, char __user *buf,
|
||||
* struct acpi_ec *ec = ((struct seq_file *)f->private_data)->private;
|
||||
*/
|
||||
unsigned int size = EC_SPACE_SIZE;
|
||||
- u8 *data = (u8 *) buf;
|
||||
loff_t init_off = *off;
|
||||
int err = 0;
|
||||
|
||||
@@ -56,9 +56,15 @@ static ssize_t acpi_ec_read_io(struct file *f, char __user *buf,
|
||||
size = count;
|
||||
|
||||
while (size) {
|
||||
- err = ec_read(*off, &data[*off - init_off]);
|
||||
+ u8 byte_read;
|
||||
+ err = ec_read(*off, &byte_read);
|
||||
if (err)
|
||||
return err;
|
||||
+ if (put_user(byte_read, buf + *off - init_off)) {
|
||||
+ if (*off - init_off)
|
||||
+ return *off - init_off; /* partial read */
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
*off += 1;
|
||||
size--;
|
||||
}
|
||||
@@ -74,7 +80,6 @@ static ssize_t acpi_ec_write_io(struct file *f, const char __user *buf,
|
||||
|
||||
unsigned int size = count;
|
||||
loff_t init_off = *off;
|
||||
- u8 *data = (u8 *) buf;
|
||||
int err = 0;
|
||||
|
||||
if (*off >= EC_SPACE_SIZE)
|
||||
@@ -85,7 +90,12 @@ static ssize_t acpi_ec_write_io(struct file *f, const char __user *buf,
|
||||
}
|
||||
|
||||
while (size) {
|
||||
- u8 byte_write = data[*off - init_off];
|
||||
+ u8 byte_write;
|
||||
+ if (get_user(byte_write, buf + *off - init_off)) {
|
||||
+ if (*off - init_off)
|
||||
+ return *off - init_off; /* partial write */
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
err = ec_write(*off, byte_write);
|
||||
if (err)
|
||||
return err;
|
||||
--
|
||||
1.7.0.4
|
||||
|
@ -1,67 +0,0 @@
|
||||
From: Nick Piggin <npiggin@suse.de>
|
||||
Subject: be more aggressive with zone reclaims
|
||||
References: bnc#476525
|
||||
Patch-mainline: no
|
||||
|
||||
The zone reclaim design is not very good for parallel allocations.
|
||||
The primary problem is that only one thread is allowed to perform
|
||||
zone-reclaim at a time. If another thread needs memory from that
|
||||
zone/node, then its zone-reclaim will fail and it will be forced
|
||||
to fall back to allocating from another zone.
|
||||
|
||||
Additionally, the default zone reclaim priority is insufficient
|
||||
for massively parallel allocations. Lower ZONE_RECLAIM_PRIORITY
|
||||
to fix it. This can result in higher latency spikes, but similar
|
||||
kind of page allocation latency can often be encountered as
|
||||
normal part of page reclaim when pagecache fills memory.
|
||||
|
||||
Signed-off-by: Petr Tesarik <ptesarik@suse.cz>
|
||||
|
||||
---
|
||||
mm/vmscan.c | 13 ++++---------
|
||||
1 file changed, 4 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -2515,7 +2515,7 @@ int zone_reclaim_mode __read_mostly;
|
||||
* of a node considered for each zone_reclaim. 4 scans 1/16th of
|
||||
* a zone.
|
||||
*/
|
||||
-#define ZONE_RECLAIM_PRIORITY 4
|
||||
+#define ZONE_RECLAIM_PRIORITY 0
|
||||
|
||||
/*
|
||||
* Percentage of pages in a zone that must be unmapped for zone_reclaim to
|
||||
@@ -2620,6 +2620,8 @@ static int __zone_reclaim(struct zone *z
|
||||
|
||||
slab_reclaimable = zone_page_state(zone, NR_SLAB_RECLAIMABLE);
|
||||
if (slab_reclaimable > zone->min_slab_pages) {
|
||||
+ unsigned long lru_pages = zone_reclaimable_pages(zone);
|
||||
+
|
||||
/*
|
||||
* shrink_slab() does not currently allow us to determine how
|
||||
* many pages were freed in this zone. So we take the current
|
||||
@@ -2630,10 +2632,7 @@ static int __zone_reclaim(struct zone *z
|
||||
* Note that shrink_slab will free memory on all zones and may
|
||||
* take a long time.
|
||||
*/
|
||||
- while (shrink_slab(sc.nr_scanned, gfp_mask, order) &&
|
||||
- zone_page_state(zone, NR_SLAB_RECLAIMABLE) >
|
||||
- slab_reclaimable - nr_pages)
|
||||
- ;
|
||||
+ shrink_slab(sc.nr_scanned, gfp_mask, lru_pages);
|
||||
|
||||
/*
|
||||
* Update nr_reclaimed by the number of slab pages we
|
||||
@@ -2687,11 +2686,7 @@ int zone_reclaim(struct zone *zone, gfp_
|
||||
if (node_state(node_id, N_CPU) && node_id != numa_node_id())
|
||||
return ZONE_RECLAIM_NOSCAN;
|
||||
|
||||
- if (zone_test_and_set_flag(zone, ZONE_RECLAIM_LOCKED))
|
||||
- return ZONE_RECLAIM_NOSCAN;
|
||||
-
|
||||
ret = __zone_reclaim(zone, gfp_mask, order);
|
||||
- zone_clear_flag(zone, ZONE_RECLAIM_LOCKED);
|
||||
|
||||
if (!ret)
|
||||
count_vm_event(PGSCAN_ZONE_RECLAIM_FAILED);
|
@ -1,61 +0,0 @@
|
||||
From fd0e435b0fe85622f167b84432552885a4856ac8 Mon Sep 17 00:00:00 2001
|
||||
From: Phil Oester <kernel@linuxace.com>
|
||||
Date: Mon, 14 Mar 2011 06:22:04 +0000
|
||||
Subject: [PATCH] bonding: Incorrect TX queue offset
|
||||
Git-commit: fd0e435b0fe85622f167b84432552885a4856ac8
|
||||
Patch-mainline: v2.6.39-rc1~468^2~15
|
||||
Reference: bnc#687116, CVE-2011-1581
|
||||
|
||||
When packets come in from a device with >= 16 receive queues
|
||||
headed out a bonding interface, syslog gets filled with this:
|
||||
|
||||
kernel: bond0 selects TX queue 16, but real number of TX queues is 16
|
||||
|
||||
because queue_mapping is offset by 1. Adjust return value
|
||||
to account for the offset.
|
||||
|
||||
This is a revision of my earlier patch (which did not use the
|
||||
skb_rx_queue_* helpers - thanks to Ben for the suggestion).
|
||||
Andy submitted a similar patch which emits a pr_warning on
|
||||
invalid queue selection, but I believe the log spew is
|
||||
not useful. We can revisit that question in the future,
|
||||
but in the interim I believe fixing the core problem is
|
||||
worthwhile.
|
||||
|
||||
Signed-off-by: Phil Oester <kernel@linuxace.com>
|
||||
Signed-off-by: Andy Gospodarek <andy@greyhouse.net>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Brandon Philips <bphilips@suse.de>
|
||||
|
||||
---
|
||||
drivers/net/bonding/bond_main.c | 11 +++++++++--
|
||||
1 files changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
|
||||
index 3ad4f50..a93d941 100644
|
||||
--- a/drivers/net/bonding/bond_main.c
|
||||
+++ b/drivers/net/bonding/bond_main.c
|
||||
@@ -4341,11 +4341,18 @@ static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb)
|
||||
{
|
||||
/*
|
||||
* This helper function exists to help dev_pick_tx get the correct
|
||||
- * destination queue. Using a helper function skips the a call to
|
||||
+ * destination queue. Using a helper function skips a call to
|
||||
* skb_tx_hash and will put the skbs in the queue we expect on their
|
||||
* way down to the bonding driver.
|
||||
*/
|
||||
- return skb->queue_mapping;
|
||||
+ u16 txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0;
|
||||
+
|
||||
+ if (unlikely(txq >= dev->real_num_tx_queues)) {
|
||||
+ do
|
||||
+ txq -= dev->real_num_tx_queues;
|
||||
+ while (txq >= dev->real_num_tx_queues);
|
||||
+ }
|
||||
+ return txq;
|
||||
}
|
||||
|
||||
static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
--
|
||||
1.7.3.4
|
||||
|
@ -1,45 +0,0 @@
|
||||
From: jbeulich@novell.com
|
||||
Subject: Module use count must be updated as bridges are created/destroyed
|
||||
Patch-mainline: unknown
|
||||
References: 267651
|
||||
|
||||
Otherwise 'modprobe -r' on a module having a dependency on bridge will
|
||||
implicitly unload bridge, bringing down all connectivity that was using
|
||||
bridges.
|
||||
|
||||
---
|
||||
net/bridge/br_if.c | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
--- a/net/bridge/br_if.c
|
||||
+++ b/net/bridge/br_if.c
|
||||
@@ -291,6 +291,11 @@ int br_add_bridge(struct net *net, const
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
|
||||
+ if (!try_module_get(THIS_MODULE)) {
|
||||
+ free_netdev(dev);
|
||||
+ return -ENOENT;
|
||||
+ }
|
||||
+
|
||||
rtnl_lock();
|
||||
if (strchr(dev->name, '%')) {
|
||||
ret = dev_alloc_name(dev, dev->name);
|
||||
@@ -309,6 +314,8 @@ int br_add_bridge(struct net *net, const
|
||||
unregister_netdevice(dev);
|
||||
out:
|
||||
rtnl_unlock();
|
||||
+ if (ret)
|
||||
+ module_put(THIS_MODULE);
|
||||
return ret;
|
||||
|
||||
out_free:
|
||||
@@ -340,6 +347,8 @@ int br_del_bridge(struct net *net, const
|
||||
del_br(netdev_priv(dev), NULL);
|
||||
|
||||
rtnl_unlock();
|
||||
+ if (ret == 0)
|
||||
+ module_put(THIS_MODULE);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,74 +0,0 @@
|
||||
From 468c3f924f043cad7a04f4f4d5224a2c9bc886c1 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Slaby <jslaby@suse.cz>
|
||||
Date: Sun, 13 Mar 2011 06:54:31 +0000
|
||||
Subject: NET: cdc-phonet, handle empty phonet header
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Git-commit: 468c3f924f043cad7a04f4f4d5224a2c9bc886c1
|
||||
Patch-mainline: yes
|
||||
References: bnc#673992
|
||||
|
||||
Currently, for N 5800 XM I get:
|
||||
cdc_phonet: probe of 1-6:1.10 failed with error -22
|
||||
|
||||
It's because phonet_header is empty. Extra altsetting looks like
|
||||
there:
|
||||
E 05 24 00 01 10 03 24 ab 05 24 06 0a 0b 04 24 fd .$....$..$....$.
|
||||
E 00 .
|
||||
|
||||
I don't see the header used anywhere so just check if the phonet
|
||||
descriptor is there, not the structure itself.
|
||||
|
||||
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
|
||||
Cc: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
|
||||
Cc: David S. Miller <davem@davemloft.net>
|
||||
Acked-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/usb/cdc-phonet.c | 9 +++------
|
||||
1 files changed, 3 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/usb/cdc-phonet.c b/drivers/net/usb/cdc-phonet.c
|
||||
index 4cf4e36..f967913 100644
|
||||
--- a/drivers/net/usb/cdc-phonet.c
|
||||
+++ b/drivers/net/usb/cdc-phonet.c
|
||||
@@ -328,13 +328,13 @@ int usbpn_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
||||
{
|
||||
static const char ifname[] = "usbpn%d";
|
||||
const struct usb_cdc_union_desc *union_header = NULL;
|
||||
- const struct usb_cdc_header_desc *phonet_header = NULL;
|
||||
const struct usb_host_interface *data_desc;
|
||||
struct usb_interface *data_intf;
|
||||
struct usb_device *usbdev = interface_to_usbdev(intf);
|
||||
struct net_device *dev;
|
||||
struct usbpn_dev *pnd;
|
||||
u8 *data;
|
||||
+ int phonet = 0;
|
||||
int len, err;
|
||||
|
||||
data = intf->altsetting->extra;
|
||||
@@ -355,10 +355,7 @@ int usbpn_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
||||
(struct usb_cdc_union_desc *)data;
|
||||
break;
|
||||
case 0xAB:
|
||||
- if (phonet_header || dlen < 5)
|
||||
- break;
|
||||
- phonet_header =
|
||||
- (struct usb_cdc_header_desc *)data;
|
||||
+ phonet = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -366,7 +363,7 @@ int usbpn_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
||||
len -= dlen;
|
||||
}
|
||||
|
||||
- if (!union_header || !phonet_header)
|
||||
+ if (!union_header || !phonet)
|
||||
return -EINVAL;
|
||||
|
||||
data_intf = usb_ifnum_to_if(usbdev, union_header->bSlaveInterface0);
|
||||
--
|
||||
1.7.4.1
|
||||
|
@ -1,65 +0,0 @@
|
||||
From: Thomas Renninger <trenn@suse.de>
|
||||
Subject: CPUFREQ: ondemand: Limit default sampling rate to 300ms max.
|
||||
References: bnc#464461
|
||||
Patch-Mainline: never, SLE11 only
|
||||
|
||||
Modified for SP1 by Jiri Bohac <jbohac@suse.cz>
|
||||
|
||||
HW cpufreq drivers (e.g. all non-acpi AMD) may report too high latency values.
|
||||
The default sampling rate (how often the ondemand/conservative governor
|
||||
checks for frequency adjustments) may therefore be much too high,
|
||||
resulting in performance loss.
|
||||
|
||||
Restrict default sampling rate to 300ms. 333ms sampling rate is field
|
||||
tested with userspace governors, 300ms should be a fine maximum default
|
||||
value for the ondemand kernel governor for all HW out there.
|
||||
|
||||
Set default up_threshold to 40 on multi core systems.
|
||||
This should avoid effects where two CPU intensive threads are waiting on
|
||||
each other on separate cores. On a single core machine these would all be
|
||||
processed on one core resulting in higher utilization of the one core.
|
||||
|
||||
---
|
||||
drivers/cpufreq/cpufreq_ondemand.c | 24 ++++++++++++++++++++++++
|
||||
1 file changed, 24 insertions(+)
|
||||
|
||||
--- a/drivers/cpufreq/cpufreq_ondemand.c
|
||||
+++ b/drivers/cpufreq/cpufreq_ondemand.c
|
||||
@@ -35,6 +35,7 @@
|
||||
#define MICRO_FREQUENCY_MIN_SAMPLE_RATE (10000)
|
||||
#define MIN_FREQUENCY_UP_THRESHOLD (11)
|
||||
#define MAX_FREQUENCY_UP_THRESHOLD (100)
|
||||
+#define MAX_DEFAULT_SAMPLING_RATE (300 * 1000U)
|
||||
|
||||
/*
|
||||
* The polling frequency of this governor depends on the capability of
|
||||
@@ -736,6 +737,29 @@ static int cpufreq_governor_dbs(struct c
|
||||
dbs_tuners_ins.sampling_rate =
|
||||
max(min_sampling_rate,
|
||||
latency * LATENCY_MULTIPLIER);
|
||||
+ /*
|
||||
+ * Cut def_sampling rate to 300ms if it was above,
|
||||
+ * still consider to not set it above latency
|
||||
+ * transition * 100
|
||||
+ */
|
||||
+ if (dbs_tuners_ins.sampling_rate > MAX_DEFAULT_SAMPLING_RATE) {
|
||||
+ dbs_tuners_ins.sampling_rate =
|
||||
+ max(min_sampling_rate, MAX_DEFAULT_SAMPLING_RATE);
|
||||
+ printk(KERN_INFO "CPUFREQ: ondemand sampling "
|
||||
+ "rate set to %d ms\n",
|
||||
+ dbs_tuners_ins.sampling_rate / 1000);
|
||||
+ }
|
||||
+ /*
|
||||
+ * Be conservative in respect to performance.
|
||||
+ * If an application calculates using two threads
|
||||
+ * depending on each other, they will be run on several
|
||||
+ * CPU cores resulting on 50% load on both.
|
||||
+ * SLED might still want to prefer 80% up_threshold
|
||||
+ * by default, but we cannot differ that here.
|
||||
+ */
|
||||
+ if (num_online_cpus() > 1)
|
||||
+ dbs_tuners_ins.up_threshold =
|
||||
+ DEF_FREQUENCY_UP_THRESHOLD / 2;
|
||||
dbs_tuners_ins.io_is_busy = should_io_be_busy();
|
||||
}
|
||||
mutex_unlock(&dbs_mutex);
|
@ -1,29 +0,0 @@
|
||||
From: Hannes Reinecke <hare@suse.de>
|
||||
Subject: Reattach device handler for multipath devices
|
||||
References: bnc#435688
|
||||
Patch-mainline: not yet
|
||||
|
||||
The multipath daemon might have specified a different device_handler
|
||||
than the one a device is attached to by default.
|
||||
So we should try to re-attach with the user-specified device_handler
|
||||
and only return an error if that fails.
|
||||
And we should _not_ detach existing hardware handlers. This will
|
||||
set the path to failed during failover.
|
||||
|
||||
Signed-off-by: Hannes Reinecke <hare@suse.de
|
||||
|
||||
---
|
||||
drivers/md/dm-mpath.c | 2 --
|
||||
1 file changed, 2 deletions(-)
|
||||
|
||||
--- a/drivers/md/dm-mpath.c
|
||||
+++ b/drivers/md/dm-mpath.c
|
||||
@@ -168,8 +168,6 @@ static void free_pgpaths(struct list_hea
|
||||
|
||||
list_for_each_entry_safe(pgpath, tmp, pgpaths, list) {
|
||||
list_del(&pgpath->list);
|
||||
- if (m->hw_handler_name)
|
||||
- scsi_dh_detach(bdev_get_queue(pgpath->path.dev->bdev));
|
||||
dm_put_device(ti, pgpath->path.dev);
|
||||
free_pgpath(pgpath);
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
From: Nikanth Karthikesan <knikanth@suse.de>
|
||||
Subject: Release md->map_lock before set_disk_ro
|
||||
Patch-mainline: No
|
||||
References: bnc#556899 bnc#479784
|
||||
|
||||
Signed-off-by: Nikanth Karthikesan <knikanth@suse.de>
|
||||
|
||||
Calling set_disk_ro() with irqs disabled triggers a warning.
|
||||
|
||||
set_disk_ro() can be called outside the
|
||||
write_lock_irqsave(&md->map_lock)? And to get the
|
||||
dm_table_get_mode(md->map), we just need to hold a reference
|
||||
with dm_get_table() and dm_table_put()
|
||||
|
||||
---
|
||||
drivers/md/dm.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/md/dm.c
|
||||
+++ b/drivers/md/dm.c
|
||||
@@ -2174,12 +2174,15 @@ static struct dm_table *__bind(struct ma
|
||||
old_map = md->map;
|
||||
md->map = t;
|
||||
dm_table_set_restrictions(t, q, limits);
|
||||
+ write_unlock_irqrestore(&md->map_lock, flags);
|
||||
+
|
||||
+ dm_table_get(md->map);
|
||||
if (!(dm_table_get_mode(t) & FMODE_WRITE)) {
|
||||
set_disk_ro(md->disk, 1);
|
||||
} else {
|
||||
set_disk_ro(md->disk, 0);
|
||||
}
|
||||
- write_unlock_irqrestore(&md->map_lock, flags);
|
||||
+ dm_table_put(md->map);
|
||||
|
||||
return old_map;
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
From: Hannes Reinecke <hare@suse.de>
|
||||
Subject: dm multipath devices are not getting created for readonly devices
|
||||
References: bnc#382705
|
||||
Patch-mainline: not yet
|
||||
|
||||
Currently we cannot create device-mapper tables for multipath devices
|
||||
whenever they are read-only.
|
||||
This patch modifies the device-mapper to set the 'READ-ONLY' flag
|
||||
automatically whenever a read-only is added to the table.
|
||||
|
||||
Signed-off-by: Hannes Reinecke <hare@suse.de>
|
||||
|
||||
---
|
||||
drivers/md/dm-table.c | 10 +++++++++-
|
||||
drivers/md/dm.c | 18 ++++++++++++++++--
|
||||
2 files changed, 25 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/md/dm-table.c
|
||||
+++ b/drivers/md/dm-table.c
|
||||
@@ -465,11 +465,19 @@ static int __table_get_device(struct dm_
|
||||
dd->dm_dev.mode = mode;
|
||||
dd->dm_dev.bdev = NULL;
|
||||
|
||||
- if ((r = open_dev(dd, dev, t->md))) {
|
||||
+ r = open_dev(dd, dev, t->md);
|
||||
+ if (r == -EROFS) {
|
||||
+ dd->dm_dev.mode &= ~FMODE_WRITE;
|
||||
+ r = open_dev(dd, dev, t->md);
|
||||
+ }
|
||||
+ if (r) {
|
||||
kfree(dd);
|
||||
return r;
|
||||
}
|
||||
|
||||
+ if (dd->dm_dev.mode != mode)
|
||||
+ t->mode = dd->dm_dev.mode;
|
||||
+
|
||||
format_dev_t(dd->dm_dev.name, dev);
|
||||
|
||||
atomic_set(&dd->count, 0);
|
||||
--- a/drivers/md/dm.c
|
||||
+++ b/drivers/md/dm.c
|
||||
@@ -343,16 +343,25 @@ int dm_deleting_md(struct mapped_device
|
||||
static int dm_blk_open(struct block_device *bdev, fmode_t mode)
|
||||
{
|
||||
struct mapped_device *md;
|
||||
+ int retval = 0;
|
||||
|
||||
spin_lock(&_minor_lock);
|
||||
|
||||
md = bdev->bd_disk->private_data;
|
||||
- if (!md)
|
||||
+ if (!md) {
|
||||
+ retval = -ENXIO;
|
||||
goto out;
|
||||
+ }
|
||||
|
||||
if (test_bit(DMF_FREEING, &md->flags) ||
|
||||
dm_deleting_md(md)) {
|
||||
md = NULL;
|
||||
+ retval = -ENXIO;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (get_disk_ro(md->disk) && (mode & FMODE_WRITE)) {
|
||||
+ md = NULL;
|
||||
+ retval = -EROFS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -364,7 +373,7 @@ out:
|
||||
out:
|
||||
spin_unlock(&_minor_lock);
|
||||
|
||||
- return md ? 0 : -ENXIO;
|
||||
+ return retval;
|
||||
}
|
||||
|
||||
static int dm_blk_close(struct gendisk *disk, fmode_t mode)
|
||||
@@ -2165,6 +2174,11 @@ static struct dm_table *__bind(struct ma
|
||||
old_map = md->map;
|
||||
md->map = t;
|
||||
dm_table_set_restrictions(t, q, limits);
|
||||
+ if (!(dm_table_get_mode(t) & FMODE_WRITE)) {
|
||||
+ set_disk_ro(md->disk, 1);
|
||||
+ } else {
|
||||
+ set_disk_ro(md->disk, 0);
|
||||
+ }
|
||||
write_unlock_irqrestore(&md->map_lock, flags);
|
||||
|
||||
return old_map;
|
@ -1,63 +0,0 @@
|
||||
From: Ludwig Nussel <lnussel@novell.com>
|
||||
Subject: make nf_conntrack_slp actually work
|
||||
References: bnc#470963
|
||||
Patch-mainline: not yet, depends on patches.suse/netfilter-ip_conntrack_slp.patch
|
||||
|
||||
Acked-by: Jeff Mahoney <jeffm@suse.com>
|
||||
---
|
||||
|
||||
net/netfilter/nf_conntrack_slp.c | 18 +++++++++++-------
|
||||
1 file changed, 11 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/net/netfilter/nf_conntrack_slp.c
|
||||
+++ b/net/netfilter/nf_conntrack_slp.c
|
||||
@@ -47,15 +47,15 @@ static int help(struct sk_buff *skb, uns
|
||||
struct nf_conn *ct, enum ip_conntrack_info ctinfo)
|
||||
{
|
||||
struct nf_conntrack_expect *exp;
|
||||
- struct iphdr *iph = ip_hdr(skb);
|
||||
struct rtable *rt = skb_rtable(skb);
|
||||
struct in_device *in_dev;
|
||||
__be32 mask = 0;
|
||||
+ __be32 src = 0;
|
||||
|
||||
/* we're only interested in locally generated packets */
|
||||
if (skb->sk == NULL)
|
||||
goto out;
|
||||
- if (rt == NULL || !(rt->rt_flags & RTCF_BROADCAST))
|
||||
+ if (rt == NULL || !(rt->rt_flags & (RTCF_MULTICAST|RTCF_BROADCAST)))
|
||||
goto out;
|
||||
if (CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL)
|
||||
goto out;
|
||||
@@ -64,15 +64,18 @@ static int help(struct sk_buff *skb, uns
|
||||
in_dev = __in_dev_get_rcu(rt->dst.dev);
|
||||
if (in_dev != NULL) {
|
||||
for_primary_ifa(in_dev) {
|
||||
- if (ifa->ifa_broadcast == iph->daddr) {
|
||||
- mask = ifa->ifa_mask;
|
||||
- break;
|
||||
- }
|
||||
+ /* this is a hack as slp uses multicast we can't match
|
||||
+ * the destination address to some broadcast address. So
|
||||
+ * just take the first one. Better would be to install
|
||||
+ * expectations for all addresses */
|
||||
+ mask = ifa->ifa_mask;
|
||||
+ src = ifa->ifa_broadcast;
|
||||
+ break;
|
||||
} endfor_ifa(in_dev);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
- if (mask == 0)
|
||||
+ if (mask == 0 || src == 0)
|
||||
goto out;
|
||||
|
||||
exp = nf_ct_expect_alloc(ct);
|
||||
@@ -80,6 +83,7 @@ static int help(struct sk_buff *skb, uns
|
||||
goto out;
|
||||
|
||||
exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
|
||||
+ exp->tuple.src.u3.ip = src;
|
||||
exp->tuple.src.u.udp.port = htons(SLP_PORT);
|
||||
|
||||
exp->mask.src.u3.ip = mask;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user