Создание правильной структуры сегмента состояния задачи (TSS) с и без битовой карты ввода-вывода? - PullRequest
0 голосов
/ 26 февраля 2019

Чтение документации между Intel и AMD и просмотр кода порой затрудняет понимание того, как создать правильный сегмент состояния задачи (TSS), у которого нет битовой карты портов ввода-вывода (IOPB).Также кажется, что возникает путаница по поводу создания TSS с IOPB, так как кажется неоднозначным, требует ли IO Bitmap (IOPB) завершающий 0xff байт.

Я знаю, что естьзависимость между TSS и дескриптором TSS (в GDT).Дескриптор TSS управляет базовым адресом TSS, а также пределом.Предел в дескрипторе на единицу меньше, чем фактический размер структуры (по своей природе аналогичен размеру, указанному в записи GDT и IDT).Предел TSS вступает в игру, чтобы определить размер IOPB.

Я знаю, что:

  • Предел дескриптора TSS на единицу меньше размера всей структуры TSS
  • 16-битный TSS не имеет IOPB, а структура имеет фиксированный размер
  • Базовые 32-битные и 64-битные структуры TSS схожи по размеру (данные имеют разное значение)
  • 32-битный TSS может поддерживать принудительное выполнение потока управления, добавляя дополнительный DWORD к базовой структуре.
  • Смещение IOPB (слово) в TSS указывает на смещение относительно начала задачисегмент.
  • Смещение IOPB указывает на начало структуры IOPB, и с помощью Виртуальный режим (VME) позволил 32 байта до того, как IOPB станет таблицей перенаправления прерываний.
  • Если VME не включен, ядро ​​может размещать дополнительные данные для каждого экземпляра задачи между концом базовой структуры TSS и смещением IOPB
  • Если VME включено, ядро ​​может размещать дополнительные данные в соответствии с потребностями.k данных экземпляра между концом базовой структуры TSS и смещением на 32 байта ниже IOPB.
  • Если присутствует IOPB, каждый бит 0 является разрешением для доступа к порту, а 1 запрещает разрешение.

32-битная структура TSS может быть визуализирована следующим образом:

enter image description here

Ссылка также содержит макет16-битных TSS и 64-битных структур TSS.


Вопросы:

  • Если я хочу TSS без IOPB, чтозначение, которое я должен заполнить для смещения IOPB в + 66h?
  • Если я хочу TSS с IOPB, должен ли я добавить 0xff байт в конец IOPB?
  • На диаграмме выше, почему дополнительный байт в конце представлен как xxxxx111.Если предполагается, что последний байт будет 0xff, не будет ли это 11111111?

1 Ответ

0 голосов
/ 26 февраля 2019

Это очень справедливый вопрос.Хотя на первый взгляд TSS с или без битовой карты портов IO (IOPB) кажется довольно тривиальной по своей природе, она была в центре интенсивного обсуждения;дебаты;неверная документация;неоднозначная документация;и информация от разработчиков процессоров, которые время от времени пачкали воду.Очень хорошее прочтение на эту тему можно найти в OS / 2 Museum .Несмотря на название, информация не ограничивается OS / 2.Один отрывок из этой статьи, который подводит итог:

Очевидно, что правильно использовать IOPB не тривиально.Кроме того, неправильно настроенная IOPB вряд ли вызовет очевидные проблемы, но может запретить доступ к нужным портам или (что намного хуже, с точки зрения безопасности) разрешить доступ к нежелательным портам.

Грязная историяTSS и IOPB в том, что касается дыр в безопасности и ошибок в 386BSD, NetBSD, OpenBSD, делают чтение интересным и должны служить индикатором того, что вопросы, которые вы задаете, являются разумными, если вы хотите избежать появления ошибок.


Ответы на вопросы

Если вы не хотите IOPB, вы можете просто заполнить поле смещения IOPB длиной всей вашей структуры TSS (не вычитайте 1).В вашей структуре TSS не должно быть завершающего байта 0xff.Предел TSS в дескрипторе TSS (как вы уже знаете) будет на единицу меньше этого значения.В руководствах Intel говорится, что IOPB отсутствует, если значение в значении смещения IOPB превышает предел TSS.Если значение в поле смещения IOPB всегда на 1 больше, чем предел, это условие выполняется.Вот как современные Microsoft Windows справляются с этим.

