aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/emulate.c
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2012-06-13 09:29:39 -0400
committerAvi Kivity <avi@redhat.com>2012-07-09 07:19:04 -0400
commite919464b53ea29aed46ff10f7d6416268678bdb9 (patch)
treecc9b3ec3043a6edbd6a6ae8adf2bed272ffba5fa /arch/x86/kvm/emulate.c
parenta14e579f224ba929fe2f1d9bbbff688ae67e2ec4 (diff)
KVM: x86 emulator: make read_segment_descriptor() return the address
Some operations want to modify the descriptor later on, so save the address for future use. Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/emulate.c')
-rw-r--r--arch/x86/kvm/emulate.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 7b575adaf1fd..99e3df2bf880 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -1296,7 +1296,8 @@ static void get_descriptor_table_ptr(struct x86_emulate_ctxt *ctxt,
1296 1296
1297/* allowed just for 8 bytes segments */ 1297/* allowed just for 8 bytes segments */
1298static int read_segment_descriptor(struct x86_emulate_ctxt *ctxt, 1298static int read_segment_descriptor(struct x86_emulate_ctxt *ctxt,
1299 u16 selector, struct desc_struct *desc) 1299 u16 selector, struct desc_struct *desc,
1300 ulong *desc_addr_p)
1300{ 1301{
1301 struct desc_ptr dt; 1302 struct desc_ptr dt;
1302 u16 index = selector >> 3; 1303 u16 index = selector >> 3;
@@ -1307,7 +1308,7 @@ static int read_segment_descriptor(struct x86_emulate_ctxt *ctxt,
1307 if (dt.size < index * 8 + 7) 1308 if (dt.size < index * 8 + 7)
1308 return emulate_gp(ctxt, selector & 0xfffc); 1309 return emulate_gp(ctxt, selector & 0xfffc);
1309 1310
1310 addr = dt.address + index * 8; 1311 *desc_addr_p = addr = dt.address + index * 8;
1311 return ctxt->ops->read_std(ctxt, addr, desc, sizeof *desc, 1312 return ctxt->ops->read_std(ctxt, addr, desc, sizeof *desc,
1312 &ctxt->exception); 1313 &ctxt->exception);
1313} 1314}
@@ -1339,6 +1340,7 @@ static int load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
1339 unsigned err_vec = GP_VECTOR; 1340 unsigned err_vec = GP_VECTOR;
1340 u32 err_code = 0; 1341 u32 err_code = 0;
1341 bool null_selector = !(selector & ~0x3); /* 0000-0003 are null */ 1342 bool null_selector = !(selector & ~0x3); /* 0000-0003 are null */
1343 ulong desc_addr;
1342 int ret; 1344 int ret;
1343 1345
1344 memset(&seg_desc, 0, sizeof seg_desc); 1346 memset(&seg_desc, 0, sizeof seg_desc);
@@ -1374,7 +1376,7 @@ static int load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
1374 if (null_selector) /* for NULL selector skip all following checks */ 1376 if (null_selector) /* for NULL selector skip all following checks */
1375 goto load; 1377 goto load;
1376 1378
1377 ret = read_segment_descriptor(ctxt, selector, &seg_desc); 1379 ret = read_segment_descriptor(ctxt, selector, &seg_desc, &desc_addr);
1378 if (ret != X86EMUL_CONTINUE) 1380 if (ret != X86EMUL_CONTINUE)
1379 return ret; 1381 return ret;
1380 1382
@@ -2614,13 +2616,14 @@ static int emulator_do_task_switch(struct x86_emulate_ctxt *ctxt,
2614 ulong old_tss_base = 2616 ulong old_tss_base =
2615 ops->get_cached_segment_base(ctxt, VCPU_SREG_TR); 2617 ops->get_cached_segment_base(ctxt, VCPU_SREG_TR);
2616 u32 desc_limit; 2618 u32 desc_limit;
2619 ulong desc_addr;
2617 2620
2618 /* FIXME: old_tss_base == ~0 ? */ 2621 /* FIXME: old_tss_base == ~0 ? */
2619 2622
2620 ret = read_segment_descriptor(ctxt, tss_selector, &next_tss_desc); 2623 ret = read_segment_descriptor(ctxt, tss_selector, &next_tss_desc, &desc_addr);
2621 if (ret != X86EMUL_CONTINUE) 2624 if (ret != X86EMUL_CONTINUE)
2622 return ret; 2625 return ret;
2623 ret = read_segment_descriptor(ctxt, old_tss_sel, &curr_tss_desc); 2626 ret = read_segment_descriptor(ctxt, old_tss_sel, &curr_tss_desc, &desc_addr);
2624 if (ret != X86EMUL_CONTINUE) 2627 if (ret != X86EMUL_CONTINUE)
2625 return ret; 2628 return ret;
2626 2629