LINUX.ORG.RU

регистры fs и gs


0

0

Для чего в ядре Linux используются регистры fs и gs. Как правильно называются дескрипторы, на которые указывают селекторы загружаемые в эти регистры

#define GDT_ENTRY_PERCPU			(GDT_ENTRY_KERNEL_BASE + 15)
#ifdef CONFIG_SMP
#define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8)
#else
#define __KERNEL_PERCPU 0
#endif
...
#define GDT_ENTRY_STACK_CANARY		(GDT_ENTRY_KERNEL_BASE + 16)
#ifdef CONFIG_CC_STACKPROTECTOR
#define __KERNEL_STACK_CANARY		(GDT_ENTRY_STACK_CANARY * 8)
#else
#define __KERNEL_STACK_CANARY		0
#endif

почему они используються только ядром, для юзерспейса нету аналогичных дескрипторов, также при выполнение инстпукцмм iret (в слечае понижение привилегий) регистры fs и gs обнуляются.

Почему при заполнении GDT дескриптор

[GDT_ENTRY_PERCPU]		= GDT_ENTRY_INIT(0xc092, 0, 0xfffff),
аналогичен __KERNEL_DS а во время загрузки после отработки функции
static inline void setup_percpu_segment(int cpu)
{
#ifdef CONFIG_X86_32
	struct desc_struct gdt;

	pack_descriptor(&gdt, per_cpu_offset(cpu), 0xFFFFF,
			0x2 | DESCTYPE_S, 0x8);
	gdt.s = 1;
	write_gdt_entry(get_cpu_gdt_table(cpu),
			GDT_ENTRY_PERCPU, &gdt, DESCTYPE_S);
значение его base и limit модифицируються ? Почему ?

Инициализация дескриптора _KERNEL_STACK_CANARY, имеет еще более странные значения

#define GDT_STACK_CANARY_INIT						\
	[GDT_ENTRY_STACK_CANARY] = GDT_ENTRY_INIT(0x4090, 0, 0x18),
Суть которых еще большая загадка.

Почти не нашел не какой информации по этому вопросу. Надеюсь что хоть кто то сможет пролить свет на сею темную сторону


Linux использует сегментацию только когда это требует архитектура x86, больше она ему нафиг не нужна.

для юзерспейса нету аналогичных дескрипторов

man 2 modify_ldt

frey ★★
()

> Для чего в ядре Linux используются регистры fs и gs

с (относительно) недавнего времени fs или gs (в зависимости от X86_64)
используется для доступа к per_cpu данным.

насколько я знаю - больше ни для чего. ну, если не считать всякое
баловство типа apm_bios или stackprotector (x86_32).

еще раз, я говорю только про kernel. user-space может использовать
эти регистры тоже, поэтому kernel должен их сохранять/восстанавливать.

__KERNEL_STACK_CANARY

для юзерспейса нету аналогичных дескрипторов,



а зачем они для user-space ???

при выполнение инстпукцмм iret (в слечае понижение привилегий) регистры

fs и gs обнуляются.



хм. где вы такое увидели?

аналогичен __KERNEL_DS а во время загрузки после отработки функции

setup_percpu_segment(int cpu)


значение его base и limit модифицируються ?



потому, что каждому CPU нужен свой дескриптор, естественно. смотрите
внимательнее на setup_percpu_segment(), там меняется per_cpu(gdt_page).

#define GDT_STACK_CANARY_INIT

Суть которых еще большая загадка.



см жЫрный коммент в arch/x86/include/asm/stackprotector.h

idle ★★★★★
()
Ответ на: комментарий от idle

> при выполнение инстпукцмм iret (в слечае понижение привилегий) регистры

fs и gs обнуляются.

хм. где вы такое увидели?

Сначала на практике, в виде непонятной ошибки, потом в книжке при поиске причины, потом опять на практике после исправления ошибки :) (Бовети, Чезати)

> Для чего в ядре Linux используются регистры fs и gs

с (относительно) недавнего времени fs или gs (в зависимости от X86_64) используется для доступа к per_cpu данным.

насколько я знаю - больше ни для чего. ну, если не считать всякое

баловство типа apm_bios или stackprotector (x86_32).

забыл указать, что именно в ядре и именно в x86_32. Вот как раз это apm_bios или stackprotector :) Можно про них чуть поподробней ?

А что такое per_cpu данные ?

> #define GDT_STACK_CANARY_INIT

Суть которых еще большая загадка.

см жЫрный коммент в arch/x86/include/asm/stackprotector.h


Супер, спасибо.

Cupper
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.