Re: [Xen-devel] Re: Next steps with pv_ops for Xen
Keir Fraser wrote: You'd need to track pte->grant_handle mappings somewhere, but it could certainly be done this way, yes. At the moment, blktap and gntdev provide struct pages to get_user_pages by smuggling them in the vm_private_data field of the relevant vm_area_struct. Could we use this field to get the handles to ptep_get_and_clear_full as well? Only downside that I can see is that we would need to find the vma for each PTE that needs to be cleared this way (since we don't get this passed to ptep_get_and_clear_full), but this is mitigated by (i) it only happening in the erroneous, unclean-shutdown case, and (ii) getting a hit in the mm->mmap_cache for consecutive runs of mapped grants. Regards, Derek. ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/virtualization
Re: [Xen-devel] Re: Next steps with pv_ops for Xen
Geoffrey Lefebvre wrote: > In order to unmap a grant, you need the grant handle obtained when the > grant is mapped. That handle needs to be stored somewhere for the > lifetime of the mapping. Where would the handle be stored (as Gerd > proposed) in order to be able to unmap from ptep_get_and_clear_full? Sure. the kernel has to keep track of the grant mappings somewhere, so it can lookup the grant handle from the available information. Hashing by machine address should work reasonable fast. It's probably useful to have an in-kernel API for that which then can be used by both gntdev and the in-kernel backend drivers. This API can also abstract out arch-specific bits to make life easier for the ia64 guys ... cheers, Gerd ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/virtualization
[PATCH] xen: Make xen-blkfront write its protocol ABI to xenstore
Frontends are expected to write their protocol ABI to xenstore. Since the protocol ABI defaults to the backend's native ABI, things work fine without that as long as the frontend's native ABI is identical to the backend's native ABI. This is not the case for xen-blkfront running 32-on-64, because its ABI differs between 32 and 64 bit, and thus needs this fix. Based on http://xenbits.xensource.com/xen-unstable.hg?rev/c545932a18f3 and http://xenbits.xensource.com/xen-unstable.hg?rev/ffe52263b430 by Gerd Hoffmann <[EMAIL PROTECTED]> Signed-off-by: Markus Armbruster <[EMAIL PROTECTED]> --- drivers/block/xen-blkfront.c |7 +++ include/xen/interface/io/protocols.h | 21 + 2 files changed, 28 insertions(+), 0 deletions(-) create mode 100644 include/xen/interface/io/protocols.h diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 2bdebcb..70ddb8c 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -46,6 +46,7 @@ #include #include +#include #include @@ -599,6 +600,12 @@ again: message = "writing event-channel"; goto abort_transaction; } + err = xenbus_printf(xbt, dev->nodename, "protocol", "%s", + XEN_IO_PROTO_ABI_NATIVE); + if (err) { + message = "writing protocol"; + goto abort_transaction; + } err = xenbus_transaction_end(xbt, 0); if (err) { diff --git a/include/xen/interface/io/protocols.h b/include/xen/interface/io/protocols.h new file mode 100644 index 000..01fc8ae --- /dev/null +++ b/include/xen/interface/io/protocols.h @@ -0,0 +1,21 @@ +#ifndef __XEN_PROTOCOLS_H__ +#define __XEN_PROTOCOLS_H__ + +#define XEN_IO_PROTO_ABI_X86_32 "x86_32-abi" +#define XEN_IO_PROTO_ABI_X86_64 "x86_64-abi" +#define XEN_IO_PROTO_ABI_IA64 "ia64-abi" +#define XEN_IO_PROTO_ABI_POWERPC64 "powerpc64-abi" + +#if defined(__i386__) +# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_X86_32 +#elif defined(__x86_64__) +# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_X86_64 +#elif defined(__ia64__) +# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_IA64 +#elif defined(__powerpc64__) +# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_POWERPC64 +#else +# error arch fixup needed here +#endif + +#endif -- 1.5.3.3 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/virtualization
[PATCH] virtnet: remove double ether_setup
Hello Rusty, virtnet_probe already calls alloc_etherdev, which calls ether_setup. There is no need to do that again. Signed-off-by: Christian Borntraeger <[EMAIL PROTECTED]> --- drivers/net/virtio_net.c |1 - 1 file changed, 1 deletion(-) Index: kvm/drivers/net/virtio_net.c === --- kvm.orig/drivers/net/virtio_net.c +++ kvm/drivers/net/virtio_net.c @@ -329,11 +329,10 @@ static int virtnet_probe(struct virtio_d dev = alloc_etherdev(sizeof(struct virtnet_info)); if (!dev) return -ENOMEM; /* Set up network device as normal. */ - ether_setup(dev); dev->open = virtnet_open; dev->stop = virtnet_close; dev->hard_start_xmit = start_xmit; dev->features = NETIF_F_HIGHDMA; SET_NETDEV_DEV(dev, &vdev->dev); ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/virtualization
Re: [Xen-devel] Re: Next steps with pv_ops for Xen
D.G. Murray wrote: > Hi Mark, > >> Maybe a change to the gntdev userspace API to allow batching >> of mapping requests? > > Something along the lines of the following? > > void *xc_gnttab_map_grant_refs(int xcg_handle, >uint32_t count, >uint32_t *domids, >uint32_t *refs, >int prot); Yes, except that it should actually work ;) It doesn't for me (Fedora 8 again). Grab xenner 0.9 (just uploaded), edit blkbackd.c and flip the BATCH_MAPS from 0 to 1, compile, run, see it not work. With BATCH_MAPS being 0 blkbackd works nicely as blktap/tapdisk drop-in replacement. cheers, Gerd ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/virtualization
Re: [Xen-devel] Re: Next steps with pv_ops for Xen
Gerd Hoffmann wrote: Yes, except that it should actually work ;) It doesn't for me (Fedora 8 again). Grab xenner 0.9 (just uploaded), edit blkbackd.c and flip the BATCH_MAPS from 0 to 1, compile, run, see it not work. Which version of the Xen tools are you using? There was a bug in the version released with Xen 3.1, which should have been cleaned up in the subsequent minor versions. Try grabbing the patch to libxc at: http://xenbits.xensource.com/xen-3.1-testing.hg?raw-rev/135d5088909f Otherwise, if this doesn't work/is some other issue, could you post the OOPS and relevant Xen console output? Thanks, Derek. ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/virtualization
[PATCH] virtio_net: Fix stalled inbound traffic on early packets
The current virtio_net driver has a startup race, which prevents any incoming traffic: If try_fill_recv submits buffers to the host system data might be filled in and an interrupt is sent, before napi_enable finishes. In that case the interrupt will kick skb_recv_done which will then call netif_rx_schedule. netif_rx_schedule checks, if NAPI_STATE_SCHED is set - which is not as we did not run napi_enable. No poll routine is scheduled. Furthermore, skb_recv_done returns false, we disables interrupts for this device. One solution is the enable napi before inbound buffer are available. Signed-off-by: Christian Borntraeger <[EMAIL PROTECTED]> --- drivers/net/virtio_net.c |6 -- 1 file changed, 4 insertions(+), 2 deletions(-) Index: kvm/drivers/net/virtio_net.c === --- kvm.orig/drivers/net/virtio_net.c +++ kvm/drivers/net/virtio_net.c @@ -285,13 +285,15 @@ static int virtnet_open(struct net_devic { struct virtnet_info *vi = netdev_priv(dev); + napi_enable(&vi->napi); try_fill_recv(vi); /* If we didn't even get one input buffer, we're useless. */ - if (vi->num == 0) + if (vi->num == 0) { + napi_disable(&vi->napi); return -ENOMEM; + } - napi_enable(&vi->napi); return 0; } ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/virtualization
Re: [Xen-devel] Re: Next steps with pv_ops for Xen
> Which version of the Xen tools are you using? There was a bug in the > version released with Xen 3.1, which should have been cleaned up in the > subsequent minor versions. Try grabbing the patch to libxc at: > > http://xenbits.xensource.com/xen-3.1-testing.hg?raw-rev/135d5088909f Probably it is this one, according to rpm version is 3.1.0, so most likely the fix isn't there. > Otherwise, if this doesn't work/is some other issue, could you post the > OOPS and relevant Xen console output? There isn't any, the mapping just doesn't work (libxc returning NULL). thanks, Gerd ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/virtualization
[PATCH 3/19] change gdt acessor macro name
This patch changes the name of x86_64 macro used to access the per-cpu gdt. It is now equal to the i386 version, which will allow code to be shared. Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]> --- arch/x86/kernel/setup64.c |2 +- arch/x86/kernel/suspend_64.c |2 +- arch/x86/kernel/vsyscall_64.c |2 +- include/asm-x86/desc_64.h | 10 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/x86/kernel/setup64.c b/arch/x86/kernel/setup64.c index 51297cc..05cafcb 100644 --- a/arch/x86/kernel/setup64.c +++ b/arch/x86/kernel/setup64.c @@ -228,7 +228,7 @@ void __cpuinit cpu_init (void) * and set up the GDT descriptor: */ if (cpu) - memcpy(cpu_gdt(cpu), cpu_gdt_table, GDT_SIZE); + memcpy(get_cpu_gdt_table(cpu), cpu_gdt_table, GDT_SIZE); cpu_gdt_descr[cpu].size = GDT_SIZE; load_gdt((const struct desc_ptr *)&cpu_gdt_descr[cpu]); diff --git a/arch/x86/kernel/suspend_64.c b/arch/x86/kernel/suspend_64.c index c58ca08..54eca46 100644 --- a/arch/x86/kernel/suspend_64.c +++ b/arch/x86/kernel/suspend_64.c @@ -118,7 +118,7 @@ void fix_processor_context(void) set_tss_desc(cpu,t);/* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */ - cpu_gdt(cpu)[GDT_ENTRY_TSS].type = 9; + get_cpu_gdt_table(cpu)[GDT_ENTRY_TSS].type = 9; syscall_init(); /* This sets MSR_*STAR and related */ load_TR_desc(); /* This does ltr */ diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c index c4c5e76..e5c1118 100644 --- a/arch/x86/kernel/vsyscall_64.c +++ b/arch/x86/kernel/vsyscall_64.c @@ -297,7 +297,7 @@ static void __cpuinit vsyscall_set_cpu(int cpu) /* Store cpu number in limit so that it can be loaded quickly in user space in vgetcpu. 12 bits for the CPU and 8 bits for the node. */ - d = (unsigned long *)(cpu_gdt(cpu) + GDT_ENTRY_PER_CPU); + d = (unsigned long *)(get_cpu_gdt_table(cpu) + GDT_ENTRY_PER_CPU); *d = 0x0f400ULL; *d |= cpu; *d |= (node & 0xf) << 12; diff --git a/include/asm-x86/desc_64.h b/include/asm-x86/desc_64.h index 230ac6e..1c26dbb 100644 --- a/include/asm-x86/desc_64.h +++ b/include/asm-x86/desc_64.h @@ -48,7 +48,7 @@ static inline void write_ldt_entry(struct desc_struct *ldt, } /* the cpu gdt accessor */ -#define cpu_gdt(_cpu) ((struct desc_struct *)cpu_gdt_descr[_cpu].address) +#define get_cpu_gdt_table(_cpu) ((struct desc_struct *)cpu_gdt_descr[_cpu].address) static inline void load_gdt(const struct desc_ptr *ptr) { @@ -141,15 +141,15 @@ static inline void set_tss_desc(unsigned cpu, void *addr) * -1? seg base+limit should be pointing to the address of the * last valid byte */ - set_tssldt_descriptor(&cpu_gdt(cpu)[GDT_ENTRY_TSS], + set_tssldt_descriptor(&get_cpu_gdt_table(cpu)[GDT_ENTRY_TSS], (unsigned long)addr, DESC_TSS, IO_BITMAP_OFFSET + IO_BITMAP_BYTES + sizeof(unsigned long) - 1); } static inline void set_ldt_desc(unsigned cpu, void *addr, int size) { - set_tssldt_descriptor(&cpu_gdt(cpu)[GDT_ENTRY_LDT], (unsigned long)addr, - DESC_LDT, size * 8 - 1); + set_tssldt_descriptor(&get_cpu_gdt_table(cpu)[GDT_ENTRY_LDT], +(unsigned long)addr, DESC_LDT, size * 8 - 1); } #define LDT_entry_a(info) \ @@ -183,7 +183,7 @@ static inline void set_ldt_desc(unsigned cpu, void *addr, int size) static inline void load_TLS(struct thread_struct *t, unsigned int cpu) { unsigned int i; - u64 *gdt = (u64 *)(cpu_gdt(cpu) + GDT_ENTRY_TLS_MIN); + u64 *gdt = (u64 *)(get_cpu_gdt_table(cpu) + GDT_ENTRY_TLS_MIN); for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++) gdt[i] = t->tls_array[i]; -- 1.4.4.2 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/virtualization
[PATCH 1/19] unify desc_struct
This patch aims to make the access of struct desc_struct variables equal across architectures. In this patch, I unify the i386 and x86_64 versions under an anonymous union, keeping the way they are accessed untouched (a and b for 32-bit code, individual bit-fields for 64-bit). This solution is not beautiful, but will allow us to integrate common code that differed by the way descriptors were used. This is to be viewed incrementally. There's simply too much code to be fixed at once. In the future, goal is to set up in a single way of acessing the desc_struct fields. Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]> --- arch/x86/kernel/apm_32.c |2 +- arch/x86/kernel/cpu/common.c | 28 ++-- arch/x86/kernel/process_64.c |2 +- arch/x86/kernel/traps_32.c |2 +- include/asm-x86/desc_defs.h| 28 include/asm-x86/processor_32.h |5 + 6 files changed, 38 insertions(+), 29 deletions(-) diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c index 8cd9778..b8b9339 100644 --- a/arch/x86/kernel/apm_32.c +++ b/arch/x86/kernel/apm_32.c @@ -405,7 +405,7 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue); static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); static struct apm_user * user_list; static DEFINE_SPINLOCK(user_list_lock); -static const struct desc_structbad_bios_desc = { 0, 0x00409200 }; +static const struct desc_structbad_bios_desc = {{{ 0, 0x00409200 }}}; static const char driver_version[] = "1.16ac";/* no spaces */ diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 235cd61..0fe1c1d 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -22,31 +22,31 @@ #include "cpu.h" DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = { - [GDT_ENTRY_KERNEL_CS] = { 0x, 0x00cf9a00 }, - [GDT_ENTRY_KERNEL_DS] = { 0x, 0x00cf9200 }, - [GDT_ENTRY_DEFAULT_USER_CS] = { 0x, 0x00cffa00 }, - [GDT_ENTRY_DEFAULT_USER_DS] = { 0x, 0x00cff200 }, + [GDT_ENTRY_KERNEL_CS] = {{{ 0x, 0x00cf9a00 }}}, + [GDT_ENTRY_KERNEL_DS] = {{{ 0x, 0x00cf9200 }}}, + [GDT_ENTRY_DEFAULT_USER_CS] = {{{ 0x, 0x00cffa00 }}}, + [GDT_ENTRY_DEFAULT_USER_DS] = {{{ 0x, 0x00cff200 }}}, /* * Segments used for calling PnP BIOS have byte granularity. * They code segments and data segments have fixed 64k limits, * the transfer segment sizes are set at run time. */ - [GDT_ENTRY_PNPBIOS_CS32] = { 0x, 0x00409a00 },/* 32-bit code */ - [GDT_ENTRY_PNPBIOS_CS16] = { 0x, 0x9a00 },/* 16-bit code */ - [GDT_ENTRY_PNPBIOS_DS] = { 0x, 0x9200 }, /* 16-bit data */ - [GDT_ENTRY_PNPBIOS_TS1] = { 0x, 0x9200 },/* 16-bit data */ - [GDT_ENTRY_PNPBIOS_TS2] = { 0x, 0x9200 },/* 16-bit data */ + [GDT_ENTRY_PNPBIOS_CS32] = {{{ 0x, 0x00409a00 }}},/* 32-bit code */ + [GDT_ENTRY_PNPBIOS_CS16] = {{{ 0x, 0x9a00 }}},/* 16-bit code */ + [GDT_ENTRY_PNPBIOS_DS] = {{{ 0x, 0x9200 }}}, /* 16-bit data */ + [GDT_ENTRY_PNPBIOS_TS1] = {{{ 0x, 0x9200 }}},/* 16-bit data */ + [GDT_ENTRY_PNPBIOS_TS2] = {{{ 0x, 0x9200 }}},/* 16-bit data */ /* * The APM segments have byte granularity and their bases * are set at run time. All have 64k limits. */ - [GDT_ENTRY_APMBIOS_BASE] = { 0x, 0x00409a00 },/* 32-bit code */ + [GDT_ENTRY_APMBIOS_BASE] = {{{ 0x, 0x00409a00 }}},/* 32-bit code */ /* 16-bit code */ - [GDT_ENTRY_APMBIOS_BASE+1] = { 0x, 0x9a00 }, - [GDT_ENTRY_APMBIOS_BASE+2] = { 0x, 0x00409200 }, /* data */ + [GDT_ENTRY_APMBIOS_BASE+1] = {{{ 0x, 0x9a00 }}}, + [GDT_ENTRY_APMBIOS_BASE+2] = {{{ 0x, 0x00409200 }}}, /* data */ - [GDT_ENTRY_ESPFIX_SS] = { 0x, 0x00c09200 }, - [GDT_ENTRY_PERCPU] = { 0x, 0x }, + [GDT_ENTRY_ESPFIX_SS] = {{{ 0x, 0x00c09200 }}}, + [GDT_ENTRY_PERCPU] = {{{ 0x, 0x }}}, } }; EXPORT_PER_CPU_SYMBOL_GPL(gdt_page); diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 6724840..9e99cb7 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -437,7 +437,7 @@ static inline void set_32bit_tls(struct task_struct *t, int tls, u32 addr) .limit_in_pages = 1, .useable = 1, }; - struct n_desc_struct *desc = (void *)t->thread.tls_array; + struct desc_struct *desc = (void *)t->thread.tls_array; desc += tls; desc->a = LDT_entry_a(&ud); desc->b = LDT_entry_b(&ud); diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c index e15014e.
[PATCH 0/19] desc_struct integration
Hi, this is a series of patches that unify the struct desc_struct and friends across x86_64 and i386. As usual, it provides paravirt capabilities as a side-effect for x86_64. I consider the main goal, namely, of unifying the desc_struct, an ongoing effort, being this the beginning. A lot of old code has to be touched to accomplish that. I don't consider this patch ready for inclusion. Basically, the main reason is that I change the signatures of write_idt_entry(), write_gdt_entry(), and write_ldt_entry(). This is needed to account for the differences between the two architectures. (For example, gate descriptors in x86_64 are 16-byte long and can't be represented by low and high entries). As my patch series were 64-bit only, I hadn't come across the problem before. I think this interface is sane, but I'd like to hear opinions. Specially from Jeremy and Zach, since it would touch xen and vmi code. The later, by the way, is _not_ included in this series. Being the interface acked, we still have to write it. Thanks in advance for the review in opinions to come. ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/virtualization
[PATCH 4/19] removed unused variable
This variable is not used anywere, and is then removed Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]> --- include/asm-x86/desc_64.h |5 - 1 files changed, 0 insertions(+), 5 deletions(-) diff --git a/include/asm-x86/desc_64.h b/include/asm-x86/desc_64.h index 1c26dbb..660cc84 100644 --- a/include/asm-x86/desc_64.h +++ b/include/asm-x86/desc_64.h @@ -30,11 +30,6 @@ static inline unsigned long __store_tr(void) #define store_tr(tr) (tr) = __store_tr() -/* - * This is the ldt that every process will get unless we need - * something other than this. - */ -extern struct desc_struct default_ldt[]; extern struct gate_struct idt_table[]; extern struct desc_ptr cpu_gdt_descr[]; -- 1.4.4.2 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/virtualization
[PATCH 6/19] change write_idt_entry signature
this patch changes write_idt_entry signature. It now takes a gate_desc instead of the a and b parameters. It will allow it to be later unified between i386 and x86_64. Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]> --- arch/x86/kernel/paravirt_32.c |2 +- arch/x86/xen/enlighten.c |5 ++--- include/asm-x86/desc_32.h |9 +++-- include/asm-x86/paravirt.h|9 + 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/arch/x86/kernel/paravirt_32.c b/arch/x86/kernel/paravirt_32.c index f4e3a8e..9ed46da 100644 --- a/arch/x86/kernel/paravirt_32.c +++ b/arch/x86/kernel/paravirt_32.c @@ -381,7 +381,7 @@ struct pv_cpu_ops pv_cpu_ops = { .load_tls = native_load_tls, .write_ldt_entry = write_dt_entry, .write_gdt_entry = write_dt_entry, - .write_idt_entry = write_dt_entry, + .write_idt_entry = write_idt_entry, .load_sp0 = native_load_sp0, .irq_enable_syscall_ret = native_irq_enable_syscall_ret, diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 53b097a..829a450 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -399,8 +399,7 @@ static DEFINE_PER_CPU(struct desc_ptr, idt_desc); /* Set an IDT entry. If the entry is part of the current IDT, then also update Xen. */ -static void xen_write_idt_entry(struct desc_struct *dt, int entrynum, - u32 low, u32 high) +static void xen_write_idt_entry(gate_desc *dt, int entrynum, gate_desc *g) { unsigned long p = (unsigned long)&dt[entrynum]; unsigned long start, end; @@ -412,7 +411,7 @@ static void xen_write_idt_entry(struct desc_struct *dt, int entrynum, xen_mc_flush(); - write_dt_entry(dt, entrynum, low, high); + native_write_idt_entry(dt, entrynum, g); if (p >= start && (p + 8) <= end) { struct trap_info info[2]; diff --git a/include/asm-x86/desc_32.h b/include/asm-x86/desc_32.h index 77f1e5a..e77ed8c 100644 --- a/include/asm-x86/desc_32.h +++ b/include/asm-x86/desc_32.h @@ -70,9 +70,14 @@ static inline void pack_gate(gate_desc *gate, #define write_ldt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) #define write_gdt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) -#define write_idt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) +#define write_idt_entry(dt, entry, g) native_write_idt_entry(dt, entry, g) #endif +static inline void native_write_idt_entry(gate_desc *idt, int entry, gate_desc *gate) +{ + memcpy(&idt[entry], gate, sizeof(*gate)); +} + static inline void write_dt_entry(struct desc_struct *dt, int entry, u32 entry_low, u32 entry_high) { @@ -142,7 +147,7 @@ static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned s { gate_desc g; pack_gate(&g, (unsigned long)addr, seg, type, 0); - write_idt_entry(idt_table, gate, g.a, g.b); + write_idt_entry(idt_table, gate, &g); } static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, const void *addr) diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index 0333fb6..d369b85 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -24,6 +24,7 @@ struct desc_ptr; struct tss_struct; struct mm_struct; struct desc_struct; +gate_desc; /* general info */ struct pv_info { @@ -99,8 +100,8 @@ struct pv_cpu_ops { int entrynum, u32 low, u32 high); void (*write_gdt_entry)(struct desc_struct *, int entrynum, u32 low, u32 high); - void (*write_idt_entry)(struct desc_struct *, - int entrynum, u32 low, u32 high); + void (*write_idt_entry)(gate_desc *, + int entrynum, gate_desc *gate); void (*load_sp0)(struct tss_struct *tss, struct thread_struct *t); void (*set_iopl_mask)(unsigned mask); @@ -667,9 +668,9 @@ static inline void write_gdt_entry(void *dt, int entry, u32 low, u32 high) { PVOP_VCALL4(pv_cpu_ops.write_gdt_entry, dt, entry, low, high); } -static inline void write_idt_entry(void *dt, int entry, u32 low, u32 high) +static inline void write_idt_entry(gate_desc *dt, int entry, gate_desc *g) { - PVOP_VCALL4(pv_cpu_ops.write_idt_entry, dt, entry, low, high); + PVOP_VCALL4(pv_cpu_ops.write_idt_entry, dt, entry, g); } static inline void set_iopl_mask(unsigned mask) { -- 1.4.4.2 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/virtualization
[PATCH 5/19] introduce gate_desc type.
To account for the differences in gate descriptor in i386 and x86_64 a gate_desc type is introduced. Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]> --- arch/x86/kernel/traps_32.c |3 ++- include/asm-x86/desc_32.h | 15 --- include/asm-x86/desc_64.h |4 ++-- include/asm-x86/desc_defs.h |8 +++- 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c index 94c5aea..6b03d88 100644 --- a/arch/x86/kernel/traps_32.c +++ b/arch/x86/kernel/traps_32.c @@ -76,7 +76,8 @@ char ignore_fpu_irq = 0; * F0 0F bug workaround.. We have a special link segment * for this. */ -struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {{{ 0, 0 }}}, }; +gate_desc idt_table[256] + __attribute__((__section__(".data.idt"))) = { {{{ 0, 0 }}}, }; asmlinkage void divide_error(void); asmlinkage void debug(void); diff --git a/include/asm-x86/desc_32.h b/include/asm-x86/desc_32.h index bc5ca34..77f1e5a 100644 --- a/include/asm-x86/desc_32.h +++ b/include/asm-x86/desc_32.h @@ -3,6 +3,7 @@ #include #include +#include #ifndef __ASSEMBLY__ @@ -24,7 +25,7 @@ static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) } extern struct desc_ptr idt_descr; -extern struct desc_struct idt_table[]; +extern gate_desc idt_table[]; extern void set_intr_gate(unsigned int irq, void * addr); static inline void pack_descriptor(__u32 *a, __u32 *b, @@ -35,11 +36,11 @@ static inline void pack_descriptor(__u32 *a, __u32 *b, (limit & 0x000f) | ((type & 0xff) << 8) | ((flags & 0xf) << 20); } -static inline void pack_gate(__u32 *a, __u32 *b, +static inline void pack_gate(gate_desc *gate, unsigned long base, unsigned short seg, unsigned char type, unsigned char flags) { - *a = (seg << 16) | (base & 0x); - *b = (base & 0x) | ((type & 0xff) << 8) | (flags & 0xff); + gate->a = (seg << 16) | (base & 0x); + gate->b = (base & 0x) | ((type & 0xff) << 8) | (flags & 0xff); } #define DESCTYPE_LDT 0x82/* present, system, DPL-0, LDT */ @@ -139,9 +140,9 @@ static inline void native_load_tls(struct thread_struct *t, unsigned int cpu) static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned short seg) { - __u32 a, b; - pack_gate(&a, &b, (unsigned long)addr, seg, type, 0); - write_idt_entry(idt_table, gate, a, b); + gate_desc g; + pack_gate(&g, (unsigned long)addr, seg, type, 0); + write_idt_entry(idt_table, gate, g.a, g.b); } static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, const void *addr) diff --git a/include/asm-x86/desc_64.h b/include/asm-x86/desc_64.h index 660cc84..ffc6c06 100644 --- a/include/asm-x86/desc_64.h +++ b/include/asm-x86/desc_64.h @@ -30,7 +30,7 @@ static inline unsigned long __store_tr(void) #define store_tr(tr) (tr) = __store_tr() -extern struct gate_struct idt_table[]; +extern gate_desc idt_table[]; extern struct desc_ptr cpu_gdt_descr[]; static inline void write_ldt_entry(struct desc_struct *ldt, @@ -58,7 +58,7 @@ static inline void store_gdt(struct desc_ptr *ptr) static inline void _set_gate(void *adr, unsigned type, unsigned long func, unsigned dpl, unsigned ist) { - struct gate_struct s; + gate_desc s; s.offset_low = PTR_LOW(func); s.segment = __KERNEL_CS; diff --git a/include/asm-x86/desc_defs.h b/include/asm-x86/desc_defs.h index b3db064..e502549 100644 --- a/include/asm-x86/desc_defs.h +++ b/include/asm-x86/desc_defs.h @@ -42,7 +42,7 @@ enum { }; // 16byte gate -struct gate_struct { +struct gate_struct64 { u16 offset_low; u16 segment; unsigned ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1; @@ -70,6 +70,12 @@ struct ldttss_desc { u32 zero1; } __attribute__((packed)); +#ifdef CONFIG_X86_64 +typedef struct gate_struct64 gate_desc; +#else +typedef struct desc_struct gate_desc; +#endif + struct desc_ptr { unsigned short size; unsigned long address; -- 1.4.4.2 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/virtualization
[PATCH 2/19] unify struct desc_ptr
This patch unifies struct desc_ptr between i386 and x86_64. They can be expressed in the exact same way in C code, only having to change the name of one of them. As Xgt_desc_struct is ugly and big, this is the one that goes away. There's also a padding field in i386, but it is not really needed in the C structure definition. Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]> --- arch/x86/kernel/asm-offsets_32.c |5 ++--- arch/x86/kernel/cpu/common.c |2 +- arch/x86/kernel/doublefault_32.c |2 +- arch/x86/kernel/efi_32.c |4 ++-- arch/x86/kernel/machine_kexec_32.c |4 ++-- arch/x86/kernel/reboot_32.c|2 +- arch/x86/lguest/boot.c |4 ++-- arch/x86/xen/enlighten.c | 10 +- drivers/kvm/svm.c |2 +- include/asm-x86/desc_32.h | 16 +--- include/asm-x86/lguest.h |8 include/asm-x86/paravirt.h | 18 +- include/asm-x86/processor_32.h |2 +- include/asm-x86/suspend_32.h |4 ++-- 14 files changed, 38 insertions(+), 45 deletions(-) diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c index 4153135..afd8446 100644 --- a/arch/x86/kernel/asm-offsets_32.c +++ b/arch/x86/kernel/asm-offsets_32.c @@ -70,9 +70,8 @@ void foo(void) OFFSET(TI_cpu, thread_info, cpu); BLANK(); - OFFSET(GDS_size, Xgt_desc_struct, size); - OFFSET(GDS_address, Xgt_desc_struct, address); - OFFSET(GDS_pad, Xgt_desc_struct, pad); + OFFSET(GDS_size, desc_ptr, size); + OFFSET(GDS_address, desc_ptr, address); BLANK(); OFFSET(PT_EBX, pt_regs, bx); diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 0fe1c1d..a80847f 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -642,7 +642,7 @@ struct pt_regs * __devinit idle_regs(struct pt_regs *regs) * it's on the real one. */ void switch_to_new_gdt(void) { - struct Xgt_desc_struct gdt_descr; + struct desc_ptr gdt_descr; gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id()); gdt_descr.size = GDT_SIZE - 1; diff --git a/arch/x86/kernel/doublefault_32.c b/arch/x86/kernel/doublefault_32.c index cc19a3e..d16122a 100644 --- a/arch/x86/kernel/doublefault_32.c +++ b/arch/x86/kernel/doublefault_32.c @@ -17,7 +17,7 @@ static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE]; static void doublefault_fn(void) { - struct Xgt_desc_struct gdt_desc = {0, 0}; + struct desc_ptr gdt_desc = {0, 0}; unsigned long gdt, tss; store_gdt(&gdt_desc); diff --git a/arch/x86/kernel/efi_32.c b/arch/x86/kernel/efi_32.c index e2be78f..863e892 100644 --- a/arch/x86/kernel/efi_32.c +++ b/arch/x86/kernel/efi_32.c @@ -69,7 +69,7 @@ static void efi_call_phys_prelog(void) __acquires(efi_rt_lock) { unsigned long cr4; unsigned long temp; - struct Xgt_desc_struct gdt_descr; + struct desc_ptr gdt_descr; spin_lock(&efi_rt_lock); local_irq_save(efi_rt_eflags); @@ -111,7 +111,7 @@ static void efi_call_phys_prelog(void) __acquires(efi_rt_lock) static void efi_call_phys_epilog(void) __releases(efi_rt_lock) { unsigned long cr4; - struct Xgt_desc_struct gdt_descr; + struct desc_ptr gdt_descr; gdt_descr.address = (unsigned long)get_cpu_gdt_table(0); gdt_descr.size = GDT_SIZE - 1; diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c index 11b935f..c1cfd60 100644 --- a/arch/x86/kernel/machine_kexec_32.c +++ b/arch/x86/kernel/machine_kexec_32.c @@ -32,7 +32,7 @@ static u32 kexec_pte1[1024] PAGE_ALIGNED; static void set_idt(void *newidt, __u16 limit) { - struct Xgt_desc_struct curidt; + struct desc_ptr curidt; /* ia32 supports unaliged loads & stores */ curidt.size= limit; @@ -44,7 +44,7 @@ static void set_idt(void *newidt, __u16 limit) static void set_gdt(void *newgdt, __u16 limit) { - struct Xgt_desc_struct curgdt; + struct desc_ptr curgdt; /* ia32 supports unaligned loads & stores */ curgdt.size= limit; diff --git a/arch/x86/kernel/reboot_32.c b/arch/x86/kernel/reboot_32.c index bb1a0f8..c3376fa 100644 --- a/arch/x86/kernel/reboot_32.c +++ b/arch/x86/kernel/reboot_32.c @@ -161,7 +161,7 @@ real_mode_gdt_entries [3] = 0x92000100ULL /* 16-bit real-mode 64k data at 0x0100 */ }; -static struct Xgt_desc_struct +static struct desc_ptr real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (long)real_mode_gdt_entries }, real_mode_idt = { 0x3ff, 0 }, no_idt = { 0, 0 }; diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index c751e3c..aa0bdd5 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c @@ -229,7 +229,7 @@ static void lguest_write_idt_entry(struct desc_struct *dt, /* Changing to a different
[PATCH 7/19] introduce ldt_desc type.
this patch introduces ldt_desc type to account for the differences in the ldt descriptor in x86_64 and i386 Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]> --- include/asm-x86/desc_64.h |2 +- include/asm-x86/desc_defs.h |4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/include/asm-x86/desc_64.h b/include/asm-x86/desc_64.h index ffc6c06..8fe1b4c 100644 --- a/include/asm-x86/desc_64.h +++ b/include/asm-x86/desc_64.h @@ -113,7 +113,7 @@ static inline void store_idt(struct desc_ptr *dtr) static inline void set_tssldt_descriptor(void *ptr, unsigned long tss, unsigned type, unsigned size) { - struct ldttss_desc d; + struct ldttss_desc64 d; memset(&d, 0, sizeof(d)); d.limit0 = size & 0x; diff --git a/include/asm-x86/desc_defs.h b/include/asm-x86/desc_defs.h index e502549..3a562d1 100644 --- a/include/asm-x86/desc_defs.h +++ b/include/asm-x86/desc_defs.h @@ -61,7 +61,7 @@ enum { }; // LDT or TSS descriptor in the GDT. 16 bytes. -struct ldttss_desc { +struct ldttss_desc64 { u16 limit0; u16 base0; unsigned base1 : 8, type : 5, dpl : 2, p : 1; @@ -72,8 +72,10 @@ struct ldttss_desc { #ifdef CONFIG_X86_64 typedef struct gate_struct64 gate_desc; +typedef struct ldttss_desc64 ldt_desc; #else typedef struct desc_struct gate_desc; +typedef struct desc_struct ldt_desc; #endif struct desc_ptr { -- 1.4.4.2 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/virtualization
[PATCH 9/19] introduce fill_ldt
This patch introduces fill_ldt(), which populates a ldt descriptor from a user_desc in once, instead of relying in the LDT_entry_a and LDT_entry_b macros Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]> --- arch/x86/kernel/ldt.c|3 +-- arch/x86/kernel/process_64.c |3 +-- arch/x86/kernel/tls.c|7 +++ include/asm-x86/desc_32.h| 15 --- include/asm-x86/desc_64.h| 17 - include/asm-x86/ldt.h| 19 +++ 6 files changed, 24 insertions(+), 40 deletions(-) diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c index 7eb0c8a..3e872b4 100644 --- a/arch/x86/kernel/ldt.c +++ b/arch/x86/kernel/ldt.c @@ -223,8 +223,7 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode) } } - ldt.a = LDT_entry_a(&ldt_info); - ldt.b = LDT_entry_b(&ldt_info); + fill_ldt(&ldt, &ldt_info); if (oldmode) ldt.avl = 0; diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 9e99cb7..8b6d492 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -439,8 +439,7 @@ static inline void set_32bit_tls(struct task_struct *t, int tls, u32 addr) }; struct desc_struct *desc = (void *)t->thread.tls_array; desc += tls; - desc->a = LDT_entry_a(&ud); - desc->b = LDT_entry_b(&ud); + fill_ldt(desc, &ud); } static inline u32 read_32bit_tls(struct task_struct *t, int tls) diff --git a/arch/x86/kernel/tls.c b/arch/x86/kernel/tls.c index 67a3776..74d2b65 100644 --- a/arch/x86/kernel/tls.c +++ b/arch/x86/kernel/tls.c @@ -67,10 +67,9 @@ int do_set_thread_area(struct task_struct *p, int idx, if (LDT_empty(&info)) { desc[0] = 0; desc[1] = 0; - } else { - desc[0] = LDT_entry_a(&info); - desc[1] = LDT_entry_b(&info); - } + } else + fill_ldt((struct desc_struct *)desc, &info); + if (t == ¤t->thread) load_TLS(t, cpu); diff --git a/include/asm-x86/desc_32.h b/include/asm-x86/desc_32.h index e77ed8c..3653c9f 100644 --- a/include/asm-x86/desc_32.h +++ b/include/asm-x86/desc_32.h @@ -162,21 +162,6 @@ static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, const vo #define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr) -#define LDT_entry_a(info) \ - info)->base_addr & 0x) << 16) | ((info)->limit & 0x0)) - -#define LDT_entry_b(info) \ - (((info)->base_addr & 0xff00) | \ - (((info)->base_addr & 0x00ff) >> 16) | \ - ((info)->limit & 0xf) | \ - (((info)->read_exec_only ^ 1) << 9) | \ - ((info)->contents << 10) | \ - (((info)->seg_not_present ^ 1) << 15) | \ - ((info)->seg_32bit << 22) | \ - ((info)->limit_in_pages << 23) | \ - ((info)->useable << 20) | \ - 0x7000) - #define LDT_empty(info) (\ (info)->base_addr == 0&& \ (info)->limit == 0&& \ diff --git a/include/asm-x86/desc_64.h b/include/asm-x86/desc_64.h index 8fe1b4c..e0aa4bc 100644 --- a/include/asm-x86/desc_64.h +++ b/include/asm-x86/desc_64.h @@ -147,23 +147,6 @@ static inline void set_ldt_desc(unsigned cpu, void *addr, int size) (unsigned long)addr, DESC_LDT, size * 8 - 1); } -#define LDT_entry_a(info) \ - info)->base_addr & 0x) << 16) | ((info)->limit & 0x0)) -/* Don't allow setting of the lm bit. It is useless anyways because - 64bit system calls require __USER_CS. */ -#define LDT_entry_b(info) \ - (((info)->base_addr & 0xff00) | \ - (((info)->base_addr & 0x00ff) >> 16) | \ - ((info)->limit & 0xf) | \ - (((info)->read_exec_only ^ 1) << 9) | \ - ((info)->contents << 10) | \ - (((info)->seg_not_present ^ 1) << 15) | \ - ((info)->seg_32bit << 22) | \ - ((info)->limit_in_pages << 23) | \ - ((info)->useable << 20) | \ - /* ((info)->lm << 21) | */ \ - 0x7000) - #define LDT_empty(info) (\ (info)->base_addr == 0&& \ (info)->limit == 0&& \ diff --git a/include/asm-x86/ldt.h b/include/asm-x86/ldt.h index 20c5972..5f00d02 100644 --- a/include/asm-x86/ldt.h +++ b/include/asm-x86/ldt.h @@ -5,6 +5,7 @@ */ #ifndef _ASM_X86_LDT_H #define _ASM_X86_LDT_H +#include /* Maximum number of LDT entries supported. */ #define LDT_ENTRIES8192 @@ -32,6 +33,24 @@ struct user_desc { #endif }; +static inline void fill_ldt(struct desc_struct *desc, struct user_desc *info) +{ + desc->limit0 = info->limit & 0x0; + desc->base0 = info->base_addr & 0x; + + desc->base1 = info->base_addr & 0x00ff; + desc->type = (info->read_exec_only ^ 1) << 1; + desc->type |= info->contents << 2; + desc->s = 1; + desc->dpl = 0x3; +
[PATCH 8/19] modify write_ldt function
This patch modifies the write_ldt() function to make use of the new struct desc_struct instead of entry_1 and entry_2 entries Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]> --- arch/x86/kernel/ldt.c | 15 +++ 1 files changed, 7 insertions(+), 8 deletions(-) diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c index a8cdca3..7eb0c8a 100644 --- a/arch/x86/kernel/ldt.c +++ b/arch/x86/kernel/ldt.c @@ -186,7 +186,7 @@ static int read_default_ldt(void __user *ptr, unsigned long bytecount) static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode) { struct mm_struct *mm = current->mm; - __u32 entry_1, entry_2; + struct desc_struct ldt; int error; struct user_desc ldt_info; @@ -218,21 +218,20 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode) /* Allow LDTs to be cleared by the user. */ if (ldt_info.base_addr == 0 && ldt_info.limit == 0) { if (oldmode || LDT_empty(&ldt_info)) { - entry_1 = 0; - entry_2 = 0; + memset(&ldt, 0, sizeof(ldt)); goto install; } } - entry_1 = LDT_entry_a(&ldt_info); - entry_2 = LDT_entry_b(&ldt_info); + ldt.a = LDT_entry_a(&ldt_info); + ldt.b = LDT_entry_b(&ldt_info); if (oldmode) - entry_2 &= ~(1 << 20); + ldt.avl = 0; /* Install the new entry ... */ install: - write_ldt_entry(mm->context.ldt, ldt_info.entry_number, entry_1, - entry_2); + write_ldt_entry(mm->context.ldt, ldt_info.entry_number, + ldt.a, ldt.b); error = 0; out_unlock: -- 1.4.4.2 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/virtualization
[PATCH 11/19] change write_ldt_entry signature
this patch changes the signature of write_ldt_entry. Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]> --- arch/x86/kernel/ldt.c |3 +-- arch/x86/xen/enlighten.c |4 ++-- include/asm-x86/desc_32.h |9 - include/asm-x86/desc_64.h |7 ++- include/asm-x86/paravirt.h | 10 ++ 5 files changed, 19 insertions(+), 14 deletions(-) diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c index 3e872b4..b8ef462 100644 --- a/arch/x86/kernel/ldt.c +++ b/arch/x86/kernel/ldt.c @@ -229,8 +229,7 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode) /* Install the new entry ... */ install: - write_ldt_entry(mm->context.ldt, ldt_info.entry_number, - ldt.a, ldt.b); + write_ldt_entry(mm->context.ldt, ldt_info.entry_number, &ldt); error = 0; out_unlock: diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index a552103..16223b6 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -357,11 +357,11 @@ static void xen_load_tls(struct thread_struct *t, unsigned int cpu) } static void xen_write_ldt_entry(struct desc_struct *dt, int entrynum, - u32 low, u32 high) + void *ptr) { unsigned long lp = (unsigned long)&dt[entrynum]; xmaddr_t mach_lp = virt_to_machine(lp); - u64 entry = (u64)high << 32 | low; + u64 entry = *(u64 *)ptr; preempt_disable(); diff --git a/include/asm-x86/desc_32.h b/include/asm-x86/desc_32.h index 622b0e7..46fe80a 100644 --- a/include/asm-x86/desc_32.h +++ b/include/asm-x86/desc_32.h @@ -68,12 +68,19 @@ static inline void pack_gate(gate_desc *gate, #define load_TLS(t, cpu) native_load_tls(t, cpu) #define set_ldt native_set_ldt -#define write_ldt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) +#define write_ldt_entry(dt, entry, desc) \ + native_write_ldt_entry(dt, entry, desc) #define write_gdt_entry(dt, entry, desc, size) \ native_write_gdt_entry(dt, entry, desc, size) #define write_idt_entry(dt, entry, g) native_write_idt_entry(dt, entry, g) #endif +static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry, + void *desc) +{ + memcpy(&ldt[entry], desc, size); +} + static inline void native_write_idt_entry(gate_desc *idt, int entry, gate_desc *gate) { memcpy(&idt[entry], gate, sizeof(*gate)); diff --git a/include/asm-x86/desc_64.h b/include/asm-x86/desc_64.h index e0aa4bc..3cd5f10 100644 --- a/include/asm-x86/desc_64.h +++ b/include/asm-x86/desc_64.h @@ -34,12 +34,9 @@ extern gate_desc idt_table[]; extern struct desc_ptr cpu_gdt_descr[]; static inline void write_ldt_entry(struct desc_struct *ldt, - int entry, u32 entry_low, u32 entry_high) + int entry, void *ptr) { - __u32 *lp = (__u32 *)((entry << 3) + (char *)ldt); - - lp[0] = entry_low; - lp[1] = entry_high; + memcpy(&ldt[entry], ptr, 8); } /* the cpu gdt accessor */ diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index a3e22b7..b855264 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -96,8 +96,8 @@ struct pv_cpu_ops { void (*set_ldt)(const void *desc, unsigned entries); unsigned long (*store_tr)(void); void (*load_tls)(struct thread_struct *t, unsigned int cpu); - void (*write_ldt_entry)(struct desc_struct *, - int entrynum, u32 low, u32 high); + void (*write_ldt_entry)(struct desc_struct *ldt, int entrynum, + void *desc); void (*write_gdt_entry)(struct desc_struct *, int entrynum, void *desc, int size); void (*write_idt_entry)(gate_desc *, @@ -660,9 +660,11 @@ static inline void load_TLS(struct thread_struct *t, unsigned cpu) { PVOP_VCALL2(pv_cpu_ops.load_tls, t, cpu); } -static inline void write_ldt_entry(void *dt, int entry, u32 low, u32 high) + +static inline void write_ldt_entry(struct desc_struct *dt, int entry, + void *desc) { - PVOP_VCALL4(pv_cpu_ops.write_ldt_entry, dt, entry, low, high); + PVOP_VCALL3(pv_cpu_ops.write_ldt_entry, dt, entry, desc); } static inline void write_gdt_entry(struct desc_struct *dt, int entry, -- 1.4.4.2 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/virtualization
[PATCH 16/19] provide tss_desc
Provide a new type, tss_desc, to represent the tss descriptor in a unified way accross x86_64 and i386 Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]> --- include/asm-x86/desc_defs.h |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/include/asm-x86/desc_defs.h b/include/asm-x86/desc_defs.h index 3bfb7d9..d4ae70d 100644 --- a/include/asm-x86/desc_defs.h +++ b/include/asm-x86/desc_defs.h @@ -80,9 +80,11 @@ struct ldttss_desc64 { #ifdef CONFIG_X86_64 typedef struct gate_struct64 gate_desc; typedef struct ldttss_desc64 ldt_desc; +typedef struct ldttss_desc64 tss_desc; #else typedef struct desc_struct gate_desc; typedef struct desc_struct ldt_desc; +typedef struct desc_struct tss_desc; #endif struct desc_ptr { -- 1.4.4.2 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/virtualization
[PATCH 15/19] modify get_desc_base
This patch makes get_desc_base() receive a struct desc_struct, and then uses its internal fields to compute the base address. Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]> --- arch/x86/kernel/tls.c |2 +- arch/x86/mm/fault_32.c |2 +- include/asm-x86/desc.h |8 ++-- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/arch/x86/kernel/tls.c b/arch/x86/kernel/tls.c index 74d2b65..98f428b 100644 --- a/arch/x86/kernel/tls.c +++ b/arch/x86/kernel/tls.c @@ -112,7 +112,7 @@ int do_get_thread_area(struct task_struct *p, int idx, memset(&info, 0, sizeof(struct user_desc)); info.entry_number = idx; - info.base_addr = get_desc_base((void *)desc); + info.base_addr = get_desc_base((struct desc_struct *)desc); info.limit = GET_LIMIT(desc); info.seg_32bit = GET_32BIT(desc); info.contents = GET_CONTENTS(desc); diff --git a/arch/x86/mm/fault_32.c b/arch/x86/mm/fault_32.c index 6056c6d..ef5ab2b 100644 --- a/arch/x86/mm/fault_32.c +++ b/arch/x86/mm/fault_32.c @@ -115,7 +115,7 @@ static inline unsigned long get_segment_eip(struct pt_regs *regs, } /* Decode the code segment base from the descriptor */ - base = get_desc_base((unsigned long *)desc); + base = get_desc_base((struct desc_struct *)desc); if (seg & (1<<2)) { mutex_unlock(¤t->mm->context.lock); diff --git a/include/asm-x86/desc.h b/include/asm-x86/desc.h index 926d6f8..3480cb1 100644 --- a/include/asm-x86/desc.h +++ b/include/asm-x86/desc.h @@ -55,13 +55,9 @@ static inline void load_LDT(mm_context_t *pc) preempt_enable(); } -static inline unsigned long get_desc_base(unsigned long *desc) +static inline unsigned long get_desc_base(struct desc_struct *desc) { - unsigned long base; - base = ((desc[0] >> 16) & 0x) | - ((desc[1] << 16) & 0x00ff) | - (desc[1] & 0xff00); - return base; + return desc->base0 | ((desc->base1) << 16) | ((desc->base2) << 24); } #else -- 1.4.4.2 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/virtualization
[PATCH 13/19] unify non-paravirt parts of desc.h
This patch unifies the non-paravirt part of desc_{32,64}.h into desc.h. Most of it, is simply common code, that is moved to the shared header. The only exception is the set_ldt_desc in desc_64.h, which is changed - included its name - to accomodate for the way the ldt is set up in i386. Also, constant definitions used in desc_32.h are moved to desc_defs.h Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]> --- include/asm-x86/desc.h | 87 ++ include/asm-x86/desc_32.h| 66 include/asm-x86/desc_64.h| 64 --- include/asm-x86/mmu_context_64.h |4 +- 4 files changed, 99 insertions(+), 122 deletions(-) diff --git a/include/asm-x86/desc.h b/include/asm-x86/desc.h index 6065c50..926d6f8 100644 --- a/include/asm-x86/desc.h +++ b/include/asm-x86/desc.h @@ -1,5 +1,92 @@ +#ifndef _ASM_DESC_H_ +#define _ASM_DESC_H_ + +#include + +#ifndef __ASSEMBLY__ +#include + +extern struct desc_ptr idt_descr; +extern gate_desc idt_table[]; + +#endif + #ifdef CONFIG_X86_32 # include "desc_32.h" #else # include "desc_64.h" #endif + +#ifndef __ASSEMBLY__ + +#define _LDT_empty(info) (\ + (info)->base_addr == 0&& \ + (info)->limit == 0&& \ + (info)->contents== 0&& \ + (info)->read_exec_only == 1&& \ + (info)->seg_32bit == 0&& \ + (info)->limit_in_pages == 0&& \ + (info)->seg_not_present == 1&& \ + (info)->useable == 0) + +#ifdef CONFIG_X86_64 +#define LDT_empty(info) (_LDT_empty(info) && ((info)->lm == 0)) +#else +#define LDT_empty(info) (_LDT_empty(info)) +#endif + +static inline void clear_LDT(void) +{ + set_ldt(NULL, 0); +} + +/* + * load one particular LDT into the current CPU + */ +static inline void load_LDT_nolock(mm_context_t *pc) +{ + set_ldt(pc->ldt, pc->size); +} + +static inline void load_LDT(mm_context_t *pc) +{ + preempt_disable(); + load_LDT_nolock(pc); + preempt_enable(); +} + +static inline unsigned long get_desc_base(unsigned long *desc) +{ + unsigned long base; + base = ((desc[0] >> 16) & 0x) | + ((desc[1] << 16) & 0x00ff) | + (desc[1] & 0xff00); + return base; +} + +#else +/* + * GET_DESC_BASE reads the descriptor base of the specified segment. + * + * Args: + *idx - descriptor index + *gdt - GDT pointer + *base - 32bit register to which the base will be written + *lo_w - lo word of the "base" register + *lo_b - lo byte of the "base" register + *hi_b - hi byte of the low word of the "base" register + * + * Example: + *GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah) + *Will read the base address of GDT_ENTRY_ESPFIX_SS and put it into %eax. + */ +#define GET_DESC_BASE(idx, gdt, base, lo_w, lo_b, hi_b) \ + movb idx*8+4(gdt), lo_b; \ + movb idx*8+7(gdt), hi_b; \ + shll $16, base; \ + movw idx*8+2(gdt), lo_w; + + +#endif /* __ASSEMBLY__ */ + +#endif diff --git a/include/asm-x86/desc_32.h b/include/asm-x86/desc_32.h index 5d1e848..960ec77 100644 --- a/include/asm-x86/desc_32.h +++ b/include/asm-x86/desc_32.h @@ -11,8 +11,6 @@ #include #include -#include - struct gdt_page { struct desc_struct gdt[GDT_ENTRIES]; @@ -24,8 +22,6 @@ static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) return per_cpu(gdt_page, cpu).gdt; } -extern struct desc_ptr idt_descr; -extern gate_desc idt_table[]; extern void set_intr_gate(unsigned int irq, void * addr); static inline void pack_descriptor(struct desc_struct *desc, @@ -162,68 +158,6 @@ static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, const vo #define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr) -#define LDT_empty(info) (\ - (info)->base_addr == 0&& \ - (info)->limit == 0&& \ - (info)->contents== 0&& \ - (info)->read_exec_only == 1&& \ - (info)->seg_32bit == 0&& \ - (info)->limit_in_pages == 0&& \ - (info)->seg_not_present == 1&& \ - (info)->useable == 0) - -static inline void clear_LDT(void) -{ - set_ldt(NULL, 0); -} - -/* - * load one particular LDT into the current CPU - */ -static inline void load_LDT_nolock(mm_context_t *pc) -{ - set_ldt(pc->ldt, pc->size); -} - -static inline void load_LDT(mm_context_t *pc) -{ - preempt_disable(); - load_LDT_nolock(pc); - preempt_enable(); -} - -static inline unsigned long get_desc_base(unsigned long *desc) -{ - unsigned long base; - base = ((desc[0] >> 16) & 0x) | - ((desc[1] << 16) & 0x00ff) | - (desc[1] & 0xff00); - return base; -} - -#else /* __ASSEMBLY__ */ - -/* - * GET_DESC_BASE reads the descriptor base of the specified
[PATCH 12/19] move constants to desc_defs.h
this patch moves constant definitions regarding descriptor types from desc_32.h to desc_defs.h. The change from defines to enum to comply with previous versions in desc_defs.h Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]> --- include/asm-x86/desc_32.h |8 include/asm-x86/desc_defs.h |7 +++ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/include/asm-x86/desc_32.h b/include/asm-x86/desc_32.h index 46fe80a..5d1e848 100644 --- a/include/asm-x86/desc_32.h +++ b/include/asm-x86/desc_32.h @@ -43,14 +43,6 @@ static inline void pack_gate(gate_desc *gate, gate->b = (base & 0x) | ((type & 0xff) << 8) | (flags & 0xff); } -#define DESCTYPE_LDT 0x82/* present, system, DPL-0, LDT */ -#define DESCTYPE_TSS 0x89/* present, system, DPL-0, 32-bit TSS */ -#define DESCTYPE_TASK 0x85/* present, system, DPL-0, task gate */ -#define DESCTYPE_INT 0x8e/* present, system, DPL-0, interrupt gate */ -#define DESCTYPE_TRAP 0x8f/* present, system, DPL-0, trap gate */ -#define DESCTYPE_DPL3 0x60/* DPL-3 */ -#define DESCTYPE_S 0x10/* !system */ - #ifdef CONFIG_PARAVIRT #include #else diff --git a/include/asm-x86/desc_defs.h b/include/asm-x86/desc_defs.h index 3a562d1..3bfb7d9 100644 --- a/include/asm-x86/desc_defs.h +++ b/include/asm-x86/desc_defs.h @@ -58,6 +58,13 @@ struct gate_struct64 { enum { DESC_TSS = 0x9, DESC_LDT = 0x2, + DESCTYPE_LDT = 0x82, /* present, system, DPL-0, LDT */ + DESCTYPE_TSS = 0x89, /* present, system, DPL-0, 32-bit TSS */ + DESCTYPE_TASK = 0x85, /* present, system, DPL-0, task gate */ + DESCTYPE_INT = 0x8e, /* present, system, DPL-0, interrupt gate */ + DESCTYPE_TRAP = 0x8f, /* present, system, DPL-0, trap gate */ + DESCTYPE_DPL3 = 0x60, /* DPL-3 */ + DESCTYPE_S =0x10, /* !system */ }; // LDT or TSS descriptor in the GDT. 16 bytes. -- 1.4.4.2 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/virtualization
[PATCH 18/19] move _set_gate and its users to a common location
This patch moves _set_gate and its users to desc.h. We can now use common code for x86_64 and i386. Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]> --- arch/x86/kernel/traps_32.c | 34 include/asm-x86/desc.h | 88 +++ include/asm-x86/desc_32.h | 43 - include/asm-x86/desc_64.h | 45 -- include/asm-x86/desc_defs.h |5 +-- 5 files changed, 89 insertions(+), 126 deletions(-) diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c index 6b03d88..776e19b 100644 --- a/arch/x86/kernel/traps_32.c +++ b/arch/x86/kernel/traps_32.c @@ -1102,40 +1102,6 @@ asmlinkage void math_emulate(long arg) #endif /* CONFIG_MATH_EMULATION */ -/* - * This needs to use 'idt_table' rather than 'idt', and - * thus use the _nonmapped_ version of the IDT, as the - * Pentium F0 0F bugfix can have resulted in the mapped - * IDT being write-protected. - */ -void set_intr_gate(unsigned int n, void *addr) -{ - _set_gate(n, DESCTYPE_INT, addr, __KERNEL_CS); -} - -/* - * This routine sets up an interrupt gate at directory privilege level 3. - */ -static inline void set_system_intr_gate(unsigned int n, void *addr) -{ - _set_gate(n, DESCTYPE_INT | DESCTYPE_DPL3, addr, __KERNEL_CS); -} - -static void __init set_trap_gate(unsigned int n, void *addr) -{ - _set_gate(n, DESCTYPE_TRAP, addr, __KERNEL_CS); -} - -static void __init set_system_gate(unsigned int n, void *addr) -{ - _set_gate(n, DESCTYPE_TRAP | DESCTYPE_DPL3, addr, __KERNEL_CS); -} - -static void __init set_task_gate(unsigned int n, unsigned int gdt_entry) -{ - _set_gate(n, DESCTYPE_TASK, (void *)0, (gdt_entry<<3)); -} - void __init trap_init(void) { diff --git a/include/asm-x86/desc.h b/include/asm-x86/desc.h index 1773dd2..1290757 100644 --- a/include/asm-x86/desc.h +++ b/include/asm-x86/desc.h @@ -15,6 +15,22 @@ extern struct desc_struct cpu_gdt_table[GDT_ENTRIES]; extern struct desc_ptr cpu_gdt_descr[]; /* the cpu gdt accessor */ #define get_cpu_gdt_table(_cpu) ((struct desc_struct *)cpu_gdt_descr[_cpu].address) + +static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func, +unsigned dpl, unsigned ist, unsigned seg) +{ + gate->offset_low = PTR_LOW(func); + gate->segment = __KERNEL_CS; + gate->ist = ist; + gate->p = 1; + gate->dpl = dpl; + gate->zero0 = 0; + gate->zero1 = 0; + gate->type = type; + gate->offset_middle = PTR_MIDDLE(func); + gate->offset_high = PTR_HIGH(func); +} + #else struct gdt_page { @@ -26,6 +42,16 @@ static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) { return per_cpu(gdt_page, cpu).gdt; } + +static inline void pack_gate(gate_desc *gate,unsigned char type, + unsigned long base, unsigned dpl, unsigned flags, unsigned short seg) + +{ + gate->a = (seg << 16) | (base & 0x); + gate->b = (base & 0x) | + ((( 0x80 | type | (dpl << 5)) & 0xff) << 8); +} + #endif #ifdef CONFIG_PARAVIRT @@ -214,6 +240,68 @@ static inline unsigned long get_desc_base(struct desc_struct *desc) { return desc->base0 | ((desc->base1) << 16) | ((desc->base2) << 24); } +static inline void _set_gate(int gate, unsigned type, void *addr, + unsigned dpl, unsigned ist, unsigned seg) +{ + gate_desc s; + pack_gate(&s, type, (unsigned long)addr, dpl, ist, seg); + /* +* does not need to be atomic because it is only done once at +* setup time +*/ + write_idt_entry(idt_table, gate, &s); +} + +/* + * This needs to use 'idt_table' rather than 'idt', and + * thus use the _nonmapped_ version of the IDT, as the + * Pentium F0 0F bugfix can have resulted in the mapped + * IDT being write-protected. + */ +static inline void set_intr_gate(unsigned int n, void *addr) +{ + BUG_ON((unsigned)n > 0xFF); + _set_gate(n, GATE_INTERRUPT, addr, 0, 0, __KERNEL_CS); +} + +/* + * This routine sets up an interrupt gate at directory privilege level 3. + */ +static inline void set_system_intr_gate(unsigned int n, void *addr) +{ + BUG_ON((unsigned)n > 0xFF); + _set_gate(n, GATE_INTERRUPT, addr, 0x3, 0, __KERNEL_CS); +} + +static inline void set_trap_gate(unsigned int n, void *addr) +{ + BUG_ON((unsigned)n > 0xFF); + _set_gate(n, GATE_TRAP, addr, 0, 0, __KERNEL_CS); +} + +static inline void set_system_gate(unsigned int n, void *addr) +{ + BUG_ON((unsigned)n > 0xFF); + _set_gate(n, GATE_TRAP, addr, 0x3, 0, __KERNEL_CS); +} + +static inline void set_task_gate(unsigned int n, unsigned int gdt_entry) +{ + BUG_ON((unsigned)n > 0xFF); + _set_gate(n, GATE_TASK, (void *)0, 0, 0, (gdt_entry<<3)); +} + +static inline void set_intr_gate_ist(int n, void *addr, unsigned ist) +{ + BUG_ON((unsigned)n > 0xFF); + _set_gate(
[PATCH 17/19] unify paravirt pieces of descriptor handling
With the types used to access descriptors in x86_64 and i386 now being the same, the code that effectively handles them can now be easily shared. This patch moves the paravirt part of desc_32.h into desc.h, and then, we get paravirt support in x86_64 for free. Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]> --- include/asm-x86/desc.h | 155 +++ include/asm-x86/desc_32.h | 120 - include/asm-x86/desc_64.h | 104 +++-- include/asm-x86/desc_defs.h |6 +- 4 files changed, 169 insertions(+), 216 deletions(-) diff --git a/include/asm-x86/desc.h b/include/asm-x86/desc.h index 3480cb1..1773dd2 100644 --- a/include/asm-x86/desc.h +++ b/include/asm-x86/desc.h @@ -5,11 +5,166 @@ #ifndef __ASSEMBLY__ #include +#include extern struct desc_ptr idt_descr; extern gate_desc idt_table[]; +#ifdef CONFIG_X86_64 +extern struct desc_struct cpu_gdt_table[GDT_ENTRIES]; +extern struct desc_ptr cpu_gdt_descr[]; +/* the cpu gdt accessor */ +#define get_cpu_gdt_table(_cpu) ((struct desc_struct *)cpu_gdt_descr[_cpu].address) +#else +struct gdt_page +{ + struct desc_struct gdt[GDT_ENTRIES]; +} __attribute__((aligned(PAGE_SIZE))); +DECLARE_PER_CPU(struct gdt_page, gdt_page); + +static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) +{ + return per_cpu(gdt_page, cpu).gdt; +} +#endif + +#ifdef CONFIG_PARAVIRT +#include +#else +#define load_TR_desc() native_load_tr_desc() +#define load_gdt(dtr) native_load_gdt(dtr) +#define load_idt(dtr) native_load_idt(dtr) +#define load_tr(tr) __asm__ __volatile("ltr %0"::"m" (tr)) +#define load_ldt(ldt) __asm__ __volatile("lldt %0"::"m" (ldt)) + +#define store_gdt(dtr) native_store_gdt(dtr) +#define store_idt(dtr) native_store_idt(dtr) +#define store_tr(tr) (tr = native_store_tr()) +#define store_ldt(ldt) __asm__ ("sldt %0":"=m" (ldt)) + +#define load_TLS(t, cpu) native_load_tls(t, cpu) +#define set_ldt native_set_ldt + +#define write_ldt_entry(dt, entry, desc) \ + native_write_ldt_entry(dt, entry, desc) +#define write_gdt_entry(dt, entry, desc, size) \ + native_write_gdt_entry(dt, entry, desc, size) +#define write_idt_entry(dt, entry, g) native_write_idt_entry(dt, entry, g) +#endif + +static inline void native_write_idt_entry(gate_desc *idt, int entry, gate_desc *gate) +{ + memcpy(&idt[entry], gate, sizeof(*gate)); +} + +static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry, + void *desc) +{ + memcpy(&ldt[entry], desc, 8); +} + +static inline void native_write_gdt_entry(struct desc_struct *gdt, int entry, + void *desc, int size) +{ + memcpy(&gdt[entry], desc, size); +} + +static inline void set_tssldt_descriptor(struct ldttss_desc64 *d, unsigned long tss, +unsigned type, unsigned size) +{ + memset(d, 0, sizeof(*d)); + d->limit0 = size & 0x; + d->base0 = PTR_LOW(tss); + d->base1 = PTR_MIDDLE(tss) & 0xFF; + d->type = type; + d->p = 1; + d->limit1 = (size >> 16) & 0xF; + d->base2 = (PTR_MIDDLE(tss) >> 8) & 0xFF; + d->base3 = PTR_HIGH(tss); +} + +static inline void pack_descriptor(struct desc_struct *desc, unsigned long base, + unsigned long limit, unsigned char type, + unsigned char flags) +{ + desc->a = ((base & 0x) << 16) | (limit & 0x); + desc->b = (base & 0xff00) | ((base & 0xff) >> 16) | + (limit & 0x000f) | ((type & 0xff) << 8) | + ((flags & 0xf) << 20); +} + +static inline void pack_ldt(ldt_desc *ldt, unsigned long addr, + unsigned size) +{ + +#ifdef CONFIG_X86_64 + set_tssldt_descriptor(ldt, +addr, DESC_LDT, size); +#else + pack_descriptor(ldt, (unsigned long)addr, + size, + 0x80 | DESC_LDT, 0); #endif +} + +static inline void native_set_ldt(const void *addr, unsigned int entries) +{ + if (likely(entries == 0)) + __asm__ __volatile__("lldt %w0"::"q" (0)); + else { + unsigned cpu = smp_processor_id(); + ldt_desc ldt; + + pack_ldt(&ldt, (unsigned long)addr, + entries * sizeof(ldt) - 1); + write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_LDT, + &ldt, sizeof(ldt)); + __asm__ __volatile__("lldt %w0"::"q" (GDT_ENTRY_LDT*8)); + } +} + +static inline void native_load_tr_desc(void) +{ + asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8)); +} + +static inline void native_load_gdt(const struct desc_ptr *dtr) +{ + asm volatile("lgd
[PATCH 19/19] unify set_tss_desc
This patch unifies the set_tss_desc between i386 and x86_64, which can now have a common implementation. After the old functions are removed from desc_{32,64}.h, nothing important is left, and the files can be removed. Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]> --- include/asm-x86/desc.h| 40 +--- include/asm-x86/desc_64.h | 34 -- 2 files changed, 33 insertions(+), 41 deletions(-) diff --git a/include/asm-x86/desc.h b/include/asm-x86/desc.h index 1290757..4aab1fd 100644 --- a/include/asm-x86/desc.h +++ b/include/asm-x86/desc.h @@ -133,6 +133,39 @@ static inline void pack_ldt(ldt_desc *ldt, unsigned long addr, #endif } +static inline void pack_tss(tss_desc *tss, unsigned long addr, + unsigned size, unsigned entry) +{ +#ifdef CONFIG_X86_64 + set_tssldt_descriptor(tss, +addr, entry, size); +#else + pack_descriptor(tss, (unsigned long)addr, + size, + 0x80 | entry, 0); +#endif +} + +static inline void __set_tss_desc(unsigned cpu, unsigned int entry, void *addr) +{ + struct desc_struct *d = get_cpu_gdt_table(cpu); + tss_desc tss; + + /* +* sizeof(unsigned long) coming from an extra "long" at the end +* of the iobitmap. See tss_struct definition in processor.h +* +* -1? seg base+limit should be pointing to the address of the +* last valid byte +*/ + pack_tss(&tss, (unsigned long)addr, + IO_BITMAP_OFFSET + IO_BITMAP_BYTES + sizeof(unsigned long) - 1, + DESC_TSS); + write_gdt_entry(d, entry, &tss, sizeof(tss)); +} + +#define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr) + static inline void native_set_ldt(const void *addr, unsigned int entries) { if (likely(entries == 0)) @@ -191,13 +224,6 @@ static inline void native_load_tls(struct thread_struct *t, unsigned int cpu) } #endif /* __ASSEMBLY__ */ - -#ifdef CONFIG_X86_32 -# include "desc_32.h" -#else -# include "desc_64.h" -#endif - #ifndef __ASSEMBLY__ #define _LDT_empty(info) (\ diff --git a/include/asm-x86/desc_64.h b/include/asm-x86/desc_64.h deleted file mode 100644 index de37b9b..000 --- a/include/asm-x86/desc_64.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Written 2000 by Andi Kleen */ -#ifndef __ARCH_DESC_H -#define __ARCH_DESC_H - -#include -#include - -#ifndef __ASSEMBLY__ - -#include - -#include - -static inline void set_tss_desc(unsigned cpu, void *addr) -{ - struct desc_struct *d = get_cpu_gdt_table(cpu); - tss_desc tss; - - /* -* sizeof(unsigned long) coming from an extra "long" at the end -* of the iobitmap. See tss_struct definition in processor.h -* -* -1? seg base+limit should be pointing to the address of the -* last valid byte -*/ - set_tssldt_descriptor(&tss, - (unsigned long)addr, DESC_TSS, - IO_BITMAP_OFFSET + IO_BITMAP_BYTES + sizeof(unsigned long) - 1); - write_gdt_entry(d, GDT_ENTRY_TSS, &tss, sizeof(tss_desc)); -} - -#endif /* !__ASSEMBLY__ */ - -#endif -- 1.4.4.2 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/virtualization
[PATCH 14/19] use the same data type for tls_array.
This patch changes the type of tls_array in x86_64 to a desc_struct. Now, both i386 and x86_64 tls_array have the same type, and code accessing it can be shared. Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]> --- include/asm-x86/desc_64.h |2 +- include/asm-x86/processor_64.h |3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/asm-x86/desc_64.h b/include/asm-x86/desc_64.h index 2dc19e2..7fd9876 100644 --- a/include/asm-x86/desc_64.h +++ b/include/asm-x86/desc_64.h @@ -150,7 +150,7 @@ static inline void set_ldt(void *addr, int entries) static inline void load_TLS(struct thread_struct *t, unsigned int cpu) { unsigned int i; - u64 *gdt = (u64 *)(get_cpu_gdt_table(cpu) + GDT_ENTRY_TLS_MIN); + struct desc_struct *gdt = (get_cpu_gdt_table(cpu) + GDT_ENTRY_TLS_MIN); for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++) gdt[i] = t->tls_array[i]; diff --git a/include/asm-x86/processor_64.h b/include/asm-x86/processor_64.h index 5689a8a..742090f 100644 --- a/include/asm-x86/processor_64.h +++ b/include/asm-x86/processor_64.h @@ -19,6 +19,7 @@ #include #include #include +#include #define TF_MASK0x0100 #define IF_MASK0x0200 @@ -241,7 +242,7 @@ struct thread_struct { /* MSR_IA32_DEBUGCTLMSR value to switch in if TIF_DEBUGCTLMSR is set. */ unsigned long debugctlmsr; /* cached TLS descriptors. */ - u64 tls_array[GDT_ENTRY_TLS_ENTRIES]; + struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES]; } __attribute__((aligned(16))); #define INIT_THREAD { \ -- 1.4.4.2 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/virtualization
[PATCH 10/19] change write_gdt_entry signature.
This patch changes the write_gdt_entry function signature. Instead of the old "a" and "b" parameters, it now receives a pointer to a desc_struct, and the size of the entry being handled. This is because x86_64 can have some 16-byte entries as well as 8-byte ones. Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]> --- arch/x86/kernel/paravirt_32.c |4 ++-- arch/x86/kernel/smpcommon_32.c |7 --- arch/x86/xen/enlighten.c |5 ++--- include/asm-x86/desc_32.h | 29 +++-- include/asm-x86/paravirt.h |9 ++--- 5 files changed, 29 insertions(+), 25 deletions(-) diff --git a/arch/x86/kernel/paravirt_32.c b/arch/x86/kernel/paravirt_32.c index 9ed46da..edff853 100644 --- a/arch/x86/kernel/paravirt_32.c +++ b/arch/x86/kernel/paravirt_32.c @@ -379,8 +379,8 @@ struct pv_cpu_ops pv_cpu_ops = { .store_idt = native_store_idt, .store_tr = native_store_tr, .load_tls = native_load_tls, - .write_ldt_entry = write_dt_entry, - .write_gdt_entry = write_dt_entry, + .write_ldt_entry = write_ldt_entry, + .write_gdt_entry = write_gdt_entry, .write_idt_entry = write_idt_entry, .load_sp0 = native_load_sp0, diff --git a/arch/x86/kernel/smpcommon_32.c b/arch/x86/kernel/smpcommon_32.c index bbfe85a..a6f9b41 100644 --- a/arch/x86/kernel/smpcommon_32.c +++ b/arch/x86/kernel/smpcommon_32.c @@ -14,10 +14,11 @@ __cpuinit void init_gdt(int cpu) { struct desc_struct *gdt = get_cpu_gdt_table(cpu); - pack_descriptor((u32 *)&gdt[GDT_ENTRY_PERCPU].a, - (u32 *)&gdt[GDT_ENTRY_PERCPU].b, + pack_descriptor(&gdt[GDT_ENTRY_PERCPU], __per_cpu_offset[cpu], 0xF, - 0x80 | DESCTYPE_S | 0x2, 0x8); + 0x80 | 0x2, 0x8); + + gdt[GDT_ENTRY_PERCPU].s = 1; per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu]; per_cpu(cpu_number, cpu) = cpu; diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 829a450..a552103 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -474,7 +474,7 @@ static void xen_load_idt(const struct desc_ptr *desc) /* Write a GDT descriptor entry. Ignore LDT descriptors, since they're handled differently. */ static void xen_write_gdt_entry(struct desc_struct *dt, int entry, - u32 low, u32 high) + void *desc, int size) { preempt_disable(); @@ -486,10 +486,9 @@ static void xen_write_gdt_entry(struct desc_struct *dt, int entry, default: { xmaddr_t maddr = virt_to_machine(&dt[entry]); - u64 desc = (u64)high << 32 | low; xen_mc_flush(); - if (HYPERVISOR_update_descriptor(maddr.maddr, desc)) + if (HYPERVISOR_update_descriptor(maddr.maddr, *(u64 *)desc)) BUG(); } diff --git a/include/asm-x86/desc_32.h b/include/asm-x86/desc_32.h index 3653c9f..622b0e7 100644 --- a/include/asm-x86/desc_32.h +++ b/include/asm-x86/desc_32.h @@ -28,11 +28,11 @@ extern struct desc_ptr idt_descr; extern gate_desc idt_table[]; extern void set_intr_gate(unsigned int irq, void * addr); -static inline void pack_descriptor(__u32 *a, __u32 *b, +static inline void pack_descriptor(struct desc_struct *desc, unsigned long base, unsigned long limit, unsigned char type, unsigned char flags) { - *a = ((base & 0x) << 16) | (limit & 0x); - *b = (base & 0xff00) | ((base & 0xff) >> 16) | + desc->a = ((base & 0x) << 16) | (limit & 0x); + desc->b = (base & 0xff00) | ((base & 0xff) >> 16) | (limit & 0x000f) | ((type & 0xff) << 8) | ((flags & 0xf) << 20); } @@ -69,7 +69,8 @@ static inline void pack_gate(gate_desc *gate, #define set_ldt native_set_ldt #define write_ldt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) -#define write_gdt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) +#define write_gdt_entry(dt, entry, desc, size) \ + native_write_gdt_entry(dt, entry, desc, size) #define write_idt_entry(dt, entry, g) native_write_idt_entry(dt, entry, g) #endif @@ -78,11 +79,10 @@ static inline void native_write_idt_entry(gate_desc *idt, int entry, gate_desc * memcpy(&idt[entry], gate, sizeof(*gate)); } -static inline void write_dt_entry(struct desc_struct *dt, - int entry, u32 entry_low, u32 entry_high) +static inline void native_write_gdt_entry(struct desc_struct *gdt, int entry, + void *desc, int size) { - dt[entry].a = entry_low; - dt[entry].b = entry_high; + memcpy(&gdt[entry], desc, size); } static inline void native_set_ldt(const void *addr, unsigned int entries) @@ -91,12 +91,13 @@ static inline void native_set_ldt(const void *addr, unsigne
Re: [PATCH 1/19] unify desc_struct
Glauber de Oliveira Costa wrote: > This patch aims to make the access of struct desc_struct variables > equal across architectures. In this patch, I unify the i386 and x86_64 > versions under an anonymous union, keeping the way they are accessed > untouched (a and b for 32-bit code, individual bit-fields for 64-bit). > > This solution is not beautiful, but will allow us to integrate common > code that differed by the way descriptors were used. This is to be viewed > incrementally. There's simply too much code to be fixed at once. > > In the future, goal is to set up in a single way of acessing > the desc_struct fields. > > Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]> > --- > arch/x86/kernel/apm_32.c |2 +- > arch/x86/kernel/cpu/common.c | 28 ++-- > arch/x86/kernel/process_64.c |2 +- > arch/x86/kernel/traps_32.c |2 +- > include/asm-x86/desc_defs.h| 28 > include/asm-x86/processor_32.h |5 + > 6 files changed, 38 insertions(+), 29 deletions(-) > > diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c > index 8cd9778..b8b9339 100644 > --- a/arch/x86/kernel/apm_32.c > +++ b/arch/x86/kernel/apm_32.c > @@ -405,7 +405,7 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue); > static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); > static struct apm_user * user_list; > static DEFINE_SPINLOCK(user_list_lock); > -static const struct desc_struct bad_bios_desc = { 0, 0x00409200 }; > +static const struct desc_struct bad_bios_desc = {{{ 0, 0x00409200 }}}; > > static const chardriver_version[] = "1.16ac";/* no spaces */ > > diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c > index 235cd61..0fe1c1d 100644 > --- a/arch/x86/kernel/cpu/common.c > +++ b/arch/x86/kernel/cpu/common.c > @@ -22,31 +22,31 @@ > #include "cpu.h" > > DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = { > - [GDT_ENTRY_KERNEL_CS] = { 0x, 0x00cf9a00 }, > - [GDT_ENTRY_KERNEL_DS] = { 0x, 0x00cf9200 }, > - [GDT_ENTRY_DEFAULT_USER_CS] = { 0x, 0x00cffa00 }, > - [GDT_ENTRY_DEFAULT_USER_DS] = { 0x, 0x00cff200 }, > + [GDT_ENTRY_KERNEL_CS] = {{{ 0x, 0x00cf9a00 }}}, > + [GDT_ENTRY_KERNEL_DS] = {{{ 0x, 0x00cf9200 }}}, > + [GDT_ENTRY_DEFAULT_USER_CS] = {{{ 0x, 0x00cffa00 }}}, > + [GDT_ENTRY_DEFAULT_USER_DS] = {{{ 0x, 0x00cff200 }}}, > I don't suppose there's some way to make all this more symbolic? > /* >* Segments used for calling PnP BIOS have byte granularity. >* They code segments and data segments have fixed 64k limits, >* the transfer segment sizes are set at run time. >*/ > - [GDT_ENTRY_PNPBIOS_CS32] = { 0x, 0x00409a00 },/* 32-bit code */ > - [GDT_ENTRY_PNPBIOS_CS16] = { 0x, 0x9a00 },/* 16-bit code */ > - [GDT_ENTRY_PNPBIOS_DS] = { 0x, 0x9200 }, /* 16-bit data */ > - [GDT_ENTRY_PNPBIOS_TS1] = { 0x, 0x9200 },/* 16-bit data */ > - [GDT_ENTRY_PNPBIOS_TS2] = { 0x, 0x9200 },/* 16-bit data */ > + [GDT_ENTRY_PNPBIOS_CS32] = {{{ 0x, 0x00409a00 }}},/* 32-bit > code */ > + [GDT_ENTRY_PNPBIOS_CS16] = {{{ 0x, 0x9a00 }}},/* 16-bit > code */ > + [GDT_ENTRY_PNPBIOS_DS] = {{{ 0x, 0x9200 }}}, /* 16-bit data > */ > + [GDT_ENTRY_PNPBIOS_TS1] = {{{ 0x, 0x9200 }}},/* 16-bit data > */ > + [GDT_ENTRY_PNPBIOS_TS2] = {{{ 0x, 0x9200 }}},/* 16-bit data > */ > /* >* The APM segments have byte granularity and their bases >* are set at run time. All have 64k limits. >*/ > - [GDT_ENTRY_APMBIOS_BASE] = { 0x, 0x00409a00 },/* 32-bit code */ > + [GDT_ENTRY_APMBIOS_BASE] = {{{ 0x, 0x00409a00 }}},/* 32-bit > code */ > /* 16-bit code */ > - [GDT_ENTRY_APMBIOS_BASE+1] = { 0x, 0x9a00 }, > - [GDT_ENTRY_APMBIOS_BASE+2] = { 0x, 0x00409200 }, /* data */ > + [GDT_ENTRY_APMBIOS_BASE+1] = {{{ 0x, 0x9a00 }}}, > + [GDT_ENTRY_APMBIOS_BASE+2] = {{{ 0x, 0x00409200 }}}, /* data */ > > - [GDT_ENTRY_ESPFIX_SS] = { 0x, 0x00c09200 }, > - [GDT_ENTRY_PERCPU] = { 0x, 0x }, > + [GDT_ENTRY_ESPFIX_SS] = {{{ 0x, 0x00c09200 }}}, > + [GDT_ENTRY_PERCPU] = {{{ 0x, 0x }}}, > } }; > EXPORT_PER_CPU_SYMBOL_GPL(gdt_page); > > diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c > index 6724840..9e99cb7 100644 > --- a/arch/x86/kernel/process_64.c > +++ b/arch/x86/kernel/process_64.c > @@ -437,7 +437,7 @@ static inline void set_32bit_tls(struct task_struct *t, > int tls, u32 addr) > .limit_in_pages = 1, > .useable = 1, > }; > - struct n_desc_struct *desc = (void *)t->thread.tls_array; > + struct desc_struct *d
Re: [PATCH 1/19] unify desc_struct
On Dec 6, 2007 5:24 PM, Jeremy Fitzhardinge <[EMAIL PROTECTED]> wrote: > > Glauber de Oliveira Costa wrote: > > This patch aims to make the access of struct desc_struct variables > > equal across architectures. In this patch, I unify the i386 and x86_64 > > versions under an anonymous union, keeping the way they are accessed > > untouched (a and b for 32-bit code, individual bit-fields for 64-bit). > > > > This solution is not beautiful, but will allow us to integrate common > > code that differed by the way descriptors were used. This is to be viewed > > incrementally. There's simply too much code to be fixed at once. > > > > In the future, goal is to set up in a single way of acessing > > the desc_struct fields. > > > > Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]> > > --- > > arch/x86/kernel/apm_32.c |2 +- > > arch/x86/kernel/cpu/common.c | 28 ++-- > > arch/x86/kernel/process_64.c |2 +- > > arch/x86/kernel/traps_32.c |2 +- > > include/asm-x86/desc_defs.h| 28 > > include/asm-x86/processor_32.h |5 + > > 6 files changed, 38 insertions(+), 29 deletions(-) > > > > diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c > > index 8cd9778..b8b9339 100644 > > --- a/arch/x86/kernel/apm_32.c > > +++ b/arch/x86/kernel/apm_32.c > > @@ -405,7 +405,7 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue); > > static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); > > static struct apm_user * user_list; > > static DEFINE_SPINLOCK(user_list_lock); > > -static const struct desc_struct bad_bios_desc = { 0, 0x00409200 }; > > +static const struct desc_struct bad_bios_desc = {{{ 0, 0x00409200 }}}; > > > > static const chardriver_version[] = "1.16ac";/* no spaces > > */ > > > > diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c > > index 235cd61..0fe1c1d 100644 > > --- a/arch/x86/kernel/cpu/common.c > > +++ b/arch/x86/kernel/cpu/common.c > > @@ -22,31 +22,31 @@ > > #include "cpu.h" > > > > DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = { > > - [GDT_ENTRY_KERNEL_CS] = { 0x, 0x00cf9a00 }, > > - [GDT_ENTRY_KERNEL_DS] = { 0x, 0x00cf9200 }, > > - [GDT_ENTRY_DEFAULT_USER_CS] = { 0x, 0x00cffa00 }, > > - [GDT_ENTRY_DEFAULT_USER_DS] = { 0x, 0x00cff200 }, > > + [GDT_ENTRY_KERNEL_CS] = {{{ 0x, 0x00cf9a00 }}}, > > + [GDT_ENTRY_KERNEL_DS] = {{{ 0x, 0x00cf9200 }}}, > > + [GDT_ENTRY_DEFAULT_USER_CS] = {{{ 0x, 0x00cffa00 }}}, > > + [GDT_ENTRY_DEFAULT_USER_DS] = {{{ 0x, 0x00cff200 }}}, > > > > I don't suppose there's some way to make all this more symbolic? There may be, but it's not the problem I'm trying to address in this series. It's probably not too hard to come up with a macro that receives the relevant parts of the descriptors and create the initializers. but it's deferred work. > > > > /* > >* Segments used for calling PnP BIOS have byte granularity. > >* They code segments and data segments have fixed 64k limits, > >* the transfer segment sizes are set at run time. > >*/ > > - [GDT_ENTRY_PNPBIOS_CS32] = { 0x, 0x00409a00 },/* 32-bit code > > */ > > - [GDT_ENTRY_PNPBIOS_CS16] = { 0x, 0x9a00 },/* 16-bit code > > */ > > - [GDT_ENTRY_PNPBIOS_DS] = { 0x, 0x9200 }, /* 16-bit data */ > > - [GDT_ENTRY_PNPBIOS_TS1] = { 0x, 0x9200 },/* 16-bit data */ > > - [GDT_ENTRY_PNPBIOS_TS2] = { 0x, 0x9200 },/* 16-bit data */ > > + [GDT_ENTRY_PNPBIOS_CS32] = {{{ 0x, 0x00409a00 }}},/* 32-bit > > code */ > > + [GDT_ENTRY_PNPBIOS_CS16] = {{{ 0x, 0x9a00 }}},/* 16-bit > > code */ > > + [GDT_ENTRY_PNPBIOS_DS] = {{{ 0x, 0x9200 }}}, /* 16-bit > > data */ > > + [GDT_ENTRY_PNPBIOS_TS1] = {{{ 0x, 0x9200 }}},/* 16-bit > > data */ > > + [GDT_ENTRY_PNPBIOS_TS2] = {{{ 0x, 0x9200 }}},/* 16-bit > > data */ > > /* > >* The APM segments have byte granularity and their bases > >* are set at run time. All have 64k limits. > >*/ > > - [GDT_ENTRY_APMBIOS_BASE] = { 0x, 0x00409a00 },/* 32-bit code > > */ > > + [GDT_ENTRY_APMBIOS_BASE] = {{{ 0x, 0x00409a00 }}},/* 32-bit > > code */ > > /* 16-bit code */ > > - [GDT_ENTRY_APMBIOS_BASE+1] = { 0x, 0x9a00 }, > > - [GDT_ENTRY_APMBIOS_BASE+2] = { 0x, 0x00409200 }, /* data */ > > + [GDT_ENTRY_APMBIOS_BASE+1] = {{{ 0x, 0x9a00 }}}, > > + [GDT_ENTRY_APMBIOS_BASE+2] = {{{ 0x, 0x00409200 }}}, /* data > > */ > > > > - [GDT_ENTRY_ESPFIX_SS] = { 0x, 0x00c09200 }, > > - [GDT_ENTRY_PERCPU] = { 0x, 0x }, > > + [GDT_ENTRY_ESPFIX_SS] = {{{ 0x, 0x00c09200 }}}, > > + [GDT_ENTRY_PERCPU] = {{{ 0x, 0x }}
Re: [PATCH 1/19] unify desc_struct
> +/* > + * FIXME: Acessing the desc_struct through its fields is more elegant, > + * and should be the one valid thing to do. However, a lot of open code > + * still touches the a and b acessors, and doing this allow us to do it > + * incrementally. We keep the signature as a struct, rather than an union, > + * so we can get rid of it transparently in the future -- glommer > + */ > +#define raw_desc_struct struct { unsigned int a, b; } > +#define detailed_desc_struct \ > + struct { \ > + u16 limit0; \ > + u16 base0; \ > + unsigned base1 : 8, type : 4, s : 1, dpl : 2, p : 1;\ > + unsigned limit : 4, avl : 1, l : 1, d : 1, g : 1, base2 :8;\ > + } The standard clean way to do this is with a anonymous union. -Andi ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/virtualization
Re: [PATCH 1/9] remove volatile keyword from clflush.
Glauber de Oliveira Costa wrote: > the p parameter is an explicit memory reference, and is > enough to prevent gcc to being nasty here. The volatile > seems completely not needed. > The usual reason for these types of "volatiles" is to make type checking happier, since "volatile void *" is compatible with any argument you might pass. IOW, if you pass a plain "char *" then the compiler will promote it to "volatile char *" and not complain, and passing an already volatile pointer will be OK too. The volatile isn't there to modify the generated code in any way. J ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/virtualization
Re: [PATCH 1/19] unify desc_struct
On Dec 6, 2007 6:54 PM, Andi Kleen <[EMAIL PROTECTED]> wrote: > > > +/* > > + * FIXME: Acessing the desc_struct through its fields is more elegant, > > + * and should be the one valid thing to do. However, a lot of open code > > + * still touches the a and b acessors, and doing this allow us to do it > > + * incrementally. We keep the signature as a struct, rather than an union, > > + * so we can get rid of it transparently in the future -- glommer > > + */ > > +#define raw_desc_struct struct { unsigned int a, b; } > > +#define detailed_desc_struct \ > > + struct { \ > > + u16 limit0; \ > > + u16 base0; \ > > + unsigned base1 : 8, type : 4, s : 1, dpl : 2, p : 1;\ > > + unsigned limit : 4, avl : 1, l : 1, d : 1, g : 1, base2 :8;\ > > + } > > The standard clean way to do this is with a anonymous union. It is an anonymous union. However: * It's an union of structs * I wished to keep the toplevel type as a struct The alternative would be to write: struct desc_struct { union { struct { unsigned int a, b; }; struct { u16 limit0; u16 base0; unsigned base1 : 8, type : 4, s : 1, dpl : 2, p : 1; unsigned limit : 4, avl : 1, l : 1, d : 1, g : 1, base2 :8; }; }; }; Which is fine, it's all the same in the end. Just with more shift rights, and more visual pollution. -- Glauber de Oliveira Costa. "Free as in Freedom" http://glommer.net "The less confident you are, the more serious you have to act." ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/virtualization
Re: [PATCH 1/19] unify desc_struct
Glauber de Oliveira Costa wrote: > On Dec 6, 2007 6:54 PM, Andi Kleen <[EMAIL PROTECTED]> wrote: > >>> +/* >>> + * FIXME: Acessing the desc_struct through its fields is more elegant, >>> + * and should be the one valid thing to do. However, a lot of open code >>> + * still touches the a and b acessors, and doing this allow us to do it >>> + * incrementally. We keep the signature as a struct, rather than an union, >>> + * so we can get rid of it transparently in the future -- glommer >>> + */ >>> +#define raw_desc_struct struct { unsigned int a, b; } >>> +#define detailed_desc_struct \ >>> + struct { \ >>> + u16 limit0; \ >>> + u16 base0; \ >>> + unsigned base1 : 8, type : 4, s : 1, dpl : 2, p : 1;\ >>> + unsigned limit : 4, avl : 1, l : 1, d : 1, g : 1, base2 :8;\ >>> + } >>> >> The standard clean way to do this is with a anonymous union. >> > It is an anonymous union. > > However: > > * It's an union of structs > * I wished to keep the toplevel type as a struct > The alternative would be to write: > > struct desc_struct { > union { > struct { unsigned int a, b; }; > struct { >u16 limit0; >u16 base0; >unsigned base1 : 8, type : 4, s : 1, dpl : 2, p : 1; >unsigned limit : 4, avl : 1, l : 1, d : 1, g : 1, base2 :8; > }; > }; > }; > > Which is fine, it's all the same in the end. Just with more shift > rights, and more visual pollution. > No, that's much clearer. It's a pity that the anonymous struct/union syntax isn't general enough to allow: struct desc_packed { u16 limit0; u16 base0; unsigned base1 : 8, type : 4, s : 1, dpl : 2, p : 1; unsigned limit : 4, avl : 1, l : 1, d : 1, g : 1, base2 :8; }; struct desc { struct desc_packed; }; J ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/virtualization
Re: [Xen-devel] Re: Next steps with pv_ops for Xen
Derek Murray wrote: > Keir Fraser wrote: >> You'd need to track pte->grant_handle mappings somewhere, but it could >> certainly be done this way, yes. > > At the moment, blktap and gntdev provide struct pages to > get_user_pages by smuggling them in the vm_private_data field of the > relevant vm_area_struct. Could we use this field to get the handles to > ptep_get_and_clear_full as well? Yes. Given the mm and a vaddr passed to ptep_get_and_clear, find_vma() will return the vma_struct. If we assert that anyone who sets the "I'm foreign" bit in a pte has a standard format for the vm_private_data field, then we can stash a callback pointer there and make the appropriate callback. > Only downside that I can see is that we would need to find the vma for > each PTE that needs to be cleared this way (since we don't get this > passed to ptep_get_and_clear_full), but this is mitigated by (i) it > only happening in the erroneous, unclean-shutdown case, and (ii) > getting a hit in the mm->mmap_cache for consecutive runs of mapped > grants. Yes. find_vma is fairly hot, since its used on every fault, so it should be reasonably fast. And it doesn't sound like our case is particularly performance critical. J ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/virtualization