Buchbinder adam.buchbinder@gmail.com,Colin Ian King colin.king@canonical.com,Lorenzo Stoakes lstoakes@gmail.com,Qiaowei Ren qiaowei.ren@intel.com,Arnaldo Carvalho de Melo acme@redhat.com,Adrian Hunter adrian.hunter@intel.com,Kees Cook keescook@chromium.org,Thomas Garnier thgarnie@google.com,Dmitry Vyukov dvyukov@google.com From: hpa@zytor.com Message-ID: 18E8698F-6C60-4B98-AE73-C371184C5135@zytor.com
On January 25, 2017 1:58:27 PM PST, Andy Lutomirski luto@amacapital.net wrote:
On Wed, Jan 25, 2017 at 12:23 PM, Ricardo Neri ricardo.neri-calderon@linux.intel.com wrote:
Tasks running in virtual-8086 mode will use 16-bit addressing form encodings as described in the Intel 64 and IA-32 Architecture
Software
Developer's Manual Volume 2A Section 2.1.5. 16-bit addressing
encodings
differ in several ways from the 32-bit/64-bit addressing form
encodings:
the r/m part of the ModRM byte points to different registers and, in
some
cases, addresses can be indicated by the addition of the value of two registers. Also, there is no support for SiB bytes. Thus, a separate function is needed to parse this form of addressing.
Furthermore, virtual-8086 mode tasks will use real-mode addressing.
This
implies that the segment selectors do not point to a segment
descriptor
but are used to compute logical addresses. Hence, there is a need to add support to compute addresses using the segment selectors. If
segment-
override prefixes are present in the instructions, they take
precedence.
Lastly, it is important to note that when a tasks is running in
virtual-
8086 mode and an interrupt/exception occurs, the CPU pushes to the
stack
the segment selectors for ds, es, fs and gs. These are accesible via
the
struct kernel_vm86_regs rather than pt_regs.
Code for 16-bit addressing encodings is likely to be used only by
virtual-
8086 mode tasks. Thus, this code is wrapped to be built only if the option CONFIG_VM86 is selected.
That's not true. It's used in 16-bit protected mode, too. And there are (ugh!) six possibilities:
- Normal 32-bit protected mode. This should already work.
- Normal 64-bit protected mode. This should also already work. (I
forget whether a 16-bit SS is either illegal or has no effect in this case.)
- Virtual 8086 mode
- Normal 16-bit protected mode, used by DOSEMU and Wine. (16-bit CS,
16-bit address segment)
- 16-bit CS, 32-bit address segment. IIRC this might be used by some
32-bit DOS programs to call BIOS.
- 32-bit CS, 16-bit address segment. I don't know whether anything
uses this.
I don't know if anything you're doing cares about SS's, DS's, etc. size, but I suspect you'll need to handle 16-bit CS.
Only the CS bitness matters for the purpose of addressing modes; the SS bitness (which has no effect in 64-bit mode) only matters for implicit stack references unless I'm completely out to sea.