Что такое соглашения о кодировании для использования плавающих точек в драйверах устройств Linux?

Это связано с этот вопрос.

Я не эксперт в драйверах устройств Linux или модулей ядра, но я читал "Драйверы устройств Linux" [O'Reilly] от Rubini и Corbet и ряд онлайн-источников, но я не был в состоянии найти что-либо по этой конкретной проблеме.

Когда модуль ядра или драйвера разрешен для использования регистров с плавающей запятой?
Если да, кто несет ответственность за сохранение и восстановление их содержимого?
(Предположим, что архитектура x86-64)

Если я правильно понимаю, всякий раз, когда выполняется KM, он использует аппаратный контекст (или аппаратный поток или набор регистров - все, что вы хотите назвать), которое было выгружено из какого-либо потока приложений. Если вы пишете свой KM в c, компилятор будет правильно застраховать, чтобы регистры общего назначения были правильно сохранены и восстановлены (как и в приложении), но это не происходит автоматически с регистрами с плавающей запятой. В этом отношении многие КМ не могут даже предположить, что процессор имеет любую возможность с плавающей запятой.

Правильно ли я предполагаю, что KM, который хочет использовать плавающую точку, должен тщательно сохранять и восстанавливать состояние с плавающей запятой? Существуют ли стандартные функции ядра для этого?

Являются ли соглашения о кодировании для этого прописанными в любом месте?
Разные ли они для драйверов SMP-non SMP?
Разнообразны ли они для более старых неперехваченных ядер и более новых упреждающих ядер?

Ответ 1

Короткий ответ: код ядра может использовать с плавающей запятой, если это использование окружено kernel_fpu_begin()/kernel_fpu_end(). Эти функции обрабатывают сохранение и восстановление контекста fpu. Кроме того, они вызывают preempt_disable()/preempt_enable(), что означает отсутствие спама, ошибок страницы и т.д. В коде между этими функциями. Google имена функций для получения дополнительной информации.

Если я правильно понимаю, всякий раз, когда KM работает, он использует аппаратное обеспечение контекст (или аппаратная нить или набор регистров - все, что вы хотите назовите это), который был выгружен из некоторые прикладные потоки.

Нет, модуль ядра может работать и в контексте пользователя (например, когда пользовательское пространство вызывает системные вызовы на устройстве, предоставляемом KM). Однако он не имеет отношения к проблеме с плавающей точкой.

Если вы пишете свой KM в c, компилятор будет правильно гарантировать, что регистры общего назначения правильно сохранены и восстановлены ( в приложении), но это не автоматически происходит с регистры с плавающей запятой.

Это не из-за компилятора, а из-за кода переключения ядра.

Ответ 2

Ответ Linus дает эту довольно ясную цитату для использования в качестве ориентира:

Другими словами: правило состоит в том, что вы действительно не должны использовать FP в ядре.