Pull to refresh
40
0.1
Valentin Nechayev @netch80

Программист (backend/сети)

Send message

Вполне возможно, вы вспоминаете вот это про GCC:

    For the purposes of branch prediction optimizations, the probability that a '__builtin_expect' expression is 'true' is controlled by GCC's 'builtin-expect-probability' parameter, which defaults to 90%. You can also use '__builtin_expect_with_probability' to explicitly assign a probability value to individual expressions.  If the built-in is used in a loop construct, the provided probability will influence the expected number of iterations made by loop optimizations.

По умолчанию он как-то оценивает вероятности веток.

Но при этом, как видите, можно сделать и определения, которые дают не 10%/90%, а конкретную вероятность. Так что вообще отказываться от unlikely смысла нет.

Я бы, конечно, расширил этот набор средств не перекрытием его эвристик, а их коррекцией - типа "раздели свою вероятности на 2". Но вряд ли это входит в ближайшие планы его команды.

А с многослойными платами получится так легко? Интересно было бы прочитать, как их расслаивают, на таком же уровне подробностей...

Я знаю про подзадачи. Вы сами сказали, это конец 60-х. А задача разделения прав между ядром/супервизором с одной стороны и пользовательскими задачами с другой - это на десять лет раньше.

Ко всем фото неплохо бы приложить линейку с делениями, чтобы был виден размер устройств и их частей.

Разделение по трём процессорам выглядит странновато. Это получается, что нельзя собрать всю функциональность в D0, если это подходит по остальным критериям - а надо в M0 делать какой-то прокси для внешних обменов? Или "используется" в вашем тексте это только рекомендации, а можно реально доступаться из любого из них?

Что значит "P" в "RV32IMAFCP"? Packed SIMD, как в основном комитете? Если да, то чем они там полезны?

Теперь я понял, что мы говорим с разных позиций и точек зрения. Вы - про сервера и виртуализацию в корпорате (а значит зарабатыванию денег и прочих вещей), а я с позиции пользователя ПК дома.

Я говорю в контексте полной виртуализации, потому что ветка дискуссии посвящена именно этому. "Пользователь ПК дома" таким практически не пользуется. Если что-то и виртуализуется, то без его ведома.

Если смотреть с вашей точки зрения, то я считаю, что там должно быть принципиально другое оборудование. И оно таким и было, пока кое-кто не подмял под себя большую часть рынка.

Про что речь? Про линию S/360 с потомками? У неё свои особенности, которые могут и мешать тут (хотя больше помогают).

всё я понимаю, но не могу повлиять на тех, кто заявленное производителем использует на своё усмотрение, часто не придерживаясь официальной спецификации.

А это всегда со всеми происходит. И иногда производителю приходится выгинаться под то, что не просто не ожидал, но и противоречит всему ожидаемому. Увы. Но опять же это другая история.

Посмотрите, столько колец (уровней) доступа у х86. А та же моторола обходилась всего 2мя: супервизор и юзер и отлично себя ощущала в разных машинах.