Если используется IOPB, установите дополнительный байт в конце 0xff в соответствии с документацией Intel.Установка дополнительного байта для всех 0xff предотвратит любой многопортовый доступ (INW / OUTW / INL / OUTL), начинающийся или заканчивающийся в последних 8 портах.Это позволило бы избежать ситуации, когда многопортовое чтение / запись может охватывать конец IOPB, вызывая доступ к портам, которые выходят за пределы диапазона IOPB.Это также запретит многопортовый доступ, который начался на порте, предшествующем последним 8 портам, которые пересекают следующие 8 портов.Если любой порт многопортового доступа имеет бит разрешения, установленный в 1, доступ ко всему порту будет запрещен (согласно документации Intel)

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

Из таблицы данных микропроцессора Intel386 DX :

Каждый бит в битовой карте разрешений ввода / вывода соответствует одному байтовому порту ввода / вывода, как показано на рисунке 4-15a.Если бит равен 0, ввод-вывод для соответствующего байтового порта может происходить без генерации исключения.В противном случае инструкция ввода / вывода вызывает ошибку исключения 13.Так как каждый порт ввода-вывода шириной в байт должен быть защищаемым, все биты, соответствующие порту шириной слова или шириной слова, должны быть 0, чтобы разрешить ввод слова ввода в ширину или ширину слова.Если все указанные биты равны 0, ввод / вывод будет разрешен.Если биты, на которые есть ссылки, равны 1, попытка ввода-вывода вызовет ошибку исключения 13.

и

** ВАЖНОЕ РЕАЛИЗАЦИЯ ПРИМЕЧАНИЕ: за последним байтом IИнформация отображения / O в битовой карте разрешения ввода / вывода должна быть байтом, содержащим все 1.Байт всех 1 должен находиться в пределах предела сегмента Intel386 DX TSS (см. Рисунок 4-15a).


В сборке NASM вы можете создать структуру, которая выглядит следующим образом:

tss_entry:
.back_link: dd 0
.esp0:      dd 0              ; Kernel stack pointer used on ring transitions
.ss0:       dd 0              ; Kernel stack segment used on ring transitions
.esp1:      dd 0
.ss1:       dd 0
.esp2:      dd 0
.ss2:       dd 0
.cr3:       dd 0
.eip:       dd 0
.eflags:    dd 0
.eax:       dd 0
.ecx:       dd 0
.edx:       dd 0
.ebx:       dd 0
.esp:       dd 0
.ebp:       dd 0
.esi:       dd 0
.edi:       dd 0
.es:        dd 0
.cs:        dd 0
.ss:        dd 0
.ds:        dd 0
.fs:        dd 0
.gs:        dd 0
.ldt:       dd 0
.trap:      dw 0
.iomap_base:dw TSS_SIZE         ; IOPB offset
;.cetssp:    dd 0              ; Need this if CET is enabled

; Insert any kernel defined task instance data here
; ...

; If using VME (Virtual Mode extensions) there need to bean additional 32 bytes
; available immediately preceding iomap. If using VME uncomment next 2 lines
;.vmeintmap:                     ; If VME enabled uncomment this line and the next
;TIMES 32    db 0                ;     32*8 bits = 256 bits (one bit for each interrupt)

.iomap:
TIMES TSS_IO_BITMAP_SIZE db 0x0
                                ; IO bitmap (IOPB) size 8192 (8*8192=65536) representing
                                ; all ports. An IO bitmap size of 0 would fault all IO
                                ; port access if IOPL < CPL (CPL=3 with v8086)
%if TSS_IO_BITMAP_SIZE > 0
.iomap_pad: db 0xff             ; Padding byte that has to be filled with 0xff
                                ; To deal with issues on some CPUs when using an IOPB
%endif
TSS_SIZE EQU $-tss_entry

Специальное примечание:

  • Если вы используете язык высокого уровня и создаете структуру TSS, убедитесь, что вы используете упакованную структуру (то есть: с помощью GCC __attribute__((packed)) или MSVC #pragma pack).Просмотрите документацию вашего компилятора для более подробной информации.Несоблюдение этого совета может привести к добавлению дополнительных байтов в конец структуры TSS, что может вызвать проблемы при наличии IOPB.Если IOPB присутствует в TSS и добавлены дополнительные байты заполнения, эти байты станут частью битовой карты ввода-вывода и могут предоставлять / запрещать разрешения, которые вы не намеревались.Это был один из сбоев, которые привели к ошибкам в ядрах BSD.
  • Правила для 64-битного TSS одинаковы, когда речь идет о создании TSS с IOPB или без него.64-битный TSS по-прежнему используется даже в длинных режимах (64-битный режим и режим совместимости) и загружается в регистр задач так же, как это делается в устаревшем защищенном режиме с помощью инструкции LTR.
...