-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathindex4.html
More file actions
750 lines (712 loc) · 46.6 KB
/
index4.html
File metadata and controls
750 lines (712 loc) · 46.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<title>Store Halfword Byte-Reverse Indexed</title>
<meta name="author" content="OzLabs">
<link href="https://sthbrx.github.io/rss.xml" type="application/rss+xml" rel="alternate"
title="Store Halfword Byte-Reverse Indexed RSS Feed" />
<!-- http://t.co/dKP3o1e -->
<meta name="HandheldFriendly" content="True">
<meta name="MobileOptimized" content="320">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://sthbrx.github.io/favicon.png" rel="icon">
<link href="https://sthbrx.github.io/theme/css/main.css" media="screen, projection"
rel="stylesheet" type="text/css">
<link href="//fonts.googleapis.com/css?family=PT+Serif:regular,italic,bold,bolditalic"
rel="stylesheet" type="text/css">
<link href="//fonts.googleapis.com/css?family=PT+Sans:regular,italic,bold,bolditalic"
rel="stylesheet" type="text/css">
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function() {
var ts = document.createElement('span')
ts.className = 'toggle-sidebar'
ts = document.getElementById('content').appendChild(ts);
ts.addEventListener('click', function(e) {
e.preventDefault();
body = document.getElementsByTagName('body')[0];
bodyClasses = body.classList.toggle('collapse-sidebar');
});
var sections = document.querySelectorAll('aside.sidebar > section');
if (sections.length > 1) {
for (index = 0; index < sections.length; index++) {
section = sections[index];
if ((sections.length >= 3) && index % 3 === 0) {
section.classList.add("first");
}
var count = ((index +1) % 2) ? "odd" : "even";
section.classList.add(count);
}
}
if (sections.length >= 3) {
document.querySelector('aside.sidebar').classList.add('thirds');
}
});
</script>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-91189608-1', 'auto');
ga('send', 'pageview');
</script>
</head>
<body>
<header role="banner"><hgroup>
<h1><a href="https://sthbrx.github.io/">Store Halfword Byte-Reverse Indexed</a></h1>
<h2>A Power Technical Blog</h2>
</hgroup></header>
<nav role="navigation"><ul class="subscription" data-subscription="rss">
<li><a href="https://sthbrx.github.io/rss.xml" rel="subscribe-rss">RSS</a></li>
</ul>
<ul class="main-navigation">
<li >
<a href="https://sthbrx.github.io/category/cryptography.html">Cryptography</a>
</li>
<li >
<a href="https://sthbrx.github.io/category/development.html">Development</a>
</li>
<li >
<a href="https://sthbrx.github.io/category/education.html">Education</a>
</li>
<li >
<a href="https://sthbrx.github.io/category/openpower.html">OpenPOWER</a>
</li>
<li >
<a href="https://sthbrx.github.io/category/performance.html">Performance</a>
</li>
<li >
<a href="https://sthbrx.github.io/category/petitboot.html">Petitboot</a>
</li>
<li >
<a href="https://sthbrx.github.io/category/snowpatch.html">snowpatch</a>
</li>
<li >
<a href="https://sthbrx.github.io/category/virtualisation-and-emulation.html">Virtualisation and Emulation</a>
</li>
</ul></nav>
<div id="main">
<div id="content">
<div class="blog-index">
<article>
<header>
<h1 class="entry-title">
<a href="https://sthbrx.github.io/blog/2019/02/25/what-do-you-mean-no/">What Do You Mean "No"?</a>
</h1>
<p class="meta">
<time datetime="2019-02-25T16:47:00+11:00" pubdate>Mon 25 February 2019</time> </p>
</header>
<div class="byline_index">
<span class="byline author vcard">
Posted by <span class="fn">
<a href="https://sthbrx.github.io/author/samuel-mendoza-jonas.html">Samuel Mendoza-Jonas</a>
</span>
</span>
<time datetime="2019-02-25T16:47:00+11:00" pubdate>Mon 25 February 2019</time></div>
<div class="entry-content"><p>Quite often when building small Linux images having separate user accounts isn't always at the top of the list of things to include. Petitboot is no different; the most common operations like mounting disks, configuring interfaces, and calling <code>kexec</code> all require root and Petitboot generally only exists long enough to boot into the next thing, so why not run it all as root?</p>
<p>The picture is less clear when we start to think about what is possible to do in Petitboot by default. If someone comes across an open Petitboot console they're only a few keystrokes away from wiping disks, changing files, or even flashing firmware. Depending on how your system is used that may or may not be something you care about, but over time there have been a few requests to "add a password screen to Petitboot" to at least make it so that the system isn't open season for whoever sees it.</p>
<h2>Enter Password:</h2>
<p>The most direct way to avoid this would be to slap a password prompt onto Petitboot before any changes can be made. There are two immediate drawbacks to this:</p>
<ul>
<li>The Petitboot UI still runs as root, and</li>
<li>Exiting to the shell gives the user root permissions as well.</li>
</ul>
<p>There is already a <a href="https://github.com/open-power/petitboot/commit/f5dab0206a3baca73895a587583ddfa402f8f569">mechanism</a> to prevent the user exiting to the shell, but this puts all of our eggs in the basket of petitboot-nc being a secure program. If a user can accidentally or otherwise find a way to exit or crash the UI then they're immediately in a root shell, and while petitboot-nc is a good UI it was never designed to be a hardened program protecting the system.</p>
<h2>You Have No Power Here</h2>
<p>The idea instead as of Petitboot v1.10.0 is not to care if the user drops to the shell; because now it's completely unprivileged.</p>
<p><img alt="Normal shell" src="/images/sammj/users-reboot.png"></p>
<p>The only process now that runs as root is pb-discover itself; the console, UI, and helper scripts run as a new 'petituser'. For the server and clients to still communicate the "petitiboot.ui" socket permissions are modified to allow processes that are part of the 'petitgroup' to connect. However now if pb-discover notices that a client in the petitgroup is connecting (or more accurately the client isn't running as root) by default it ignores any commands from it that would configure or boot the system.</p>
<p>A new command, <code>PB_PROTOCOL_ACTION_AUTHENTICATE</code>, lets a client send a password to the server to then be allowed to send all the usual commands like updating the config or booting a specific option. This keeps all the authentication on the server side, avoiding writing any "secure" ncurses code. In the UI the biggest difference is that when trying to change something the user will hit a password field:</p>
<p><img alt="Denied" src="/images/sammj/users-denied.png"></p>
<p>Then the password is sent to the server, checked, and if correct the action goes ahead.</p>
<h2>Whose Passwords?</h2>
<p>But where does this password come from? Technically it's just the root password. The server computes a hash of the supplied password and compares it against the system's root password. Similarly in the shell the user can run <code>sudo</code> with the root password to enter a full shell if needed:</p>
<p><img alt="Oops" src="/images/sammj/users-dd-random.png"></p>
<p>Petitboot of course runs in memory, and writing a root password into the image itself would mean recompiling to change the password, so instead Petitboot pulls the root password from NVRAM. On startup Petitboot reads the <code>petitboot,password</code> parameter which is the <em>hash</em> of the root password and updates <code>/etc/shadow</code> with it. This happens before any clients are up or can connect to the server.</p>
<h2>Don't Panic</h2>
<p>By default no password is set. After all we don't want people upgrading and then being somehow locked out of their system. For ease of use, and for testing-purposes, if no password is configured and the user drops to the shell it is automatically upgraded to a root shell:</p>
<p><img alt="Elevated" src="/images/sammj/users-elevated.png"></p>
<p>To set a password there is a new subscreen in System Configuration:</p>
<p><img alt="New Password" src="/images/sammj/users-new-password.png"></p>
<p>This sends an authentication command to the server, and assuming the client is authenticated with the current password as well pb-discover updates the shadow file, and writes the hash back to NVRAM.</p>
<hr>
<p>User support exists in Petitboot v1.10.0 onwards. You will also need some support in your build system to set up the users, see how <a href="https://github.com/open-power/op-build/commit/7b5f1efbee6ace9d4ee80640875aa3ad57e95c69">op-build did it for an example</a>.</p>
<p>There are a few items on the TODO list still which would be good to have. For example storing the password hash in an attached TPM if available, as well as splitting out more of what runs as root; for example the bootloader parsers in pb-discover preferably wouldn't run with root privileges, but they are all part of the one binary.</p>
<p>As always, comments, suggestions, and patches welcome on the <a href="https://lists.ozlabs.org/listinfo/petitboot">list</a>!</p></div>
</article>
<article>
<header>
<h1 class="entry-title">
<a href="https://sthbrx.github.io/blog/2018/12/19/ipmi-initiating-better-overrides/">IPMI: Initiating Better Overrides</a>
</h1>
<p class="meta">
<time datetime="2018-12-19T10:08:00+11:00" pubdate>Wed 19 December 2018</time> </p>
</header>
<div class="byline_index">
<span class="byline author vcard">
Posted by <span class="fn">
<a href="https://sthbrx.github.io/author/samuel-mendoza-jonas.html">Samuel Mendoza-Jonas</a>
</span>
</span>
<time datetime="2018-12-19T10:08:00+11:00" pubdate>Wed 19 December 2018</time></div>
<div class="entry-content"><p>On platforms that support it Petitboot can interact with the inband IPMI interface to pull information from the BMC. One particularly useful example of this is the "Get System Boot Options" command which we use to implement boot "overrides". By setting parameter 5 of the command a user can remotely force Petitboot to boot from only one class of device or disable autoboot completely. This is great for automation or debug purposes, but since it can only specify device types like "disk" or "network" it can't be used to boot from specific devices.</p>
<p>Introducing..</p>
<p><strong>The Boot Initiator Mailbox</strong></p>
<p>Alexander Amelkin <a href="https://github.com/open-power/petitboot/issues/45">pointed out</a> that the "Get System Boot Options" command also specifies parameter 7, "Boot Initiator Mailbox". This parameter just defines a region of vendor-defined data that can be used to influence the booting behaviour of the system. The parameter description specifies that a BMC must support at least 80 bytes of data in that mailbox so as Alex pointed out we could easily use it to set a partition UUID. But why stop there? Let's go further and use the mailbox to provide an alterate "petitboot,bootdevs=.." parameter and let a user set a full substitute boot order!</p>
<p><strong>The Mailbox Format</strong></p>
<p>Parameter 7 has two fields, 1 byte for the "set selector", and up to 16 bytes of "block data". The spec sets the minimum amount of data to support at 80 bytes, which means a BMC must support at least 5 of these 16-byte "blocks" which can be individually accessed via the set selector. Aside from the first 3 bytes which must be an IANA ID number, the rest of the data is defined by us.</p>
<p>So if we want to set an alternate Petitboot boot order such as "network, usb, disk", the format of the mailbox would be:</p>
<div class="highlight"><pre><span></span><code><span class="gh">Block # | Block Data |</span>
<span class="gh">-----------------------------------------</span>
0 |2|0|0|p|e|t|i|t|b|o|o|t|,|b|o|o|
1 |t|d|e|v|s|=|n|e|t|w|o|r|k| |u|s|
2 |b| |d|i|s|k| | | | | | | | | | |
3 | | | | | | | | | | | | | | | | |
4 | | | | | | | | | | | | | | | | |
</code></pre></div>
<p>Where the string is null-terminated, <code>2,0,0</code> is the IBM IANA ID, and the contents of any remaining data is not important. The <a href="https://github.com/open-power/petitboot/blob/master/utils/ipmi-mailbox-config.py">ipmi-mailbox-config.py</a> script constructs and sends the required IPMI commands from a given parameter string to make this easier, eg:</p>
<div class="highlight"><pre><span></span><code>./utils/ipmi-mailbox-config.py -b bmc-ip -u user -p pass -m 5 \
-c "petitboot,bootdevs=uuid:c6e4c4f9-a9a2-4c30-b0db-6fa00f433b3b"
</code></pre></div>
<p><img alt="Active Mailbox Override" src="/images/sammj/ipmi-mailbox.png"></p>
<hr>
<p>That is basically all there is to it. Setting a boot order this way overrides the existing order from NVRAM if there is one. Parameter 7 doesn't have a 'persistent' flag so the contents need to either be manually cleared from the BMC or cleared via the "Clear" button in the System Configuration screen.</p>
<p>From the machines I've been able to test on at least AMI BMCs support the mailbox, and hopefully <a href="https://lists.ozlabs.org/pipermail/openbmc/2018-December/014224.html">OpenBMC</a> will be able to add it to their IPMI implementation. This is supported in Petitboot as of v1.10.0 so go ahead and try it out!</p></div>
</article>
<article>
<header>
<h1 class="entry-title">
<a href="https://sthbrx.github.io/blog/2018/11/21/openpower-summit-europe-2018-a-software-developers-introduction-to-opencapi/">OpenPOWER Summit Europe 2018: A Software Developer's Introduction to OpenCAPI</a>
</h1>
<p class="meta">
<time datetime="2018-11-21T18:20:00+11:00" pubdate>Wed 21 November 2018</time> </p>
</header>
<div class="byline_index">
<span class="byline author vcard">
Posted by <span class="fn">
<a href="https://sthbrx.github.io/author/andrew-donnellan.html">Andrew Donnellan</a>
</span>
</span>
<time datetime="2018-11-21T18:20:00+11:00" pubdate>Wed 21 November 2018</time></div>
<div class="entry-content"><p>Last month, I was in Amsterdam at <a href="https://openpowerfoundation.org/summit-2018-10-eu/">OpenPOWER Summit Europe</a>. It was great to see so much interest in OpenPOWER, with a particularly strong contingent of researchers sharing how they're exploiting the unique advantages of OpenPOWER platforms, and a number of OpenPOWER hardware partners announcing products.</p>
<p>(It was also my first time visiting Europe, so I had a lot of fun exploring Amsterdam, taking a few days off in Vienna, then meeting some of my IBM Linux Technology Centre colleagues in Toulouse. I also now appreciate just what ~50 hours on planes does to you!)</p>
<p>One particular area which got a lot of attention at the Summit was <a href="https://opencapi.org">OpenCAPI</a>, an open coherent high-performance bus interface designed for accelerators, which is supported on POWER9. We had plenty of talks about OpenCAPI and the interesting work that is already happening with OpenCAPI accelerators.</p>
<p>I was invited to present on the Linux Technology Centre's work on enabling OpenCAPI from the software side. In this talk, I outline the OpenCAPI software stack and how you can interface with an OpenCAPI device through the ocxl kernel driver and the <a href="https://github.com/opencapi/libocxl">libocxl</a> userspace library.</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/zCIMHbZDRS0" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<p>My <a href="https://sthbrx.github.io/misc/OPFEU2018_OpenCAPI.pdf">slides</a> are available, though you'll want to watch the presentation for context.</p>
<p>Apart from myself, the OzLabs team were well represented at the Summit:</p>
<ul>
<li><a href="https://github.com/grooverdan">Daniel Black</a> spoke on Power performance optimisation</li>
<li><a href="https://www.flamingspork.com/">Stewart Smith</a> gave an overview of the Power boot process</li>
<li><a href="https://shenki.github.io/">Joel Stanley</a> presented on recent developments in OpenBMC</li>
<li><a href="http://jk.ozlabs.org/">Jeremy Kerr</a> talked about the various OpenPOWER firmware projects</li>
</ul>
<p>Unfortunately none of their videos are up yet, but they'll be there over the next few weeks. Keep an eye on the <a href="https://openpowerfoundation.org/summit-2018-10-eu/">Summit website</a> and the <a href="https://www.youtube.com/playlist?list=PLEqfbaomKgQo5CimgYbVxdtiVtyloWc9e">Summit YouTube playlist</a>, where you'll find all the rest of the Summit content.</p>
<p>If you've got any questions about OpenCAPI feel free to leave a comment!</p></div>
</article>
<article>
<header>
<h1 class="entry-title">
<a href="https://sthbrx.github.io/blog/2018/10/09/open-source-firmware-conference-2018/">Open Source Firmware Conference 2018</a>
</h1>
<p class="meta">
<time datetime="2018-10-09T10:08:00+11:00" pubdate>Tue 09 October 2018</time> </p>
</header>
<div class="byline_index">
<span class="byline author vcard">
Posted by <span class="fn">
<a href="https://sthbrx.github.io/author/samuel-mendoza-jonas.html">Samuel Mendoza-Jonas</a>
</span>
</span>
<time datetime="2018-10-09T10:08:00+11:00" pubdate>Tue 09 October 2018</time></div>
<div class="entry-content"><p>I recently had the pleasure of attending the <a href="https://osfc.io">2018 Open Source Firmware Conference</a> in Erlangen, Germany. Compared to other more general conferences I've attended in the past, the laser focus of OSFC on firmware and especially firmware security was fascinating. Seeing developers from across the world coming together to discuss how they are improving their corner of the stack was great, and I've walked away with plenty of new knowledge and ideas (and several kilos of German food and drink..).</p>
<hr>
<p>What was especially exciting though is that I had the chance to talk about my work on <a href="https://github.com/open-power/petitboot">Petitboot</a> and what's happened from the POWER8 launch until now. If you're interested in that, or seeing how I talk after 36 hours of travel, check it out here:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/8Z1vEinNU7I" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
<hr>
<p>OSFC have made all the talks from the first two days available in a <a href="https://www.youtube.com/playlist?list=PLJ4u8GLmFVmoRCX_gFXV6fhWmsOQ5cmuj">playlist on Youtube</a><br>
If you're after a few suggestions there was, in no particular order:</p>
<p><a href="https://www.youtube.com/watch?v=ZjAu0VYRTno">Ryan O'Leary giving an update on Linuxboot</a> - also known as NERF, Google's approach to a Linux bootloader all written in Go.</p>
<p><a href="https://www.youtube.com/watch?v=qUgo-AVsSC">Subrate Banik talking about porting Coreboot on top of Intel's FSP</a></p>
<p><a href="https://www.youtube.com/watch?v=ukSh1n7wjSA">Ron Minnich describing his work with "rompayloads" on Coreboot</a></p>
<p><a href="https://www.youtube.com/watch?v=gC-lbMNmIsg">Vadmin Bendebury describing Google's "Secure Microcontroller" Chip</a></p>
<p><a href="https://www.youtube.com/watch?v=eKVSBESoKUc">Facebook presenting their use of Linuxboot and "systemboot"</a></p>
<p>And heaps more, check out the full playlist!</p></div>
</article>
<article>
<header>
<h1 class="entry-title">
<a href="https://sthbrx.github.io/blog/2018/08/15/improving-performance-of-phoronix-benchmarks-on-power9/">Improving performance of Phoronix benchmarks on POWER9</a>
</h1>
<p class="meta">
<time datetime="2018-08-15T14:22:00+10:00" pubdate>Wed 15 August 2018</time> </p>
</header>
<div class="byline_index">
<span class="byline author vcard">
Posted by <span class="fn">
<a href="https://sthbrx.github.io/author/rashmica-gupta.html">Rashmica Gupta</a>,
<a href="https://sthbrx.github.io/author/daniel-black.html">Daniel Black</a>,
<a href="https://sthbrx.github.io/author/anton-blanchard.html">Anton Blanchard</a>,
<a href="https://sthbrx.github.io/author/nick-piggin.html">Nick Piggin</a>,
<a href="https://sthbrx.github.io/author/joel-stanley.html">Joel Stanley</a>
</span>
</span>
<time datetime="2018-08-15T14:22:00+10:00" pubdate>Wed 15 August 2018</time></div>
<div class="entry-content"><p>Recently Phoronix ran a range of
<a href="https://www.phoronix.com/scan.php?page=article&item=power9-talos-2&num=1">benchmarks</a>
comparing the performance of our POWER9 processor against the Intel Xeon and AMD
EPYC processors. </p>
<p>We did well in the Stockfish, LLVM Compilation, Zstd compression, and the
Tinymembench benchmarks. A few of my colleagues did a bit of investigating into
some the benchmarks where we didn't perform quite so well.</p>
<h3>LBM / Parboil</h3>
<p>The <a href="http://impact.crhc.illinois.edu/parboil/parboil.aspx">Parboil benchmarks</a> are a
collection of programs from various scientific and commercial fields that are
useful for examining the performance and development of different architectures
and tools. In this round of benchmarks Phoronix used the lbm
<a href="https://www.spec.org/cpu2006/Docs/470.lbm.html">benchmark</a>: a fluid dynamics
simulation using the Lattice-Boltzmann Method.</p>
<p>lbm is an iterative algorithm - the problem is broken down into discrete
time steps, and at each time step a bunch of calculations are done to
simulate the change in the system. Each time step relies on the results
of the previous one.</p>
<p>The benchmark uses OpenMP to parallelise the workload, spreading the
calculations done in each time step across many CPUs. The number of
calculations scales with the resolution of the simulation.</p>
<p>Unfortunately, the resolution (and therefore the work done in each time
step) is too small for modern CPUs with large numbers of SMT (simultaneous multi-threading) threads. OpenMP
doesn't have enough work to parallelise and the system stays relatively idle. This
means the benchmark scales relatively poorly, and is definitely
not making use of the large POWER9 system</p>
<p>Also this benchmark is compiled without any optimisation. Recompiling with -O3 improves the
results 3.2x on POWER9.</p>
<h3>x264 Video Encoding</h3>
<p>x264 is a library that encodes videos into the H.264/MPEG-4 format. x264 encoding
requires a lot of integer kernels doing operations on image elements. The math
and vectorisation optimisations are quite complex, so Nick only had a quick look at
the basics. The systems and environments (e.g. gcc version 8.1 for Skylake, 8.0
for POWER9) are not completely apples to apples so for now patterns are more
important than the absolute results. Interestingly the output video files between
architectures are not the same, particularly with different asm routines and
compiler options used, which makes it difficult to verify the correctness of any changes.</p>
<p>All tests were run single threaded to avoid any SMT effects.</p>
<p>With the default upstream build of x264, Skylake is significantly faster than POWER9 on this benchmark
(Skylake: 9.20 fps, POWER9: 3.39 fps). POWER9 contains some vectorised routines, so an
initial suspicion is that Skylake's larger vector size may be responsible for its higher throughput.</p>
<p>Let's test our vector size suspicion by restricting
Skylake to SSE4.2 code (with 128 bit vectors, the same width as POWER9). This hardly
slows down the x86 CPU at all (Skylake: 8.37 fps, POWER9: 3.39 fps), which indicates it's
not taking much advantage of the larger vectors.</p>
<p>So the next guess would be that x86 just has more and better optimized versions of costly
functions (in the version of x264 that Phoronix used there are only six powerpc specific
files compared with 21 x86 specific files). Without the time or expertise to dig into the
complex task of writing vector code, we'll see if the compiler can help, and turn
on autovectorisation (x264 compiles with -fno-tree-vectorize by default, which disables
auto vectorization). Looking at a perf profile of the benchmark we can see
that one costly function, quant_4x4x4, is not autovectorised. With a small change to the
code, gcc does vectorise it, giving a slight speedup with the output file checksum unchanged
(Skylake: 9.20 fps, POWER9: 3.83 fps).</p>
<p>We got a small improvement with the compiler, but it looks like we may have gains left on the
table with our vector code. If you're interested in looking into this, we do have some
<a href="https://www.bountysource.com/teams/ibm/bounties">active bounties</a> for x264 (lu-zero/x264).</p>
<table>
<thead>
<tr>
<th>Test</th>
<th>Skylake</th>
<th>POWER9</th>
</tr>
</thead>
<tbody>
<tr>
<td>Original - AVX256</td>
<td>9.20 fps</td>
<td>3.39 fps</td>
</tr>
<tr>
<td>Original - SSE4.2</td>
<td>8.37 fps</td>
<td>3.39 fps</td>
</tr>
<tr>
<td>Autovectorisation enabled, quant_4x4x4 vectorised</td>
<td>9.20 fps</td>
<td>3.83 fps</td>
</tr>
</tbody>
</table>
<p>Nick also investigated running this benchmark with SMT enabled and across multiple cores, and it looks like the code is
not scalable enough to feed 176 threads on a 44 core system. Disabling SMT in parallel runs
actually helped, but there was still idle time. That may be another thing to look at,
although it may not be such a problem for smaller systems.</p>
<h3>Primesieve</h3>
<p><a href="https://primesieve.org/">Primesieve</a> is a program and C/C++
library that generates all the prime numbers below a given number. It uses an
optimised <a href="https://upload.wikimedia.org/wikipedia/commons/b/b9/Sieve_of_Eratosthenes_animation.gif">Sieve of Eratosthenes</a>
implementation.</p>
<p>The algorithm uses the L1 cache size as the sieve size for the core loop. This
is an issue when we are running in SMT mode (aka more than one thread per core)
as all threads on a core share the same L1 cache and so will constantly be
invalidating each others cache-lines. As you can see
in the table below, running the benchmark in single threaded mode is 30% faster
than in SMT4 mode!</p>
<p>This means in SMT-4 mode the workload is about 4x too large for the L1 cache. A
better sieve size to use would be the L1 cache size / number of
threads per core. Anton posted a <a href="https://github.com/kimwalisch/primesieve/pull/54">pull request</a>
to update the sieve size.</p>
<p>It is interesting that the best overall performance on POWER9 is with the patch applied and in
SMT2 mode:</p>
<table>
<thead>
<tr>
<th>SMT level</th>
<th>baseline</th>
<th>patched</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>14.728s</td>
<td>14.899s</td>
</tr>
<tr>
<td>2</td>
<td>15.362s</td>
<td>14.040s</td>
</tr>
<tr>
<td>4</td>
<td>19.489s</td>
<td>17.458s</td>
</tr>
</tbody>
</table>
<h3>LAME</h3>
<p>Despite its name, a recursive acronym for "LAME Ain't an MP3 Encoder",
<a href="http://lame.sourceforge.net/">LAME</a> is indeed an MP3 encoder.</p>
<p>Due to configure options <a href="https://sourceforge.net/p/lame/mailman/message/36371506/">not being parsed correctly</a> this
benchmark is built without any optimisation regardless of architecture. We see a
massive speedup by turning optimisations on, and a further 6-8% speedup by
enabling
<a href="https://sourceforge.net/p/lame/mailman/message/36372005/">USE_FAST_LOG</a> (which
is already enabled for Intel).</p>
<table>
<thead>
<tr>
<th>LAME</th>
<th>Duration</th>
<th>Speedup</th>
</tr>
</thead>
<tbody>
<tr>
<td>Default</td>
<td>82.1s</td>
<td>n/a</td>
</tr>
<tr>
<td>With optimisation flags</td>
<td>16.3s</td>
<td>5.0x</td>
</tr>
<tr>
<td>With optimisation flags and USE_FAST_LOG set</td>
<td>15.6s</td>
<td>5.3x</td>
</tr>
</tbody>
</table>
<p>For more detail see Joel's
<a href="https://shenki.github.io/LameMP3-on-Power9/">writeup</a>.</p>
<h3>FLAC</h3>
<p><a href="https://xiph.org/flac/">FLAC</a> is an alternative encoding format to
MP3. But unlike MP3 encoding it is lossless! The benchmark here was encoding
audio files into the FLAC format. </p>
<p>The key part of this workload is missing
vector support for POWER8 and POWER9. Anton and Amitay submitted this
<a href="http://lists.xiph.org/pipermail/flac-dev/2018-July/006351.html">patch series</a> that
adds in POWER specific vector instructions. It also fixes the configuration options
to correctly detect the POWER8 and POWER9 platforms. With this patch series we get see about a 3x
improvement in this benchmark.</p>
<h3>OpenSSL</h3>
<p><a href="https://www.openssl.org/">OpenSSL</a> is among other things a cryptographic library. The Phoronix benchmark
measures the number of RSA 4096 signs per second:</p>
<div class="highlight"><pre><span></span><code>$<span class="w"> </span>openssl<span class="w"> </span>speed<span class="w"> </span>-multi<span class="w"> </span><span class="k">$(</span>nproc<span class="k">)</span><span class="w"> </span>rsa4096
</code></pre></div>
<p>Phoronix used OpenSSL-1.1.0f, which is almost half as slow for this benchmark (on POWER9) than mainline OpenSSL.
Mainline OpenSSL has some powerpc multiplication and squaring assembly code which seems
to be responsible for most of this speedup.</p>
<p>To see this for yourself, add these four powerpc specific commits on top of OpenSSL-1.1.0f:</p>
<ol>
<li><a href="https://github.com/openssl/openssl/commit/b17ff188b17499e83ca3b9df0be47a2f513ac3c5">perlasm/ppc-xlate.pl: recognize .type directive</a></li>
<li><a href="https://github.com/openssl/openssl/commit/0310becc82d240288a4ab5c6656c10c18cab4454">bn/asm/ppc-mont.pl: prepare for extension</a></li>
<li><a href="https://github.com/openssl/openssl/commit/68f6d2a02c8cc30c5c737fc948b7cf023a234b47">bn/asm/ppc-mont.pl: add optimized multiplication and squaring subroutines</a></li>
<li><a href="https://github.com/openssl/openssl/commit/80d27cdb84985c697f8fabb7649abf1f54714d13">ppccap.c: engage new multipplication and squaring subroutines</a></li>
</ol>
<p>The following results were from a dual 16-core POWER9:</p>
<table>
<thead>
<tr>
<th>Version of OpenSSL</th>
<th>Signs/s</th>
<th>Speedup</th>
</tr>
</thead>
<tbody>
<tr>
<td>1.1.0f</td>
<td>1921</td>
<td>n/a</td>
</tr>
<tr>
<td>1.1.0f with 4 patches</td>
<td>3353</td>
<td>1.74x</td>
</tr>
<tr>
<td>1.1.1-pre1</td>
<td>3383</td>
<td>1.76x</td>
</tr>
</tbody>
</table>
<h3>SciKit-Learn</h3>
<p><a href="http://scikit-learn.org/">SciKit-Learn</a> is a bunch of python tools for data mining and
analysis (aka machine learning).</p>
<p>Joel noticed that the benchmark spent 92% of the time in libblas. Libblas is a
very basic BLAS (basic linear algebra subprograms) library that python-numpy
uses to do vector and matrix operations. The default libblas on Ubuntu is only
compiled with -O2. Compiling with -Ofast and using alternative BLAS's that have
powerpc optimisations (such as libatlas or libopenblas) we see big improvements
in this benchmark:</p>
<table>
<thead>
<tr>
<th>BLAS used</th>
<th>Duration</th>
<th>Speedup</th>
</tr>
</thead>
<tbody>
<tr>
<td>libblas -O2</td>
<td>64.2s</td>
<td>n/a</td>
</tr>
<tr>
<td>libblas -Ofast</td>
<td>36.1s</td>
<td>1.8x</td>
</tr>
<tr>
<td>libatlas</td>
<td>8.3s</td>
<td>7.7x</td>
</tr>
<tr>
<td>libopenblas</td>
<td>4.2s</td>
<td>15.3x</td>
</tr>
</tbody>
</table>
<p>You can read more details about this
<a href="https://shenki.github.io/Scikit-Learn-on-Power9/">here</a>.</p>
<h3>Blender</h3>
<p><a href="https://www.blender.org/">Blender</a> is a 3D graphics suite that supports image rendering,
animation, simulation and game creation. On the surface it appears that Blender
2.79b (the distro package version that Phoronix used by system/blender-1.0.2)
failed to use more than 15 threads, even when "-t 128" was added to the Blender
command line.</p>
<p>It turns out that even though this benchmark was supposed to be run on CPUs only
(you can choose to render on CPUs or GPUs), the GPU file was always being used.
The GPU file is configured with a very large tile size (256x256) -
which is <a href="https://docs.blender.org/manual/en/dev/render/cycles/settings/scene/render/performance.html#tiles">fine for
GPUs</a>
but not great for CPUs. The image size (1280x720) to tile size ratio limits the
number of jobs created and therefore the number threads used.</p>
<p>To obtain a realistic CPU measurement with more that 15 threads you can force
the use of the CPU file by overwriting the GPU file with the CPU one:</p>
<div class="highlight"><pre><span></span><code>$<span class="w"> </span>cp
~/.phoronix-test-suite/installed-tests/system/blender-1.0.2/benchmark/pabellon_barcelona/pavillon_barcelone_cpu.blend
~/.phoronix-test-suite/installed-tests/system/blender-1.0.2/benchmark/pabellon_barcelona/pavillon_barcelone_gpu.blend
</code></pre></div>
<p>As you can see in the image below, now all of the cores are being utilised!
<img alt="Blender with CPU Blend file" src="/images/phoronix/blender-88threads.png" title="Blender with CPU Blend file"></p>
<p>Fortunately this has already been fixed in
<a href="https://openbenchmarking.org/test/pts/blender">pts/blender-1.1.1</a>.
Thanks to the <a href="https://github.com/phoronix-test-suite/test-profiles/issues/24">report</a> by Daniel it
has also been fixed in <a href="http://openbenchmarking.org/test/system/blender-1.1.0">system/blender-1.1.0</a>.</p>
<p>Pinning the pts/bender-1.0.2, Pabellon Barcelona, CPU-Only test to a single
22-core POWER9 chip (<code>sudo ppc64_cpu --cores-on=22</code>) and two POWER9 chips
(<code>sudo ppc64_cpu --cores-on=44</code>) show a huge speedup:</p>
<table>
<thead>
<tr>
<th>Benchmark</th>
<th>Duration (deviation over 3 runs)</th>
<th>Speedup</th>
</tr>
</thead>
<tbody>
<tr>
<td>Baseline (GPU blend file)</td>
<td>1509.97s (0.30%)</td>
<td>n/a</td>
</tr>
<tr>
<td>Single 22-core POWER9 chip (CPU blend file)</td>
<td>458.64s (0.19%)</td>
<td>3.29x</td>
</tr>
<tr>
<td>Two 22-core POWER9 chips (CPU blend file)</td>
<td>241.33s (0.25%)</td>
<td>6.25x</td>
</tr>
</tbody>
</table>
<h3>tl;dr</h3>
<p>Some of the benchmarks where we don't perform as well as Intel are where the
benchmark has inline assembly for x86 but uses generic C compiler generated
assembly for POWER9. We could probably benefit with some more powerpc optimsed functions.</p>
<p>We also found a couple of things that should result in better performance for all three architectures,
not just POWER.</p>
<p>A summary of the performance improvements we found:</p>
<table>
<thead>
<tr>
<th>Benchmark</th>
<th>Approximate Improvement</th>
</tr>
</thead>
<tbody>
<tr>
<td>Parboil</td>
<td>3x</td>
</tr>
<tr>
<td>x264</td>
<td>1.1x</td>
</tr>
<tr>
<td>Primesieve</td>
<td>1.1x</td>
</tr>
<tr>
<td>LAME</td>
<td>5x</td>
</tr>
<tr>
<td>FLAC</td>
<td>3x</td>
</tr>
<tr>
<td>OpenSSL</td>
<td>2x</td>
</tr>
<tr>
<td>SciKit-Learn</td>
<td>7-15x</td>
</tr>
<tr>
<td>Blender</td>
<td>3x</td>
</tr>
</tbody>
</table>
<p>There is obviously room for more improvements, especially with the Primesieve and x264 benchmarks,
but it would be interesting to see a re-run of the Phoronix benchmarks with these changes. </p>
<p>Thanks to Anton, Daniel, Joel and Nick for the analysis of the above benchmarks.</p></div>
</article>
<div class="pagination">
<a class="prev" href="https://sthbrx.github.io/index5.html">← Older</a>
<a class="next" href="https://sthbrx.github.io/index3.html">Newer →</a>
<br />
</div></div>
<aside class="sidebar">
<section>
<h1>Recent Posts</h1>
<ul id="recent_posts">
<li class="post">
<a href="https://sthbrx.github.io/blog/2023/08/07/going-out-on-a-limb-efficient-elliptic-curve-arithmetic-in-openssl/">Going out on a Limb: Efficient Elliptic Curve Arithmetic in OpenSSL</a>
</li>
<li class="post">
<a href="https://sthbrx.github.io/blog/2023/08/04/quirks-of-parsing-ssh-configs/">Quirks of parsing SSH configs</a>
</li>
<li class="post">
<a href="https://sthbrx.github.io/blog/2023/04/05/detecting-rootless-docker/">Detecting rootless Docker</a>
</li>
<li class="post">
<a href="https://sthbrx.github.io/blog/2023/04/04/dumb-bugs-the-pci-device-that-wasnt/">Dumb bugs: the PCI device that wasn't</a>
</li>
<li class="post">
<a href="https://sthbrx.github.io/blog/2023/03/24/dumb-bugs-when-a-date-breaks-booting-the-kernel/">Dumb bugs: When a date breaks booting the kernel</a>
</li>
</ul>
</section>
<section>
<h1>Categories</h1>
<ul id="recent_posts">
<li><a href="https://sthbrx.github.io/category/cryptography.html">Cryptography</a></li>
<li><a href="https://sthbrx.github.io/category/development.html">Development</a></li>
<li><a href="https://sthbrx.github.io/category/education.html">Education</a></li>
<li><a href="https://sthbrx.github.io/category/openpower.html">OpenPOWER</a></li>
<li><a href="https://sthbrx.github.io/category/performance.html">Performance</a></li>
<li><a href="https://sthbrx.github.io/category/petitboot.html">Petitboot</a></li>
<li><a href="https://sthbrx.github.io/category/snowpatch.html">snowpatch</a></li>
<li><a href="https://sthbrx.github.io/category/virtualisation-and-emulation.html">Virtualisation and Emulation</a></li>
</ul>
</section>
<section>
<h1>Tags</h1>
<a href="https://sthbrx.github.io/tag/ssh.html">ssh</a>, <a href="https://sthbrx.github.io/tag/docker.html">Docker</a>, <a href="https://sthbrx.github.io/tag/syzkaller.html">syzkaller</a>, <a href="https://sthbrx.github.io/tag/linux.html">linux</a>, <a href="https://sthbrx.github.io/tag/power8.html">power8</a>, <a href="https://sthbrx.github.io/tag/distro.html">distro</a>, <a href="https://sthbrx.github.io/tag/kernel.html">kernel</a>, <a href="https://sthbrx.github.io/tag/hardening.html">hardening</a>, <a href="https://sthbrx.github.io/tag/testing.html">testing</a>, <a href="https://sthbrx.github.io/tag/conferences.html">conferences</a>, <a href="https://sthbrx.github.io/tag/instruction-set-architecture.html">Instruction Set Architecture</a>, <a href="https://sthbrx.github.io/tag/openpower.html">openpower</a>, <a href="https://sthbrx.github.io/tag/firmware.html">firmware</a>, <a href="https://sthbrx.github.io/tag/goodposts.html">goodposts</a>, <a href="https://sthbrx.github.io/tag/realcontent.html">realcontent</a>, <a href="https://sthbrx.github.io/tag/madposting.html">madposting</a>, <a href="https://sthbrx.github.io/tag/op-test.html">op-test</a>, <a href="https://sthbrx.github.io/tag/qemu.html">qemu</a>, <a href="https://sthbrx.github.io/tag/pci.html">pci</a>, <a href="https://sthbrx.github.io/tag/sparseposting.html">sparseposting</a>, <a href="https://sthbrx.github.io/tag/petitboot.html">petitboot</a>, <a href="https://sthbrx.github.io/tag/security.html">security</a>, <a href="https://sthbrx.github.io/tag/vscode.html">vscode</a>, <a href="https://sthbrx.github.io/tag/code.html">code</a>, <a href="https://sthbrx.github.io/tag/openbmc.html">openbmc</a>, <a href="https://sthbrx.github.io/tag/ipmi.html">ipmi</a>, <a href="https://sthbrx.github.io/tag/opencapi.html">opencapi</a>, <a href="https://sthbrx.github.io/tag/openpower-summit.html">openpower summit</a>, <a href="https://sthbrx.github.io/tag/easyposts.html">easyposts</a>, <a href="https://sthbrx.github.io/tag/linuxboot.html">linuxboot</a>, <a href="https://sthbrx.github.io/tag/google.html">google</a>, <a href="https://sthbrx.github.io/tag/intel.html">intel</a>, <a href="https://sthbrx.github.io/tag/osfc.html">osfc</a>, <a href="https://sthbrx.github.io/tag/shortposts.html">shortposts</a>, <a href="https://sthbrx.github.io/tag/facebook.html">facebook</a>, <a href="https://sthbrx.github.io/tag/performance.html">performance</a>, <a href="https://sthbrx.github.io/tag/phoronix.html">phoronix</a>, <a href="https://sthbrx.github.io/tag/benchmarks.html">benchmarks</a>, <a href="https://sthbrx.github.io/tag/stupid-ideas.html">stupid ideas</a>, <a href="https://sthbrx.github.io/tag/network.html">network</a>, <a href="https://sthbrx.github.io/tag/power.html">power</a>, <a href="https://sthbrx.github.io/tag/xdp.html">xdp</a>, <a href="https://sthbrx.github.io/tag/networking.html">networking</a>, <a href="https://sthbrx.github.io/tag/remoteposts.html">remoteposts</a>, <a href="https://sthbrx.github.io/tag/ceph.html">ceph</a>, <a href="https://sthbrx.github.io/tag/raid.html">raid</a>, <a href="https://sthbrx.github.io/tag/storage.html">storage</a>, <a href="https://sthbrx.github.io/tag/erasure.html">erasure</a>, <a href="https://sthbrx.github.io/tag/lustre.html">lustre</a>, <a href="https://sthbrx.github.io/tag/hpc.html">hpc</a>, <a href="https://sthbrx.github.io/tag/nvlink.html">nvlink</a>, <a href="https://sthbrx.github.io/tag/namd.html">namd</a>, <a href="https://sthbrx.github.io/tag/cuda.html">cuda</a>, <a href="https://sthbrx.github.io/tag/gpu.html">gpu</a>, <a href="https://sthbrx.github.io/tag/minsky.html">minsky</a>, <a href="https://sthbrx.github.io/tag/s822lc-for-hpc.html">S822LC for hpc</a>, <a href="https://sthbrx.github.io/tag/debug.html">debug</a>, <a href="https://sthbrx.github.io/tag/virtualisation.html">virtualisation</a>, <a href="https://sthbrx.github.io/tag/dmesg.html">dmesg</a>, <a href="https://sthbrx.github.io/tag/printk.html">printk</a>, <a href="https://sthbrx.github.io/tag/boot.html">boot</a>, <a href="https://sthbrx.github.io/tag/early.html">early</a>, <a href="https://sthbrx.github.io/tag/error.html">error</a>, <a href="https://sthbrx.github.io/tag/centos.html">centos</a>, <a href="https://sthbrx.github.io/tag/centos7.html">centos7</a>, <a href="https://sthbrx.github.io/tag/p8.html">p8</a>, <a href="https://sthbrx.github.io/tag/bmc.html">bmc</a>, <a href="https://sthbrx.github.io/tag/rhel.html">RHEL</a>, <a href="https://sthbrx.github.io/tag/skiroot.html">skiroot</a>, <a href="https://sthbrx.github.io/tag/devmapper.html">devmapper</a>, <a href="https://sthbrx.github.io/tag/lvm.html">lvm</a>, <a href="https://sthbrx.github.io/tag/cgroups.html">cgroups</a>, <a href="https://sthbrx.github.io/tag/numa.html">numa</a>, <a href="https://sthbrx.github.io/tag/development.html">Development</a>, <a href="https://sthbrx.github.io/tag/netboot.html">netboot</a>, <a href="https://sthbrx.github.io/tag/pxe.html">pxe</a>, <a href="https://sthbrx.github.io/tag/education.html">Education</a>, <a href="https://sthbrx.github.io/tag/work-experience.html">work experience</a>, <a href="https://sthbrx.github.io/tag/asm.html">asm</a>, <a href="https://sthbrx.github.io/tag/vdso.html">vdso</a>, <a href="https://sthbrx.github.io/tag/snowpatch.html">snowpatch</a>, <a href="https://sthbrx.github.io/tag/tools.html">tools</a>, <a href="https://sthbrx.github.io/tag/intern.html">intern</a>, <a href="https://sthbrx.github.io/tag/srop.html">SROP</a>, <a href="https://sthbrx.github.io/tag/mitigation.html">mitigation</a>, <a href="https://sthbrx.github.io/tag/double.html">double</a>, <a href="https://sthbrx.github.io/tag/float.html">float</a>, <a href="https://sthbrx.github.io/tag/hex.html">hex</a>, <a href="https://sthbrx.github.io/tag/debugging.html">debugging</a>, <a href="https://sthbrx.github.io/tag/skiboot.html">skiboot</a>, <a href="https://sthbrx.github.io/tag/opal.html">OPAL</a>, <a href="https://sthbrx.github.io/tag/fsp.html">FSP</a>, <a href="https://sthbrx.github.io/tag/patches.html">patches</a>, <a href="https://sthbrx.github.io/tag/based16.html">based16</a>, <a href="https://sthbrx.github.io/tag/linux-gods.html">Linux Gods</a>, <a href="https://sthbrx.github.io/tag/ozlabs.html">Ozlabs</a>, <a href="https://sthbrx.github.io/tag/offtopic.html">offtopic</a>, <a href="https://sthbrx.github.io/tag/autoboot.html">autoboot</a>, <a href="https://sthbrx.github.io/tag/kexec.html">kexec</a>, <a href="https://sthbrx.github.io/tag/aufs.html">aufs</a>, <a href="https://sthbrx.github.io/tag/overlay.html">overlay</a>, <a href="https://sthbrx.github.io/tag/php.html">php</a>, <a href="https://sthbrx.github.io/tag/capi.html">capi</a> </section>
<section>
<h1><a href="https://sthbrx.github.io/authors.html">Authors</a></h1>
<ul id="authors_list">
<li><a href="https://sthbrx.github.io/author/alastair-dsilva.html">Alastair D'Silva</a></li>
<li><a href="https://sthbrx.github.io/author/andrew-donnellan.html">Andrew Donnellan</a></li>
<li><a href="https://sthbrx.github.io/author/anton-blanchard.html">Anton Blanchard</a></li>
<li><a href="https://sthbrx.github.io/author/benjamin-gray.html">Benjamin Gray</a></li>
<li><a href="https://sthbrx.github.io/author/callum-scarvell.html">Callum Scarvell</a></li>
<li><a href="https://sthbrx.github.io/author/cyril-bur.html">Cyril Bur</a></li>
<li><a href="https://sthbrx.github.io/author/daniel-axtens.html">Daniel Axtens</a></li>
<li><a href="https://sthbrx.github.io/author/daniel-black.html">Daniel Black</a></li>
<li><a href="https://sthbrx.github.io/author/joel-stanley.html">Joel Stanley</a></li>
<li><a href="https://sthbrx.github.io/author/nick-piggin.html">Nick Piggin</a></li>
<li><a href="https://sthbrx.github.io/author/rashmica-gupta.html">Rashmica Gupta</a></li>
<li><a href="https://sthbrx.github.io/author/rohan-mclure.html">Rohan McLure</a></li>
<li><a href="https://sthbrx.github.io/author/russell-currey.html">Russell Currey</a></li>
<li><a href="https://sthbrx.github.io/author/samuel-mendoza-jonas.html">Samuel Mendoza-Jonas</a></li>
<li><a href="https://sthbrx.github.io/author/suraj-jitindar-singh.html">Suraj Jitindar Singh</a></li>
</ul>
</section>
<section>
<h1>Social</h1>
<ul>
<li><a href="https://sthbrx.github.io/rss.xml" type="application/rss+xml" rel="alternate">RSS</a></li>
<li><a href="https://github.com/sthbrx/" target="_blank">GitHub</a></li>
<li><a href="https://lists.ozlabs.org/listinfo/linuxppc-dev" target="_blank">linuxppc mailing list</a></li>
<li><a href="https://lists.ozlabs.org/listinfo/skiboot" target="_blank">Skiboot mailing list</a></li>
</ul>
</section>
<section>
<h1>Blogroll</h1>
<ul>
<li><a href="http://ozlabs.org" target="_blank">OzLabs</a></li>
</ul>
</section>
<section>
<h1>Disclaimer</h1>
<div>
This blog represents the views of the individual authors, and doesn't necessarily represent IBM's positions, strategies or opinions. </div>
</section>
</aside> </div>
</div>
<footer role="contentinfo"><p>
Copyright © 2015–2023 OzLabs —
<span class="credit">Powered by <a href="http://getpelican.com">Pelican</a></span>
</p></footer>
</body>
</html>