Ну вот этого уже достаточно, чтобы понять, что вы просто не понимаете, о чём говорите :(

Реально из тех колец, начиная с 80386, два: 0 (супервизор) и 3 (пользователь). Это так потому, что в системе пейджинга есть только один бит на уровень доступа на страницу: цитирую SDM:

Every access to a linear address is either a supervisor-mode access or a user-mode access. For all instruction fetches and most data accesses, this distinction is determined by the current privilege level (CPL): accesses made
while CPL < 3 are supervisor-mode accesses, while accesses made while CPL = 3 are user-mode accesses.

<...>

If the U/S flag (bit 2) is 0 in at least one of the paging-structure entries, the address is a supervisor-mode address. Otherwise, the address is a user-mode address.

Соответственно уровни (кольца) 1 и 2, оставшиеся в наследие от 80286, просто никем никогда всерьёз не использовались. Кто и зачем их придумал в x86 - ХЗ. Возможно, они просто косплеили VAX и тому подобных, где есть реальная польза в этой схеме уровней и её никто не ломал.

Зато добавление SMM даёт в этой нумерации условный уровень -1 (а ME - -2, но уже не лезем туда). И это уже соответствует традициям новых архитектур - ARM, RISC-V: 0 - user, 1 - supervisor, 2 - hypervisor (только в ARM; RISC-V не стал его в итоге вводить), 3 - machine (аналог SMM и т.п.) - вот это уже разумная схема. У VAX достаточно близко к этому.

А то, что вы говорите про Motorola (какой? M68k?), точно так же до чёрта где, включая упоминаемые тут в треде S/360 с потомками.

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

Важно. Именно что важно. Вы опять не в курсе и фантазируете. В условиях одной очень дорогой машины отдаваемой по факту в субаренду многим пользователям - разделение доступа имело смысл и коммерческий (нефиг воровать секреты друг от друга), и специально-служебный (разные отделы даже в одной воинской части или в каком-нибудь местном ГБ не должны знать данные друг друга и менять чужие данные), и прочий аналогичный. "Многопоточность" в смысле multithreading одного процесса тут никаким боком, она появилась заметно позже.

Повторюсь, приведённый мной пример самый наивный. По факту там есть гораздо более извращённые методы. Были даже абьюзы системы внеочередного выполнения инструкций.

Если мы говорим про то, когда в коде ядра/супервизора есть ошибка, которая позволяет допустить что-то на основании недопроверки данных - то это одно. Если meltdown, spectre и прочее - это уже совсем другое. Утечка подобного рода может быть вообще на чём угодно, и там, где её всерьёз опасаются, вообще не допускают одновременного физического присутствия на одном железе (а то и в одном помещении); эти уязвимости просто легче всего, автоматизированно и скрыто эксплуатировались. Смешивая эти случаи, вы убиваете возможность серьёзного обсуждения. Перестаньте смешивать, тогда можно будет обсуждать.

Я лишь хотел сказать, что чем сложнее становится процессор тем сложнее предвидеть все случаи, которые обеспечат несанкционированный прямой или косвенный доступ пользовательскому коду.

Верно. Стандартные модели не ловят побочные каналы доступа. Но сами эти каналы - особенность оптимизации, которая может быть легко устранена на программном уровне - средства к этому есть.

Но - в третий раз говорю - не собираюсь смешивать эти вопросы с общими вопросами защиты.

Реально граница между микрокодом (микропрограммой) и схемным управлением не очень чёткая.

Есть такая проблема, да. Вот например таким примером дополню - это уже микропрограмма или ещё просто логика, которая для удобства уложена в ПЗУ?

(Мне тут показателен термин "секвенсор".)

Но, если речь идёт о визуально отделяемом автомате исполнения отдельных команд процессора - даже если программа сидит в ПЗУ, это таки микрокод.

То, что вы описали, не имеет никакого отношения к понятиям привилегированных и чувствительных команд. Иначе надо было бы вообще любые действия считать такими - они же получают данные, из которых генерируются другие данные, в которых могут быть ошибки, которые приведут к уязвимостям. Это несерьёзный подход, и поэтому так никто в здравом уме не считает.

В том то и проблема, что изначально не ясно, какие инструкции потенциально привилегированные.

Это в каком смысле-то? В спеке ISA должно быть сказано, какие привилегированные.

Для соответствия PG важно выяснить, какие из них "sensitive", то есть затрагивают те аспекты режимы работы компьютера, которые относятся к управлению доступом. А вот это выясняется достаточно легко: есть чётко очерченный набор параметров. Собственно режим (kernel/user). Защита памяти. Весь I/O, по умолчанию (поэтому его команды должны быть привилегированными). Регистры/память обработки прерываний/исключений. Общее состояние (типа, полный останов относится => команда такого останова должна быть привилегированной). И так далее. Сильная зависимость от конкретной архитектуры, но понимание простое и однозначное.

И вот случай 80286, когда SMSW позволяет даже просто читать, в каком режиме работаем - уже подпадает под нарушение. Нельзя позволять читать режим, не имея привилегий - или же команда чтения должна показывать всегда фейковое значение, если это не спец. команда "прочитать имея на то полные права" (как в 386 то же самое делается чтением CR0).

А есть такие, которые могут влиять на защищённый режим только в определённых условиях.

Тогда или надо разделять их на разные команды, или как-то управлять этими условиями, так, чтобы не позволять лишнего доступа.

Проблема x86-до-VMX/SVM в том, что не просто не могли чего-то ожидать и понять - могли, но сначала бездумно игнорировали, а потом почему-то тормозили с лечением.

На это они оба, PSE36 и PAE, годились. Но PSE36 сложнее, это работало только на 4MB страницах, а это могло само по себе подпортить удобство системе. PAE сделано более традиционным (4KB базовая страница), зато физический адрес с ходу получался до 64 бит (дальше срабатывало уже ограничение конкретной модели процессора на его шине).

Виртуалки на z/Arch покупаются точно так же как любой облачный ресурс, хотя, конечно, по распространению до x86 не дотягивают в K тысяч раз ;/

А кто бедный - не знаю, IBM вполне себе процветает на потоке денег с линий Z и I и за счёт наработанного реноме. Вот работать с ними (включая и писать) это, да, особый скилл, там всё заметно иначе.

Вы сейчас описали разницу между ванильным command.com из DOS/Win9x и его заменителем cmd.exe из WinNT. Все привелегированные вызовы (в том числе и сервис DOS) эмулируются через исключение.

Я не вижу, в чём тут аналогия, но с виртуализацией сильно сложнее.

​1. Пачка команд: SMSW, SLDT, SIDT, SGDT, STR - могла быть выполнена в user mode (IOPL=3). С этим нельзя виртуализировать режим супервизора напрямую: он мог, например, через SMSW убедиться, что реально работает в защищённом режиме вместо реального. К чести Intel, они сделали, что при CR4.UMIP==1 на эти команды срабатывает защита. Не вижу, в каком процессоре они это сделали (текущий SDM не упоминает версию); CharGPT сказал, что это только с Skylake (Corei 6е поколение), то есть очень поздно (сильно позже введения собственно VMX).

То есть до появления VMX надо было для гарантии защиты от такого транслировать каждую страницу, разбирая по командам. При этом учтите, что код может быть самомодифицирующийся - и гипервизор должен перехватывать эти изменения.

​2. Регистр Flags содержит IOPL. Команда PUSHF должна сохранять его полностью. Вот и снова светим значением поля. Кроме IOPL, туда же RF, IF, VIF... Причём в отличие от пункта 1, это не регулируется и сейчас. Значит, аналогичные PUSHF тоже перехватывать, снова без бинарной трансляции не обойтись.

И это я явно ещё не все случаи вспомнил, только самые видимые на поверхности.

Итого, я очень сочувствую тем ребятам из VMWare и прочих, которым пришлось всё это костылять ;[

А вот если бы они хотя бы попробовали ввести соответствие даже тому примитивному критерию Попека-Голдберга, который был опубликован в 1974 (ещё 8086 не было в проекте), а придуман явно раньше - "Any sensitive instruction must be privileged" - то тут проблемы бы не было. Даже с подпорками в виде shadow paging, как в SystemZ, оно бы уже работало, и пошёл бы вопрос о том, как сделать эту работу быстрее, а не как сделать её в принципе.

Поэтому VMX (Intel) и SMX (AMD) стали глотком воды в пустыне.

После ошибки с делением они сделали возможность этот микрокод апгрейдить из БИОСа или драйверов. В ПЗУ, разумеется, оставалась базовая версия.

Тут чуть не так. В случае FDIV, например, или аналогичной проблемной команды могло делаться и две версии железа, с переключением между ними флажком. А вот дальше вопрос, как этот флажок реализовывался: мог идти во внутренний регистр, а мог патчем, который накладывался на микрокод - какая именно из команд выполняется.

Они таким образом несколько раз пытались сделать TSX и деактивировали... кажется, так и не запустили (хочу послушать, почему. У ARM получилось, а у Intel - нет? в чём сложность?)

Shadowed ПЗУ на ОЗУ - да, стандартный подход.

С 80286 более вероятно. Ссылку не дам, но такие вещи, как загрузка-выгрузка всех регистров при переключении задачи через task gate, выполнение команды loadall... - были в микрокоде.

Что-то путаете, похоже. Перед PAE был ещё PSE36 и вот он был "вначале" костылём с 4MB страницами, где в свободных питах в PTE размещались старшие биты физ. адреса.

PAE пошло вторым и вот оно было уже полноценным решением, расширяемым на 64 бита.

Про гостевые MFT/MVT согласен. В доке VM/370 явно сказано "если вижу систему с base control (максимум один CR0 трогается), то всё просто, иначе включаем тяжёлую артиллерию". Для обстановки на x86 такое не годилось, все виртуализуемые системы уже сами были с пейджингом.

А вот правильно или нет и сейчас оставаться без двухэтапной трансляции - вот тут основной вопрос. Мне кажется, она бы таки многое облегчила. Но тут уже вопрос больше психологический и коммерческий. Какая-нибудь Microsoft виртуализацией Windows не очень довольна, потому что фиг его знает как лицензию трекать. А игра, особенно с защитой, тем более. А в мире SystemZ, если знаешь, что даже верхний уровень наверняка виртуализирован за счёт LPAR manager, бечь некуда, надо сотрудничать.

Кстати говоря, не со всеми Вашими утверждениями в том посте я согласен. Например, что MOV меняет флаги, мне как раз нравилось, и я нередко этим пользовался. Хотя, конечно, 32-разрядный ARM в этом плане больше свободы даёт: там половина команд может изменять флаги, а может не изменять в зависимости от одного битика в коде команды.

Пользоваться-то можно, но на практике оказывается, что мешает - поэтому в 8086 как раз MOV не меняет флаги. Если надо менять, то на это есть TEST. А в S/360 тоже не меняет, хотите менять - есть LTR :)

ARM, да, ещё дальше тут продвинулся. Не зря Intel в обещанном APX его тут косплеит.

Вот насчёт ADC/SBC спорить глупо -- но им банально не хватало разрядности команды, как не хватило и на полноценную адресацию для XOR.

Могли сделать и на двух регистрах в стиле 0065ds. Всё равно лучше, чем костыль, что сделали.

А вот тамошний MMU вполне себе эффективен и очень прост в железе -- тоже немаловажная деталь. Не удивлюсь, если деление адресного пространства на 8 страниц по 8 Кбайт пошло из технических соображений

Да вот на PDP-11 страницы слишком крупные, а на VAX слишком мелкие. Баланса нет.

Про iAPX432 тут бы, конечно, устроить каким-то образом честные интервью у руководства. Но Гроув уже ушёл на поля вечной охоты, а остальные вряд ли расскажут...

Увы.

PDP-11: сумма тут. Плюс к тому виртуальная память системы "взгляд из подводной лодки через перископ" (в пространство в до 64 раз шире).

VAX: чудовищное количество сверхусложнённых команд со сложной логикой, которые старались минимально использовать - их нельзя было сделать быстрыми. (Соответственно, эпоху трансляции для out-of-order оно не могло пережить.) Тупой размер страницы (512 байт) и при этом плоский каталог, которым было неудобно управлять (или даже невозможно, если не находилось связного куска нужного размера).

Alpha: в погоне за RISC частично убили даже control flow dependency, надо было руками ставить барьеры. Чрезмерная зависимость от PALcode, медленного, там, где наоборот можно было загнать в железо. Тупейший подход к побайтовому и невыровненному доступу (даже в MIPS сделали лучше). Вообще такое впечатление, что Alpha сделали по принципу "посмотри на VAX и сделай наоборот".

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

PDP-11, конечно, красиво - для человека. Но неэффективно. В недавнем треде с вашим же участием я об этом писал. Называть его "лучшей (16-разрядной) архитектурой в истории" очень поспешно.

Но для машины с первым годом выпуска 1970, пачкой революционных решений, выживших после и расползшихся на всю индустрию (как MMIO и NZVC флаги), это было грандиозно.

8086 был хорош для его условий (попытка сделать за три месяца быструю замену негодному iAPX432). Плохо то, что аж два момента возможности расширения - переход к 32 и 64 битам - Intel пролюбил с максимальной эффективностью пролюбления, имея все ресурсы для грамотного рассмотрения, что делать. Вот это уже однозначно вопрос качества их R&D и вообще технического руководства.

Может, в Интел работали всё-таки не идиоты, а ровно наоборот?

Intel выжила за счёт процессора для IBM PC - в первый раз когда совсем уже падали в пропасть, за счёт госконтракта на ASCI Red - во второй. IBM PC - как открытая архитектура (IBM в итоге получила имя, но не доходы от неё). Это единственное, что их спасло. Microsoft пришла опять же на открытую архитектуру. Intel пытался самоликвидироваться много раз: iAPX432, Rambus, NetBurst, Itanium, попытка потом сделать ещё одну 64-битную ISA поверх x86... - но им всё время не давали. Продажники обеспечивали имя, а кто-то в руководстве оказывался достаточно умным, чтобы остановиться уже скользая в пропасть. Мне интересно, кто был в руководстве (вероятно, из основной троицы) таким кретином, пытавшимся голой рукой схватить звезду с неба - но это откроется, наверно, ещё лет через 20.

А подавляющее большинство их конкретных технических решений - ноль собственной разработки и всё максимально через зад. Именно за это и плач.

И таки да, где-то были не идиоты. Иначе бы Intel давно уже сдох. Но, таки, не в технической части.

Жду мемуаров...

1
23 ...

Information

Rating
3,765-th
Location
Киев, Киевская обл., Украина
Date of birth
Registered
Activity