mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-08-09 12:08:30 +00:00
hv: move check out of vie_calculate_gla
We will do check only during instruction decode phase. vie_calculate_gla will be called both in instruction emulation phase, we move the check out of vie_calculate_gla. Signed-off-by: Yin Fengwei <fengwei.yin@intel.com> Acked-by: Anthony Xu <anthony.xu@intel.com>
This commit is contained in:
parent
54c254169d
commit
8480c98053
@ -405,6 +405,40 @@ static int vie_canonical_check(enum vm_cpu_mode cpu_mode, uint64_t gla)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool is_desc_valid(struct seg_desc *desc, uint32_t prot)
|
||||||
|
{
|
||||||
|
uint32_t type;
|
||||||
|
|
||||||
|
/* The descriptor type must indicate a code/data segment. */
|
||||||
|
type = SEG_DESC_TYPE(desc->access);
|
||||||
|
if (type < 16U || type > 31U) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((prot & PROT_READ) != 0U) {
|
||||||
|
/* #GP on a read access to a exec-only code segment */
|
||||||
|
if ((type & 0xAU) == 0x8U) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((prot & PROT_WRITE) != 0U) {
|
||||||
|
/*
|
||||||
|
* #GP on a write access to a code segment or a
|
||||||
|
* read-only data segment.
|
||||||
|
*/
|
||||||
|
if ((type & 0x8U) != 0U) { /* code segment */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((type & 0xAU) == 0U) { /* read-only data seg */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*@pre seg must be segment register index
|
*@pre seg must be segment register index
|
||||||
*@pre length_arg must be 1, 2, 4 or 8
|
*@pre length_arg must be 1, 2, 4 or 8
|
||||||
@ -415,7 +449,7 @@ static int vie_canonical_check(enum vm_cpu_mode cpu_mode, uint64_t gla)
|
|||||||
*/
|
*/
|
||||||
static int vie_calculate_gla(enum vm_cpu_mode cpu_mode, enum cpu_reg_name seg,
|
static int vie_calculate_gla(enum vm_cpu_mode cpu_mode, enum cpu_reg_name seg,
|
||||||
struct seg_desc *desc, uint64_t offset_arg, uint8_t addrsize,
|
struct seg_desc *desc, uint64_t offset_arg, uint8_t addrsize,
|
||||||
uint32_t prot, uint64_t *gla)
|
uint64_t *gla)
|
||||||
{
|
{
|
||||||
uint64_t firstoff, segbase;
|
uint64_t firstoff, segbase;
|
||||||
uint64_t offset = offset_arg;
|
uint64_t offset = offset_arg;
|
||||||
@ -423,49 +457,7 @@ static int vie_calculate_gla(enum vm_cpu_mode cpu_mode, enum cpu_reg_name seg,
|
|||||||
uint32_t type;
|
uint32_t type;
|
||||||
|
|
||||||
firstoff = offset;
|
firstoff = offset;
|
||||||
if (cpu_mode == CPU_MODE_64BIT) {
|
glasize = (cpu_mode == CPU_MODE_64BIT) ? 8U: 4U;
|
||||||
if (addrsize != 4U && addrsize != 8U) {
|
|
||||||
pr_dbg("%s: invalid addr size %d for cpu mode %d",
|
|
||||||
__func__, addrsize, cpu_mode);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
glasize = 8U;
|
|
||||||
} else {
|
|
||||||
if (addrsize != 2U && addrsize != 4U) {
|
|
||||||
pr_dbg("%s: invalid addr size %d for cpu mode %d",
|
|
||||||
__func__, addrsize, cpu_mode);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
glasize = 4U;
|
|
||||||
|
|
||||||
/* The descriptor type must indicate a code/data segment. */
|
|
||||||
type = SEG_DESC_TYPE(desc->access);
|
|
||||||
if (type < 16 || type > 31) {
|
|
||||||
/*TODO: Inject #GP */
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((prot & PROT_READ) != 0U) {
|
|
||||||
/* #GP on a read access to a exec-only code segment */
|
|
||||||
if ((type & 0xAU) == 0x8U) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((prot & PROT_WRITE) != 0U) {
|
|
||||||
/*
|
|
||||||
* #GP on a write access to a code segment or a
|
|
||||||
* read-only data segment.
|
|
||||||
*/
|
|
||||||
if ((type & 0x8U) != 0U) { /* code segment */
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((type & 0xAU) == 0U) { /* read-only data seg */
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In 64-bit mode all segments except %fs and %gs have a segment
|
* In 64-bit mode all segments except %fs and %gs have a segment
|
||||||
@ -886,7 +878,7 @@ static int get_gla(struct vcpu *vcpu, __unused struct instr_emul_vie *vie,
|
|||||||
vm_get_seg_desc(seg, &desc);
|
vm_get_seg_desc(seg, &desc);
|
||||||
|
|
||||||
if (vie_calculate_gla(paging->cpu_mode, seg, &desc, val,
|
if (vie_calculate_gla(paging->cpu_mode, seg, &desc, val,
|
||||||
addrsize, prot, gla) != 0) {
|
addrsize, gla) != 0) {
|
||||||
if (seg == CPU_REG_SS) {
|
if (seg == CPU_REG_SS) {
|
||||||
pr_err("TODO: inject ss exception");
|
pr_err("TODO: inject ss exception");
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user