Linuxカーネル4.4をビルド・動作確認と差分について(ゴホッ、android-x86、ゴホッのx86-32 sysenter ABI誤用について)

昨日、Linuxカーネル4.4がリリースされました。

Linuxカーネル4.4はLTS(Long Term Support)で、今後2年間サポートされます。

いつもの確認事項

ビルド〜起動確認で行ったことは前回と同じで、
問題なく起動し、使用できています。

unameコマンドの実行結果

$ uname -a
Linux seven 4.4.0 #1 SMP Mon Jan 11 11:48:25 JST 2016 x86_64 GNU/Linux

また、バージョン間で差分のあるファイル数もいつもどおり調べてみました。

$ git diff --name-only v4.2 v4.3 | wc -l
10385
$ git diff --name-only v4.3 v4.4 | wc -l
10606

v4.2〜v4.3よりは修正項目が多いようですが、v4.2〜v4.2では10292個のファイルが修正されているので、
それよりは少ないですね。


各種ニュース記事など

1/11 15時頃の時点で、既にいくつかの記事で紹介されています。

特に、PhoronixはRCの時点でLinux 4.4の新機能をまとめています。

なお、LinusLinuxカーネル4.4リリースのメール(LKML)自体は短く、
以下のような内容が書かれています。

  • Linux 4.4は通常通りリリースできた
  • rc8からの変更点について
    • 多くない
    • 1/3がアーキテクチャ依存部のアップデート
    • 1/3がドライバ
    • 1/3がその他(主にカーネルのコア部分とネットワーク)
    • すべての変更点は小さい
    • 名士がx86-32の"sysenter" ABIをおそらく壊れない様にしてくれた。
      • 誰かさん(ゴホッ、android-x86、ゴホッ)がvdsoを使わずにsysenter命令を直接使用するというsysenter ABIの誤用をした為
  • 完全なショートログは以降に記載
  • 4.5のマージウィンドウは既に開いている

x86-32の"sysenter" ABIが壊れない様にする修正について

「ABIが壊れない様にしてくれた」という修正コミットは以下のコミットです。

コミットのタイトルから、このコミットでは「SYSENTER呼び出し規約を伝統的な方法へ復元する」という変更を行っています。



上記のコミットのコミットメッセージ冒頭では以下の内容が書かれています。

  • Android(コミットメッセージでは濁さずに書かれていますね)のいくつかのバージョンでSYSENTER呼び出し規約をハードコーディングしている事が発覚した
  • これはバグりやすく、カーネルが何をするにしても問題の原因となる
  • とはいえ、我々はこれに対応することにした

それじゃあ、ユーザ空間からシステムコールを呼び出すにはどうすれば良いのかというと、
カーネルは、vDSO(Virtual Dynamic Shared Object)という仮想的な動的ライブラリを用意しているので、
その枠組みの中で呼び出すと良いようです。



また、「SYSENTER命令を直接使用してはいけない事」についてはvsyscall定義箇所に以下のコメントも追加されています。

* Note to future user developers: DO NOT USE SYSENTER IN YOUR CODE.
* Execute an indirect call to the address in the AT_SYSINFO auxv
* entry.  That is the ONLY correct way to make a fast 32-bit system
* call on Linux.  (Open-coding int $0x80 is also fine, but it's
* slow.)

auxv(auxiliary vector)はプログラムが実行時にカーネルがユーザ空間に情報を渡すための仕組みで、AT_SYSINFOにはvDSOのシステムコール関数へのエントリポイントが格納されています。

なお、上記のコミットでは、主に以下の2つの変更を行っているようです。

  1. ECXレジスタを使用していた箇所を、EBPレジスタへ変更
  2. 併せてvsyscallの変更

(これがコミットメッセージの「伝統的な方法へ復元する」ということとどう繋がってくるのかは分かっていません。。)



# はっきりと「Android側の誤用」としているにも関わらず、Linuxカーネルを修正するに至った経緯は何なのだろうか。。



■ 勉強になったページ

pbzip2の圧縮時間について

Phoronixで1/10に公開された以下の記事で、Linux 4.3とLiquorix 4.3とLinux 4.4の性能比較を行っています。

なお、LiquorixはLinuxカーネルにマルチメディアやゲーム特化のパッチを適用したカーネルです。


上記の記事で、Linux 4.4はpzip2の圧縮時間が、
4.3系のカーネル(Linux 4.3やLiquorix 4.3)の半分以下になる結果を示しているのですが、
私の手元では確認できませんでした。



■ /dev/urandomから生成した1GBデータのpbzip2圧縮時間

Linux 4.3 78.248559 seconds
Linux 4.4 76.004530 seconds

Linux 4.3の実行ログ

$ pbzip2 -v testdata.dat
Parallel BZIP2 v1.1.9     - by: Jeff Gilchrist [http://compression.ca]
[Apr. 13, 2014]               (uses libbzip2 by Julian Seward)
Major contributions: Yavor Nikolov <nikolov.javor+pbzip2@gmail.com>

         # CPUs: 4
 BWT Block Size: 900 KB
File Block Size: 900 KB
 Maximum Memory: 100 MB
-------------------------------------------
         File #: 1 of 1
     Input Name: testdata.dat
    Output Name: testdata.dat.bz2

     Input Size: 1048576000 bytes
Compressing data...
    Output Size: 1053279079 bytes
-------------------------------------------

     Wall Clock: 78.248559 seconds
$ ls -l testdata.dat.bz2 
-rw-r--r-- 1 yarakawa yarakawa 1053279079  1月 11 12:52 testdata.dat.bz2

Linux 4.4の実行ログ

$ ls -l testdata.dat
-rw-r--r-- 1 yarakawa yarakawa 1048576000  1月 11 13:45 testdata.dat
$ pbzip2 -v testdata.dat
Parallel BZIP2 v1.1.9     - by: Jeff Gilchrist [http://compression.ca]
[Apr. 13, 2014]               (uses libbzip2 by Julian Seward)
Major contributions: Yavor Nikolov <nikolov.javor+pbzip2@gmail.com>

         # CPUs: 4
 BWT Block Size: 900 KB
File Block Size: 900 KB
 Maximum Memory: 100 MB
-------------------------------------------
         File #: 1 of 1
     Input Name: testdata.dat
    Output Name: testdata.dat.bz2

     Input Size: 1048576000 bytes
Compressing data...
    Output Size: 1053279079 bytes
-------------------------------------------

     Wall Clock: 76.004530 seconds
$ ls -l testdata.dat.bz2 
-rw-r--r-- 1 yarakawa yarakawa 1053279079  1月 11 13:45 testdata.dat.bz2