PCI-E、sysfs、およびユーザーID権限例外

PCI-E、sysfs、およびユーザーID権限例外

3.Xシリーズカーネルでは、独自のPCI-Expressデバイスには独自のカーネルドライバがあります。 PCI機能の検索中にいくつかの奇妙なバグが見つかりました。素晴らしいドキュメントが見つかりません。カーネルドライバがsysfsユーザーIDに基づいてどのデータを制御/露出できるかを知っている人はいますか?procfs

特に、この呼び出しはベンダーユーティリティで失敗します。

c = pci_find_cap(mdev->pdev, VENDOR_EXT_CAP_ID, PCI_CAP_EXTENDED);

多くの調査の終わりにsetpciを使用して見つけることができましたVENDOR_EXT_CAP_ID

私が見るものは:

  • FS権限は、ユーザーとルートに読み取り権限を付与します。
  • "config"ファイルをsysfs開きます$data
  • $dataユーザーとルートは$data異なります。

これを行う方法については多くの文書がなく、ベンダーに設定された良いアップグレードパスもありません。これ見た人いますか?

答え1

はい、カーネルドライバは、ユーザーIDおよび/またはデフォルトでカーネルがアクセスできるすべての情報に基づいてsysfs / procfsに公開されるデータを制御できます。

procfsまたはsysfsから何かを読み取るときに情報を読み取るために使用されるシステムコールは、デフォルトでそのドライバの関数を呼び出すことになります。この関数は、読み取り操作を呼び出したユーザー空間プロセスに関するすべての情報を表示し、その情報またはカーネルがアクセスできる他のすべての項目に基づいて出力を変更できます。

の特定の場合に/sys/bus/pci/devices/<PCI device ID>/configこれを読み取ろうとするすべての試みは、次のように終了します。pci_read_config()ファイルの機能drivers/pci/pci-sysfs.c呼び出すユーザースペースプロセスにCAP_SYS_ADMIN機能があることを確認します(ほとんどの場合、ユーザーにCAP_SYS_ADMIN機能があることを意味しますroot)。ユーザーにこの機能がない場合、この機能は読み取り可能なPCI構成データを最初のバイト(dev->cfg_size)(CardBusの場合は128バイト)に制限します。

カーネルバージョン2.6.5以下では制限は256バイトでしたが、2.6.6ではより厳しくなりました(dev->cfg_size)。最新のシステムでは、(dev->cfg_size)関連デバイスによって64バイトまたは256バイトになる傾向があります。

単純なlspci -v.dllをrootとして実行すると、各デバイスのPCI / PCIe機能を表示できます。ただし、通常のユーザーとして実行すると、次の結果が表示されます。

Capabilities: <access denied>

答え2

カーネルと共に AlmaLinux 8.8 を使用すると、4.18.0-477.27.2.el8_8.x86_64一般ユーザーとして PCIe 機能をデコードするユーザー空間アプリケーションを生成するように設計されています。このアプリケーションでは、エンドポイントのPCIeリンク幅と速度機能を、エンドポイントが接続されているPCIeルートポートに関連付けようとします。

さまざまなメカニズムのうち:

  1. pci_device_cfg_read*実行可能ファイルにLinux機能を提供せずに一般ユーザーとしてPCIe機能を読み取ろうとすると、関数は失敗として返されますlibpciaccessENXIO

    使用後は、sudo setcap cap_sys_admin=ep <executable>通常のユーザーのようにPCIe機能を読むことができます。

  2. 使用pciutils:

    • pci_read_byteおよび関数は、実行可能ファイルにLinux機能を提供せず、通常のユーザーとしてPCI機能を読み取ろうとすると、すべて1を返しますpci_read_word。失敗すると設定されません。pci_read_longerrno
    • このpci_read_block関数は、実行可能ファイルにLinux機能を提供せず、通常のユーザーとしてPCIe機能を読み取ろうとすると、失敗を示すために0を返します。

    使用後は、sudo setcap cap_sys_admin=ep <executable>通常のユーザーのようにPCIe機能を読むことができます。

  3. 使用VFIO、取得されたファイル記述子は、VFIO_GROUP_GET_DEVICE_FDPCIe機能を持つ一般ユーザーとして読むことができます。いいえすべてのLinux機能には実行可能ファイルを提供する必要があります。

    vfio-pciただし、このアプローチの欠点は、ドライバがヘッダタイプのPCIデバイスにのみバインドされるため、VFIOをPCIeルートポートで使用できないことですNORMALvfio_pci_probeBRIDGEヘッダータイプを使用してVFIOをPCIeルートポートにバインドしようとしたときに発生するエラーを説明する次のコードが含まれています。

     if (pdev->hdr_type != PCI_HEADER_TYPE_NORMAL)
         return -EINVAL;
    

関連情報